try, except and while loop in Python - python

I'm trying to do this exercise for school, but the code won't work, precisely it doesn't execute if statements, after calculating BMI. Further if the input is not correct, the except statment is now checked. Please advise what to correct in the code. Thanks!
user_input_1 = input('What is your weight')
user_input_2 = input('What is your height')
b = 'BMI'
b = int(user_input_1)/(float(user_input_2)**2)
while True:
try:
user_input_1 == int and user_input_1 > 0
user_input_2 == float and user_input_2 > 0
print(b)
if b in range(1, 19):
print('You are skinny as a rail')
break
if b in range(19, 26):
print('You are fit as a butcher\'s dog')
break
if b >= 25:
print('You are as plum as a partridge')
break
break
except ZeroDivisionError:
input('Enter your height in meters as a float')
except user_input_1 != int:
input('Please enter your weight in kg')

for start: note that you declare the variable b row after another. this means that the first deceleration is redundant.
second, don't use break, but elif instead of the 'if'.
third, the first two rows after try, do nothing..

Where to start?
The only division takes place before entering the try block, so your except ZeroDivisionError will never get triggered.
except user_input_1 != int evaluates to except True which is meaningless and will never get triggered
The only way you don't hit a break in your while loop, is if you throw an exception that gets caught (if it's not caught, it'll escape your while loop and exit your program). Since the code that gets user input is outside of the while loop, there would be (if the exceptions could ever be caught) no difference and you'd see the error messages just repeating forever.
There seem to be some fundamental gaps in your understanding of python. I'd suggest filling those first; try and implement just a single desired feature (for example, take user input and display suitable error message if it is invalid) and build from there.

There are lots of problems with your code as SpoonMeiser already mentioned:
The only division takes place before entering the try block, so your except ZeroDivisionError will never get triggered.
except user_input_1 != int evaluates to except True which is meaningless and will never get triggered
The only way you don't hit a break in your while loop, is if you throw an exception that gets caught (if it's not caught, it'll
escape your while loop and exit your program). Since the code that
gets user input is outside of the while loop, there would be (if
the exceptions could ever be caught) no difference and you'd see the
error messages just repeating forever.
Other errors are:
The use of b in range(x, y): These only include integer values values in that interval. And you can test it with:
print(2.1 in range(0,10)) # Prints: False
print(2 in range(0,10)) # Prints: True
You should use = float(input(...)) from the start: if you'll always will use the user input as a float just do it once.
b = 'BMI' ?
Here is the resulting code:
def foo():
try:
user_input_1 = float(input('What is your weight? '))
user_input_2 = float(input('What is your height? '))
if all(x>0 for x in [user_input_1,user_input_2]):
b = user_input_1/user_input_2**2
print(b)
if 0 > b > 26:
print('You are skinny as a rail')
elif 19 > b > 26:
print("You are fit as a butcher's dog")
else:
print('You are as plum as a partridge')
else: raise ValueError
except ValueError:
print('Enter your height in meters as a float')
foo()

Related

How to print a message to the user when a negative number is inputed?

