livepython.net
CHAPTER 17Handling Errors (Exceptions)
17.5  SAFE INPUT

Python Input Validation: Ask Again with try except

Ask Again Until the User Types a Number

Input validation means checking what the user typed before you use it. With while True, try and except together, your program can keep asking until it gets a real number, instead of crashing at the first typo.

PYTHONedit me
while True:
    try:
        number = int(input())
        break
    except ValueError:
        print("Please type a whole number.")
print("You typed", number)
OUTPUT
Please type a whole number.
Please type a whole number.
You typed 7

The Input box has three lines. abc and 2.5 fail, and the program asks again. 7 works, and the loop ends.

This is the promise from chapters 7 and 11: no more crashes when the user types a word instead of a number.

Think of it like a ticket machine that gives your coin back when it doesn't fit, and waits for another one. It never breaks down. It just asks again.

How it works

  1. while True: repeats forever, until a break (chapter 11).
  2. Inside the try, int() tries to convert the input.
  3. If it works, the next line, break, ends the loop.
  4. If it fails, Python jumps to except, skipping the break. The message prints, and the loop asks again.
  5. After the loop, number is sure to be a whole number.

The same loop with else

You can also put the break in an else block. It runs only when int() worked:

while True:
    try:
        number = int(input())
    except ValueError:
        print("Please type a whole number.")
    else:
        break

Both versions work the same way. The else version keeps the try block to the one risky line.

Common beginner doubt: "Isn't while True an endless loop?" Only if nothing ever reaches the break. Here the break runs as soon as the user types a valid number, so the loop always has a way out.

while True, try int(input()), break on success, and print a message in except.

your turnPredict the output

What will this print?

while True: try: n = int(input()) break except ValueError: print("again") print("got", n)

The user types: ten10

Your turn! What will this code show on the screen?
your turnFill the gap

End the loop when the number is valid

while True: try: n = int(input()) ? except ValueError: print("Try again") print(n * 2)

The user types: x4

It should print: Try again 8

Which piece makes this code work?

Check the Range Too: Valid Number, Valid Value

A number can be a real number and still be wrong for your program: marks of 150, an age of -3. Good input validation checks two things: is it a number, and is it in the allowed range?

PYTHONedit me
while True:
    try:
        marks = int(input())
    except ValueError:
        print("Please type a whole number.")
        continue
    if 0 <= marks <= 100:
        break
    print("Marks must be 0 to 100.")
print("Saved:", marks)
OUTPUT
Please type a whole number.
Marks must be 0 to 100.
Saved: 85

Each bad answer gets its own message: abc isn't a number, and 150 is a number but too big. 85 passes both checks.

Think of it like a form at a doctor's office. The first check: did you write a number in the age box? The second: is it a believable age?

How it works

  1. try the conversion. If it fails, print a message and continue: jump back to the top of the loop and ask again (chapter 10).
  2. If the conversion worked, check the range with if. Inside the range: break.
  3. Outside the range: print a message. The loop goes round and asks again.

Another way: raise

You can also let raise send a bad range to the same except:

PYTHONedit me
while True:
    try:
        age = int(input())
        if age < 1 or age > 120:
            raise ValueError("Age must be 1 to 120.")
        break
    except ValueError as e:
        print("Try again:", e)
print("Age:", age)
OUTPUT
Try again: Age must be 1 to 120.
Age: 35

This version is shorter, but there's a catch: if the user types abc, they see Python's message, invalid literal for int() with base 10: 'abc'. The first version gives a friendly message for each problem, which is better for users.

Common beginner doubt: "Can I check the range in the while condition, like in chapter 11?" With while True, the loop has no condition to change. All the checks live inside the loop, and break is the only way out. That keeps every check in one place.

First check that it's a number, then check that it's in range. Only break when both pass.

your turnFix the code

Fix the loop so it prints: Try again, then Got 4

It should print: Try again Got 4

The user types: abc4

while True:
    try:
        n = int(input())
    except ValueError:
        print("Try again")
        break
print("Got", n)
This code does not work yet. Fix it, then press Run.
your turnType the output

Type what this prints

n = 1 while n < 20: n *= 3 print(n)
Read the code line by line, then type the output exactly.

A Reusable Function for Safe Input

When a program asks for several numbers, writing the same loop again and again gets long. Put the loop in a function (chapter 15), and call it whenever you need a safe number.

