Python input(): get user input and validate it
Python input() always returns a string. Learn to convert it, catch bad answers, ask again in a loop, and reuse that in a function.

Why does input() hand you text when you asked how many tickets someone wants, and how do you ask again when the answer is wrong?
Short answer: input() always returns a string. Convert it with int() or float(), catch the ValueError when that fails, and keep asking in a loop until the value is one your program can use.
By the end of this post you will ask for a ticket count, reject a blank line, a word and a zero, wrap that in a function you can reuse, and validate a yes-or-no answer too. If input() is new, start with Asking With Input (opens in a new tab). If loops are still shaky, While Loops (opens in a new tab) is the prerequisite.
input() always returns a string
input() prints a prompt, pauses your program, and waits for the person at the keyboard to press Enter. Whatever they typed comes back as a string, even when it looks like a number.
raw = input("How many tickets? ") # always a string, even if they type 2
print(type(raw)) # <class 'str'>If they type 2, raw is the string "2", not the number 2. You can print it, but you can't do ticket math with it yet. "2" * 3 gives you "222", and "2" + 12 raises TypeError: can only concatenate str (not "int") to str.
End the prompt with a space, as in "How many tickets? ". Otherwise the answer sits right up against the question mark.
Convert the text with int() or float()
int() turns a string of digits into a whole number. float() does the same for a number with a decimal point. Use int() for a ticket count, because half a ticket isn't an order you can sell.
raw = input("How many tickets? ")
count = int(raw) # "2" becomes 2
print(count * 12) # 24int() is forgiving about spaces at the ends, so int(" 2 ") is still 2. It isn't forgiving about anything else. Each of these raises ValueError: invalid literal for int() with base 10:
- a word, like
"two" - a blank line,
"" - a decimal, like
"2.5"
That error isn't a problem. It's the signal you want, because it tells you the answer wasn't a whole number, which is exactly when you should ask again. Converting Input (opens in a new tab) stays on this step.
Ask again until the answer is valid
One input() is fine when you trust the person typing. A ticket booth can't. You want a loop that keeps the question open until the answer passes every check, and a message after each failure that tells them what to fix.
while True:
raw = input("How many tickets? ").strip()
if raw == "":
print("Please type a number.")
continue
try:
count = int(raw)
except ValueError:
print(f"'{raw}' isn't a whole number.")
continue
if count < 1:
print("Order at least one ticket.")
continue
break
print(f"{count} ticket(s) for ${count * 12}")Here's what happens on each pass:
.strip()removes spaces at the ends, so someone who only pressed the space bar counts as a blank answer.- A blank answer gets its own friendlier message, then
continuegoes back to the question. int()runs insidetry. If it raisesValueError, theexceptbranch explains and asks again, instead of crashing the program.- A number that converts can still be wrong.
0and-3are valid integers but bad orders, so the range check comes after the conversion. - Only an answer that survives all three checks reaches
break, andcountis a real number you can multiply by a price.
This is the pattern Re Asking Until Valid (opens in a new tab) practices, and Try And Except (opens in a new tab) covers try and except in more depth.
Wrap it in a function you can reuse
Most programs ask more than one question. Instead of copying the loop, put it in a function that returns the first valid answer.
def ask_int(prompt, minimum=1):
while True:
raw = input(prompt).strip()
try:
value = int(raw)
except ValueError:
print("Please type a whole number.")
continue
if value < minimum:
print(f"Please type {minimum} or more.")
continue
return value
tickets = ask_int("How many tickets? ")
children = ask_int("How many are for children? ", minimum=0)return ends both the loop and the function, so there's no break to forget. A blank line is handled too, because int("") raises the same ValueError. The minimum argument lets each question set its own rule: you need at least one ticket, but zero children is a perfectly good answer.
Validate text answers too
Not every answer is a number. For a yes-or-no question, clean the text first, then check it against the answers you accept.
def ask_yes_no(prompt):
while True:
answer = input(prompt).strip().lower()
if answer in ("y", "yes"):
return True
if answer in ("n", "no"):
return False
print("Please answer yes or no.")
if ask_yes_no("Add popcorn? (y/n) "):
print("Popcorn added.").lower() means Yes, YES and yes all match. The function returns a real True or False, so the rest of your program never has to look at the raw text again. The same shape works for a menu: check the answer against a list of choices, and ask again if it isn't one of them. Cleaning Text (opens in a new tab) covers the string methods that do the cleaning.
Why not just use isdigit()?
You might see if raw.isdigit(): used instead of try. It looks simpler, but it gets edge cases wrong in both directions:
"-3".isdigit()isFalse, so it rejects negative numbers even when your program should allow them."²".isdigit()isTrue, butint("²")still raisesValueError, so the program can crash on an answer that passed the check.
Letting int() decide, and catching ValueError, is the safer default. isdigit() is still useful for checking text, which Testing Text (opens in a new tab) covers.
Common mistakes
count = int(input("How many tickets? "))
# crashes with ValueError on a word, a blank line, or 2.5- Converting with no
try. The one-liner above is fine in a quick experiment, but one typo ends the program. Putint()insidetryand ask again. - Keeping the string and doing math later. Convert once, store the number, and use that name everywhere after.
- Skipping the range check.
-3converts cleanly and is still a bad order. Check the range after the conversion, not instead of it. - Trusting float() too much.
float()accepts"nan","inf"and"1e3". If you ask for a price, check the result is a sensible number, not just that it converted. - Using
input()where there's no keyboard. A file, a web form or an API response isn't a person typing. When a program has no keyboard attached,input()raisesEOFError. Read the file or the request instead, then run the same checks on that value.
Quick recap
input()returns a string, even when it looks like a number.int()andfloat()convert it, and raiseValueErrorwhen they can't.- Loop with
tryandexceptuntil the answer converts, then check its range. - Put the loop in a function that returns a clean value, and reuse it.
- For text answers,
.strip().lower(), then check against the answers you accept.
Frequently asked questions
What does Python input() return?
Always a string. The prompt you pass in is only the message on screen. The value is whatever was typed before Enter, without the newline.
How do I get a number from input()?
Wrap it in int() for a whole number or float() for a decimal, and catch ValueError in case they typed something that isn't a number.
How do I ask again when the input is invalid?
Put the question in a while True loop. Use continue after each failed check, and break or return once you have a value that passes them all.
Why does int("2.5") fail?
int() only reads whole numbers. Use float("2.5") if a decimal is allowed, or ask again if you need a whole number.
How can someone quit a loop that keeps asking?
Pressing Ctrl+C stops the program with KeyboardInterrupt. For a friendlier exit, accept a word like q before you convert: if raw == "q": break.
Practice
The matching exercises run in your browser, with nothing to install: Asking With Input (opens in a new tab), then Converting Input (opens in a new tab), then Re Asking Until Valid (opens in a new tab). Cinema Tickets (opens in a new tab) puts all three into one small program, and Unbreakable Calculator (opens in a new tab) does the same with error handling. For quick reps on the conditions and loops behind this pattern, try the Python Conditionals and Python Loops challenges.
Where to go next
Open Asking With Input (opens in a new tab) and type the ticket question yourself. If loops still feel new, start with Python for Beginners (opens in a new tab) and come back. For the bigger picture, our Python roadmap for your first 30 days shows where input and validation fit.







