Python Python Basics (2015) Number Game App Number Game Refinement

Povilas Jurgaitis
Povilas Jurgaitis
6,792 Points

Error in teachers code?

My code is exact as following teacher.. it does not handle exception if I enter a letter instead of a number.

exception handling line is: <p> try: # get a number guess from the player guess = int(input("Guess a number between 1 and 10: ")) except ValueError: print("{} isn't a number!".format(guess)) else: </p>

Error message is:

Guess a number between 1 and 10: h
Traceback (most recent call last):
File "number_game.py", line 20, in game
guess = int(input("Guess a number between 1 and 10: "))
ValueError: invalid literal for int() with base 10: 'h'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "number_game.py", line 45, in <module>
game()
File "number_game.py", line 22, in game
print("{} isn't a number!".format(guess))
UnboundLocalError: local variable 'guess' referenced before assignment

7 Answers

I'm just a complete beginner, but I think I figured out what the problem is.

Okay, so, you've got a line that says

 try:
            # get a number guess from the player
            guess = int(input("Guess a number between 1 and 10: "))

The computer says, "Okay, I'm going to try to create a variable called 'guess' out of the integer value of whatever the user types."

If the user types in a number, the computer happily creates the variable called "guess" and goes about its business, and the code works.

But what if the user types in something that isn't a number?

Well, the computer goes, "Okay, I tried to make the user's input into an integer, but I wasn't able to. And since I wasn't able to, I just won't make a variable called "guess" at all."

The italic part is important.

Now, it tried to do the "try" part and failed, so it goes to read what you told it to do in the "except" block:

 except ValueError:
            print("{} isn't a number!".format(guess))

The computer goes "Okay, now the code's telling me to print the contents of a variable called "guess". But I never created a variable called "guess"! There is no such variable! How can I print the contents of "guess" when "guess" doesn't exist?! Help!"

So it gives us an error.

Here's my solution, I don't think it creates any bugs anywhere else in the game:

 while len(guesses) < 5:
        guess = input("Guess a number between 1 and 10: ")
        try:
            #Get a number guess from the user
            guess = int(guess)
        except ValueError:
            print("{} is not a whole number! Please enter a whole number.".format(guess))

And then the rest of the code is the same. I've just made sure that the variable "guess" is always created out of the user's input, and then once it has been created, the code attempts to turn it into an integer, but it atill exists even if it can't be turned into an integer.

Povilas Jurgaitis
Povilas Jurgaitis
6,792 Points

I believe you are right, very good explanation, couldn't spell any clearer. Thank you! Also, got a deeper understanding on what's happening inside try function. Thank you again for your effort.

Scott Benton
Scott Benton
2,563 Points

Exactly right. In the original code, if a non-integer string is entered, 'guess' never receives a value.

Freddy Venegas
Freddy Venegas
1,226 Points

Thank you for this. Makes me understand referencing objects a little better.

Thank you Christopher Hazell !

John Forbes
John Forbes
10,879 Points

So Christopher Hazell has a great answer, (see his notes) one other idea that I found when doing some searching there is a function isinstance( <var>, int ) that returns true or false and could be used in an if statement. That being said, the variable still needs to be created first.

Josh Keenan
Josh Keenan
19,306 Points

Can you post your code please?

Povilas Jurgaitis
Povilas Jurgaitis
6,792 Points
<p>
import random

# safely mane an in
# limit guesses
# too high message
# too low message
# play again

def game():

    # generate a random number between 1 - 10
    secret_num = random.randint(1, 10)

    guesses = []

    while len(guesses) < 5:

        try:
            # get a number guess from the player
            guess = int(input("Guess a number between 1 and 10: "))
        except ValueError:
            print("{} isn't a number!".format(guess))
        else:

            # compare guees to secret number
            if guess == secret_num:
                print("You got it! My number was {}".format(secret_num))
                break
            elif guess < secret_num:
                print("My number is higher than {}".format(guess))

            else:
                print("My number is lower than {}".format(guess))
            guesses.append(guess)
            # print hit/miss
    else:
        print("You didn't get it! My number was {}".format(secret_num))        

    play_again = input("Do toy want to play again? Y/n ")
    if play_again.lower() != 'n':
        game()
    else:
        print("Bye!")

game()

</p>
Josh Keenan
Josh Keenan
19,306 Points

Your problem is a simple one, you need to import the random library.

import random

You can just add that and your problems will all go away.

Povilas Jurgaitis
Povilas Jurgaitis
6,792 Points

I believe random library is imported as you look at the first lines of code. And i don't have any issues with generating random numbers.

Josh Keenan
Josh Keenan
19,306 Points

Oh yeah sorry I'll take a look at that now :)!

Edit: Shouldn't be a ValueError but a TypeError I think, still trying to get it to work though

Ryan Dorr
Ryan Dorr
16,387 Points

I'm having the same problem. The only way I can get it to work is by not specifying an exception type but I know that's not exactly best practice.