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

EXTRA CREDIT: Number Game App - Computer Guesses Number.

Tell me what you think. Can anything be simplified? Any revisions needed?

import random

def game():
    secret_num = None
    rand_guess = random.randint(1, 10)
    guesses = []
    low_or_high = None

    while True:
        try:
            num = int(input("\nEnter a number from 1 to 10: "))
        except:
            ValueError
            print("Must be a number!")
            continue
        else:
            if num < 1 or num > 10:
                print("Numbers from 1 to 10 only!")
                continue
            else:
                secret_num = num
                break


    while len(guesses) < 4:
        print("(your number: {})".format(secret_num))
        print("Is the number {}?".format(rand_guess))
        if rand_guess == secret_num:
            print("Computer has won! The number was {}".format(rand_guess))
            break
        else:
            while True:
                print("\nNumber too low\t[1]")
                print("Number too high\t[2]")
                try:
                    low_or_high = int(input("> "))
                except:
                    ValueError
                    print("Incorrect input!")
                    continue
                else:
                    if low_or_high < 1 or low_or_high > 2:
                        print("Incorrect input!")
                        continue
                    elif low_or_high == 1 or low_or_high == 2:
                        break
            if low_or_high == 1:
                print("\n...re-creating higher guess...\n")
                rand_guess = random.randint(rand_guess + 1, 10)
                guesses.append(rand_guess)
                continue
            elif low_or_high == 2:
                print("\n...re-creating lower guess...\n")
                rand_guess = random.randint(1, rand_guess - 1)
                guesses.append(rand_guess)
                continue
    else:
        print("Computer has lost.")
    while True:
        replay = input("Play again? [y/n]: ")
        if replay.upper() == 'Y':
            game()
        elif replay.upper() == 'N':
            break

game()

2 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,468 Points

Well done!! The flow is very straightforward. It worked well with one logic anomaly. Plus I have two coding comments.

  • You might want to relook at the limits when generating the next guess. If the guess is too high then too low, the third guess upper bound is set back to 10 instead of the "previous lowest too high guess". The same goes for a too low, then too high guess where the lower bound is set back to 1. This is not an obvious bug. I found it by playing multiple games and seeing the guess oscillation.
  • There are many places where the use of a continue is not specifically needed due to the flow. In the code below, I've commented the unnecessary continue statements.
import random


def game():  # Added blank line above for PEP-8
    secret_num = None
    rand_guess = random.randint(1, 10)
    guesses = []
    low_or_high = None

    while True:
        try:
            num = int(input("\nEnter a number from 1 to 10: "))
        except ValueError:  # <--Error class is part of 'except'
            print("Must be a number!")
            # continue  # <-- unnecessary: will fall out to while loop
        else:
            if num < 1 or num > 10:
                print("Numbers from 1 to 10 only!")
                # continue  # <-- unnecessary: will fall out to while loop
            else:
                secret_num = num
                break

    while len(guesses) < 4:  # Removed blank line above for PEP-8
        print("(your number: {})".format(secret_num))
        print("Is the number {}?".format(rand_guess))
        if rand_guess == secret_num:
            print("Computer has won! The number was {}".format(rand_guess))
            break
        else:
            while True:
                print("\nNumber too low\t[1]")
                print("Number too high\t[2]")
                try:
                    low_or_high = int(input("> "))
                except ValueError:  # <--Error class is part of 'except'
                    print("Incorrect input!")
                    # continue  # <-- unnecessary: will fall out to while loop
                else:
                    if low_or_high < 1 or low_or_high > 2:
                        print("Incorrect input!")
                        # continue  # <-- unnecessary: will fall out to loop
                    elif low_or_high == 1 or low_or_high == 2:
                        break
            if low_or_high == 1:
                print("\n...re-creating higher guess...\n")
                rand_guess = random.randint(rand_guess + 1, 10)
                guesses.append(rand_guess)
                # continue  # <-- unnecessary: will fall out to while loop
            elif low_or_high == 2:
                print("\n...re-creating lower guess...\n")
                rand_guess = random.randint(1, rand_guess - 1)
                guesses.append(rand_guess)
                # continue  # <-- unnecessary: will fall out to while loop
    else:
        print("Computer has lost.")
    while True:
        replay = input("Play again? [y/n]: ")
        if replay.upper() == 'Y':
            game()
        elif replay.upper() == 'N':
            break

game()
  • The syntax of your except is not illegal, but it's not doing what your think.
# You are using the following code....

try:
    # code to try
    pass
except:  # <-- this will accept all exceptions
    ValueError  # <-- this is legal code, but doesn't do anything except
                #     return a pointer to it's class which is then thrown away
    # error handling code


# What you want is:

try:
    # code to try
    pass
except ValueError:  # <-- this says allow only exceptions of this class
    # error handling code

Thanks for posting your solution to the forum!

Got it. I am pretty sure I understand what you are saying about the limits for generating the guess. I added blocks to check for this. Also, after testing multiple times, I noticed that it was possible for the guess to generate a repeat, so I added a function to check for this. Here is what I came up with.

import random