PYTHONedit me
def ask_int():
    while True:
        try:
            return int(input())
        except ValueError:
            print("Please type a whole number.")

a = ask_int()
b = ask_int()
print("Sum:", a + b)
OUTPUT
Please type a whole number.
Sum: 15

return does the job of break here: as soon as int() works, the function hands the number back and stops, and the loop stops with it.

Think of it like a receptionist at a front desk. Every visitor goes through the same check, and you only have to train the receptionist once.

Add the range as parameters

Parameters (chapter 15) make the function work for any range:

PYTHONedit me
def ask_int(low, high):
    while True:
        try:
            number = int(input())
        except ValueError:
            print("Please type a whole number.")
            continue
        if low <= number <= high:
            return number
        print(f"Please type a number from {low} to {high}.")

month = ask_int(1, 12)
day = ask_int(1, 31)
print(f"Date: {day}/{month}")
OUTPUT
Please type a number from 1 to 12.
Please type a whole number.
Date: 15/4

Follow the four input lines: 13 is a number, but too big for a month, so the function asks again. 4 is fine. For the day, first isn't a number at all, and 15 is fine. Each call checks with its own range.

The rules

  • One function, one job: get a valid number and return it.
  • The loop and the try live inside the function, so the rest of the program stays short and clean.
  • Give the function a clear name, like ask_int (PEP 8, chapter 16).

Common beginner doubt: "Should the function print the question, like Month:?" In real programs, yes: you'd give input() a prompt. In these lessons and the practice questions, input() has no prompt, so the output stays easy to check.

Put the safe-input loop in a function, and return the number as soon as it's valid.

your turnOrder the lines

Put the safe-input function in order

  1. print("Number please")
  2. try:
  3. print(ask_int() * 3)
  4. def ask_int():
  5. while True:
  6. return int(input())
  7. except ValueError:

The user types: one2

These lines are mixed up. Put them back in order, then press Check.

Common Input Validation Mistakes

Input loops are short, but a small slip can make them loop forever or crash anyway. These are the common mistakes; learn them now, and you'll spot them in seconds.

Think of this list as a pre-flight checklist: run through it whenever an input loop doesn't behave.

1. input() outside the loop

text = input()
while True:
    try:
        number = int(text)
        break
    except ValueError:
        print("Please type a whole number.")

Don't run this one! If the first answer is bad, the loop converts the same text again and again, and prints the message forever. The input() must be inside the loop, so every round gets a new answer.

2. break in the wrong place

A break inside the except block ends the loop exactly when the input is bad. The variable was never set, and the next line crashes:

PYTHONedit me
while True:
    try:
        n = int(input())
    except ValueError:
        print("Try again")
        break
print(n + 1)
OUTPUT
Try again
NameError: name 'n' is not defined

The break belongs right after the line that can fail, inside the try, or in an else block.

3. A bare except in a loop

A bare except: in an input loop is even worse than usual. A typo in the try block fails every round, and the loop asks forever, printing a message that blames the user:

while True:
    try:
        number = int(inptu())    # a typo: NameError every time
        break
    except:
        print("Please type a whole number.")

With except ValueError:, the typo shows up at once as a NameError, and you fix it.

4. Converting outside the try

PYTHONedit me
while True:
    number = int(input())
    try:
        print("Double:", number * 2)
        break
    except ValueError:
        print("Please type a whole number.")
OUTPUT
ValueError: invalid literal for int() with base 10: 'abc'

The int() line is the risky one, so it must be inside the try. Here it sits above it, unprotected, and a bad answer still crashes the program. The try only guards a line that can't fail.

Common beginner doubt: "How do I test an input loop?" Type a bad answer first, then a good one, like abc, then 7. Make sure you see the message once, and then the result.

Keep input() and int() inside the loop and inside the try, break only on success, and name the error.

your turnSpot the bug

Which line breaks?

The user types: abc

One line stops this program. Tap it.
your turnPick the right idea

Where should input() go in a safe-input loop?

Think about it, then pick one.

Practice: Safe input

Solve these to lock in what you learned in this topic. Each one runs in your browser.

  1. 158.Python Program to Keep Asking for a Valid AgeMediumSolve
  2. 159.Python Program to Make a Safe CalculatorHardSolve