Exception handling in Python [duplicate] - python

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 3 years ago.
I am trying to create an exception handling into a loop .
I have created the below code and I would like to put an exception in userId1 and userid2.
For example, the total amount of users is 943, so when the user enters an userId which is greater than 943, to put an exception with a message 'Sorry, this userId does not exist' and to start the loop over again.
I tried to do it with the try: and except KeyError:
but didn't play correct or I didn't write in appropriate order.
How can I write it?
exit=False
while exit is False:
print("Hello Lady or Gentleman, this is a very primitive movie recommnedation system, please follow the instructions below : ")
print("---------------------------------------------------------------------------")
print("1) If you would like to find the difference 1 please press 1")
print("2) If you would like to find the difference 2 please press 2")
print("3) If you would like to exit, then press 0")
option=False
while option is False:
print("Εnter what would you like to find please :",end=" ")
option=input();
if option =='1':
print("The total number of users is 943, so you should enter 2 user_ids lower than 944")
print('---------------------')
print("Enter the first userId please :",end=" ")
user1 = input();
print("Enter the second userId please :",end=" ")
user2 = input();
elif option == '2':
print("The total number of movies is 1682, so you should enter 2 movie_ids lower than 1683")
print('-------------------')
print("Enter the first bookId please :",end=" ")
bookId1 = input();
print("Enter the second bookId1 please :",end=" ")
bookId2= input();
elif option == '0':
exit = True
print("Thank you very much")
break
else:
option = False
print("This option is not valid, Please try again!")

Use the continue statement return to the start of the loop.
if int(user1) > 943:
print('Sorry, this userId does not exist')
continue

Exceptions stop execution - i.e. they make your program close. You cannot continue to loop after raising an exception. As well, it doesn't make any sense to handle an exception that you raise from the same scope (except in advanced cases).
I suspect what you're actually trying to do is print an error if the input is invalid. For that, see Asking the user for input until they give a valid response. You would want to put the validation while loop inside the if option == blocks, something like this:
if option == '1':
while True:
user = int(input('User: '))
if user > 943:
print('There are only 943 users!')
continue
else:
break

I don't see the try and except statement in your code block. Did you remove that?
In order for a try/except statement to do something, an error needs to be raised. You could raise the KeyError exception yourself.
I think you'll need something along the lines of:
if userID > 943:
raise KeyError(userID)
More info on raising exceptions here: https://docs.python.org/3/tutorial/errors.html#raising-exceptions

Related

How to prevent user from inputting spaces/nothing in Python?