I am learning about the try and except statements now and I want the program to print out a message when a negative number is inserted but I don't know how to create the order of the statements for this output:
print("how many dogs do you have?")
numDogs= input()
try:
if int(numDogs)>=4:
print("that is a lof of dogs")
else:
print("that is not that many dogs")
except:
print("you did not enter a number")
I want the program to print tje output when the user enters a negative number.
How can I do it?
Just code is like
try:
if no<0:
print("no is negative ")
raise error
And further code will be as it is
Here is what you are trying to achieve.
class CustomError(Exception):
pass
print("how many dogs do you have?")
try:
numDogs = int(input())
if numDogs < 0:
raise CustomError
elif int(numDogs)>=4:
print("that is a lot of dogs")
else:
print("that is not that many dogs")
except CustomError:
print("No Negative Dogs")
except:
print("you did not enter a number")
You can start by creating a custom exception. See https://www.programiz.com/python-programming/user-defined-exception
After which, you should have a condition to first detect the negative value then raise an error from it.
Finally, You can then create multiple excepts to get different error. The first except is raised on input of negative values (as your condition will do for you) whereas the second is used to catch non valid value such as characters.
Note that your int(input) segment should be WITHIN your try block to detect the error
Solution I found is from this SO question
I want the program to print out a message when a negative number is inserted
You can raise a valueError like #Jackson's answer, or you can raise an Exception like in my code below.
elif numDogs < 0:
raise Exception("\n\n\nYou entered a negative number")
def main():
try:
numDogs= int(input("how many dogs do you have? "))
if numDogs >= 4:
print("that is a lot of dogs")
elif numDogs < 0:
raise Exception("\n\n\nYou entered a negative number")
else:
print("that is not that many dogs")
except ValueError:
print("you did not enter a number")
main()
One thing that I though I should point out is that its probably better practice to just check if the number is < 0 or is NAN. But like you said, you're trying to learn about the try and except statements. I thought it was cool that in this code segment:
try:
if numDogs < 0:
raise ValueError
except ValueError:
print("Not a negative Number")
you can throw what error you want and your try will catch it. Guess im still learning a lot too. Only part is, if that happens if your code then one won't know if its a negative number issue or if the number is something like "a", which cannot be converted to one (in this way).
All in all, I think its best to solve this problem with no try / except statements:
def main():
num_dogs = input("# of dogs: ")
if not num_dogs.isnumeric():
return "Error: NAN (not a number)"
num_dogs = int(num_dogs)
return ["thats not a lot of dogs", "that's a lot of dogs!"][num_dogs >= 4] if num_dogs > 0 else "You Entered a negative amount for # of dogs"
print(main())
Notice that I wrapped everything in a `main` function, because that way we can return a string with the result; this is important because if we get an error we want to break out of the function, which is what return does.

Different Exceptions on Python

I'm warming-up with the Python and need your help regarding applying a few exceptions. This is a simple guessing game that a user enters input and tries to guess the random number generated. I'm trying to catch en exception where the user enters a number from 1 to 50.
To do so, I used IndexError. Is that the right error type I am using?
I also entered another exception, namely ValueError to prevent make sure that users enter a number, not whitespace.
My question is how can I throw an exception that the user enters a number only between 1 and 50?
import random
number_of_guesses = 0
number = random.randint(1,50)
name = input('Hi! Enter your name: ')
while number_of_guesses < 8:
try:
guess = input("Take a guess between 1 and 50 including ")
guess = int(guess)
number_of_guesses+=1
guesses_left = 8 - number_of_guesses
except IndexError:
print('Please enter a number only between 1 and 50 including')
continue
except ValueError:
print('Enter a number')
continue
if guess>number:
print('Your guess is higher than the actual number',guesses_left,'guesses left')
elif guess<number:
print('Your guess is lower than the actual number',guesses_left,'guesses left')
elif guess==number:
break
if guess==number:
print('Well done! You guessed the number in',number_of_guesses,'tries:')
if guess != number:
print('Sorry, the number I was thinking of was',number)
Welcome to SO and python
First, take a step back to understand what the try/except block does.
try/except is a construct where Python will "try" to execute a block of code and catch any exception (or unexpected error) by matching the type of Exception with error types specified by except clause(s).
An IndexError occurs when you attempt to index an object that supports indexing (eg a list) and the index you have specified is outside the range of the index for example:
my_list = ["a", "b", "c"]
print(mylist[0])
# will print "a"
print(my_list[4])
# with raise in IndexError as index 4 doesn't exist.
In your example, ValueError is raised by the call to int when a non-integer argument value is passed. Because you are not indexing anything IndexError is not raised.
As to placing if/else within or outside the try block. By placing it in the try block any exceptions raised in the if/else block are caught. In both cases, the behaviour of the if/else block remains the same.
For the index error you need to index a list
a = [1 , 2, 3]
print(a[5])
With placing statements inside the try you catch the exception(s) in your program and can handle the problem yourself so the program keeps running.
Outside the try results in an exception error and the program aborts.

How to add an if/else to an "except" statement in Python?