def game():

    def check_guess(rand_guess, guesses, start, end):   # Created function to check if any guess is a repeat
        new_guess = random.randint(guesses[start],guesses[end])
        for guess in guesses:
            if guess == rand_guess:
                rand_guess = new_guess
                return check_guess(rand_guess, guesses, start, end)
        return rand_guess



    secret_num = None
    rand_guess = random.randint(1, 10)
    guesses = []
    low_or_high = None

    while True:
        try:    
            num = int(input("\nEnter a number from 1 to 10: ")) 
        except ValueError:
            print("Must be a number!")
        else:   
            if num < 1 or num > 10:
                print("Numbers from 1 to 10 only!") 
            else:   
                secret_num = num
                break   

    while len(guesses) < 4: 
        print("(your number: {})".format(secret_num)) 
        print("Is the number {}?".format(rand_guess))
        if rand_guess == secret_num:
            print("Computer has won! The number was {}".format(rand_guess))
            break   
        else:   
            while True:
                print("\nNumber too low\t[1]")
                print("Number too high\t[2]")
                try:    
                    low_or_high = int(input("> "))
                except ValueError:
                    print("Incorrect input!")
                else:   
                    if low_or_high < 1 or low_or_high > 2:
                        print("Incorrect input!") 
                    elif low_or_high == 1 or low_or_high == 2:
                        break   
            if low_or_high == 1:
                guesses.append(rand_guess)
                print("\n...re-creating higher guess...\n")
                rand_guess = rand_guess = random.randint(rand_guess + 1, 10)               
            elif low_or_high == 2:
                guesses.append(rand_guess)
                print("\n...re-creating lower guess...\n")
                rand_guess = random.randint(1, rand_guess - 1)
            if len(guesses) == 2:   # Checks guesses to determine limits for guess generation
                if guesses[0] > secret_num and guesses[1] < secret_num:
                    rand_guess = random.randint(guesses[1], guesses[0])
                    rand_guess = check_guess(rand_guess, guesses, 1, 0)
                elif guesses[0] < secret_num and guesses[1] > secret_num:
                    rand_guess = random.randint(guesses[0], guesses[1])
                    rand_guess = check_guess(rand_guess, guesses, 0, 1) # Check if guess is a repeat         
            if len(guesses) == 3:   # Checks guesses to determine limits for guess generation
                if guesses[1] > secret_num and guesses[2] < secret_num:
                    rand_guess = random.randint(guesses[2], guesses[1])
                    rand_guess = check_guess(rand_guess, guesses, 2, 1)
                elif guesses[1] < secret_num and guesses[2] > secret_num:
                    rand_guess = random.randint(guesses[1], guesses[2])
                    rand_guess = check_guess(rand_guess, guesses, 1, 2) # Check if guess is a repeat
    else:   
        print("Computer has lost.") 
    while True:
        replay = input("Play again? [y/n]: ")
        if replay.upper() == 'Y':
            game()
        elif replay.upper() == 'N':
            break

game()
Chris Freeman
Chris Freeman
Treehouse Moderator 68,468 Points

Sometimes a good idea starts off working but causes the code to get wildly complicated as the conditions grow. Imaging trying to extend your code for allowing 5 or 6 guesses. An alternative approach would be to track the guess limits explicitly:

import random


def game():
    secret_num = None
    # Track guess limits
    limits = {'low': 1, 'high': 10}
    rand_guess = random.randint(limits['low'], limits['high'])
    guesses = []
    low_or_high = None

    while True:
        try:
            num = int(input("\nEnter a number from 1 to 10: "))
        except ValueError:
            print("Must be a number!")
        else:
            if num < 1 or num > 10:
                print("Numbers from 1 to 10 only!")
            else:
                secret_num = num
                break

    while len(guesses) < 4:
        print("(your number: {})".format(secret_num))
        print("Is the number {}?".format(rand_guess))
        if rand_guess == secret_num:
            print("Computer has won! The number was {}".format(rand_guess))
            break
        else:
            while True:
                print("\nNumber too low\t[1]")
                print("Number too high\t[2]")
                try:
                    low_or_high = int(input("> "))
                except ValueError:
                    print("Incorrect input!")
                else:
                    if low_or_high < 1 or low_or_high > 2:
                        print("Incorrect input!")
                    elif low_or_high == 1 or low_or_high == 2:
                        break
            if low_or_high == 1:
                # modify limits for higher  guess
                limits['low'] = rand_guess + 1
                print("\n...re-creating higher guess between {} and {}...\n"
                      "".format(limits['low'], limits['high']))
                rand_guess = random.randint(limits['low'], limits['high'])
                guesses.append(rand_guess)
            elif low_or_high == 2:
                # modify limits for lower  guess
                limits['high'] = rand_guess - 1
                print("\n...re-creating lower guess between {} and {}...\n"
                      "".format(limits['low'], limits['high']))
                rand_guess = random.randint(limits['low'], limits['high'])
                guesses.append(rand_guess)
    else:
        print("Computer has lost.")
    while True:
        replay = input("Play again? [y/n]: ")
        if replay.upper() == 'Y':
            game()
        elif replay.upper() == 'N':
            break

game()