Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

Letter game introduction

Could you please tell me where and why my code in't working, I'm not sure, thanks.

import random

#make a list of words
words = [
    'apple',
    'banana',
    'orange',
    'coconut',
    'strawberry',
    'lime',
    'grapefruit',
    'lemon',
    'kumquat',
    'blueberry',
    'melon'

]

while True:
    start = input("Press enter to start, or enter 'q' to quit")
    if start.lower() == 'q':
        break
    #pick random word
    secret_word = random.choice(words)
    bad_guesses = []
    good_guesses = []

    while len(bad_guesses) < 7 and len (good_guesses) != len(list(secret_word)):
        #draw guessed letters, spaces and strikes
        for letter in secret_word:
            if letter in good_guesses:
                print(letter, end='')
            else:
                print('_', end='')

        print('')
        print('Strike: {}/7'.format(len(bad_guesses)))
        print('')

    #take guess
    guess = input("Guess a letter: ").lower()

    if len(guess) != 1:
        print("You can only guess a single letter!")
        continue
    elif guess in bad_guesses or guess in good_guesses:
        print("You've already guessed that letter!")
        continue
    elif not guess.isalpha():
        print("You can only guess letters!")
        continue

    if guess in secret_word:
        good_guesses.append(guess)
        if len(good_guesses) == len(list(secret_word)):
            print("You win! The word was {}".format(secret_word))
            break
    else:
        bad_guesses.append(guess)
else:
    print("You didn't guess it! My secret word was {}".format(secret_word))
    #print out win/ lose

4 Answers

Chris Howell
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Chris Howell
Python Web Development Techdegree Graduate 49,703 Points

So I am going to take this snippet out to explain why your "win condition" is never run. ( in comments)

# ... rest of starting code...

if len(guess) != 1:
            print("You can only guess a single letter!")
            continue 
        elif guess in bad_guesses or guess in good_guesses:
            print("You've already guessed that letter!")
            continue
        elif not guess.isalpha():
            print("You can only guess letters!")
            continue

        # If any of the 3 conditions above are True
        # The stuff below doesnt run because of 'continue'
        # continue starts at the top of the loop.

        if guess in secret_word:
            good_guesses.append(guess)
            if len(good_guesses) == len(list(secret_word)):
                print("You win! The word was {}".format(secret_word))
                break

# ... rest of ending code below....

So now knowing that what If we move that block somewhere above the continue calls.

import random

#make a list of words
words = [
    'apple',
    'banana',
    'orange',
    'coconut',
    'strawberry',
    'lime',
    'grapefruit',
    'lemon',
    'kumquat',
    'blueberry',
    'melon'

]

while True:
    start = input("Press enter/return to start, or enter Q  to quit")
    if start.lower() == 'q':
        break
    #pick random word
    secret_word = random.choice(words)
    bad_guesses = []
    good_guesses = []

    while len(bad_guesses) < 7 and len(good_guesses) != len(list(secret_word)):
        #draw guessed letters, spaces and strikes
        for letter in secret_word:
            if letter in good_guesses:
                print(letter, end='')
            else:
                print('_', end='')

        print('')
        print('Strikes {}/7'.format(len(bad_guesses)))
        print('')


        #take guess
        guess = input("Guess a letter: ").lower()

        # So what if we move it up higher,
        # it will check the guess earlier before 
        # the continues...
        # but that means its checking the word
        # before its doing those other checks
        # which could be bad? 
        # so maybe we only want to call
        # continue in certain conditions.
        if guess in secret_word:
            good_guesses.append(guess)
            if len(good_guesses) == len(list(secret_word)):
                print("You win! The word was {}".format(secret_word))
                break
        else:
            bad_guesses.append(guess)

        if len(guess) != 1:
            print("You can only guess a single letter!")
            continue 
        elif guess in bad_guesses or guess in good_guesses:
            print("You've already guessed that letter!")
            continue
        elif not guess.isalpha():
            print("You can only guess letters!")
            continue


    else:
        print("You didn't guess it! My secret word was {}".format(secret_word))
        #print out win/ lose

This way it will allow you to hit that win state, but because of where its at. You have to make an additional guess before the win conditions are met. Though the win conditions are only looking for the lengths to match. Where it should really look for if each letter in the secret word to be in the list of guesses. ;)

Chris Howell
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Chris Howell
Python Web Development Techdegree Graduate 49,703 Points

Hi augustine makachemu

I notice a few things wrong with it, we can break it down in steps.

Anytime you write your code out in a single full script (as you did above) or even if you were to write it like that above but put it all inside 1 function that you call. Either way, when you write it like that your code will basically run from top to bottom in order you put it in.

