3

For a practice problem in my homework, i'm making a guessing game that starts off by asking for a number. I'm trying to implement a way that prints "invalid input" when given a string, but i get an error message. here is my code:

def get_input():
    '''
    Continually prompt the user for a number, 1,2 or 3 until
    the user provides a good input. You will need a type conversion.
    :return: The users chosen number as an integer
    '''
    guess=int(input("give me 1,2,3"))
    while True:
        if guess==1 or guess==2 or guess==3:
            return guess
        else:
            print "Invalid input!"

        guess=int(input("give me 1,2,3"))

I get this message when I put in a string such as

hello/System/Library/Frameworks/Python.framework/Versions/2.6/bin/python2.6 /Users/bob/PycharmProjects/untitled/warmup/__init__.py

give me 1,2,3hello

Traceback (most recent call last):
  File "/Users/bob/PycharmProjects/untitled/warmup/__init__.py", line 51, in <module>
    get_input()
  File "/Users/bob/PycharmProjects/untitled/warmup/__init__.py", line 43, in get_input
    guess=int(input("give me 1,2,3"))
  File "<string>", line 1, in <module>
NameError: name 'hello' is not defined

Process finished with exit code 1
3
  • You may use try catch for this scenario. Commented Oct 3, 2015 at 18:43
  • 1
    Possible duplicate of Python input() error - NameError: name '...' is not defined Commented Oct 3, 2015 at 18:46
  • input('enter an integer') and raw_input('enter a string') Commented Oct 3, 2015 at 19:07

2 Answers 2

5

You need to use raw_input for python2, input tries to evaluate the string so it looks for a variable called name and errors as there is no variable called name defined anywhere. You should never use input in python2, it is equivalent to eval(raw_input()) which has obvious security risks.

So to spell it out more clearly, don't use input to take input from a user in python2, use raw_input() and in your case take the raw_input using a try/except catching a ValueError.

def get_input():
    '''
    Continually prompt the user for a number, 1,2 or 3 until
    the user provides a good input. You will need a type conversion.
    :return: The users chosen number as an integer
    '''

    while True:
        try:
            guess = int(raw_input("give me 1,2,3"))
            if guess in (1, 2, 3):
                return guess
        except ValueError:
            pass
        print("Invalid input!")

The fact you are just cheking for 1,2 or 3 means you could also just do the casting after you confirm:

def get_input():
    '''
    Continually prompt the user for a number, 1,2 or 3 until
    the user provides a good input. You will need a type conversion.
    :return: The users chosen number as an integer
    '''

    while True:
        guess = raw_input("give me 1,2,3")
        if guess in ("1", "2", "3"):
            return int(guess)
        print("Invalid input!")
Sign up to request clarification or add additional context in comments.

5 Comments

this will solve the problem but it looks more like a comment then an answer
@VigneshKalai, this is the answer to the question, input accepts integer but crashes on a string,what do you think is causing that?
I am not saying you're answer is wrong it is just that you could add a link stating about this behaviour of the input method
Answered the question! Now you've added code, just one comment doesn't print "Invalid Input" for int inputs < 1 or > 4, you could just pass on the exception and print if it loops (given the return exits the loop).
@achampion, True, easier just to pass and print.
1

You should to verify the input type before converting into a int:

guess = raw_input("give me 1,2,3")

while True:
   if guess == '1' or guess == '2' or guess == '3':
      return int(guess)
   else:
      print "Invalid input!"

   guess = raw_input("give me 1,2,3")

12 Comments

raw_input always returns a string, gess doesn't exist and else: pass is completely useless.
@gre_gor you're right, i was a bit distracted. i assume my mistake here, sorry.
Now you are using is to test for equality, not a good idea! Also else:pass is redundant.
yep. is would work at least using cpython but it is an implementation detail that should never be relied upon. is should be used for identity, == to test if two values are equal not necessarily the same object in memory
@gre_gor is a suggestion to pass the input to function arg. Thx Padraic.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.