Marije
Marije

Reputation: 1

UnboundLocalError: local variable 'number' referenced before assignment

def straight():
    print("You went straight ahead")
    print("You run into a locked door. You try to break down the door but it 
    doesn't work..")
    print("Then you see the writing on the wall next to the door..")
    print("Call a number and then we call it even!")

    try:
        number = int(input("--> "))
    except:
        print("Not a number!")
        straight()

    if number % 2 == 0:
        print(f"You cracked the code! Your even number {number} gave you access 
        to this door")
        print("The door opens..")
        final_room()
    elif number % 2 >= 1:
        dead(f"The wrong number ({number}) caused the tunnel to collapse!")
    else:
        print("test else?")
        straight()

I am pretty new to programming so I hope someone can help me in "regular" language haha!

I looked at similar questions on this forum and other sites, but I still can't figure out what I am doing wrong. This is the function where I get an error messsage. The rest of my code works fine.

I keep getting the following message: UnboundLocalError: local variable 'number' referenced before assignment

But the variable has been set inside my function so I would think it would work. It also works when I give the wrong input (so a string in this case) right away. It does not work when I first give a string like: hkjadhjkas

Then this script will ask me again since it will run again. If i put in like the number 20 after that it will give this error. But at my first try giving in 20 it will work. So this error does not appear all the time.

So what am I not doing right? Thank you in advance for helping me.

Upvotes: 0

Views: 815

Answers (1)

ShadowRanger
ShadowRanger

Reputation: 155507

Your problem is that after recursing in your except block, you keep running the original function as if the exception had not occurred, but the original function failed to set number.

That is, this code:

try:
    number = int(input("--> "))  # Oh no, not a number
except:
    print("Not a number!")  # Jumps here
    straight()              # Runs straight
# Keeps going!!!

if number % 2 == 0:  # number never assigned!!!

tries to parse and assign to number, prints the error, invokes straight recursively, then when that finishes, it continues on as if the error had not occurred, causing if number % 2 == 0: to read number, without having set it.

If the goal is to use the recursive call's result, just change your code from:

try:
    number = int(input("--> "))
except:
    print("Not a number!")
    straight()

to:

try:
    number = int(input("--> "))
except:
    print("Not a number!")
    return straight()  # <-- Makes you return the result from the recursive call

A similar change would be needed in the other place you recursively call straight.

I'd also recommend limiting your except to something more specific than "all possible exceptions"; as is, you'll ignore the user hitting Ctrl-C, the system running out of memory, etc. I'd suggest using except ValueError: which is the only exception that int() itself would raise while parsing a string, rather than blindly catching all errors and assuming it was invalid input.

Upvotes: 1

Related Questions