How can I limit the user input to only integers in Python
Question:
I’m trying to make a multiple choice survey that allows the user to pick from options 1-x. How can I make it so that if the user enters any characters besides numbers, return something like "That’s an invalid answer"
def Survey():
print('1) Blue')
print('2) Red')
print('3) Yellow')
question = int(input('Out of these options(1,2,3), which is your favourite?'))
if question == 1:
print('Nice!')
elif question == 2:
print('Cool')
elif question == 3:
print('Awesome!')
else:
print('That's not an option!')
Answers:
One solution amongst others : use the type
function or isinstance
function to check if you have an ̀int
or a float
or some other type
>>> type(1)
<type 'int'>
>>> type(1.5)
<type 'float'>
>>> isinstance(1.5, int)
False
>>> isinstance(1.5, (int, float))
True
Your code would become:
def Survey():
print('1) Blue')
print('2) Red')
print('3) Yellow')
while True:
try:
question = int(input('Out of these options(1,2,3), which is your favourite?'))
break
except:
print("That's not a valid option!")
if question == 1:
print('Nice!')
elif question == 2:
print('Cool')
elif question == 3:
print('Awesome!')
else:
print('That's not an option!')
The way this works is it makes a loop that will loop infinitely until only numbers are put in. So say I put ‘1’, it would break the loop. But if I put ‘Fooey!’ the error that WOULD have been raised gets caught by the except
statement, and it loops as it hasn’t been broken.
I would catch first the ValueError
(not integer) exception and check if the answer is acceptable (within 1, 2, 3) or raise another ValueError
exception
def survey():
print('1) Blue')
print('2) Red')
print('3) Yellow')
ans = 0
while not ans:
try:
ans = int(input('Out of these options(1, 2, 3), which is your favourite?'))
if ans not in (1, 2, 3):
raise ValueError
except ValueError:
ans = 0
print("That's not an option!")
if ans == 1:
print('Nice!')
elif ans == 2:
print('Cool')
elif ans == 3:
print('Awesome!')
return None
The best way would be to use a helper function which can accept a variable type along with the message to take input.
def _input(message, input_type=str):
while True:
try:
return input_type (input(message))
except:pass
if __name__ == '__main__':
_input("Only accepting integer : ", int)
_input("Only accepting float : ", float)
_input("Accepting anything as string : ")
So when you want an integer , you can pass it that i only want integer, just in case you can accept floating number you pass the float as a parameter. It will make your code really slim so if you have to take input 10 times , you don’t want to write try catch blocks ten times.
def func():
choice = "Wrong"
while choice.isdigit()==False :
choice = input("Enter a number: ")
if choice.isdigit()==False:
print("Wrongly entered: ")
else:
return int(choice)
I made a module for cases like this called restricted_input which checks the input in real time. Here, since you only need inputs from 1-3, this would do
from restricted_input import r_input
num = int(r_input("Out of these options(1,2,3), which is your favourite? ", input_type="nothing", allow="123", maxlength=1))
It uses msvcrt.getch/termios to get non-blocking input, so it checks it in real time and allows only the specified characters.
Note: This will not work in IDLEs like Spyder, Jupyter etc.
You can use a module named PyInputPlus.
Installation:
pip install PyInputPlus
You can use this as
def Survey():
print('1) Blue')
print('2) Red')
print('3) Yellow')
question = int(input('Out of these options(1,2,3), which is your favourite?'))
if question == 1:
print('Nice!')
elif question == 2:
print('Cool')
elif question == 3:
print('Awesome!')
else:
print('That's not an option!')
I’m trying to make a multiple choice survey that allows the user to pick from options 1-x. How can I make it so that if the user enters any characters besides numbers, return something like "That’s an invalid answer"
def Survey():
print('1) Blue')
print('2) Red')
print('3) Yellow')
question = int(input('Out of these options(1,2,3), which is your favourite?'))
if question == 1:
print('Nice!')
elif question == 2:
print('Cool')
elif question == 3:
print('Awesome!')
else:
print('That's not an option!')
One solution amongst others : use the type
function or isinstance
function to check if you have an ̀int
or a float
or some other type
>>> type(1)
<type 'int'>
>>> type(1.5)
<type 'float'>
>>> isinstance(1.5, int)
False
>>> isinstance(1.5, (int, float))
True
Your code would become:
def Survey():
print('1) Blue')
print('2) Red')
print('3) Yellow')
while True:
try:
question = int(input('Out of these options(1,2,3), which is your favourite?'))
break
except:
print("That's not a valid option!")
if question == 1:
print('Nice!')
elif question == 2:
print('Cool')
elif question == 3:
print('Awesome!')
else:
print('That's not an option!')
The way this works is it makes a loop that will loop infinitely until only numbers are put in. So say I put ‘1’, it would break the loop. But if I put ‘Fooey!’ the error that WOULD have been raised gets caught by the except
statement, and it loops as it hasn’t been broken.
I would catch first the ValueError
(not integer) exception and check if the answer is acceptable (within 1, 2, 3) or raise another ValueError
exception
def survey():
print('1) Blue')
print('2) Red')
print('3) Yellow')
ans = 0
while not ans:
try:
ans = int(input('Out of these options(1, 2, 3), which is your favourite?'))
if ans not in (1, 2, 3):
raise ValueError
except ValueError:
ans = 0
print("That's not an option!")
if ans == 1:
print('Nice!')
elif ans == 2:
print('Cool')
elif ans == 3:
print('Awesome!')
return None
The best way would be to use a helper function which can accept a variable type along with the message to take input.
def _input(message, input_type=str):
while True:
try:
return input_type (input(message))
except:pass
if __name__ == '__main__':
_input("Only accepting integer : ", int)
_input("Only accepting float : ", float)
_input("Accepting anything as string : ")
So when you want an integer , you can pass it that i only want integer, just in case you can accept floating number you pass the float as a parameter. It will make your code really slim so if you have to take input 10 times , you don’t want to write try catch blocks ten times.
def func():
choice = "Wrong"
while choice.isdigit()==False :
choice = input("Enter a number: ")
if choice.isdigit()==False:
print("Wrongly entered: ")
else:
return int(choice)
I made a module for cases like this called restricted_input which checks the input in real time. Here, since you only need inputs from 1-3, this would do
from restricted_input import r_input
num = int(r_input("Out of these options(1,2,3), which is your favourite? ", input_type="nothing", allow="123", maxlength=1))
It uses msvcrt.getch/termios to get non-blocking input, so it checks it in real time and allows only the specified characters.
Note: This will not work in IDLEs like Spyder, Jupyter etc.
You can use a module named PyInputPlus.
Installation:
pip install PyInputPlus
You can use this as
def Survey():
print('1) Blue')
print('2) Red')
print('3) Yellow')
question = int(input('Out of these options(1,2,3), which is your favourite?'))
if question == 1:
print('Nice!')
elif question == 2:
print('Cool')
elif question == 3:
print('Awesome!')
else:
print('That's not an option!')