I am trying to print the value of a key when a float string is entered.
Here's my code:
number_dict = {1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five', 6: 'Six', 7: 'Seven', 8: 'Eight', 9: 'Nine', 0: 'Zero', '-': 'Negative', '.': 'Point'}
number = input('Enter a number: ')
print(f'As Text:', end = ' ')
for char in number:
for key, value in number_dict.items():
if char == key:
print(value, end = ' ')
elif int(char) == key:
print(value, end = ' ')
What am I doing wrong? Why aren't the values associated with the '.' and '-' keys printing? They should be accessed in the elif condition.
There is already a try
and except
block to account for the ValueError. I just didn't want to post the code in its entirety, but I am aware of the error and already accounted for.
Thank you for your help in advance!!
This loop will never run more than once because it ends with a break
:
for key, value in number_dict.items():
if char == key:
print(number_dict[key], end = ' ')
elif int(char) == key:
print(number_dict[key], end = ' ')
break
The break
doesn’t make any sense. Once you remove that, you get to the main problem, which is that if int(char)
throws an exception (like it does when you pass it the "-"
or "."
characters), you’re catching the exception outside the loop. This also means that the loop doesn’t run for the remaining items of the dictionary.
To understand what’s happening better, using a debugger, step through the loop with char = "-"
.
Now, you can fix this by catching the exception inside the loop:
for key, value in number_dict.items():
if char == key:
print(number_dict[key], end = ' ')
else:
try:
if int(char) == key:
print(number_dict[key], end = ' ')
except ValueError:
pass # do nothing
But none of this is how you should use a dictionary. Dictionaries are for looking things up directly by key; by iterating over it to check every key, you’re defeating the point. To clean up your code, I would recommend starting by making your dict keys homogeneous, i.e. all strings instead of a mix of strings and integers:
number_dict = {'1': 'One', '2': 'Two', '3': 'Three', '4': 'Four', '5': 'Five', '6': 'Six', '7': 'Seven', '8': 'Eight', '9': 'Nine', '0': 'Zero', '-': 'Negative', '.': 'Point'}
Now you can get the value corresponding to any character, regardless of whether it’s a digit, with number_dict[char]
.
It’s also good practice to avoid throwing and catching exceptions when possible, and when you do have to, to make the try
cover as little as possible – otherwise, you risk catching things you didn’t expect and mishandling them.
while True:
number = input('Enter a number: ')
# can check this ahead of time! helps limit the `try` responsibilities
if ',' in number:
print('Please try again without entering commas.')
continue
# much smaller `try`!
try:
float(number)
except ValueError:
print(f'"{number}" is not a valid number. Please try again.')
continue
print(f'As Text:', end = ' ')
for char in number:
print(number_dict[char], end = ' ')
Finally, note that float
accepts some things you didn’t account for, like constants "-inf"
/"inf"
/"nan"
, scientific notation "1e-1"
, and whitespace. You should use stricter validation, which also means not needing a try
at all (good!). Here’s an example of doing it with regular expressions:
import re
number_dict = {'1': 'One', '2': 'Two', '3': 'Three', '4': 'Four', '5': 'Five', '6': 'Six', '7': 'Seven', '8': 'Eight', '9': 'Nine', '0': 'Zero', '-': 'Negative', '.': 'Point'}
while True:
number = input("Enter a number: ")
if "," in number:
print("Please try again without entering commas.")
continue
if not re.fullmatch(r"-?(?!\.?\Z)[0-9]*(?:\.[0-9]*)?", number):
print(f"{number!r} is not a valid number. Please try again.")
continue
text = " ".join(number_dict[char] for char in number)
print(f"As Text: {text}")
but since you probably don’t know regular expressions yet, try writing a strict validation function as an exercise, with a loop and the str.isdigit
method you’ve already used. Consider questions like whether "1."
should print “One Point” or “One” or an error!