I have been trying to make a simple game in Python 3.3.4, at the beginning of the game I want the user to select a difficulty between 1 and 3 and if they put in another character other than 1, 2 or 3 they receive the message 'Invalid input'.
I have written the code below, however I cannot get it to function correctly in the even if the user does input 1, 2 or 3 it will come up with the error 'invalid input', I have tried messing around with it in various combinations with no avail. I understand that this is rather basic an probably something simple that I am overlooking as I am new to Python. Thanks in advance.
while True:
while True:
cmd = input('Please select a diffuculty from 1 to 3, with three being the hardest: ')
if cmd in (1, 2, 3):
break
print ('Invalid input.')
if cmd == 1:
dopt = 3
continue
elif cmd == 2:
dopt = 4
continue
elif cmd == 2:
dopt = 5
continue
3 Answers 3
The problem is with your types. input returns a string, so cmd is a string. You then ask if cmd is in (1,2,3), a tuple of ints. Let me go through your options with you.
You can change
cmd = input("...")
to
cmd = int(input("..."))
That way, cmd is an int, as expected later on. The problem with this is that is someone enters something that's not parsable as an int, say "foo", you're program will immediately exit with a ValueError.
Try something like this instead:
...
while True:
cmd = input('Please select a diffuculty from 1 to 3, with three being the hardest: ')
if cmd in ('1', '2', '3'):
break
print ('Invalid input.')
cmd = int(cmd)
if cmd == 1:
dopt = 3
continue
...
Here, you've a tuple of strings instead of a tuple of ints in the cmd validation. After, cmd is parsed as an int, and your program continues as expected.
On another note, your if-else chain can be replaced with dopt = cmd+2
Best of luck!
Comments
From the doc:
input([prompt])
Equivalent to eval(raw_input(prompt)).
raw_input([prompt]):
If the prompt argument is present, it is written to standard output without a trailing newline. The function then reads a line from input, converts it to a string (stripping a trailing newline), and returns that.
I modified your code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
while True:
cmd = int(input('Please select a diffuculty from 1 to 3, with three being the hardest: '))
print("cmd:{}, type:{}".format(cmd, type(cmd)))
if cmd not in (1, 2, 3):
print ('Invalid input.')
continue
if cmd == 1:
dopt = 3
break
elif cmd == 2:
dopt = 4
break
elif cmd == 3:
dopt = 5
break
print ("cmd:{}; dopt:{}".format(cmd, dopt))
You can use type to know what's the type of your input.
Comments
There is one problem with your code.
input()returns a string, not an integer.
Because your input is a string, checking if a string is in a tuple of integers, would not work:
>>> tup = (1, 2, 3)
>>> '1' in tup
False
>>> '3' in tup
False
Therefore, you can cast int() to your input(), so that it takes integers and only integers as input:
>>> x = int(input())
4
>>> type(x)
<class 'int'>
>>> x = int(input())
'hello'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: "'hello'"
>>>
Because of that, you can then check if the input is in your tuple:
>>> tup = (1, 2, 3)
>>> x = int(input())
2
>>> x in tup
True
>>> x = int(input())
7
>>> x in tup
False
>>>
Here is your edited code:
while True:
while True:
cmd = int(input('Please select a diffuculty from 1 to 3, with three being the hardest: '))
if cmd in (1, 2, 3):
break
print ('Invalid input.')
if cmd == 1:
dopt = 3
continue
elif cmd == 2:
dopt = 4
continue
elif cmd == 2:
dopt = 5
continue
3 Comments
input CAN return an int, in fact, it can even return a list. input parses the string for you, in you want the raw input use... raw()raw_input() doesn't exist in python-3.x
cmd in ('1', '2', '3')?while...int(input("...")).