KeyErrors and how to raise a KeyError - python

For my homework assignment, I am told to raise a key error if the key(text) the user enters contains any non alphabetic characters and reprompt. So far I have this which seems to work but obviously doesn't use the expected try/except structure
key=input("Please enter the key word you want to use: ")
ok=key.isalpha()
while (ok==False):
print("The key you entered is invalid. Please try again")
key=input("Please enter the key word you want to use")

This is not appropriate usage of KeyError (it's supposed to be used for dict lookups, or similar situations), but if it is what you have been asked to do then try something like this :
def prompt_thing():
s = raw_input("Please enter the key word you want to use: ")
if s == '' or not s.isalnum():
print("The key you entered is invalid. Please try again")
raise KeyError('non-alphanumeric character in input')
return s
s = None
while s is None:
try:
s = prompt_thing()
except KeyError:
pass

Related

Syntax error with try/except statement highlighting 'except'

I have a very simple try/except block to basically force the variable 'password' to be defined as an integer from user input.
It is likely a dumb question, but I have tried looking around and cannot find some solution.
try:
password = int(input('Password: '))
except ValueError:
print("Please do not type letters or symbols!!")
while type(password) != 'int':
try:
password = int(input('Password '))
except ValueError:
print("Please do not type letters or symbols!!")
print('Complete, we have your password.')
But, when I try run this python shell, it comes up with a Syntax Error, highlighting 'except'...
There were couple of problems:
You have to use the comparision like this type(password) is not int:
Define password variable beforehand, otherwise it would not be recognized in your while statement
password=""
try:
password = int(input('Bob should have issued you with your 4-digit numerical password, please enter it here: '))
except ValueError:
print("Please do not type letters or symbols!!")
while type(password) is not int:
try:
password = int(input('Bob should have issued you with your 4-digit numerical password, please enter it here: '))
except ValueError:
print("Please do not type letters or symbols!!")
print('Complete, we have your password.')
Remove the new line after password = .... Shell expects an except block not a new line. Also your parenthesis are not complete.
try:
password = int(input('Bob should have issued you with your 4-digit numerical password, please enter it here: '))
except ValueError:
print("Please do not type letters or symbols!!")

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

'NoneType' Error when using a Try and Except Block

I'm having a strange issue with a try and except block I'm using to catch invalid data entry into a simple Black Jack Game I'm writing.....
def PickNumberOfPlayers():
global log
try:
inputs = int(input("How Many Players Would You Like?: "))
PlayersNumber = inputs
log.write("How Many Players Would You Like?: \n")
return PlayersNumber
except ValueError:
print("Try Typing in A Valid Number")
log.write("Try Typing in A Valid Number\n")
PickNumberOfPlayers()
I then have a method GameStart() which starts a number of method calls:
def GameStart():
global ListOfPlayers
for i in range(0, int(PickNumberOfPlayers())):
name = input("What Would You Like This Players Name To Appear As?:")
ListOfPlayers.update({name: Player(0, name)})
for key, value in ListOfPlayers.items():
value.AccountSetup()
value.Bet()
for key, value in ListOfPlayers.items():
value.PlayerDeal()
Dealer.Deal()
When I run the code and enter proper values ( a valid integer) there is no issue. When I first enter a invalid number (a string or char) I get the appropriate message "Try Typing in A Valid Number, and then when I do enter a valid integer I get the error -
for i in range(0, int(PickNumberOfPlayers())):
TypeError: int() argument must be a string or a number, not 'NoneType'
Any idea?
When you call PickNumberOfPlayers() in your except, you do not return its value. Do return PickNumberOfPlayers() instead.
You should modify PickNumberOfPlayers to always return an int.
def PickNumberOfPlayers():
global log
while 1:
try:
return int(input("How Many Players Would You Like?: "))
except ValueError:
print("Try Typing in A Valid Number")
log.write("Try Typing in A Valid Number\n")

Categories