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!')
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.
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)
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
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
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!')
Related
I'm trying to do a silly little program that will let me open an image given a specific number.
import os
c1= os.startfile('Cat1.PNG')
c2= os.startfile('Cat2.PNG')
c3= os.startfile('Cat3.PNG')
catlist= [c1,c2,c3]
valid= False
def cats(valid):
while not valid:
try:
answer=int(input('Choose a number between 1 and 3'))
valid= True
except ValueError:
print("This is not a number")
if answer >=1 and answer <=3:
print(catlist[answer-1])
else:
print('Wrong value')
del (answer)
cats(valid)
return
cats(valid)
My problem is that my pictures just get all open when I start the program, while I want to open them when I choose a specific number.
The problem with your code is in the part where you assign the os.startfile() function to a variable.
When Python interpreter goes through your code, as soon as it hits the c1= os.startfile('Cat1.PNG') line of code, it executes the command and opens the files immediately.
import os
valid = True
def cats(valid):
while valid:
try:
x = int(input("Enter a number here: "))
valid = False
except ValueError:
print("This is not a number!")
if x == 1:
os.startfile('1.jpg')
elif x == 2:
os.startfile('2.jpg')
elif x == 3:
os.startfile('3.jpg')
else:
print("Wrong value")
valid = True
cats(valid)
There is probably a better and more efficient way to do it, but here is a solution I came up with.
I am having trouble getting the proper result in this code:
class Commerce():
def Entry(_sub, test):
while True:
if _sub == "Maths" or "Busines Studies" or "Accounts" or "Economics" or "Physical Education" or "English":
try:
print("Enter marks of ", _sub, "in", test, end="=>")
x = int(input())
except:
print("Invalid input")
continue
if x in range(0, 41):
return x
break
else:
print("Marks exceded, please try again ")
else:
print("Invalid marks")
continue
class Restrict():
def limitalnum(content):
punctuations =['!','(',')','-','[',']','{','}',';',':',"'",'"',"\\",',','<','>','.','/','?','#','#','$','%','^','&','*','_','~']
count=3
while True:
ask_input=input('%s'%content)
if ask_input.isalnum()==False:
count=count-1
if count in[3,2,1]:
print("Sorry only alphabets and numeric are acceptable")
print("Remaing retry of above entry:%s"%count)
else:
pass
if count==0:
print("Remaing retry of above entry:%s"%count)
print("We are sorry you have exhausted all retry's")
break
continue
else:
break
Stream_option=Restrict.limitalnum("Which Stream you are currently pursuing")
if Stream_option=='1' or 'Maths':
MATHS_PT_MARKS=Commerce.Entry("Maths","Periodic Test-1")
elif Stream_option == '2' or 'Informatics Practices' or 'IP':
IP_PT_MARKS=Commerce.Entry("IP","Periodic Test-1")
elif Stream_option == '3' or 'Hindi':
HI_PT_MARKS = Commerce.Entry("Hindi","Periodic Test-1")
Output Coming:
Which Stream you are currently pursuing: 2
Enter marks of Maths in Periodic Test-1=>
Output Expected :
Which Stream you are currently pursuing: 2
Enter marks of IP in Periodic Test-1=>
I don't know for sure if i used if condition properly or not, Thanks
This question is not duplicate for any other questions in Stack Overflow
What i am trying to get it calling a function from a class in a conditional statement
Uniqueness:
If the Conditional statement is true
Execute the function
If the conditional statement is False
Pass to next line of command
Hi guys I was working on a shoppinglist-creator code but at the end I faced with a surprise.
My code:
import time
import math
import random
dict_of_lists={}
def addlist():
while True:
try:
listname=str(raw_input("=>Name of the list:\n"))
dict_of_lists[listname]={}
break
except ValueError:
print "=>Please enter a valid name.\n"
print "=>You added a new list named %s.\n" % (listname)
def printlists():
for lists in dict_of_lists:
return "-"+lists
def addproduct():
while True:
try:
reachlistname=input("=>Name of the list you want to add a product,Available lists are these:\n %s \nPlease enter one:\n" % (printlists()))
break
except ValueError:
print "=>Please enter a valid list name.\n"
while True:
try:
productname=raw_input("=>Name of the product:\n")
break
except ValueError:
print "=>Please enter a valid name.\n"
while True:
try:
productprice=input("=>Price of the product:\n")
if isinstance(float(productprice),float):
break
except ValueError:
print "=>Please enter a valid number.\n"
while True:
try:
productcount=input("=>Amount of the product:\n")
if isinstance(int(productcount),int):
break
except ValueError:
print "=>Please enter a valid number.\n"
dict_of_lists[reachlistname][productname]={"price":productprice,"count":productcount}
dict_of_lists[reachlistname]={productname:{"price":productprice,"count":productcount}}
allevents="1-Add a list"+" 2-Add a product to a list"
def eventtochoose():
while True:
try:
event=raw_input("=>What would you like to do? Here are the all things you can do:\n %s\nPlease enter the number before the thing you want to do:" % (allevents))
if not isinstance(int(event),int):
print "\n=>Please enter a number.\n"
else:
if event==1:
addlist()
break
elif event==2:
addproduct()
break
except ValueError:
print "\n=>Please enter a valid input.\n "
while True:
print "%s" % ("\n"*100)
eventtochoose()
So, the problem is (I suggest you run the code) it says "=>What would you like to do? Here are the all things you can do:
1-Add a list 2-Add a product to a list
Please enter the number before the thing you want to do:" and when i put an answer it simply doesn't call the fucntion.
If I put 1 It should have called the fucntion addlist but I think it doesn't. There is nothing to explain I think just look at the code and find the problem if you want to help crocodiles. Thx
When you do int(event), that returns an int if possible, and raises a ValueError if not. So, testing the type of the result doesn't do you any good—if your code gets that far, the type has to be an int.
You already have code to handle the ValueError, so you don't need any other test for the same problem.
Meanwhile, you want to start the number that you got from int(event). That's the thing that can be == 1; the original string '1' will never be == 1.
So:
while True:
try:
event=raw_input("=>What would you like to do? Here are the all things you can do:\n %s\nPlease enter the number before the thing you want to do:" % (allevents))
event = int(event)
if event==1:
addlist()
break
elif event==2:
addproduct()
break
except ValueError:
print "\n=>Please enter a valid input.\n "
You are not converting your input to an integer before comparing, so the comparisons are always false:
'1' == 1 # false
Try:
event = raw_input("=>What would you like to do? Here are the all things you can do:\n %s\nPlease enter the number before the thing you want to do:" % (allevents))
try:
event = int(event)
if event == 1:
addlist()
elif event == 2:
addproduct()
break
except ValueError:
print('Please enter a valid input')
while loop == 6:
if EVENTCOUNT >= 4:
_, username, para, value = event.split(" ", 3)
try:
self.dbcur.execute('select ? from users where name = ?', [para, username])
if rrf is None:
print notex
else:
print str(username)+" has been altered: "+str(para)+" => "+str(value)+"."
while loop == 2:
again = raw_input("Is that all? (Y/N)")
while True:
if again == "Y":
# edit another parameter
loop=4
elif again == "N":
print "Thanks! Bye! \nAll credits of this program go to Trey."
#end program
break
else:
print "Sorry! That wasn't Y or N."
loop == 2
I get an the error: "IndentationError: expected an indented block" and there is an error underneath the if EVENTCOUNT >=4:
Use an IDE, which often has an indentation tool for automatically converting mixed tabs and spaces to either all tabs or spaces. Here is your code with 4 spaces per indent.
while loop == 6:
if EVENTCOUNT >= 4:
_, username, para, value = event.split(" ", 3)
try:
self.dbcur.execute('select ? from users where name = ?', [para, username])
if rrf is None:
print notex
else:
print str(username)+" has been altered: "+str(para)+" => "+str(value)+"."
while loop == 2:
again = raw_input("Is that all? (Y/N)")
while True:
if again == "Y":
# edit another parameter
loop=4
elif again == "N":
print "Thanks! Bye! \nAll credits of this program go to Trey."
#end program
break
else:
print "Sorry! That wasn't Y or N."
loop == 2
except Exception,err:
print "error"
You must use a consistent indentation for all blocks within a file - I (and PEP8) strongly recommend four spaces.
Mixing tabs and spaces in a single file is bad because tabs have variable perceived widths based on the developer's environment. Mixing the number of spaces within a single file can confuse the interpreter.
Can I combine these functions together to shorten my python code? I'm creating a quick program!
Here are the functions:
def try1():
try:
num1=input("Enter num 1: ")
return num1
except ValueError:
print("incorrect!")
return #value
def try2():
try:
num2=input("Enter num 2: ")
return num2
except ValueError:
print ("incorrect!")
return #value
def try3():
try:
num3=input("Enter num 3: ")
return num3
except ValueError:
print ("incorrect!")
return #value
def try4():
try:
num4=input("Enter num 4: ")
return num4
except ValueError:
print ("incorrect!")
return #value
Please post your suggestions and answers below.
As you can see from my reputations, I am a new programmer hoping to find kind people on Stackoverflow.
(This answer is based on the original revision of the question which is no longer accessible but showed a different problem, where the user is keep being asked until a valid number is entered. And the code showed some skill game system or something, so that’s why my questions are longer and more specific too.)
Something like this?
def getInt(name, target):
while True:
try:
return int(input('Please enter {0} for {1}: '.format(name, target)))
except ValueError:
print('Incorrect!')
strength0 = getInt('strength', 'character 1')
skill0 = getInt('skill', 'character 1')
strength1 = getInt('strength', 'character 2')
skill1 = getInt('skill', 'character 2')
In general, when you have multiple functions that approximately do the same thing, then yes, there is a lot potential to refactor it so you don’t repeat yourself. In this case, what was different is the question the user was being asked, so if we parameterize that, we are good to use just a single function to handle it all.
The function can be generalised to ask for the input of any number, for example:
def try_num(n):
num = int(input("Enter num {} : ".format(n)))
while num != n:
print ("incorrect!")
num = int(input("Enter num {} : ".format(n)))
return num
Use it like this:
try_num(10)
Enter num 10 : 9
incorrect!
Enter num 10 : 10
10
def safe_int(x):
try:
return int(x)
except ValueError:
return 0
[safe_int(raw_input("Number %d:"%i)) for i in range(4)]
I would create a validation method and simply pass in the strings.
def validate(question):
while True:
try:
print question,
input = raw_input()
if input.isdigit():
return int(input)
else:
print "Not a valid integer"