Alphabet to integers - python

I'm trying to create a programm in which a user inputs a string e.g 'roller' and the program converts the alphabet to numbers such as a=1, b=2, c=3 etc, and the calculate the sum of these values. But, if the program finds two same letters in a row then it doubles the sum. So far I have done this:
input = raw_input('Write Text: ')
input = input.lower()
output = []
sum=0
for character in input:
number = ord(character) - 96
sum=sum+number
output.append(number)
print sum
which calculates the sum of the characters and also appends the converted characters to a new array. So can anyone help me to double the sum if two letters appear in a row?

Store the previous character and compare it to the current character. If they're the same, double the value.
word = 'hello'
out = []
c_prev = None
for c in word:
value = ord(c) - ord('a')
if c == c_prev: # double if repeated character
value = value * 2
out.append(value)
c_prev = c # store for next comparison
print(sum(out))

Related

How to link elements from a string with numbers in Python?

I'd like to link elements from a string with numbers in Python.
Users need to give an input string (one word such as "world") and then the elements of that string (here the letters of the word "world") needs to be linked to numbers starting from 0.
Then, when you give another string as an input, the corresponding numbers need to be printed.
What I tried:
# input
string = str(input())
# loop to link numbers with string input
number = -1
for letter in string:
number += 1
Now I'd like to link the first letter of the input string with the number 0 and so on.
E.g.:
string = "world"
than "w" = 0, "o" = 1, "r" = 2, "l" = 3 and "d" = 4.
And then when you give another string such as "lord" I want to get the following output:
3124
Because "lord" --> "l" = 3, "o" = 1, "r" = 2 and "d" = 4
I don't know how I can save these numbers to their corresponding letter.
a = "world"
tracker = dict()
for index, value in enumerate(a):
tracker[value] = index
b = "lord"
result = ""
for str_char in b:
result += str(tracker[str_char])
print(result)
There is built-in data structure that can store key value pairs and it is called
dictionary
You can make it as such:
string = "world"
letters_numbers = {}
numerator = 0
for char in string:
if char not in letters_numbers:
letters_numbers[char] = numerator
numerator += 1
then you can get another string, such as lord:
string2 = "lord"
numbers = []
for char in string2:
numbers.append(str(letters_numbers[char]))
print("".join(numbers)) # prints 3124
This way you can use words that has same letter multiple times and still get correct results.

What this 1 stands for in following code?

def up_low(s):
u = sum(1 for i in s if i.isupper())
l = sum(1 for i in s if i.islower())
print(s)
print( "No. of Upper case characters : %s, \nNo. of Lower case characters : %s" % (u,l))
Lets look at one of the lines and explain each path of it.
u = sum(1 for i in s if i.isupper())
sum() - A function that sums the values in a given list
inside the sum there is a generator expression (PEP-289).
The generator expression is:
1 for i in s if i.isupper()
what it actually does is:
for each value in s: # which means, iterate over the characters
if value is uppercase character:
add an integer with the value 1 to the list
which means - count the number of uppercase characters in the given string.
Lets use it in an example:
s = "HeLlo WoRLD" # We have 6 uppercase characters here.
upper_case_count_list = [1 for i in s if i.isupper()] # Evaluates to: [1,1,1,1,1,1] - A 1 for every uppercase character in s.
sum(upper_case_count_list) # Sums the numbers in our list, which will sum up to 6

How to randomly change n characters in a string

