Python Forum
How to fix UnboundLocalError - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: How to fix UnboundLocalError (/thread-7364.html)



How to fix UnboundLocalError - Tawnwen - Jan-07-2018

The code below models a simple game that tests if an input occurs in the list. The function is called twice, then the total # of correct answers is printed.

foot_bones = ["calcaneus", "talus", "cuboid", "navicular", "lateral cuneiform", "intermediate cuneiform", "medial cuneiform"]
answers_right = 0

def finder(bone_name):
    if bone_name.lower() in foot_bones:
        print("correct!")
        answers_right += + 1
    else:
        print("incorrect")
        
finder(input("enter name of a bone: "))
finder(input("enter name of another bone: "))

print("number of foot bones correctly identified: ", answers_right)
Code returns no error when the input is "incorrect", but gives an UnboundLocalError when a correct one is passed. How do I fix it? Simple issue.

Thanks!


RE: How to fix UnboundLocalError - wavic - Jan-07-2018

You have an extra "+" in line 7

        answers_right += 1



RE: How to fix UnboundLocalError - Gribouillis - Jan-07-2018

When a variable such as answers_right is on the left hand side of an assignment operator in a function, it becomes a local variable of this function. It means that the answers_right variable in function finder() is not the same as the global variable answers_right. Python complains because you are incrementing the local variable when this variable doesn't yet have a value.

A way to solve this is to add the statement global answers_right at the top of the finder()'s function body.

It is good practice to avoid global statements in python code, because they obfuscate the code somewhat, but they are allowed.


RE: How to fix UnboundLocalError - Tawnwen - Jan-07-2018

(Jan-07-2018, 08:08 AM)Gribouillis Wrote: It is good practice to avoid global statements in python code, because they obfuscate the code somewhat, but they are allowed.

Thanks! That fixed it.

No need to answer further, but would you recommend a different method of keeping track of the answers_right, without resorting to a global variable?


RE: How to fix UnboundLocalError - wavic - Jan-07-2018

Using global variables is not recommended.
You can do the same by passing answers_right as an argument to the function.

def finder(bone_name, correct):
    if bone_name.lower() in foot_bones:
        print("correct!")
        correct += 1
    else:
        print("incorrect")
Then call the function.
bone_name = input("enter name of a bone: ")
finder(bone_name, answers_right)
print(answers_right)



RE: How to fix UnboundLocalError - Gribouillis - Jan-07-2018

(Jan-07-2018, 04:16 PM)Tawnwen Wrote: would you recommend a different method of keeping track of the answers_right, without resorting to a global variable?
You are reaching the point where you have functions that manipulate external data and you need a way to manage both the data and the function. That's why classes were invented. Here is how you can code this by using a class:

class BoneFinder:
    foot_bones = [
        "calcaneus", "talus", "cuboid",
        "navicular", "lateral cuneiform",
        "intermediate cuneiform", "medial cuneiform",
    ]

    def __init__(self):
        self.answers_right = 0
 
    def examine(self, bone_name):
        if bone_name.lower() in self.foot_bones:
            print("correct!")
            self.answers_right += + 1
        else:
            print("incorrect")

finder = BoneFinder()         
finder.examine(input("enter name of a bone: "))
finder.examine(input("enter name of another bone: "))
 
print("number of foot bones correctly identified: ", finder.answers_right)
In this code, a single entity holds the variable answer_right between subsequent calls. The code looks more complicated than your program but in fact, it is easier to extend by adding new features.