I am writing a program that accepts an input from the user.
#note: Python 2.7 users should use `raw_input`, the equivalent of 3.X's `input`
age = int(input("Please enter your age: "))
if age >= 18:
print("You are able to vote in the United States!")
else:
print("You are not able to vote in the United States.")
The program works as expected as long as the the user enters meaningful data.
C:\Python\Projects> canyouvote.py
Please enter your age: 23
You are able to vote in the United States!
But it fails if the user enters invalid data:
C:\Python\Projects> canyouvote.py
Please enter your age: dickety six
Traceback (most recent call last):
File "canyouvote.py", line 1, in <module>
age = int(input("Please enter your age: "))
ValueError: invalid literal for int() with base 10: 'dickety six'
Instead of crashing, I would like the program to ask for the input again. Like this:
C:\Python\Projects> canyouvote.py
Please enter your age: dickety six
Sorry, I didn't understand that.
Please enter your age: 26
You are able to vote in the United States!
How can I make the program ask for valid inputs instead of crashing when non-sensical data is entered?
How can I reject values like -1
, which is a valid int
, but nonsensical in this context?
Best Answer
The simplest way to accomplish this is to put the
input
method in a while loop. Usecontinue
when you get bad input, andbreak
out of the loop when you're satisfied.When Your Input Might Raise an Exception
Use
try
andexcept
to detect when the user enters data that can't be parsed.Implementing Your Own Validation Rules
If you want to reject values that Python can successfully parse, you can add your own validation logic.
Combining Exception Handling and Custom Validation
Both of the above techniques can be combined into one loop.
Encapsulating it All in a Function
If you need to ask your user for a lot of different values, it might be useful to put this code in a function, so you don't have to retype it every time.
Putting It All Together
You can extend this idea to make a very generic input function:
With usage such as:
Common Pitfalls, and Why you Should Avoid Them
The Redundant Use of Redundant
input
StatementsThis method works but is generally considered poor style:
It might look attractive initially because it's shorter than the
while True
method, but it violates the Don't Repeat Yourself principle of software development. This increases the likelihood of bugs in your system. What if you want to backport to 2.7 by changinginput
toraw_input
, but accidentally change only the firstinput
above? It's aSyntaxError
just waiting to happen.Recursion Will Blow Your Stack
If you've just learned about recursion, you might be tempted to use it in
get_non_negative_int
so you can dispose of the while loop.This appears to work fine most of the time, but if the user enters invalid data enough times, the script will terminate with a
RuntimeError: maximum recursion depth exceeded
. You may think "no fool would make 1000 mistakes in a row", but you're underestimating the ingenuity of fools!