I have a problem in which users can input spaces or nothing and still pass through the program, how do I go about preventing this? I am still a beginner at python.
def orderFunction(): # The function which allows the customer to choose delivery or pickup
global deliveryPickup
deliveryPickup = input("Please input delivery or pickup: d for delivery p for pickup")
if deliveryPickup == "d":
global customerName
while True:
try:
customerName = (input("Please input your name"))
if customerName == (""):
print("Please input a valid name")
else:
break
global customerAddress
while True:
try:
customerAddress = (input("Please input your name"))
if customerAddress == (""):
print("Please input a valid Address")
else:
break
global customerPhnum
while True:
try:
customerPhnum = int(input("Please input your phone number"))
except ValueError:
print("Please input a valid phone number")
else:
break
print("There will also be a $3 delivery surcharge")
elif deliveryPickup == "p":
customerName = (input("Please input your name"))
if customerName == (""):
print("Please input a valid name")
orderFunction()
else:
print("Please ensure that you have chosen d for Delivery or p for Pickup")
orderFunction()
orderFunction()
Here is my attempt at doing this but I get all kinds of unindent and indent errors at the moment and I think my while loops are probably wrong.
Essentially if I input a space or hit enter into one of the customer inputs (customerName for instance) it gets stored. This needs to prevented and I have tried to fix it by using while loops which obviously haven't worked.
Hopefully someone has a solution to this problem
Many Thanks.
.strip() removes all tabs or spaces before and after a string.
Meaning all spaces == empty string. All tabs == empty string. So all you have to check if the length of that string != 0 or the string is not empty. Just use an infinite loop to keep on forcing the right input.
Also as a tip, you don't have to limit yourself into one function.
Here's a working code below.
def getNonBlankInput(message, error_message):
x = input(message)
while len(x.strip()) == 0:
x = input(error_message)
return x
def getValidIntegerInput(message, error_message):
msg = message
while(True):
try:
x = int(input(msg))
break
except ValueError:
msg = error_message
return x
def orderFunction(): # The function which allows the customer to choose delivery or pickup
global deliveryPickup
global customerName
global customerAddress
global customerPhnum
deliveryPickup = input("Please input delivery or pickup: d for delivery p for pickup")
if deliveryPickup == "d":
customerName = getNonBlankInput("Please input your name: ", "Please input a valid name: ")
customerAddress = getNonBlankInput("Please input your address: ", "Please input a valid address: ")
customerPhnum = getValidIntegerInput("Please input your phone number: ", "Please input a valid phone number: ")
print("There will also be a $3 delivery surcharge")
elif deliveryPickup == "p":
customerName = getNonBlankInput("Please input your name: ", "Please input a valid name: ")
else:
print("Please ensure that you have chosen d for Delivery or p for Pickup")
orderFunction()
orderFunction()
Try using a regular expression that checks if any character between "A-Z" has been inserted, if not, give an error
The while loops are a decent solution, you just need to add more checks to your if statements.
First, you don't need a try statement on the top two loops. Don't use a try statement unless you're expecting an error, which you need to handle with an except statement, like you do in the bottom while loop.
Then you just need to add more conditions to your top two loops, I don't know exactly what you want to prevent, but you could try checking the length of the input, also see this answer for an interesting method:
https://stackoverflow.com/a/2405300/8201979
Instead of using input right away you can make a function similar to this one that will only allow valid inputs.
You can use this valid_input function instead of input.
def valid_input(text):
not_valid = True
res = ''
while not_valid:
res = input(text)
if res.split(): # if text is empty or only spaces, this creates an empty list evaluated at False
not_valid = False
return res
here the check is pretty simple: every text made out of nothing or spaces won't be allowed and we will keep asking for the same input until a valid information is given.
I made this code simple just so you get a general idea. But you can change the validation test to your liking and maybe also output a warning saying why the input wasn't allowed so the person knows what to do. You can do more advanced validation with regex, and maybe you need a minimum text length etc...
You have indent error because you have a try statement without the corresponding except.
You need both to make it work (as you did in the Phone number section).
Here is a link to the try/except: docs
Also, you can check if a string is empty as detailed in this answer.
So for example you want to write:
try:
customerName = input("Please input your name")
if not customerName:
print("Please input a valid name")
else:
break
except ValueError:
print("Please input a valid name")
Although the above seems a bit redundant, so you might want to raise an exception if the customer name is empty, catch the exception in the except block, print the warning and return error (or something else).
try:
customerName = input("Please input your name")
if not customerName:
raise ValueError
except ValueError:
print("Please input a valid name")
else:
break
Try adding another while true for pick and delivery option so that it can prevent taking other inputs
you don't need any of those try/excepts (which are broken anyway).
Its difficult to figure out what you're trying to do, are you trying to raise an exception if an empty string is passed, or request another input from the user? You seem to be half implementing both at the moment.
If its the latter, something like this would work.
def func(fieldname):
while True:
val = input("Please input your {}".format(fieldname))
if val.strip() != "":
break
else:
print("Please input a valid {}".format(fieldname))
return val
delivery_pickup = input("Please input delivery or pickup: d for delivery p for pickup")
if delivery_pickup == "d":
customer_name = func("name")
address = func("address")
phone_number = func("phone number")
What you are looking for is the str.strip method that remove trailing whitespace in strings.
Also I think try is not particularly suited for your needs here.
customerName = input("Please input your name")
while not customerName.strip():
customerName = input("Please input a valid name")
for the phone number I would not convert to integer because if the phone number starts with zeros, they will not be stored.

Validating that input consists of alphabetical characters

