Try loop raises KeyError - python

When I use a try/except, I get a KeyError, but when I don't use try it works as intended. I'm sure this is a simple fix but I've been banging my head on this for over an hour by now, any help is appreciated. Here is the code, forgive the simplicity!
def return_book():
"""Return a book to the library"""
print("To return the book, you will need the ISBN")
isbn = str(input("Please enter the book's ISBN: "))
amount = input("How many books are you returning? ")
try:
isbn = int(isbn)
except ValueError:
print()
input("That is not a number, press enter to try again ")
return_book()
try:
amount = int(amount)
except ValueError:
print()
input("That is not a number, press enter to try again ")
return_book()
library[isbn][2] = library[isbn][2] + int(amount)
print(library)

A KeyError occurs when we try to access a key from a dictionary that does not exist, you are transforming a string into a integer and using that integer as the key! Use str(isbn) to make isbn a string again:
try:
isbn = int(isbn)
except ValueError:
print()
input("That is not a number, press enter to try again ")
return_book()
try:
amount = int(amount)
except ValueError:
print()
input("That is not a number, press enter to try again ")
return_book()
library[str(isbn)][2] = library[str(isbn)][2] + int(amount)
print(library)

Related

How can I specify which try block to continue from?

I have the following code
while True:
try:
height_input=input(f"Please enter your height in meters : ")
height=float(height_input)
# weight_input=input(f"Please enter your weight in kilograms")
except ValueError:
print("Invalid Input. Please Try Again")
continue
try:
weight_input=input(f"Please enter your weight in kilograms")
weight=float(weight_input)
except ValueError:
print("Invalid Input. Please Try Again")
continue
try:
bmi=weight/(height*height)
print(round(bmi,2))
finally:
break
If I encounter an error with an invalid format for the line related to the user entering weight, it asks me for the height again even though that might have been entered correctly and was part of the first try block
How do I specify that if an error is encountered in the second try block, to ask the user to input the weight again (which was part of the second try block) and not return to the user input question from the first try block? (the height)
For example the current result:
Question: Please Enter height
User Input: 2
Question: Please Enter Weight:
User Input: ghsdek
Error Message: "Invalid Input. Please Try Again"
Question: Please Enter height
Expected result:
Question: Please Enter height
User Input: 2
Question: Please Enter Weight:
User Input: ghsdek
Error Message: "Invalid Input. Please Try Again"
Question: Please Enter Weight
Firstly, your exception handling syntax is wrong. You want the following.
try:
height_input = input(f"Please enter your height in meters : ")
height = float(height_input)
except ValueError:
print("Invalid Input. Please Try Again")
continue
Secondly, continue is just going to the next loop iteration. You can't tell it where in the loop to begin. What you need are three separate loops to read each piece of information.
Thirdly, at the end of each try block you'll want to break or your loops will continue infinitely.
You can split the code to multiply while codes, also you need to check for height being different to 0 like below:
while True:
try:
height_input = input("Please enter your height in meters : ")
height = float(height_input)
if height != 0:
break
except Exception:
print("Invalid Input. Please Try Again")
while True:
try:
weight_input = input("Please enter your weight in kilograms")
weight = float(weight_input)
break
except Exception:
print("Invalid Input. Please Try Again")
bmi = weight/(height*height)
print(f"Your bmi is: {round(bmi,2)}")
I'd extract the input logic into a function in accordance with the DRY principle. That would also make the code more readable:
def input_value(msg, type):
while True:
try:
return type(input(msg))
except ValueError:
print("Invalid Input. Please Try Again")
weight = input_value("Please enter your weight in kilograms: ", float)
height = input_value("Please enter your height in meters: ", float)

How to find if the value contains characters

Right now am planning to add items into the database. The item name, price and all are all entered by the users. How do I find if theres any alphabets when entering the price? i tried using .isnumber() but it seems to be reading my decimal point as a character as well.
while True:
itemPrice = input("Please Enter Item Price: ")
if str(itemPrice).isnumeric() == False:
print("Please enter a value!")
else:
print(itemPrice)
break
For example, they allow if i enter 5 but not 5.5 and since this is item price it should have decimals.
You can catch exceptions,
while True:
itemPrice = input("Please Enter Item Price: ")
try:
itemPrice = float(itemPrice)
print(itemPrice)
break
except ValueError:
print("Please enter a value!")
you can use try/except block
a = 3.5345
a=str(a)
try: #if it can be converted to a float, it's true
float(a)
print(True)
except: # it it can't be converted to a float, it's false
print(False)
You could try using a for loop to check:
def containsAlpha(x):
if True in [char.isalpha() for char in x]:
return True
return False
while True:
itemPrice = input("Please Enter Item Price: ")
if containsAlpha(itemPrice):
print("Please enter a value!")
else:
print(itemPrice)
break

How can I get print except statement printed instead of an error below in try/except syntax in Python

