Lesson Three: Input Validation with "try / except"

Right and Wrong keyboard inputThe users that run computer programs may not follow the program instructions. Whenever the program asks for a specific kind of input - such as a number or alphabetic string - the user may actually type in something completely different!

Sometimes these mistakes are accidental, and a user has simply typed too fast or not read or understood the instructions. In other cases, a user might deliberately try to "break" your program by doing something unexpected. Either way, a high-quality program will carefully verify user input to make sure it meets the requirements. If a program tries to process invalid input, it might crash with an exception or produce incorrect results.

Risky Numeric Conversions
All user input is read from the console with input(), which returns a string value. The value may contain an integer like "42" or floating point value like "3.14". if your program needs to convert the string to an integer or float data type, you can use the int() and float() functions on that string data. You are familiar with int() and float() from earlier lessons.

The examples below pass the string result from the input() function directly into the int() or float() functions, which will return an integer or floating point result to the variables.

intAnswer = int(input("In what year were you born? "))
floatAnswer = float(input("How much do you want to spend on a milkshake? "))
Copy
This works quite well when the user types in a string that contains a valid integer for int() or a valid decimal value for float(). But what happens when the user gives unexpected input? Try running the sample below and enter a non-integer value like "oops" or "2003.4" for the first question.

Try It Now


When int() or float() are given invalid string data to convert, they will throw a ValueError exception when those statements are executed.

In what year were you born? oops
Traceback (most recent call last):
File "code1.py", line 1, in <module>
intAnswer = int(input("In what year were you born? "))
ValueError: invalid literal for int() with base 10: 'oops'
As you know, exceptions will normally halt your program immediately, and that's something we'd like to avoid!

Catching Exceptions with "try / except"
Fortunately, it is possible to build a safety net in your code! When exceptions happen at run-time, you can "catch" them with protective code that will handle the error gracefully instead of halting the program with an ugly error message.

Whenever you write code that can possibly throw an exception, you can indent that code inside a "try" block. Start with the "try" keyword, followed by a colon. Then, underneath, indent the risky code inside the body of the "try" area.

try:
intAnswer = int(input("In what year were you born? "))
floatAnswer = float(input("How much do you want to spend on a milkshake? "))
Copy
To end the "try" block, use the "except" keyword, again followed by a colon. "except" defines another block of code that will run only if an exception happens from a statement inside the "try" block.

try:
intAnswer = int(input("In what year were you born? "))
floatAnswer = float(input("How much do you want to spend on a milkshake? "))
except:
print("You entered an incorrect value!")
Copy
As summarized in the diagram below, the statements inside a "try" block will run normally. If no exception happens (green path), the "except" block will be skipped and the program flow will continue after the indented "except" block. But if an exception happens anywhere inside a "try" block, the program flow (red path) will immediately move to the "except" block, and the remaining statements inside "try" are skipped.

Illustration of exception flow

We've improved our sample code with try / except around the risky parts. Run it, enter some invalid data and observe the results!

Try It Now


The statement(s) inside the "except" block will only run if some exception happens. Otherwise, the code will continue normally and the "except" statements are skipped. You can verify this by re-running the example and entering correct data that won't cause an exception.

Using "else" or "finally" with "try / except"
You may want to run some code after the "try / except" blocks are finished, and you can add optional "else" or "finally" blocks at the end. These statements will mark blocks of code that run either when no exceptions happened ("else") or no matter what happened ("finally").

We've added an "else" and "finally" block at the end of our example. Try running it with both valid and invalid inputs. Can you predict the messages that will be printed in each case?

Try It Now


Validating Numeric Ranges
When your program asks the user for a numeric value, will any value work, or should the answer be limited to a particular range? Imagine asking the user for his or her age, and getting a valid integer input like 9001. That's an unreasonably large number that may actually cause problems later in your program. The user also might enter a negative value like -50 that doesn't make any sense at all.

You may wish to validate a numeric input to make sure it is between some minimum and maximum value. A human age, for example, might be limited to an integer between 0 and 150. You don't need any special Python keywords or functions to handle this validation. Just write some "if" logic with comparison operators. In the example below, we limit the year to a number between 1900 and 2050 and the cost of a milkshake to a value between $0.50 and $10.00.

Try It Now


The exact nature of the error-handling logic will depend on your program. How should your "if" logic and "try/except" blocks be laid out to correctly validate your particular situation? What needs to be done when invalid input is detected? That's for you to decide!

Looping until Successful
Users will often want a chance to correct any mistakes made when entering data. It can be frustrating if your program simply prints an error message and quits when the first small problem arises! Consider writing loops to continue gathering user input until the correct data is received.

A "while" loop usually makes a good choice for validation. You want to loop "while" the user has not yet entered the correct information. Of course, the exact details are up to you and depend on your program needs. You might also consider a "for" loop that will only give the user a certain number of chances before giving up.

Let's return to our example one last time and add a "while" loop around each of the input values. Notice that we are now using two different "try / except" blocks - one for each of the values. One "while" loop surrounds the first input validation area and another "while" loop covers the second area.
Again, your own programs may require different validation logic! You can make decisions like limiting the number of retries, giving hints, or performing different kinds of validations. As a programmer, you should be comfortable testing conditions, writing loops, and "if / else" logic to get the program behavior you want. The new "try / except" blocks are just another tool in your kit to help validate input values.

As you can see, validating user input can take some effort and quite a few lines of code. Professionally written programs must include this kind of validation logic because they are used by many people that may or may not follow instructions. We are going to make sure you know how to write validation logic yourself in this chapter. However, later in the course, our examples may skip most of the validation steps to keep the code short and focused on new skills.

1. If you pass a string that does not contain a valid integer or floating point number into the int() or float() functions, what will happen?
Select one:

a.
Both functions will return the length of the input string

b.
You will receive a ValueError exception at runtime

c.
Both functions will return 0

d.
Both functions will produce random output

b. You will receive a ValueError exception at runtime

2. When using try / except to protect risky code, where should you place statements that are likely to throw a runtime exception?

Select one:

a.
After the indented block of "except" statements

b.
Indented underneath the "except" statement

c.
Before the "try" statement

d.
Indented underneath the "try" statement

d. Indented underneath the "try" statement

3. Consider the code below. When it runs, if the user enters a valid integer at the first input() prompt, but an invalid floating point number for the second input prompt, which print() statements will display on the screen?

try:
intAnswer = int(input("Enter an integer: "))
print("Stage 1")
floatAnswer = float(input("Enter a floating point number: "))
print("Stage 2")
except:
print("OOPS")
Select one:

a.
"OOPS"

b.
"Stage 1", "Stage 2" and "OOPS"

c.
"Stage 1" and "Stage 2"

d.
"Stage 1" and "OOPS"

c. "Stage 1" and "Stage 2"

4. If you want to ensure user input is both numeric and within a specific range, which of the following types of code should be used in the validation?

Select one:

a.
Conditional logic only

b.
It's not possible to restrict numeric input to a range

c.
Both conditional logic and try / except protection

d.
try / except protection only

a. Conditional logic only

5. Why might you use a "while True:" loop to surround your user input and validation logic?

Select one:

a.
You want to ask the user for input and repeat the process forever

b.
You want to loop until the user successfully enters valid input, and then your logic will break out of the loop

c.
You want to give the user 3 chances to give valid input

d.
You want to ask the user for input exactly one time

b. You want to loop until the user successfully enters valid input, and then your logic will break out of the loop