-1

I'm a newbie writing hangman and have hit a bug in one of my modules. My intent in this module is to check the user input and verify it is a single character that is a letter and not a number. The error checking works in that it won't exit the module until a single letter ( or special, haven't figured a way around that yet) is entered but the return value is always the first user input entered not the last and correct entry. Any suggestions would be appreciated.

def get_guess():
    guess = str(raw_input('Please enter your guess letter: '))
    if len(guess) == 1:
        try:
            float(guess)
            is_int = True
        except ValueError:
            is_int = False
        if is_int:
            print "You have entered a number not a letter."
            get_guess()
    else:
        print "Please enter a single letter."
        get_guess()

    return guess
David
  • 3
  • 1
  • 1
    Not really related to your question but: there is a function `isalpha()` for checking that a string contains only letters. – dshepherd Aug 01 '14 at 16:57

1 Answers1

3

You are using recursion to get repeated inputs, but are not returning the recursive call results. You do need to return whatever the recursive call produced to pass it back up the stack:

return get_guess()

You'll need to do this in both locations you are calling get_guess() recursively.

Using recursion to get a response is not a good idea however; never underestimate the determination of idiots to get it wrong and instead hit your recursion limit. Use a loop instead:

def get_guess():
    while True:
        guess = raw_input('Please enter your guess letter: ')
        if len(guess) == 1:
            if guess.isdigit():
                print "You have entered a number not a letter."
            else:
                return guess
        else:
            print "Please enter a single letter."

Here the function keeps looping endlessly until you return the one valid character guess. Note that you probably want to test for str.isalpha() instead if only letters are permitted. Your code and my version allow for anything that is not a digit, so spaces and punctuation are allowed too.

You may also want to study Asking the user for input until they give a valid response

Community
  • 1
  • 1
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • instead of checking of not being a number, the guess should checked to be a letter, with the `guess.isalpha()` method. – Daniel Aug 01 '14 at 17:00
  • @Daniel: sure, but `guess.isalpha()` is functionally different; the OP's code is returning anything length 1 and not a digit, allowing for punctuation too. `str.isalpha()` is **probably** the right method, but it would alter what is acceptable. – Martijn Pieters Aug 01 '14 at 17:01
  • @MartijnPieters: I understand what your saying about the recursive nature of what I've written and appreciate the insight but I'm not following your code suggestion. Wouldn't the code:`return get_guess()` generate an infinite loop? – David Aug 01 '14 at 17:14
  • @David: why would *returning the returned value* lead to infinite recursion any more than what you have now? – Martijn Pieters Aug 01 '14 at 17:18
  • @David: Each new nested call to `get_guess()` is a new stack; with or without the `return` statement you can eventually run out of stack and an 'infinite recursion' exception is thrown, *unless something returns from one of the function calls before that*. – Martijn Pieters Aug 01 '14 at 17:19
  • @David: however, when the innermost call finally returns (the user entered a 1-character non-digit value), then next call out from that is ignoring that return value. The function ends without returning anything explicitly, so `None` is returned instead. And so on. By adding `return` all you do is replace the `None` return value by whatever the recursive call returned. – Martijn Pieters Aug 01 '14 at 17:21
  • @MartijnPieters: Thanks for taking the time to explain this to me, it makes far more sense now. I think I was missing the point that each call to get_guess() was a separate stack. I was also taking the code `return get_guess()` as a literal replacement to `return guess` hence my infinite loop comment. Funnily enough I started this module with a while loop and managed to over complicate things severely before deleting and ending up with the code above. Thanks again. – David Aug 01 '14 at 23:17