I have been trying to add some validation for users entering a new word to a text file.
The input must consists of letters only and I have got this working using if statements with .isalpha(), however I wanted to try and see if I could get it working using try, except and so far I have not got it working.
The try statement is allowing all input in no matter if it contains digits or spaces. I cant seem to spot where i've gone wrong.
def AddNewWords():
List = []
Exit = False
while not Exit:
choice = input("Please enter a word to be added to the text file: ")
try:
choice.isalpha()
except:
print("Not a valid word")
continue
else:
List.append(choice)
Exit = True
Return List
AddNewWords()
isalpha() returns True/False, it doesn't raise any exception.
Try this instead:
choice = input("Please enter a word to be added to the text file: ")
if not choice.isalpha():
print("Not a valid word")
continue
List.append(choice)
Exit = True
FWIW, you can also rewrite your loop in a more compact way without using the exit variable, but rather while True + break:
while True:
choice = input("Please enter a word to be added to the text file: ")
if choice.isalpha():
List.append(choice)
break
print("Not a valid word")
There are many way to achieve your result without a try / except clause. However, raising a manual exception is a perfectly valid approach and can be applied with only a couple of changes to your code.
First, you need to ensure a False result for str.isalpha raises an error:
if not choice.isalpha():
raise ValueError
Second, you should define explicitly the exception you are catching:
except ValueError:
print("Not a valid word")
continue
Complete solution:
def AddNewWords():
L = []
Exit = False
while not Exit:
choice = input("Please enter a word to be added to the text file: ")
try:
if not choice.isalpha():
raise ValueError
except ValueError:
print("Not a valid word")
continue
else:
L.append(choice)
Exit = True
return L
AddNewWords()
you need to check if true/false not try the except since you wont get any exception. the code should be.
def AddNewWords():
List = []
Exit = False
while not Exit:
choice = input("Please enter a word to be added to the text file: ")
if not choice.isalpha():
print("Not a valid word")
continue
else:
List.append(choice)
Exit = True
return List
AddNewWords()

Try except with If statements in Python

If I'm trying to prompt a user for their street name and they enter a # symbol i want to return an error and loop back to the top until they have entered a valid name.
Code:
def streetname():
while True:
try:
nameinput = str(input("Please enter a street name: "))
except Exception: # want to print error == if nameinput.find('#') > -1:
print("Error: name contains #, please try again")
continue
break
return nameinput
Goal of code: I want to prompt user for street name until they enter a valid name. If it contains '#', print error and try again. if it's valid, return nameinput.
I'm not quite sure how to use try and except with if statements
You probably shouldn't use try...except for such a simple input check, that can easily done with if alone.
def streetname():
while True:
nameinput = input("Please enter a street name: ")
if "#" in nameinput:
print("Error: name contains #, please try again")
continue
return nameinput
If you find a '#' in the string simply restart the loop, otherwise just return the name out of the function.
Also input already returns a str in Python 3, so there's no need to convert it. In Python 2 you should use raw_input instead which will also return a str.
First off, you're using a python's general Exception class. A string with a pound sign in it wouldn't trigger any of python's native exceptions, you have to write your own exception class and then call it.. or you can do something like this
if '#' in nameinput: #pound sign was found in the string
#either raise an Exception
raise('Can not use pound sign') # though this will probably break the while loop
# or
print 'can not use pound sign'
continue # to go back to the top of the while loop and prompt the user again

else statement python programming

How can I link the second info() call to a text file ?
print("Hi,welcome to the multiple choice quiz")
def info ():
print("Firstly we would like to collect some personal details:-?")
name = input("Please enter your first name?")
surname =input ("please enter your surname?")
email_address = input ("please enter your email addres #.co.uk")
username = input (" Chose a username?")
password = input ("Enter a Password?")
validation()
def validation():
correct = 0
while correct == 0:
correct=input(" is the following data is correct ?")
if correct in ["Y,y"]:
print("Well done you have registered for the quiz")
elif correct in ["N,n"]:
info()
else:
info()
You might want to drop your while loop.
info() calls your validation. "if" the data is correct, you finish, "else" you just call info() again.
That is pretty much what you did already. maybe you wanted it to look more like this:
print("Hi, welcome to the multiple choice quiz")
def info ():
print("Firstly we would like to collect some personal details:-?")
name = input("Please enter your first name?")
surname = input("please enter your surname?")
email_address = input("please enter your email address #.co.uk")
username = input(" Chose a username?")
password = input("Enter a Password?")
validation()
def validation():
correct = 0
correct = input(" is the data is correct ?")
if correct in ["Y,y"]:
print("Well done you have registered for the quiz")
elif correct in ["Y,y"]:
info()
else:
print "please type y or n"
validation()
info()
You wrote:
if correct in ["Y,y"]:
print("Well done you have registered for the quiz")
elif correct in ["N,n"]:
info()
else:
info()
Firstly, correct in ["Y,y"] will not do what you expect. ["Y,y"] is a list containing one element: "Y,y". That means correct in ["Y,y"] if and only if correct == "Y,y", and the user is not likely to enter that! You probably want a list with two elements: ["Y", "y"]. in can also test containment within strings, so you could use "Yy". You don't want a comma in there because then if the user enters just a comma that will pass the test as well, which is silly.
Putting that issue aside, if the user enters y or Y, it prints well done. If they enter n or N, info() is called. If they enter something else, info() is still called. That last part is surely not what you want: entering "N" and entering "A" should have different results! You want the user to be told that it's not valid. That part is easy, print a message. Then you want them to be asked again. Since they'll be asked for every iteration of your while loop, you just have to ensure that the loop continues. The loop will run as long as the condition correct == 0 is true, so just set correct to 0 and that will happen. So something like this:
else:
print("That's not valid")
correct = 0
OK, now to your question. You want to save those personal details to a file. You can't do that properly with the way your program is organised. The variables in info are local, so validation can't access them to save them. info has to do the saving (perhaps indirectly by passing the data along to another function). What we could do is have validation report the result of asking the user and let info decide what to do based on that:
def info ():
# collect data
if validation():
# save data
def validation():
correct = 0
while correct == 0:
correct=input(" is the following data is correct ?")
if correct in ["Y", "y"]:
print("Well done you have registered for the quiz")
return True
elif correct in ["N", "n"]:
return False
else:
print("That's not valid")
correct = 0
return will exit the validation function (thus ending the loop) and give the value returned to info to decide if the data should be saved.
Since the return statements end the loop, the only way the loop can continue is the else is reached, in which case explicitly making it continue with correct = 0 is silly. We can just make the loop go on forever until the function returns:
def validation():
while True:
correct=input(" is the following data is correct ?")
if correct in ["Y", "y"]:
print("Well done you have registered for the quiz")
return True
elif correct in ["N", "n"]:
info()
return False
else:
print("That's not valid")

