Reputation: 81
print "welcome to the average finder"
print """Insert the values you want to find the average for,
when you insert all the values type 'done'"""
values = []
def insert_values():
action = raw_input("> ")
if 'done' in action :
calculating_average()
elif action != 'done':
x = int(action)
values.append(x)
insert_values()
else:
print "please insert values then type done"
insert_values()
def calculating_average():
len = len(values)
sum = sum(values)
final = sum / len
print final
insert_values()
Purpose of this script: is to ask the user for numbers, then let the script find the average of the numbers and display it. I made an empty list called values, I append the user input numbers after turning them into integers.
I keep getting UnboundLocalError: local variable 'len' referenced before assignment... even thought I did assign len and sum to the length and sum of the elements in the list.
P.S. I am new to python and usually when I get an error I try to fix it on my own or research it but for this one I really dont understand why I am getting this error... any insights would be appreciated !!
Upvotes: 4
Views: 15188
Reputation: 882146
Regarding your code:
len = len(values)
sum = sum(values)
You probably don't want to use the same name for a variable and function(1):
>>> x = [1,2,3]
>>> len(x)
3
>>> len = len(x)
>>> len
3
>>> len(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
In your case, the error message UnboundLocalError: local variable 'len' referenced before assignment
is interesting but it's due to a specific Python feature.
Unless a variable within a function is marked global
, rebinding it anywhere within a function will cause it to be treated as a local variable everywhere within that function, even before the point of rebinding.
So len = len(something)
causes len
to be classified as a local variable and you're therefore trying to use it (by calling it as a function) before it's been set.
To fix the problem, change your function to be something like:
def calculating_average():
value_len = len(values)
value_sum = sum(values)
final = value_sum / value_len
print final
As a final note, I see two other potential problems. The first is the divide-by-zero error you'll get if you enter no numbers (i.e., enter done
immediately).
The second is the ... unusual ... use of recursion to go back and get the next number. I would seriously consider refactoring your code so that this is done with a loop.
(1) At some point, every Python developer has the epiphany of the "name/object distinction".
By that, I mean that every object in Python is inherently "unnamed" and we bind to them in various ways. When the last binding is removed from an object, it becomes inaccessible and therefore subject to disposal (garbage collection). For example, the code:
a = [1, 2, 3]
b = a
creates two names but only one object, meaning a[1] = 42
will affect both the a
and b
"names" because the same object is bound by both:
a b
\ /
V
[1, 42, 3]
This is what causes the issue with a statement like len = len(x)
.
Before you execute that, the len
name is bound to a function that does what you'd expect, working out the length of some object. After execution, it's bound to the value that was returned from that function.
At that point, executing something = len(something_else)
is no different to something = 3(something_else)
.
And also note that "binding" in this sense is mode than just name binding like name = some_object
. It also includes "anonymous" bindings like my_list.append(42)
- each entry in the list is a binding to the object at that position (in this case, my_list[-1]
is bound to the object 42
).
Upvotes: 7
Reputation: 86
The problem occurs when you create a local variable using the same name of a global function. Python assumes that there is a local variable called len that overwrites the len built-in function.
To fix this, you should add the line global len
(and global sum
too) before creating the len variable.
For more on Global vs Local Variables you should visit: http://www.python-course.eu/global_vs_local_variables.php
However you shouldn't name your variable as the built-in function len.
Upvotes: 2