I wanted to add an if/else to an except statement that checks for a specific input by the user (i.e "exit"). However the except statement is bound to Value Error. Running the below code gives me 2 error: Value Error and Name Error. The "user_guess" variable is not being identified in the except block, hence the Name error. I've tried using abstraction, i.e routing the data via a function called from the except statements block, however I still keep getting Name Error.
while (lives>0 and not found):
try:
user_guess=int(input(f"(Lives = {lives})Enter Your Guess: ").strip())
except ValueError:
if(user_guess == "exit"):
break
else:
raise (ValueError)
else:
if((user_guess)>guess):
print("Your guess is High. Try Something Lower. \n")
lives-=1
I would like to know how to implement the code such that the program throws the "Value Error" exception to all cases other than the one case i.e when the user inputs the word "exit" into the terminal. I'm using Python 3.6
As you said, you are trying to convert the input to integer as soon as you get it. Because of this you don't have an opportunity to compare it to "exit". So, instead, let us get and save the input as string, compare it to "exit", then try to convert it to an integer:
lives = 5
guess = 6
found = False
while lives > 0 and not found:
user_guess = input(f"(Lives = {lives})Enter Your Guess: ").strip()
if user_guess == "exit":
break
try:
user_guess_int = int(user_guess)
except ValueError:
print("Invalid input!")
else:
if user_guess_int > guess:
print("Your guess is High. Try Something Lower.")
lives -= 1
elif user_guess_int < guess:
print("Your guess is Low. Try Something Higher.")
lives -= 1
else:
print("Correct!")
found = True

Python excepting input only if in range

Hi I want to get a number from user and only except input within a certain range.
The below appears to work but I am a noob and thought whilst it works there is no doubt a more elegant example... just trying not to fall into bad habits!
One thing I have noticed is when I run the program CTL+C will not break me out of the loop and raises the exception instead.
while True:
try:
input = int(raw_input('Pick a number in range 1-10 >>> '))
# Check if input is in range
if input in range(1,10):
break
else:
print 'Out of range. Try again'
except:
print ("That's not a number")
All help greatly appreciated.
Ctrl+C raises a KeyboardInterruptException, your try … except block catches this:
while True:
try:
input = int(raw_input('Pick a number in range 1-10 >>> '))
except ValueError: # just catch the exceptions you know!
print 'That\'s not a number!'
else:
if 1 <= input < 10: # this is faster
break
else:
print 'Out of range. Try again'
Generally, you should just catch the exceptions you expect to happen (so no side effects appear, like your Ctrl+C problem). Also you should keep the try … except block as short as possible.
There are several items in your code that could be improved.
(1) Most importantly, it's not a good idea to just catch a generic exception, you should catch a specific one you are looking for, and generally have as short of a try-block as you can.
(2) Also,
if input in range(1,10):
would better be coded as
if 1 <= input < 10:
as currently function range() repeatedly creates a list of values form 1 to 9, which is probably not what you want or need. Also, do you want to include value 10? Your prompt seems to imply that, so then you need to adjust your call to range(1, 11), as the list generated will not include the upper-range value. and the if-statement should be changed to if 1 <= input <= 10:
You can use this code:
def read_int(prompt, min, max):
while True:
try:
val = int(input(prompt))
except ValueError:
print('Error: wrong input')
else:
if(min <= val < max): # this is faster
break
else:
print('Error: the value is not within permitted range (min..max)')
return val
v = read_int("Enter a number from -10 to 10: ", -10, 10)
print("The number is:", v)

How to determine when input is alphabetic?

I been trying to solve this one for a while and can't seem to make it work right.. here is my current work
while True:
guess = int(raw_input('What is your number?'))
if 100 < guess or guess < 1:
print '\ninvalid'
else:
.....continue on
Right now I have made it so when a user input a number higher than 100 or lower than 1, it prints out "invalid". BUT what if i want to make it so when a user input a string that is not a number(alphabetic, punctuation, etc.) it also returns this "invalid" message?
I have thought about using if not ...isdigit(), but it won't work since I get the guess as an integer in order for the above range to work. Try/except is another option I thought about, but still haven't figured out how to implement it in correctly.
You can use exception handling:
try:
guess = int(raw_input('What is your number?'))
if not (1 <= guess <= 100):
raise ValueError
# .....continue on
except ValueError:
print '\ninvalid'
That way, \ninvalid will be printed if the user either inputs a non-numeric string or inputs a numeric string greater than 100 or smaller than 1.
EDIT: Okay, I submit to the x < y < z syntax. Still think it loses some of its charm when it's used with not, though.
while True:
try:
guess = int(raw_input("..."))
except EOFError:
print "whoa nelly! EOF? we should probably exit"
break # or sys.exit, or raise a different exception,
# or don't catch this at all, and let it percolate up,
# depending on what you want
except ValueError:
print "illegal input: expected an integer"
else:
if not (1 <= guess <= 100):
print "out of range"
else:
print "processing guess... (but if it wasn't 42, then it's wrong)"
break # out of while loop after processing

Categories

Resources