This means you have to ensure that you:

  1. define things you want to store before you attempt to store them.
  2. do checks sometime after values are stored or returned.
  3. when using if, elif you may also need the else catchall in case anything falls through the first few.

Your code seems to get stuck in an infinite loop printing out the Strike: 0/7. This looks like its happening because you never leave that while loop until a condition is no longer met or you explicitly break from it. That condition being len(bad_guesses) is never growing inside THAT loop nor is len(good_guesses).

Also, you do not seem to be getting input from the user for a letter guess. You must get the letter guess before you check to see if its a "good" or "bad" guess and then you can conditionally say "if its good, append it to good_guesses otherwise append it to bad_guesses".

Let me know if that helps you get a bit further with your code.

You're right about in being in an infinite loop, I don't know how to actually fix the code though so could you show my code then yours next to it so I can see the difference please?

Chris Howell
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Chris Howell
Python Web Development Techdegree Graduate 49,703 Points

Here I put comment HINTS in your code. Of what to try.

import random

#make a list of words
words = [
    'apple',
    'banana',
    'orange',
    'coconut',
    'strawberry',
    'lime',
    'grapefruit',
    'lemon',
    'kumquat',
    'blueberry',
    'melon'

]

while True:
    start = input("Press enter to start, or enter 'q' to quit")
    if start.lower() == 'q':
        break
    #pick random word
    secret_word = random.choice(words)
    bad_guesses = []
    good_guesses = []

    while len(bad_guesses) < 7 and len (good_guesses) != len(list(secret_word)):
        #draw guessed letters, spaces and strikes
        for letter in secret_word:
            if letter in good_guesses:
                print(letter, end='')
            else:
                print('_', end='')

        print('')
        print('Strike: {}/7'.format(len(bad_guesses)))
        print('')

    # ========= THIS BLOCK ===========
    # Is outside the loop
    # 
    # Python reads spaces to interpret if
    # you are leaving a block of code.
    # 
    #take guess
    guess = input("Guess a letter: ").lower()

    if len(guess) != 1:
        print("You can only guess a single letter!")
        continue
    elif guess in bad_guesses or guess in good_guesses:
        print("You've already guessed that letter!")
        continue
    elif not guess.isalpha():
        print("You can only guess letters!")
        continue

    if guess in secret_word:
        good_guesses.append(guess)
        if len(good_guesses) == len(list(secret_word)):
            print("You win! The word was {}".format(secret_word))
            break
    else:
        bad_guesses.append(guess)
    # All you need to do is move this block to the right
    # 4 space to put it inside the block.
    # then things should work properly.
    # ===============================
else:
    print("You didn't guess it! My secret word was {}".format(secret_word))
    #print out win/ lose

Thanks, i'll try it out

It still isn't working

import random

#make a list of words
words = [
    'apple',
    'banana',
    'orange',
    'coconut',
    'strawberry',
    'lime',
    'grapefruit',
    'lemon',
    'kumquat',
    'blueberry',
    'melon'

]

while True:
    start = input("Press enter/return to start, or enter Q  to quit")
    if start.lower() == 'q':
        break
    #pick random word
    secret_word = random.choice(words)
    bad_guesses = []
    good_guesses = []

    while len(bad_guesses) < 7 and len(good_guesses) != len(list(secret_word)):
        #draw guessed letters, spaces and strikes
        for letter in secret_word:
            if letter in good_guesses:
                print(letter, end='')
            else:
                print('_', end='')

        print('')
        print('Strikes {}/7'.format(len(bad_guesses)))
        print('')


        #take guess
        guess = input("Guess a letter: ").lower()


        if len(guess) != 1:
            print("You can only guess a single letter!")
            continue
        elif guess in bad_guesses or guess in good_guesses:
            print("You've already guessed that letter!")
            continue
        elif not guess.isalpha():
            print("You can only guess letters!")
            continue

        if guess in secret_word:
            good_guesses.append(guess)
            if len(good_guesses) == len(list(secret_word)):
                print("You win! The word was {}".format(secret_word))
                break
        else:
            bad_guesses.append(guess)
    else:
        print("You didn't guess it! My secret word was {}".format(secret_word))
        #print out win/ lose
Chris Howell
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Chris Howell
Python Web Development Techdegree Graduate 49,703 Points

Is it giving you an error or something?

That code is working for me, except it is missing a conditional check to see if you got all letters of the secret word. So once you get all the letters it seems to keep looping having you guess and never breaking you out of the loop.

So before your next guess or at the end after the other checks you need to have a way that break out of the loop after checking if you got the secret word right. :)

I just need a way to break out of the loop, it al works, but when someone solves the puzzles. It doesn't break