I am new to Python programming. Following is the code written and it works fine when I print any numeric digit and give me the desired result as expected but the problem comes when I enter string (anything other than integer/float) instead of giving me just the except statement, it also gives me an error which I don't want. So, what I want is when a user enter anything other than numeric digits, he should be prompted with a message i.e., "Invalid input. Enter a number please" instead of an error which I am getting after the except print statement in the end. Please help.
hours_string = input("Enter Hours: ")
rate_string = input("Enter Rate: ")
try:
hours_float = float(hours_string)
rate_float = float(rate_string)
except:
print("Invalid input. Enter a number please.")
result = hours_float * rate_float
print("Pay",result)
This is the error I am getting. If I enter string, I should simply get an except statement. That's it. Not any other error. How can I accomplish to get there?
Enter Hours: 9
Enter Rate: entered string by mistake
Invalid input. Enter a number please.
Traceback (most recent call last):
File "<string>", line 9, in <module>
NameError: name 'rate_float' is not defined
For a particular Error you can do a particular Exeption like in the Code below. Also note that each question is in a whileloop that you need to acomplish the task before you get to the next one.
while True:
try:
hours_string = input("Enter Hours: ")
hours_float = float(hours_string)
except ValueError:
print("Invalid input. Enter a number please.")
else:
break
while True:
try:
rate_string = input("Enter Rate: ")
rate_float = float(rate_string)
except ValueError:
print("Invalid input. Enter a number please.")
else:
break
result = hours_float * rate_float
print("Pay",result)
hours_float = None
rate_float = None
while hours_float is None:
hours_string = input("Enter Hours: ")
try:
hours_float = float(hours_string)
except ValueError:
print("Invalid input. Enter a number please.")
while rate_float is None:
rate_string = input("Enter Rate: ")
try:
rate_float = float(rate_string)
except ValueError:
print("Invalid input. Enter a number please.")
result = hours_float * rate_float
print("Pay", result)
In the while loop we repeatedly ask user for input, while they don't enter a valid number, separately for hours and rate.
Valid input changes the initially set None value to something else, which finishes the corresponding loop.
Since this is a expected situation and it can be treated as a test I would recommend instead of trying to execute the operation with wathever input the user provided you could ask the user for the input and while it is not an integer you ask for the input again.
def get_input(name, var_type):
userin = None
while userin is None:
userin = input(f'Input {name}: ')
try:
userin = var_type(userin)
except ValueError:
print(f'{name} must be {str(var_type)}, not {str(type(userin))}')
userin = None
return userin
hours = get_input('hours', int)
rate = get_input('rate', float)
result = hours * rate
print('Pay', result)
The function get_input tries to cast the input input value to the type you want and if it is not as desired it will keep asking until the type matches.

How to detect a invalid input and put the user into a loop until an acceptable answer is typed?

I'm trying to figure out how to get the user to type on letters and return numbers as invalid inputs only.
This is my code, I'm still unclear about the ValueError as if I run the code and type in letters it'll come out as an invalid input but if I put in numbers it comes in as valid.
while True:
try:
name = int(input("What is your name? "))
except ValueError:
print("Invalid response. Letters only please.")
continue
else:
break
correctName = input("Your name is...'" + (name) + "', is this correct? \n Please use 'Y' as yes and 'N' as no.\n")
if correctName == "Y":
print("Thank you..!")
int(input()) will expect an integer as an input, so when you type your name (unless you're name wholly consists of numbers), you will get a ValueError like you're experiencing now. Instead, you can use str(input()) to get the user input, then use the str.isdigit() method to check if it's a number.
name = str(input("What is your name? "))
if name.isdigit():
print("Invalid response. Letters only please.")
continue
else:
break
you can also try regex to check if a string contains a number:
bool(re.search(r'\d', name))
\d will matches for digits [0-9].
it will return True if the string contains a number.
full code:
import re
while True:
name = input("What is your name? ")
if bool(re.search(r'\d', name)):
print("Invalid response. Letters only please.")
else:
correctName = input("Your name is...'" + (name) + "', is this correct? \n Please use 'Y' as yes and 'N' as no.\n")
if correctName == "Y":
print("Thank you..!")
break
For Python3
while True:
name = input()
if name.isalpha():
break
For Python2
while True:
name = str(input())
if name.isalpha():
break

Show an error message to the user if what they entered is not a float

Here's my code:
print('Welcome To The Balance Tracker!')
balance = float(input('Enter Your Starting Balance: ')
This is at the start of the program. How would I make it so the user cannot proceed unless the balance is a float, and if they enter anything else it shows an error message?
I know it probably has to be in a while loop. I'm just not a 100% sure on the execution.
Catching the ValueError that is raised if float fails will solve your problem.
print('Welcome To The Balance Tracker!')
balance = None
while balance is None:
try:
balance = float(input('Enter Your Starting Balance: '))
except ValueError:
print("HEY! '{}' is not a float!".format(balance))
This will print a message if it's not float and while loop will not let user to go through!
You can try
#!/usr/bin/env python3
is_balance_not_float = True
print('Welcome To The Balance Tracker!')
while (is_balance_not_float):
try:
balance = float(input('Enter Your Starting Balance: '))
except ValueError:
print("You are suppose to enter a number. ")
else:
is_balance_not_float = False
print("Balance : %s" % balance)
The best thing to do is to try to convert the input to a float, and if it fails, then try again. Reasons for failure could include a string that is not convertible to float, or an EOF on stdin.
For instance:
balance = None
while balance is None:
try:
balance = float(input('Enter Your Starting Balance: '))
except Exception:
print('Balance must be a (floating point) number')
As a point of interest, if the user hits Control-C, it raises KeyboardInterrupt, which is not a subclass of Exception, and so will not get caught by the except, and will cause the program to exit.

Categories

Resources