If you’ve ever coded an interactive text-based application in Python, then you’ve probably found that you need a reliable way of asking the user for integers as input. It’s not enough simply to display a prompt and then gather keystrokes. You must check that the user’s input really represents an integer. If it doesn’t, then your code must react appropriately—typically by repeating the prompt.
In this tutorial, you’ll learn how to create a reusable utility function that’ll guarantee valid integer inputs from an interactive user. Along the way, you’ll learn about Python’s tools for getting a string from the console and converting that string into an integer.
Whenever you’re writing a program that interacts with the keyboard, you must code defensively to manage invalid inputs, so you’ll also learn the most Pythonic way to deal with this situation. You’ll handle any errors robustly inside a function that’s guaranteed to return nothing but integers.
Free Download: Click here to download the sample code that you’ll use to get integer input from users in Python.
How to Get Integer Input Values in Python
Python’s standard library provides a built-in tool for getting string input from the user, the input()
function. Before you start using this function, double-check that you’re on a version of Python 3. If you’d like to learn why that’s so important, then check out the collapsible section below:
Python 2’s version of the input()
function was unsafe because the interpreter would actually execute the string returned by the function before the calling program had any opportunity to verify it. This allowed a malicious user to inject arbitrary code into the program.
Because of this issue, Python 2 also provided the raw_input()
function as a much safer alternative, but there was always the risk that an unsuspecting programmer might choose the more obviously-named input()
.
Python 3 renamed raw_input()
to input()
and removed the old, risky version of input()
. In this tutorial, you’ll use Python 3, so this pitfall won’t be a concern.
In Python 3, the input()
function returns a string
, so you need to convert it to an integer. You can read the string, convert it to an integer, and print the results in three lines of code:
>>> number_as_string = input("Please enter an integer: ")
Please enter an integer: 123
>>> number_as_integer = int(number_as_string)
>>> print(f"The value of the integer is {number_as_integer}")
The value of the integer is 123
When the above snippet of code is executed, the interpreter pauses at the input()
function and prompts the user to input an integer. A blinking cursor shows up at the end of the prompt, and the system waits for the user to type an arbitrary string of characters.
When the user presses the Enter key, the function returns a string containing the characters as typed, without a newline. As a reminder that the received value is a string, you’ve named the receiving variable number_as_string
.
Your next line attempts to parse number_as_string
as an integer and store the result in number_as_integer
. You use the int()
class constructor to perform the conversion.
Finally, the print()
function displays the result.
Dealing With Invalid Input
You’ve probably already noticed that the above code is hopelessly optimistic. You can’t always rely on users to provide the kind of input that you expect. You can help a lot by providing an explicit prompt message, but through confusion, carelessness, or malice, there’ll always be users who provide invalid input. Your program should be ready to deal with any kind of text.
The input()
function can return arbitrary text, or even an empty string if the user pressed Enter immediately at the prompt. How can you ensure that your program doesn’t attempt to perform arithmetic with a mess of characters when it’s expecting an int
?
You’re going to leverage Python’s own error-handling mechanism. By default, the integer conversion will throw a ValueError
exception if it fails. Try the above code again, but this time, notice how it behaves with bad input:
>>> number_as_string = input("Please enter an integer: ")
Please enter an integer: rutabaga
>>> number_as_integer = int(number_as_string)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'rutabaga'
You’ll observe that this error occurs not in the line where the value is entered but in the one where you try to convert it using the built-in function int()
. It’s up to you to handle this ValueError
exception if it occurs.
It seems a little more care is needed to ensure that your program gets good integer values. You’ll take care of that next.
Filtering Your Input for Valid Integers
You’ve seen that the Python standard library’s input()
function allows the user to type just about anything at the prompt. You need to be sure that you can interpret what you have as an integer.
You can take one of two approaches here: LBYL or EAFP, which stand for Look Before You Leap and Easier to Ask Forgiveness Than Permission, respectively. Basically, in LBYL, you aim to prevent errors from happening. EAFP focuses on handling errors after they’ve occurred.
Briefly, the LBYL strategy would be to check the input carefully before attempting the conversion. EAFP, on the other hand, plunges in headlong by immediately attempting the conversion, counting on Python’s exception handling to deal with any errors.
Although LBYL may seem like a more sophisticated approach, it often introduces complex error-checking logic and conditional flows into what should be a straightforward operation. Furthermore, you must perform the error checking on every input, even when it’s valid.
In your use case of checking for integers, the EAFP approach results in code that’s not only simpler, but also faster. If a valid integer is supplied, then you won’t waste any time checking for nonexistent error conditions. On the other hand, if the string is invalid, then Python will throw a built-in ValueError
exception.
In Python, you handle exceptions in a try
… except
block. By wrapping the try
… except
block inside a while
loop, you can guarantee that only integers will make it through. A mechanism like this is sometimes called a retry loop.
Here’s an example of how you can write this nearly bulletproof code:
1>>> number_as_integer = None
2>>> while number_as_integer is None:
3... try:
4... number_as_integer = int(input("Please enter an integer: "))
5... except ValueError:
6... print("Invalid integer!")
7...
8>>> print(f"The integer you entered was {number_as_integer}")
You’ve nested the call to input()
inside the call to int()
. This does no harm, since only the int()
function can fail.
Now, if the user’s string can be parsed as a valid integer, then that value is assigned to number_as_integer
before the interpreter returns to the top of the loop and retests the while
condition. Since this condition is now False
, the loop terminates, and execution continues at line 8 with a valid integer value.
If, however, the user’s string is invalid, then a ValueError
is thrown and the interpreter skips straight to the except
branch, where it prints the error message before looping back to the while
statement in line 2. In this case, number_as_integer
is still None
, so the loop executes again.
The result of this logic is that your code simply refuses to proceed until it’s acquired a valid integer.
Creating a Utility Function to Read Valid Integers
The code above works well enough, but it’s not very reusable. If you copy and paste it into some other logic, then you’ll probably need to adjust the name of the number_as_integer
variable and modify the prompts to suit the new situation. This approach risks introducing careless errors.
It would be much better to wrap the code into your own robust function. Once it’s been properly tested, you can treat this function as a sort of black box—a foolproof, low-effort source of user-input integers for all your projects.
Here’s how you can go about it. Since you may reuse your function in a variety of situations, it’ll provide a configurable prompt as well as an optional error message:
>>> def get_integer(prompt: str, error_message: str = "") -> int:
... while True:
... try:
... return int(input(prompt))
... except ValueError:
... print(error_message)
...
The advantage of having a function like get_integer()
in your arsenal is that it takes care of common errors internally, so the code that calls it can remain simple.
After you’ve defined your new function in the REPL as above, here’s how you can test it:
>>> print(get_integer("Please enter an integer: "))
Please enter an integer: foobar
Please enter an integer:
Please enter an integer: -123
-123
>>> print(
... get_integer(
... prompt="Enter a value for n: ",
... error_message="n must be an integer."
... )
... )
Enter a value for n: jabberwocky
n must be an integer.
Enter a value for n: 3.1415
n must be an integer.
Enter a value for n: 999
999
If you find the get_integer()
function useful, then you can save it in a module for import. Mastering absolute and relative imports in Python is a great skill that can boost your code’s reusability.
For demonstration purposes, you can simply save the function, exactly as you defined it above, in a file named get_integer.py
. Then, to make it available to another module within the same virtual environment and the same directory, you just need the following line at the top of test.py
, for example:
# test.py
from get_integer import get_integer
The get_integer()
function is a very simple example of reusable code. Once you’ve saved it in a module, you can call on it whenever you need a foolproof means of getting integers from the user.
Conclusion
Now you’re ready to take user input without fear! Even if your user doesn’t type a valid integer at first, you can be confident that no garbage data will ever make its way into your program. Your function will doggedly continue to ask for input until it gets a valid integer. With that concern out of the way, you’re free to concentrate on the more fun parts of your project.
In this tutorial, you’ve learned how to:
- Use the Python standard library’s
input()
function to get string input from the user - Convert the string value to an integer value
- Handle errors when the input string isn’t a well-formed integer
- Create a robust, reusable function that you can incorporate into many projects
Code reuse is an important topic in software engineering. The best way to build reliable code is from small, reliable components. Your get_integer()
function is one example of this.
Free Download: Click here to download the sample code that you’ll use to get integer input from users in Python.
Next Steps
In this tutorial, you’ve explored one particular strategy for validating user input. Now that you understand what goes into basic input validation in Python, you may be interested in some open-source projects that not only address this problem but also include some more sophisticated functionality:
Here’s an example of how you could use cooked_input.get_int()
just like your custom get_integer()
function:
from cooked_input import get_int
age = get_int(prompt="Enter your age")
If you’d like more detail on Python input and output operations in general, then you can read Basic Input, Output, and String Formatting in Python and the official documentation. Plus, you can find more information on Python’s numeric types in the Numbers in Python tutorial.
May all your integers be valid ones!