I think i'm very close but i cant seem to fix my issues. I need a function that takes a 10-digit input from user (me) and sets each letter to is numeric value.
Example: user inputs (941-019-abcd) the function should then take this and return (941-019-2223)
Anything that i should be doing differently please feel free to elaborate
Here is what i have thus far:
def main(phone_number):
digits = ["2", "3", "4", "5", "6", "7", "8", "9"]
numeric_phone=" "
ch = digits[i]
for ch in phone_number:
if ch.isalpha():
elif ch== 'A' or 'b' or 'c':
i=2
elif ch== 'd' or 'e' or 'f':
i=3
elif ch== 'g' or 'h' or 'i':
i=4
elif ch=='j' or 'k' or 'l':
i=5
elif ch== 'm' or 'n' or 'o':
i=6
elif ch== 'p' or 'r' or 's':
i=7
elif ch=='t' or 'u' or 'v':
i=8
else:
index=9
numeric_phone= numeric_phone+ch
print (numeric_phone)
phone_number = '941-019-aBcD'
# A map of what letters to convert to what digits.
# I've added q and wxy & z.
digit_map = {
'abc': 2,
'def': 3,
'ghi': 4,
'jkl': 5,
'mno': 6,
'pqrs': 7,
'tuv': 8,
'wxyz': 9
}
# Break this out into one letter per entry in the dictionary
# to make the actual work of looking it up much simpler.
# This is a good example of taking the data a person might
# have to deal with and making it easier for a machine to
# work with it.
real_map = {}
for letters, number in digit_map.iteritems():
for letter in letters:
real_map[letter] = number
# Empty new variable.
numeric_phone = ''
# For each character try to 'get' the number from the 'real_map'
# and if that key doesn't exist, just use the value in the
# original string. This lets existing numbers and other
# characters like - and () pass though without any special
# handling.
# Note the call to `lower` that converts all our letters to
# lowercase. This will have no effect on the existing numbers
# or other speacial symbols.
for ch in phone_number.lower():
numeric_phone += str(real_map.get(ch, ch))
print(numeric_phone)
def main(phone_number):
digits = ["2", "3", "4", "5", "6", "7", "8", "9"]
numeric_phone=" "
for ch in phone_number:
if ch.isalpha():
if ord(ch) >= 97:
ch = +2 (ord(ch)-97)/3
else:
ch = +2 (ord(ch)-65)/3
numeric_phone= numeric_phone+ch
print (numeric_phone)
Use ord() to convert chars to their ASCII values and then get the right number.
You can create a formula to ascertain the correct number to add depending on the letter:
math.ceil((index(char)+1)/3)
Use a list and depending on which character it is, append a number to the list. At the end, return the list, but joined so that it is a string:
def numerify(inp):
from math import ceil as _ceil
from string import lowercase as _lowercase
chars = []
for char in inp:
if char.isalpha():
num = _ceil((_lowercase.index(char)+1)/float(3))
chars.append(str(int(num+1)))
else:
chars.append(char)
return ''.join(chars)
>>> from numerify import numerify
>>> numerify('1')
'1'
>>> numerify('941-019-abcd')
'941-019-2223'
>>>
I think it's easiest to pre-calculate the number character for each letter.
# len(keys) == 26 so that the index of a letter
# maps to its phone key
keys = ['2']*3 + ['3']*3 \
+ ['4']*3 + ['5']*3 + ['6']*3 \
+ ['7']*4 + ['8']*3 + ['9']*4
def letter_to_key(x):
if x.isalpha():
# calculate the 'index' of a letter.
# a=0, b=1, ..., z=25
index = ord(x.lower()) - ord('a')
return keys[index]
# If it's not a letter don't change it.
return x
def translate_digits(phone_num):
return ''.join(map(letter_to_key, phone_num))
print(translate_digits('941-019-abcd'))
Related
I'm having trouble to make an integer into roman numeral for having an ouptut of integer with square brackets (I'm pretty sure it's a list, but what I want is to have an integer) and I couldn't find solution why I'm having 'None' on 'rom' value.
I'm using python3.
roman.py
#!/usr/bin/env python3
import sys
def numToRom(number):
rom = ["", "I", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
if number in range(0, 9):
result = rom[number]
return result
num = sys.argv[1:]
rom = numToRom(num)
print(num, " is ", rom)
$ ./roman.py 2
Old output:
['2'] is None
Desired output:
2 is II
Your problem stems from the fact that you're passing a list with a character inside to your function. And that function expects an integer (if number in range(0, 9)), so you need to convert it to the right integer.
import sys
def numToRom(number):
if type(number) is list: # If you know your number might be a list with only one str(value)
number = int(number[0])
rom = ["", "I", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
if number in range(0, 9):
result = rom[number]
return result
That will work specifically for your use case, if number is of the form ['{some digit}]. If you want to get fancier, you could use recursion to return a list with the roman number of each number in a list, like so:
def numToRom(number):
if type(number) is list:
rom = []
for value in number:
rom.append(numToRom(int(value)))
return rom
else:
rom = ["", "I", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
if number in range(0, 9):
result = rom[number]
return result
>>> num = ['2', '3', '5']
>>> numToRom(num)
['2', '3', '5'] is ['III', 'IV', 'VI']
Note that this function works even if the values inside the input list are not characters, but normal integers.
>>> num = [2, 3, 5]
>>> rom = numToRom(num)
[2, 3, 5] is ['III', 'IV', 'VI']
pip install roman
import roman
print(roman.toRoman(int(input())))
For this exercise I need to count the 'number of edges' in the word 'AARDGASRESERVES' (Dutch), using a for loop and a dictionary. I already have the following code, but this doesn't give me the required output (which should be 31). I believe the middle part isn't quite right yet.
# dictionary of number of edges per letter
edges = {"A": 2, "R": 2, "D": 0,"G": 2,"S": 2,"R": 2,"E": 3, "V": 2}
word = "AARDGASRESERVES"
# loop over the letters in the word and count the number of edges
total_edges = 0
for key in edges:
if edges[key] == word:
total_edges += [value]
# print the total
print("Total number of edges:", total_edges)
I tried if edges[key] in word: too but that results in an error. I'm still new to Python so I might have written something that isn't even possible.
A simple way to do what you want is:
edges = {"A": 2, "R": 2, "D": 0,"G": 2,"S": 2,"R": 2,"E": 3, "V": 2}
word = "AARDGASRESERVES"
total_edges = sum([edges[c] for c in word])
# print the total
print("Total number of edges:", total_edges) # Output: 31
However, I advise you to carefully examine your code to understand why it doesn't work. For example here:
...
if edges[key] == word:
...
you compare if a number (value of your dict) is equal to the whole word, which is an irrational if-statement.
From what I understand about the purpose of this code. It should go about this
# dictionary of number of edges per letter
edges = {"A": 2, "R": 2, "D": 0,"G": 2,"S": 2,"R": 2,"E": 3, "V": 2}
word = "AARDGASRESERVES"
# loop over the letters in the word and count the number of edges
total_edges = 0
for key in word:
total_edges += edges[key]
# print the total
print("Total number of edges:", total_edges)
What you want to do is to get a letter from the word and get the specific element associated with that key and add it.
I have been developing an application to convert decimal numbers into hexadecimal ones. Whole software is done but the problem in i have to convert digits like "11", "12" into "B", "C".
For this, i made a dictionary but i don't know how to apply that into my software.
hexadecimal_value = {1: "1",
2: "2",
3: "3",
4: "4",
5: "5",
6: "6",
7: "7",
8: "8",
9: "9",
10: "A",
11: "B",
12: "C",
14: "D",
15: "E"}
while 1:
print("we are about to convert decimal numbers into hexadecimal
numbers.")
decision = input("type 'stop' to stop, type anything to Continue")
if decision != "stop":
try:
h = int(input("Enter an integer\n>"))
except ValueError:
print("This is not an integer, silly!")
h = int(input("Enter an integer\n>"))
lup = 1
hexadecimal_digits = []
while lup == 1:
hexa = h%16
hexadecimal_digits.append(str(hexa))
h = int(h/16)
if h<1:
lup = 2
def Reverse_hexa(hexadecimal_digits):
hexadecimal_digits.reverse()
return hexadecimal_digits
print("-".join(Reverse_hexa(hexadecimal_digits)))
if decision == "stop":
input("close:")
break
First of all because your dictionary uses int as keys, don't save the digits as strings, meaning: change the appending line to:
hexadecimal_digits.append(hexa)
Now you just need to translate the digits to the symbols using your dictionary:
hexadecimal_symbols = [hexadecimal_value[digit] for digit in hexadecimal_digits]
And now print those:
print("-".join(Reverse_hexa(hexadecimal_symbols)))
Alternatively, just save the translated symbols from the start:
hexadecimal_digits.append(hexadecimal_value[hexa])
And the rest stays the same
Just the following
hexadecimal_value[10]
Alternatively you don't need to declare a dictionary:
hex(10)
>>>'0xa'
and if you want just the capital letter:
hex(10).upper()[2:]
So the input is word and I want to know if a or b comes first.
I can use a_index = word.find('a') and compare this to b_index = word.find('b') and if a is first, a is first is returned. But if b isn't in word, .find() will return -1, so simply comparing b_index < a_index would return b is first. This could be accomplished by adding more if-statements, but is there a cleaner way?
function description:
input: word, [list of characters]
output: the character in the list that appears first in the word
Example: first_instance("butterfly", ['a', 'u', 'e'] returns u
You can create a function that takes word and a list of chars - convert those chars into a set for fast lookup and looping over word take the first letter found, eg:
# Chars can be any iterable whose elements are characters
def first_of(word, chars):
# Remove duplicates and get O(1) lookup time
lookup = set(chars)
# Use optional default argument to next to return `None` if no matches found
return next((ch for ch in word if ch in lookup), None)
Example:
>>> first_of('bob', 'a')
>>> first_of('bob', 'b')
'b'
>>> first_of('abob', 'ab')
'a'
>>> first_of("butterfly", ['a', 'u', 'e'])
'u'
This way you're only ever iterating over word once and short-circuit on the first letter found instead of running multiple finds, storing the results and then computing the lowest index.
Make a list without the missing chars and then sort it by positions.
def first_found(word, chars):
places = [x for x in ((word.find(c), c) for c in chars) if x[0] != -1]
if not places:
# no char was found
return None
else:
return min(places)[1]
In any case you need to check the type of the input:
if isinstance(your_input, str):
a_index = your_input.find('a')
b_index = your_input.find('b')
# Compare the a and b indexes
elif isinstance(your_input, list):
a_index = your_input.index('a')
b_index = your_input.index('b')
# Compare the a and b indexes
else:
# Do something else
EDIT:
def first_instance(word, lst):
indexes = {}
for c in lst:
if c not in indexes:
indexes[c] = word.find(c)
else:
pass
return min(indexes, key=indexes.get)
It will return the character from list lst which comes first in the word.
If you need to return the index of this letter then replace the return statement with this:
return min_value = indexes[min(indexes, key=indexes.get)]
str = 'strings'
new_D = {'r': 1, 's': 1, 't': 1, 'r' : 3, 'i' : 4 }
How can I get each letter in the string assigned to the value in the dictionary by match 'letter-key' and then summarize the values?
Thanks
s = 'strings' #Don't name a variable str, that shadows the builtin str
new_D = {'r': 1, 's': 1, 't': 1, 'r' : 3, 'i' : 4 }
sum_of_chars = sum([newD.get(k,0) for k in s]) #assuming 0 as default for "not in dictionary"
This takes advantage of the fact that:
Strings are iterable. for i in s: print(i) would print each character, seperately.
Dictionaries have a .get(key[,default]) 1 that can take an option argument for "return this value if the key doesn't exist.
I'm using the built-in sum on a list comprehension for the sake of brevity. Brevity can both be a virtue or a vice, but, hey, one list comp is still usually pretty readable after you know what they are.
string = 'strings'
new_D = {'r': 1, 's': 1, 't': 1, 'r' : 3, 'i' : 4 }
sum_of_chars = 0
for character in string:
if character in new_D:
sum_of_chars += new_D[character]
else:
sum_of_chars += 1 # Default?
print(sum_of_chars)
btw, you should not use the name str because it shadows the builtin str and there's a mistake in your dictionary. It contains the entry r two times which doesn't make sense.