Python loop restarting even though there is a try: except:

Here is the code for a small program I just wrote to test some new things I learned.
while 1:
try:
a = input("How old are you? ")
except:
print "Your answer must be a number!"
continue
years_100 = 100 - a
years_100 = str(years_100)
a = str(a)
print "You said you were "+a+", so that means you still have "+years_100+" years"
print "to go until you are 100!"
break
while 2:
try:
b = str(raw_input('Do you want to do it again? If yes enter "yes", otherwise type "no" to stop the script.'))
except:
print 'Please try again. Enter "yes" to do it again, or "no" to stop.'
continue
if b == "yes":
print 'You entered "yes". Script will now restart... '
elif b == "no":
print 'You entered "no". Script will now stop.'
break
It works fine for the for loop. If you type something other than a number, it will tell you only numbers are allowed.
However, in the 2nd loop, it asks you to enter yes or no, but if you enter in something different, it just restarts the loop instead of printing the message after
except:
What did I do wrong and how do I fix it so it displays the message I told it to?
You do not get an exception, because you are always enter a string when using raw_input(). Thus str() on the return value of raw_input() will never fail.
Instead, add an else statement to your yes or no tests:
if b == "yes":
print 'You entered "yes". Script will now restart... '
elif b == "no":
print 'You entered "no". Script will now stop.'
break
else:
print 'Please try again. Enter "yes" to do it again, or "no" to stop.'
continue
Note that you should never use a blanket except statement; catch specific exceptions. Otherwise, you'll mask unrelated problems, making it harder for you to find those problems.
Your first except handler should only catch NameError, EOFError and SyntaxError for example:
try:
a = input("How old are you? ")
except (NameError, SyntaxError, EOFError):
print "Your answer must be a number!"
continue
as that's what input() would throw.
Also note that input() takes any python expression. If I enter "Hello program" (with the quotes), no exception would be raised, but it is not a number either. Use int(raw_input()) instead, and then catch ValueError (what would be thrown if you entered anything that's not an integer) and EOFError for raw_input:
try:
a = int(raw_input("How old are you? "))
except (ValueError, EOFError):
print "Your answer must be a number!"
continue
To use the second loop to control the first, make it a function that returns True or False:
def yes_or_no():
while True:
try:
cont = raw_input('Do you want to do it again? If yes enter "yes", otherwise type "no" to stop the script.'))
except EOFError:
cont = '' # not yes and not no, so it'll loop again.
cont = cont.strip().lower() # remove whitespace and make it lowercase
if cont == 'yes':
print 'You entered "yes". Script will now restart... '
return True
if cont == 'no':
print 'You entered "no". Script will now stop.'
return False
print 'Please try again. Enter "yes" to do it again, or "no" to stop.'
and in the other loop:
while True:
# ask for a number, etc.
if not yes_or_no():
break # False was returned from yes_or_no
# True was returned, we continue the loop

Categories