0

I need to write a couple functions that make up a hangman game. I've the code, but I keep getting an error and my code doesn't run completely, so I don't even know if my code is correct. This is the code I have:

def isWordGuessed(secretWord, lettersGuessed):
    '''
    secretWord: string, the word the user is guessing
    lettersGuessed: list, what letters have been guessed so far
    returns: boolean, True if all the letters of secretWord are in lettersGuessed;
      False otherwise
    '''
    if lettersGuessed == []:
        return False
    else:
        for i in secretWord:
            if i not in lettersGuessed:
                return False
        else:
            if i == secretWord[-1]:
                return True

def getGuessedWord(secretWord, lettersGuessed):
    lst= ''
    for e in secretWord:
        if e in lettersGuessed:
            lst += e 
        else:
            lst += '_'
    return lst

def getAvailableLetters(lettersGuessed):
    '''
    lettersGuessed: list, what letters have been guessed so far
    returns: string, comprised of letters that represents what letters have not
      yet been guessed.
    '''
    Alletters = string.ascii_lowercase
    result = list(Alletters)
    for i in lettersGuessed:
        if i in result:
            result.remove(i)
    transtring = ''.join(result)
    return transtring

def hangman(secretWord):
    '''
    secretWord: string, the secret word to guess.

    Starts up an interactive game of Hangman.

    * At the start of the game, let the user know how many 
      letters the secretWord contains.

    * Ask the user to supply one guess (i.e. letter) per round.

    * The user should receive feedback immediately after each guess 
      about whether their guess appears in the computers word.

    * After each round, you should also display to the user the 
      partially guessed word so far, as well as letters that the 
      user has not yet guessed.

    Follows the other limitations detailed in the problem write-up.
    '''
    print("Welcome to the Hangman game!")
    print("I am thinking of a word that is " + str(len(secretWord)) + " letters!")
    guesses = 8      
    lettersGuessed = []   
    Alletters = string.ascii_lowercase    
    while guesses > 0:    
        print("You have " + str(guesses) + " guesses left")
        print("Available letters: " + str(Alletters))
        letters = input("Please guess a letter: ")
        if type(letters) != str:
            print("Invalid input! please enter one letter!")
        else:
            letterslower = letters.lower()     
            lettersGuessed = lettersGuessed.append(letterslower) 
            if letterslower not in Alletters:
                print("Opps! you have already guessed that letter: " + getGuessedWord(secretWord, lettersGuessed))
            else:
                if isWordGuessed(secretWord, lettersGuessed) == "True":
                    print("Congradualations, you won!")
                else:
                    print("Good guess: " + getGuessedWord(secretWord, lettersGuessed))
                    guesses -= 1
                    Alletters = getAvailableLetters(lettersGuessed)
    print("You have ran out of guess, the word is " + str(secretWord))

This is the output (the error is in yellow):

Welcome to the Hangman game!
I am thinking of a word that is 1 letters!
You have 8 guesses left
Available letters: abcdefghijklmnopqrstuvwxyz
Please guess a letter: c
Traceback (most recent call last):

File "submission.py", line 81, in hangman
  if isWordGuessed(secretWord, lettersGuessed) == "True":
File "simple_grade_hangman.py", line 107, in isWordGuessed
  if letter not in lettersGuessed:
TypeError: argument of type 'NoneType' is not iterable

What's happening here?

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
gp0478
  • 91
  • 1
  • 8
  • Why are you comparing a boolean against a string "True"? – Carcigenicate Sep 22 '16 at 18:48
  • Change `if isWordGuessed(secretWord, lettersGuessed) == "True":` to just `if isWordGuessed(secretWord, lettersGuessed):`. 1. Never compare against true; it's unnecessarily redundant. 2. You were comparing against a string, not a boolean value itself. To highlight why this is wrong, `"False"` will evaluate to `True` in a boolean context (as will any non-empty string). – Carcigenicate Sep 22 '16 at 18:53
  • @Carcigenicate Thanks for the explanation--that makes sense. – gp0478 Sep 22 '16 at 18:56
  • Hint: notice how, in `getAvailableLetters`, the code (correctly!) **does not** say `result = result.remove(i)`? Why would that be wrong? Do you see how the same logic applies to `.append`? – Karl Knechtel Sep 14 '22 at 15:41

1 Answers1

2

Your error stems from this line:

lettersGuessed = lettersGuessed.append(letterslower)

This modifies the list in-place and returns None. You're operating under the assumption that it returns a reference to the modified list, which it doesn't.

So, when you pass it as a parameter to function isWordGuessed and if i not in lettersGuessed is executed, an error will be raised since lettersGuessed is None and None can't be used as the target of an in expression.

Simply modify with append and the changes are kept:

lettersGuessed.append(letterslower)

Also, comparing a boolean (True) against a str ("True") will give you false results:

>>> True == 'True'
False

Instead, since isWordGuessed returns booleans, use it's return value in the if clause directly:

if isWordGuessed(secretWord, lettersGuessed):
Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253