I am wondering how to randomly change n characters in a string, e.g.
orig = 'hello'
mod = 'halle'
that I want to randomly select two positions (orig[1] and orig[4]) in the string, and replace the chars in the positions of the original string (hello) with randomly selected chars (a and e here), results in a new string halle.
import random
import string
orig='hello'
char1=random.choice(string.ascii_lowercase) #random character1
char2=random.choice(string.ascii_lowercase) #random character2
while char1 == char2: # #check if both char are equal
char2=random.choice(string.ascii_lowercase)
ran_pos1 = random.randint(0,len(orig)-1) #random index1
ran_pos2 = random.randint(0,len(orig)-1) #random index2
while ran_pos1 == ran_pos2: #check if both pos are equal
ran_pos2 = random.randint(0,len(orig)-1)
orig_list = list(orig)
orig_list[ran_pos1]=char1
orig_list[ran_pos2]=char2
mod = ''.join(orig_list)
print(mod)
If you just want to change the different characters at random index in a string the below function will help. This script will ask for the input string(i.e., word) and the total places/ indexes ((i.e.,)value or 'n' places) you need to change with random characters, and this will print the modified string as needed.
import random
import string
# Method to change N characters from a string with random characters.
def randomlyChangeNChar(word, value):
length = len(word)
word = list(word)
# This will select the two distinct index for us to replace
k = random.sample(range(0,length),value)
for index in k:
# This will replace the characters at the specified index with
# the generated characters
word[index] = random.choice(string.ascii_lowercase)
# Finally print the string in the modified format.
print("" . join(word))
# Get the string to be modified
string_to_modify = raw_input("Enter the string to be replaced...\n")
# get the number of places that needed to be randomly replaced
total_places = input("Enter the total places that needs to be modified...\n")
# Function to replace 'n' characters at random
randomlyChangeNChar(string_to_modify, total_places)
Output
Enter the string to be replaced...
Hello
Enter the total places that needs to be modified...
3
Hcado

Convert an integer into a string of its ascii values

Given a number number such that its digits are grouped into parts of length n (default value of n is 3) where each group represents some ascii value, I want to convert number into a string of those ascii characters. For example:
n number Output
==================================
3 70 F
3 65066066065 ABBA
4 65006600660065 ABBA
Note that there is no leading 0 in number, so the first ascii value will not necessarily be represented with n digits.
My current code looks like this:
def number_to_string(number, n=3):
number = str(number)
segment = []
while number:
segment.append(number[:n])
number = number[n:]
return str(''.join('{:0>{}}'.format(chr(segment), n) for segment in number))
Expected outputs:
number_to_string(70)
'F'
number_to_string(65066066065)
'ABBA'
number_to_string(65006600660065, n=4)
'ABBA'
My current code however returns an empty string. For example, instead of 'F' it returns ' '. Any reason why this is? Thank you!
P.S.:
I'm wanting to reverse the process of this question, i.e. turn an integer into a string based on the ascii values of each character (number) in the string. But reading that question is not a requirement to answer this one.
Try this:
import re
def number_to_string(num, n=3):
num_str = str(num)
if len(num_str) < n:
num_str = '0' * (n-len(num_str)) + num_str
elif len(num_str) % n != 0:
num_str = '0'*(n-len(num_str)%n) + num_str
print(num_str)
chars = re.findall('.'*n, num_str)
l = [chr(int(i)) for i in chars]
return ''.join(l)
First pad the given number (converted into string) with required number of zeros, so that it can be evenly split into equal number of characters each. Then using re split the string into segments of size n. Finally convert each chunk into character using chr, and then join them using join.
def numToStr(inp):
"""Take a number and make a sequence of bytes in a string"""
out=""
while inp!=0:
out=chr(inp & 255)+out
inp=inp>>8
print "num2string:", out
return out
does this help?
Is this what you want?
def num_to_string(num, leng):
string = ""
for i in range(0,len(str(num)),leng):
n = str(num)[i:i+2]
string += chr(int(n))
print string
Output:
>>> ================================ RESTART ================================
>>>
>>> num_to_string(650065006600,4)
AAB
>>> num_to_string(650650660,3)
AAB
>>> num_to_string(656566,2)
AAB
>>>
You can just append \x to number as this prints 'p':
print '\x70'

Why isn't this character-counter program not altering the list?

