0

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
Jerry Stratton
  • 3,287
  • 1
  • 22
  • 30
  • 1
    In python 3 the input function returns strings, not integers. `cmd in ('1', '2', '3')`? – g.d.d.c Jun 03 '14 at 22:20
  • Also, there is no way to leave your outer most `while`... – Justin Jun 03 '14 at 22:21
  • 1
    You can convert the string inputs to integers using `int(input("..."))`. – Andy G Jun 03 '14 at 22:21
  • possible duplicate of [Asking the user for input until they give a valid response](http://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response) – g.d.d.c Jun 03 '14 at 22:22
  • @AndyG Yes, but then his program blows up with a value error if someone inputs 'a'. I think he'd rather tell the user the input was bad. – stewSquared Jun 03 '14 at 22:54
  • @stewSquared Yes, of course. I was essentially pointing out what the issue is. It is much better to accept the string input, and then separately check whether it is an integer. – Andy G Jun 03 '14 at 22:57
  • @AndyG Agreed. I didn't mean to insinuate that you overlooked this, but I suspect George would find the observation helpful. – stewSquared Jun 03 '14 at 23:01

3 Answers3

1

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!

stewSquared
  • 827
  • 5
  • 24
0

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.

Tanky Woo
  • 4,906
  • 9
  • 44
  • 75
0

There is one problem with your code.

  1. 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
A.J. Uppal
  • 19,117
  • 6
  • 45
  • 76