Python Arena
Step 1 of 5

Checking input before using it

Errors come in two kinds. A syntax error means Python can't read the program at all, so none of it runs; the very first module showed some. A runtime error happens while the program is running: a line that is perfectly good Python fails with certain data. Such a program can work a hundred times and fail the hundred and first, when someone types something unexpected. Runtime errors are what this module is about.

Many of them come from input a program didn't expect:

  • a number outside what makes sense, such as a negative price or month 13;
  • text where a number was expected;
  • an empty string where a name was expected;
  • the name of a file that doesn't exist;
  • an index past the end of a list or a string.

Checking values with if

The first defense is to check a value before using it. This is called input validation:

tickets = int(input("How many tickets? "))
if tickets >= 1 and tickets <= 10:
    print(f"Total: {tickets * 15} euros")
else:
    print("You can buy 1 to 10 tickets at a time.")
Input
12
Output
How many tickets? 12
You can buy 1 to 10 tickets at a time.

A loop that asks again

Instead of giving up, a program can keep asking until the input is valid. The loop ends with break only when the value passes the check:

while True:
    month = int(input("Month (1-12): "))
    if month >= 1 and month <= 12:
        break
    print("There's no such month.")
print("You chose month", month)
Input
0
13
7
Output
Month (1-12): 0
There's no such month.
Month (1-12): 13
There's no such month.
Month (1-12): 7
You chose month 7

Strings get checked the same way: if name == "": notices an empty name, and len(password) < 8 a password that's too short.

When the input isn't a number at all

The checks above work only once int has converted the input. If the user types two, the conversion itself fails, and the program stops before it ever gets to the if:

tickets = int(input("How many tickets? "))
if tickets >= 1 and tickets <= 10:
    print(f"Total: {tickets * 15} euros")
else:
    print("You can buy 1 to 10 tickets at a time.")
Input
two
Output
How many tickets? two
Python stops with
Traceback (most recent call last):
  File "main.py", line 1, in <module>
    tickets = int(input("How many tickets? "))
ValueError: invalid literal for int() with base 10: 'two'

A ValueError means a value of the right type (here a string) has contents that don't work: int can't make a whole number out of two. An if can't prevent this, but the next step shows how a program can catch the error and carry on.

Your task

Challenge 1 of 3

Fill in the blanks so the program accepts a rating from 1 to 5 stars and rejects anything else. A run looks like this:

Rating (1-5): 4
Thanks for rating us 4

Challenge 2

Write a program that asks for a new password until it's valid, and then prints Password saved. A valid password has at least 8 characters and no spaces. A password that's too short gets the message Too short; one with a space in it gets No spaces, please. (Check the length first.)

A run looks like this:

New password: cat
Too short
New password: my secret pw
No spaces, please
New password: Tr0ub4dor
Password saved

Challenge 3

Write a function is_valid_date(day, month) that returns True if the day and month make a real date in a year that isn't a leap year, and False if they don't. The starter code has the number of days in each month in a list.

Check the month before you use it as an index: a month like 13 would stop the program with an IndexError, and month 0 would quietly give index -1, which is December.

For example, is_valid_date(31, 1) returns True, and is_valid_date(30, 2) returns False.