BMI with exception handling python - python

I need help with this code I am trying to apply, a short time ago I ran a bmi calculator in index and now I am trying to update that code with exception handling. So far the portions don't give me errors they just run strangely together. For example, when it prompts "Enter the user's name or '0' to quit" it doesn't actually end the process it continues on to the exception process. Can someone help me write this more efficiently. here is my code this is updated, the issue I am specifically having now is the program is not terminating when the user enters '0':
def bmi_calculator():
end = False
print("Welcome to the BMI Calculator!")
while end == False:
user = input("Enter student's name or '0' to quit: ")
if user == "0":
print("end of report!")
end = True
else:
print("Lets gather your information,", user)
break
flag='yes'
while flag != 'no':
#Exception block for catching non integer inputs
try:
#Prompting user to input weight
weight = int(input('Enter your weight in pounds : '))
if weight == 0:
raise ValueError
except ValueError:
print ('Oops!! Kindly enter non-zero numbers only.')
flag = input('Do you want to try again? yes/no : ')
continue
try:
#Prompting user to input height
height = float(input('Enter your height in inches : '))
if height == 0:
raise ValueError
except ValueError:
print ('Oops!! Kindly enter non-zero numbers only.')
flag = input('Do you want to try again? yes/no : ')
continue
#Formula for calculating BMI
BMI = round(weight * 703/(height*height), 2)
return (BMI)
print(" Your bmi is:", bmi_calculator())

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 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.

Passing 'ValueError' & 'continue' in a function and call it

I am trying to check user inputs to ensure that:
1) It is a floating number
2) Floating number is not negative
I am trying to put above 2 checks into a function and call it after user has input into a variable.
However, I cant seem to put 'ValueError' & 'continue' in a function that I can call. Is this possible?
I have tried below code, but it repeats from the top when I key in 't' for salCredit, or any of the next few variables. The code will work if I were to repeat 'ValueError' & 'continue' for every variable. I'm just wondering if there is a shorter way of doing do?
def interestCalculator():
#User inputs required for calculation of interest earned.
while True:
try:
mul_AccBal = float(input("Enter your Account Balance: "))
#checkInputError(accBal)
salCredit = float(input("Enter your Salary: "))
#checkInputError(salCredit)
creditCard = float(input("Credit Card Spend (S$): "))
#checkInputError(creditCard)
except ValueError:
print("Please enter a valid number.")
continue
def checkInputError(userInput):
if userInput < 0:
print("Please enter a positive number.")
interestCalculator()
Expected results:
Scenario 1: if user inputs 't'
Enter your Account Balance: 5000
Enter your Salary: t
Please enter a valid number.
Enter your Salary: 500
Scenario 2: if user inputs negative number
Enter your Account Balance: 5000
Enter your Salary: -50
Please enter a valid number.
Enter your Salary: 500
Current results:
Scenario 1: if user inputs 't'
Enter your Account Balance: 5000
Enter your Salary: t
Please enter a valid number.
Enter your Account Balance:
Scenario 2: if user inputs negative number
Enter your Account Balance: 5000
Enter your Salary: -50
Please enter a positive number.
Credit Card Spend (S$):
You could create a function that continues prompting for input until a valid float is input
def get_float_input(prompt):
while True:
try:
user_input = float(input(prompt))
if user_input < 0:
print("Please enter a positive number.")
continue # start the while loop again
return user_input # return will break out of the while loop
except ValueError:
print("Please enter a valid number.")
mul_AccBal = get_float_input("Enter your Account Balance: ")
salCredit = get_float_input("Enter your Salary: ")
creditCard = get_float_input("Credit Card Spend (S$): ")
Try this:
def interestCalculator():
#User inputs required for calculation of interest earned.
while True:
invalid = True
while invalid:
try:
mul_AccBal = float(input("Enter your Account Balance: "))
invalid=checkInputError(salCredit)
except ValueError:
print("Please enter a valid number.")
continue
invalid = True
while invalid:
try:
salCredit = float(input("Enter your Salary: "))
invalid=checkInputError(salCredit)
except ValueError:
print("Please enter a valid number.")
continue
invalid = True
while invalid:
try:
creditCard = float(input("Credit Card Spend (S$): "))
invalid=checkInputError(salCredit)
except ValueError:
print("Please enter a valid number.")
continue
def checkInputError(userInput):
if userInput < 0:
print("Please enter a positive number.")
return True
return False
interestCalculator()
you need to break you while loop if all the input is successful (also note that the continue at the end of the while loop is unnecessary). and if you want to have a validation for every number separately, you could do something like this:
def get_float(message, retry_message="Please enter a valid number."):
while True:
try:
ret = float(input(message))
if ret >= 0:
return ret
else:
print(retry_message)
except ValueError:
print(retry_message)
def interestCalculator():
mul_AccBal = get_float("Enter your Account Balance: ")
salCredit = get_float("Enter your Salary: ")
creditCard = get_float("Credit Card Spend (S$): ")

Python Nested Loop Enter Value and Confirm Answer

