Python Forum

Full Version: variable referenced before assignment
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hey guys, I was trying to write a function that takes as an argument a number, and according to Newton's formula that states we can estimate the square root of a number by trying several times to "estimate" it. This is the piece of code I wrote:
def main():
    number = int(input("Insert the number:"))
    estimation = 1
    if number == "":
        print("Goodbye!")
    elif number < 0:
        print("Error: negative number")
    else:
        def estim(someNumber):
            estimation = (estimation + number / estimation) / 2
            return number
        while True:
            tollerance = 0.000000001
            estim(number)
            difference = abs(number - estim(number) **2)
            if difference <= tollerance:
                break
    return estim(x)
The problem is: even if I assign to the variable estimation a value of 1 in the first lines, python gives me this errors:
line 19, in main
    estim(number)
line 15, in estim
    estimation = (estimation + number / estimation) / 2
UnboundLocalError: local variable 'estimation' referenced before assignment
Each function has it's own scope. The function, which is called in main() could not access to the local variables of main.

The function estim does not see the variable estimation. How could a function evaluate this statement, when estimation is unknown?
estimation = (estimation + number / estimation) / 2
This error happens also, when you've assigned a global variable (on module level) and try to assign a new object to this name inside a function. You can use global, but you should avoid this. You can assign the object, which is referenced by a global name (variable) to a local name inside your function. Then you can do afterwards a new assignment to the local variable, which don't have an effect on the global variable.

In Python you're referencing by name.
 
estimation = (estimation + number / estimation) / 2
Here the right side of the equation is evaluated before the asignment to the left side. Always. But the variable is not defined yet so estimation on the right doesn't exists when you try to use it.

As @DeaD_EyE said in your case you are trying to use a global variable. But in a function all variables are local. You can pass it as an argument.

global_var = 1

def func(var):
    print(var)

func(global_var)
Thanks guys, as you advised I assigned the variable inside that second function and I put a while loop after that, and it worked.
def main():
    number = int(input("Insert the number:"))
    if number == "":
        print("Goodbye!")
    elif number < 0:
        print("Error: negative number")
    else:
        def estim(someNumber):
            estimation = 1
            while True:
                estimation = (estimation + someNumber / estimation) / 2
                tollerance = 0.000000001
                difference = abs(number - estimation **2)
                if difference <= tollerance:
                    break
            return estimation
    return estim(number)
If number is less than 0 (or blank), estim won't be defined, so calling it would be an error.  I'm not sure why you're defining it anyway, just use a while loop directly:
def main():
    number = int(input("Insert the number:"))
    if number == "":
        print("Goodbye!")
    elif number < 0:
        print("Error: negative number")
    else:
        estimation = 1
        while True:
            estimation = (estimation + number / estimation) / 2
            tollerance = 0.000000001
            difference = abs(number - estimation **2)
            if difference <= tollerance:
                break
        number = estimation
    return number