1
votes

I'm trying to write a program where the user has to guess a letter in the goal of unlocking the secret word. If the secret word is guessed correctly before the maximum 8 guesses, the function returns true else the function returns false. For some reason my function just doesn't produce the right output. I would enter the letter 'a' and it would print "Letters guessed so far: ['a']" and then the program would end. I need help in fixing this issue.

secretWord = 'hello'
lettersGuessed = []


def isWordGuessed(secretWord,lettersGuessed):
  guess  = 0
  while guess <= 8:
    secretLetters = list(secretWord)
    secretWordLen = len(secretLetters)
    letter = input('Enter a letter: ')
    lettersGuessed.append(letter)

    print('Letters guessed so far: ',lettersGuessed)

    if letter not in secretLetters:
        guess += 1

    while letter in secretLetters:
        secretLetters.remove(letter)

    if secretLetters == []:
       return True
    else:
       return False



   isWordGuessed(secretWord,lettersGuessed)
3
in last if you return in either case... - Aprillion
I'm pretty sure this isn't your actual indentation, and there's a pretty good chance this is an indentation-related problem, so please fix it to match what you're actually running. - abarnert
PS, do they call this game "secret word" instead of "hangman" nowadays to… avoid scaring kids or inspiring them to commit suicide or something? - abarnert
@abarnert lol, it's actually hangman, now they call it secret word. - Amber Roxanna
@abarnert i'm sorry, just a quick last question, can you explain how "if not" works ? the statement after if not in the program is not a boolean or something...is it used with sets specifically ? - Amber Roxanna

3 Answers

2
votes

The last if statement is indented too far, causing it to be part of your while loop. Since both branches of the condition cause the function to return, it always returns on the first iteration of the loop.

2
votes

Your first problem is, as kwatford explained, that you are returning every time through the loop. You can fix that by moving the if statement outside the while loop.

Your next problem, as Vorticity explained, is that it will never return early, even if the user guesses the whole word. To fix that, move the if part back inside the loop, but leave the else part outside the loop (meaning you no longer need the else)

After that, it still won't work, because you're doing secretLetters = list(secretWord) each time through the loop, so you can only win if you guess all the letters in one guess (which is impossible, unless the word is, say, "a" or "aaaaa"). To fix that, move that line outside the loop.

Putting it all together:

def isWordGuessed(secretWord,lettersGuessed):
  guess  = 0
  secretLetters = list(secretWord)
  while guess <= 8:
    secretWordLen = len(secretLetters)
    letter = input('Enter a letter: ')
    lettersGuessed.append(letter)

    print('Letters guessed so far: ',lettersGuessed)

    if letter not in secretLetters:
        guess += 1

    while letter in secretLetters:
        secretLetters.remove(letter)

    if secretLetters == []:
       return True

  return False

As a side note, there are a lot of things you can do to simplify this.

First, you really just need a set of all letters in the secret word—you don't need to know the order, or how many copies there are of each, etc. So, instead of a list, use a set. This also means you don't need the loop around secretLetters.remove(letter).

More trivially, you create secretWordLen but never use it.

You also accept and append to a lettersGuessed passed in by the caller, but the caller is just passing you an empty list, and never using it after the fact, so why bother? And if you don't need to mutate it for the caller's benefit, you can just keep it as a string, so the user sees help instead of ['h', 'e', 'l', 'p'], which is a lot nicer.

You've also got a few cases that are being tested even when they can't possibly be true.

Finally, an empty list (or set, or any other sequence) is false, so there's no reason to explicitly compare to the empty list.

While I'm at it, I'm going to PEP8-ify the spacing to make it easier to see the indentation.

So:

def isWordGuessed(secretWord):
    guess = 0
    lettersGuessed = ''
    secretLetters = set(secretWord)
    while guess <= 8:
        letter = input('Enter a letter: ')
        lettersGuessed += letter
        print('Letters guessed so far:', lettersGuessed)
        if letter not in secretLetters:
            guess += 1
        else:
            secretLetters.remove(letter)
            if not secretLetters:
                return True
    return False
0
votes

You just need to move your return for the False case. Basically, the way your code is written right now, you will never go back to the beginning of your loop. Also, as noted by abarnert, you will never exit the loop because you are reinitializing secretLetters every time you loop. You have to initialize it outside the loop. Your code should look like this:

secretWord = 'hello'
lettersGuessed = []

def isWordGuessed(secretWord,lettersGuessed):
    guess  = 0
    secretLetters = list(secretWord)
    secretWordLen = len(secretLetters)
    while guess <= 8:
        letter = input('Enter a letter: ')
        lettersGuessed.append(letter)

        print('Letters guessed so far: ',lettersGuessed)

        if letter not in secretLetters:
            guess += 1

        while letter in secretLetters:
            secretLetters.remove(letter)

        if secretLetters == []:
            #Return true if all correct letters have been guessed
            return True

    #Return false if guessed incorrectly eight times
    return False