I'm trying to write a simple block of code that has a user enter an interest rate. The number must be 0 or greater, any other value will be rejected, the user must be polled until a valid number is input. If the number is greater than 10%, the user must be asked if he/she really expects an interest rate that high, if the user replies in the affirmative, the number is to be used, otherwise the user will be asked to input the value again and the above checks will be made. I'm having trouble understanding the nested loop aspect of this. Any help is greatly appreciated!
def main():
while True:
try:
interest_rate = int(input("Please enter an interest rate: "))
except ValueErrror:
print("Entered value is not a number! ")
except KeyboardInterrupt:
print("Command Error!")
else:
if 0 <= interest_rate < 10:
break
elif interest_rate > 10:
print("Entered interest rate is greater than 10%. Are you sure? (y/n): ")
main()
do it all in the try, if inp > 10, ask if the user is happy and break if they are, elif user input is within threshold just break the loop:
def main():
while True:
try:
interest_rate = int(input("Please enter an interest rate: "))
if interest_rate > 10:
confirm = input("Entered interest rate is greater than 10%. Are you sure? (y/n): ")
if confirm =="y":
break
elif 0 <= interest_rate < 10:
break
except ValueError:
print("Entered value is not a number! ")
return interest_rate
main()
Three things jump out:
1) ValueErrror should be ValueError
2) You don't handle the user input on the final test
3) You probably want to change the < 10 to be <= 10
else:
if 0 <= interest_rate < 10:
break
elif interest_rate > 10:
print("Entered interest rate is greater than 10%. Are you sure? (y/n): ")
can be:
if 0 <= interest_rate <= 10:
break
print("Entered interest rate is greater than 10%. Are you sure? (y/n): ")
except the last line must take the response and process it.
Your else was not related to an if
Your elif was unnecessary after break
Make the print("Entered interest rate is greater than 10%. Are you sure? (y/n): ") an input
answer = int(input("Are you sure?"))
if answer == "y":
break
I usually prefer to break down the solution and validation into different modules. Please check the below code to see how I break them down. So it is easy when it comes to debugging and testing.
def validating_user_input(num):
"""
"""
return num > 0
def getting_user_input():
"""
"""
user_input = int(raw_input("Enter the number that is greater than 0: "))
return user_input
def confirming_choose():
"""
"""
try:
user_choose = int(raw_input("Can you confirm your input? [0|1]? "))
except ValueError:
return False
return user_choose == 1
def main():
"""
"""
initial_cond = True
while initial_cond:
user_input = getting_user_input()
if validating_user_input(user_input):
if user_input > 10:
confirmation = confirming_choose()
while not confirmation:
getting_user_input()
#do you operating here
initial_cond = False
else:
print "It is not valid input."
if __name__ == "__main__":
main()

Ask the user if they want to repeat the same task again

If the user gets to the end of the program I want them to be prompted with a question asking if they wants to try again. If they answer yes I want to rerun the program.
import random
print("The purpose of this exercise is to enter a number of coin values")
print("that add up to a displayed target value.\n")
print("Enter coins values as 1-penny, 5-nickel, 10-dime,and 25-quarter.")
print("Hit return after the last entered coin value.")
print("--------------------")
total = 0
final_coin = random.randint(1, 99)
print("Enter coins that add up to", final_coin, "cents, on per line")
user_input = int(input("Enter first coin: "))
total = total + user_input
if user_input != 1 and user_input!=5 and user_input!=10 and user_input!=25:
print("invalid input")
while total != final_coin:
user_input = int(input("Enter next coin: "))
total = total + user_input
if total > final_coin:
print("Sorry - total amount exceeds", (final_coin))
if total < final_coin:
print("Sorry - you only entered",(total))
if total== final_coin:
print("correct")
You can enclose your entire program in another while loop that asks the user if they want to try again.
while True:
# your entire program goes here
try_again = int(input("Press 1 to try again, 0 to exit. "))
if try_again == 0:
break # break out of the outer while loop
This is an incremental improvement on the accepted answer:
Used as is, any invalid input from the user (such as an empty str, or the letter "g" or some such) will cause an exception at the point where the int() function is called.
A simple solution to such a problem is to use a try/except- try to perform a task/ code and if it works- great, but otherwise (except here is like an else:) do this other thing.
Of the three approaches one might try, I think the first one below is the easiest and will not crash your program.
Option 1: Just use the string value entered with one option to go again
while True:
# your entire program goes here
try_again = input("Press 1 to try again, any other key to exit. ")
if try_again != "1":
break # break out of the outer while loop
Option 2: if using int(), safeguard against bad user input
while True:
# your entire program goes here
try_again = input("Press 1 to try again, 0 to exit. ")
try:
try_again = int(try_again) # non-numeric input from user could otherwise crash at this point
if try_again == 0:
break # break out of this while loop
except:
print("Non number entered")
Option 3: Loop until the user enters one of two valid options
while True:
# your entire program goes here
try_again = ""
# Loop until users opts to go again or quit
while (try_again != "1") or (try_again != "0"):
try_again = input("Press 1 to try again, 0 to exit. ")
if try_again in ["1", "0"]:
continue # a valid entry found
else:
print("Invalid input- Press 1 to try again, 0 to exit.")
# at this point, try_again must be "0" or "1"
if try_again == "0":
break

Categories

Resources