I'm writting a program to that counts the number of times each letter appears in a text.
I'm trying to convert that into a graph, by print out the bar graph line by line. Slowly adding the space above the letter when the countdown reaches the # of times it appears.
import string
n=input("Enter Text, I wish you luck:")
list1=[] #Empty List
list2=list(" "*26) #26 space list
for a in string.ascii_uppercase:#from a-z
n1=n.count(a) #counts letters
list1.append(n1) #appends numbers
m=max(list1) #finds most occuring letter
c=m+1
while c!=0:
c=c-1
if c==0:
print(string.ascii_uppercase)
break
for x in list1: #suppose to check every term in list1
if x >c: #x is greater than countdowner
k=list1.index(x) #find term number
list2[k]="*" #replace blank with "*"
elif x==c:
#if x is equal to countdowner
k=list1.index(x) #find term number
list2[k]="*" #replaces that term place in list2
print(''.join(list2))
The code only accepts uppercase letters, and right now it only add letters to the countdown list one at a time. So when count reaches one appearance, and 3 letters appear once, it will only print a * on top of one of those letter.
Sample input: HELLO STACKOVERFLOW
*
* *
* * *
ABCDEFGHIJKLMNOPQRSTUVWXYZ
The problem is that k=list1.index(x) can only find the first occurrence of x in list1. So you could put a loop here, using the extended form of index():
list1.index(x, start, end)
which only looks for an index that lies in the range(start, end)
The loop would have to contain a try: ... except block to handle the ValueError exception.
But there's another way to handle this.
#! /usr/bin/env python
from string import ascii_uppercase
def bargraph(data):
data = data.upper()
print(data)
print(''.join(sorted(list(data))))
#Count number of occurences of each letter in data
counts = [data.count(a) for a in ascii_uppercase]
#A single row of the bar graph, initially full of spaces
row = list(" " * 26)
for c in range(max(counts), 0, -1):
for k in range(26):
if counts[k] == c:
row[k] = "*"
print(''.join(row))
print(ascii_uppercase)
def main():
#data = input("Enter Text, I wish you luck:")
data = "This is a test string for the bar graph function"
bargraph(data)
if __name__ == '__main__':
main()
My version of your program converts the string to upper case, prints it, and then sorts it and prints it again to make it easier to check that the bar printing section is doing what it's supposed to do.
It uses a list comprehension to build the list of character counts. It can be made even shorter by using a list comprehension to construct row.
def bargraph(data):
data = data.upper()
print(data)
print(''.join(sorted(list(data))))
#Count number of occurences of each letter in data
counts = [data.count(a) for a in ascii_uppercase]
for c in range(max(counts), 0, -1):
print(''.join(["*" if counts[k] >= c else " " for k in range(26)]))
print(ascii_uppercase)
output for both versions :)
THIS IS A TEST STRING FOR THE BAR GRAPH FUNCTION
AAABCEEFFGGHHHIIIINNNOOPRRRRSSSSTTTTTTU
*
*
* ***
* ** * ***
* ***** ** ***
*** ***** *** ****
ABCDEFGHIJKLMNOPQRSTUVWXYZ
edit
I should mention that there's a more efficient way to count the occurrences of each letter. The current method has to scan through the data string 26 times, once for each letter. That's a bit inefficient, especially if there's a lot of data to process. So it's better to just scan through the data once, and accumulate the counts. One way to do that is to use a dict.
#! /usr/bin/env python
from string import ascii_uppercase
def bargraph(data):
data = data.upper()
print(data)
print(''.join(sorted(list(data))))
#Count number of occurences of each letter in data
counts = dict(zip(ascii_uppercase, 26*(0,)))
for c in data:
if c.isupper():
counts[c] += 1
highcount = max(counts.values())
for c in range(highcount, 0, -1):
print(''.join([" *"[counts[k] >= c] for k in ascii_uppercase]))
print(ascii_uppercase)
def main():
#data = input("Enter Text, I wish you luck:")
data = "This is a test string for the bar graph function"
bargraph(data)
if __name__ == '__main__':
main()
I've also used a little trick to make the row printing step even more compact.
counts[k] >= c will either be False or True.
But Python lets us use boolean values as if they were int values, with False == 0 and True == 1.
Thus " *"[counts[k] >= c] results in " " if counts[k] >= c is False, and "*" if it's True.

Categories

Resources