How do i replace Numbers with letters using dictionaries in python - python-3.x

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:]

Related

How to convert an integer into a roman numeral?

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())))

How do I count the amount of 'edges' in a word in Python, using a dictionary?

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.

int() or dict for single digit string to int conversions

I am trying to convert a single-digit string to an integer. For example, if I have "2" <-- str I want to change it to 2 <-- int. I know that the int() function in python can do this for me, but I want to know if I made a dictionary like this,
strToNumDict{
"0": 0
"1": 1
"2": 2
"3": 3
"4": 4
"5": 5
"6": 6
"7": 7
"8": 8
"9": 9
}
Would using this dictionary to convert single digits be faster than the int() function? And if one is faster, is it fast enough to make a difference on which one I should use?
Let's do a quick timeit benchmark. We generate at random one digit and will try to convert it to integer (x 1_000_000 times):
strToNumDict = {
"0": 0,
"1": 1,
"2": 2,
"3": 3,
"4": 4,
"5": 5,
"6": 6,
"7": 7,
"8": 8,
"9": 9
}
def convert1(s):
return strToNumDict[s]
def convert2(s):
return int(s)
import timeit
import random
digits = list('0123456789')
t1 = timeit.timeit(lambda: convert1(random.choice(digits)), number=1_000_000)
t2 = timeit.timeit(lambda: convert2(random.choice(digits)), number=1_000_000)
print(t1)
print(t2)
Prints on my machine (AMD 2400G, Python 3.6.8):
0.6220340259897057
0.727682675991673
So dict-based version is marginally faster in this case. Personally, not worth the effort. With int() you get conversion from negative numbers, more than number 9 etc. And it's more readable.

Create dictionary using dictionary comprehension and assign multiple values to each key

Need to turn a list of words into a dictionary using dictionary comprehension. The keys would be the length of the words, and the values are the set of words from the original list whose length are that of its keys.
I am able to create a regular function for this purpose, but unable to do so in one dictionary comprehension.
As an example, I created a list of names of different lengths.
word_list = ["Amber", "Steven", "Carol", "Tuan", "Michael", "sam", "Wayne", "Anna", "Kay", "Jim", "D", "Belinda", "CharlieYu"]
def word_lengths_notit(input_list):
wl_dict = {}
for word in input_list:
if len(word) not in wl_dict.keys():
wl_dict[len(word)]=[] #create key that is the length of the word
wl_dict[len(word)].append(word.lower())
else:
if word.lower() not in wl_dict[len(word)]:
wl_dict[len(word)].append(word.lower())
print(wl_dict)
word_lengths_notit(word_list)
My output:
{5: ['amber', 'carol', 'wayne'], 6: ['steven'], 4: ['tuan', 'anna'], 7: ['michael', 'belinda'], 3: ['sam', 'kay', 'jim'], 1: ['d'], 9: ['charlieyu']}
This might not be the cleanest/most efficient code (I just started learning two weeks ago), but the output is correct.
Below, I tried dictionary comprehension, but it keeps overwriting my previous values instead of appending to it. I'm thinking I might have to use a list comprehension to collect all the words of the same length, but I'm not sure how (or if I can) create multiple lists of words of different lengths in one list comprehension.
def word_lengths(input_list):
wl_dict = {len(word):word for word in input_list]
print(wl_dict)
word_lengths(word_list)
Output: {5: 'Wayne', 6: 'Steven', 4: 'Anna', 7: 'Belinda', 3: 'Jim', 1: 'D', 9: 'CharlieYu'}
So you're looking to make a dict where each key is an integer and each value is a list, and you're looking to do it via dict comprehension. My advice for doing it in vanilla python is to simply nest a list comprehension (to filter words by name) inside of the dict comprehension:
word_list = ["Amber", "Steven", "Carol", "Tuan", "Michael", "sam", "Wayne", "Anna", "Kay", "Jim", "D", "Belinda", "CharlieYu"]
word_lengths = {n: [word for word in word_list if len(word) == n]
for n in range(10)}
If you want to avoid cases like 0: [], you could throw a ternary if clause on the end there to filter them out (e.g. if len([word for word in word_list if len(word) == n])). Alternatively, you could simply make a set of all the unique lengths that are present and iterate over that:
word_list = ["Amber", "Steven", "Carol", "Tuan", "Michael", "sam", "Wayne", "Anna", "Kay", "Jim", "D", "Belinda", "CharlieYu"]
possible_lengths = set([len(word) for word in word_list])
word_lengths = {n: [word for word in word_list if len(word) == n]
for n in possible_lengths}
The above code outputs the following on my machine:
>>> print(word_lengths)
{1: ['D'], 3: ['sam', 'Kay', 'Jim'], 4: ['Tuan', 'Anna'], 5: ['Amber', 'Carol', 'Wayne'], 6: ['Steven'], 7: ['Michael', 'Belinda'], 9: ['CharlieYu']}
Note that this solution is O(n^2) complexity. Look into the collections library, which almost certainly has some clever things in it you can do to get a faster solution.

converting individual digits to string

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'))

Resources