UnboundLocalError: local variable 'text' referenced before assignment
Hi, I'm getting this error 'UnboundLocalError: local variable 'text' referenced before assignment'. How do you fix this?
Here is my Code:
even = None
def is_even(num):
if num % 2 == 0:
even = True
return even
elif num % 2 != 0:
even = False
return even
def lastmes():
if even == True:
text = "The last value of even is True"
elif even == False:
text = "The last value of even is False"
return text
print(lastmes())
print(is_even(51))
Here is my error message:
Traceback (most recent call last):
File "main.py", line 17, in <module>
print(lastmes())
File "main.py", line 15, in lastmes
return text
UnboundLocalError: local variable 'text' referenced before assignment
You should do 3 things.
First, make even variable inside the is_even function global. You are just creating another local variable and setting it's value which wont change the even you created outside the function.
def is_even(num):
global even #Here
if num % 2 == 0:
even = True
return even
elif num % 2 != 0: #You should change this to just an else but this works too
even = False
return even
Second, change the elif in your lastmes function to else. If you plan on using elif and want to consider a possibility for even to be None, then you should add another else to deal with the None possibility.
def lastmes():
if even == True:
text = "The last value of even is True"
else:
text = "The last value of even is False"
return text
Third, call is_even before lastmes so that the values are calculated, before checking them and displaying the messages.
print(is_even(50))
print(lastmes())
If even is neither True nor False, then text is never defined. even is set to None at the beginning of your program.
Related
After you get to the part when the program prints 6 it gives me the error that is mentioned below. Even though the value if properly attributed. I want it to print a 6 when the Mario.x_location value is equal to the LifeShroom.x value. Then after that, I want it to increase the value of the Mario.x_location by one whenever w is pressed. Type yes than press enter, and type w to see what I mean. What am I doing wrong?
start = input('say yes: ')
class Mario:
x_location = 4 #location of you
class LifeShroom:
x = 4 #location of the object.
if start == 'yes':
while start == 'yes':
command = input('') #press enter here, after you input yes.
if command == 'w':
Mario.x_location += 1 #change Mario.x_location
print(Mario.x_location,)
rules = [Mario.x_location == LifeShroom.x,]
if all(rules):
LifeShroom = True
if LifeShroom:
print(6) #type w again after it prints 6 and you will get the error below.
Exact error that I got:
Traceback (most recent call last):
File "main.py", line 25, in <module>
rules_8 = [Mario.x_location == LifeShroom.x,
AttributeError: 'bool' object has no attribute 'x'
I can say that you are doing a infinite loop. There is no scape for the while loop.
In the first if-statement isn't runned the first if (if command == 'w':), but runs the other two. In the first one, it destroies your class (LifeShroom = True). But it is True, so it will run the third. Your variable LifeShroom is not more a class but a boolean (True).
Next loop there is no more LifeShroom class, so no LifeShroom.x class atribute.
I tried to make the variable action global but it didn't work. It seems that any variable inside the else statement is isolated from the rest of the code, although they are in the same block of code in the for loop.
for group in auto_scaling_groups:
if servers_need_to_be_started(group):
pass
else:
action = "Stopping"
min_size = 0
max_size = 0
desired_capacity = 0
print("Version is {}".format(botocore.__version__))
print (action + ": " + group) #Error in this line
response = client.update_auto_scaling_group(
AutoScalingGroupName=group,
MinSize=min_size,
MaxSize=max_size,
DesiredCapacity=desired_capacity,
)
print (response)
If servers_need_to_be_started(group) is True, var action will never be assigned.
Set some default value at start for action.
The error is saying "after executing the "then" block of the if statement, action is not set but is used on the error line". The fix is to ensure action, min_size, max_size, and desired_capacity are assigned when the "then" block of the if statement is executed.
The error message pretty much sums it up: your variable action is being used (in some cases) before it is defined.
To be more specific, your action variable is only defined in your else block, meaning that if your condition servers_need_to_be_started(group) is true, action will never be defined.
So, simply define your variable outside of if/else blocks with some default value (e.g. an empty string), and then modify it in your else block as needed:
for group in auto_scaling_groups:
action = ""
if servers_need_to_be_started(group):
pass
else:
action = "Stopping"
min_size = 0
max_size = 0
desired_capacity = 0
print("Version is {}".format(botocore.__version__))
print (action + ": " + group) #Error in this line
response = client.update_auto_scaling_group(
AutoScalingGroupName=group,
MinSize=min_size,
MaxSize=max_size,
DesiredCapacity=desired_capacity,
)
print (response)
a python beginner here. My previous programming experience is with basic in the eighties, and logic programming in a proprietary system, neither of which is much help for learning python. So, to my question:
I'm writing a math quiz program (just for learning), and I've made a "main menu" by defining a function block; within it, if input is a then another func addition() is called, if input is s then func subtraction() is called and this works as intended. Within those function blocks, I'm setting a global variable quiztype to name of that function. Then I call yet another function again() from within those, to query if user wants another question of the same sort, if yes, I try to return to the relevant function with quiztype () and this fails with TypeError: 'str' object is not callable.
I did find some seemingly-related topics but either couldn't implement the answers or didn't even understand what they were talking about as I'm a beginner.
What options do I have for returning to the previously executed function?
Here's the code: (notice that variable names are not what above - different language)
from random import randint
def Alku ():
kysy = True
while kysy:
lasku = input('Yhteen, Vähennys, Lopeta? ')
if lasku == 'y':
Yhteenlasku ()
kysy = False
elif lasku == 'l':
break
kysy = False
def Uudestaan ():
kysy = True
while kysy:
samauudestaan = input('uudestaan? (k/e)? ')
if samauudestaan == 'k':
Lasku()
kysy = False
elif samauudestaan == 'e':
Alku ()
kysy = False
def Yhteenlasku ():
global Lasku
Lasku='Yhteenlasku'
n1=(randint(1,10))
n2=(randint(1,10))
a1=n1+n2
print(n1, end="")
print(" + ", end="")
print (n2, end="")
print(" = ", end="")
a2=int(input())
print()
if a1==a2:
print('oikein!')
elif a1!=a2:
print('väärin!')
Uudestaan()
Alku ()
And what is returned in terminal:
Traceback (most recent call last):
File "laskut2.py", line 43, in <module>
Alku ()
File "laskut2.py", line 8, in Alku
Yhteenlasku ()
File "laskut2.py", line 41, in Yhteenlasku
Uudestaan()
File "laskut2.py", line 19, in Uudestaan
Lasku()
TypeError: 'str' object is not callable
Your code is fine as it stands, although your global declaration is in an odd place. Still, remove the inverted comma's around your definition of Lasku which is defining it as a string and it will work.
global Lasku
Lasku=Yhteenlasku
P.S. Welcome back to programming!
In response to your question, globals would normally be declared at the beginning of your code or when the data to define becomes available but in this case you are defining it as a function, so you can't define it until the function has been defined. I guess as long as it works, where it is is fine. Personally, in this case, I'd define it here:
global Lasku
Lasku=Yhteenlasku
Alku ()
We really need to see your code to see what you want to achieve but from the sound of it you want to do something like this. From the question it look like you will be recalling function within functions and returning functions, creating recursions which is not that pythonic and also will eventually throw errors and the other is not really needed in this situation. jedruniu has put really quite a good explanation on function variable assignment too.
Less robust version:
def addition():
pass # Put code here
def subtraction():
pass # Put code here
def menu():
while True:
cmd = input("Addition or subtraction? (a/s): ")
if cmd == "a":
addition()
elif cmd == "s":
subtraction()
menu()
Other version (w/ score):
def addition():
# Put code here
result = True
return result # Will be added to score, so any integer or True/False
def subtraction():
# Put code here
result = True
return result # Will be added to score, so any integer or True/False
def menu():
score = 0
while True:
cmd = input("Addition or subtraction? (a/s/exit): ").strip().lower()
if cmd == "exit":
break
elif cmd == "a":
score += addition()
elif cmd == "s":
score += subtraction()
else:
print("Unknown option...")
# Do something with score or return score
if __main__ == "__main__":
menu()
You can assign function to a variable (because function is in Python first-class citizen), so effectively, for example:
def fun1():
print("fun1")
def fun2():
print("fun2")
def fun3():
print("fun3")
f1 = fun1
f2 = fun2
f3 = fun3
functions = {
"invoke_f1" : f1,
"invoke_f2" : f2,
"invoke_f3" : f3
}
functions["invoke_f1"]()
function_to_invoke = functions["invoke_f2"]
function_to_invoke()
yields:
fun1
fun2
More reading: https://en.wikipedia.org/wiki/First-class_function
In your specific example, modify your Uudestaan function.
def Uudestaan ():
Lasku = Yhteenlasku #Add this line
kysy = True
while kysy:
samauudestaan = input('uudestaan? (k/e)? ')
if samauudestaan == 'k':
Lasku()
kysy = False
elif samauudestaan == 'e':
Alku ()
kysy = False
because you were trying to invoke string, and this is not possible. Try to invoke type(Lasku) in your case and you'll see that it is of type str. Invoke it in function with my modification and you'll see type of function.
However I am not sure what is going on in this code, is this finnish? swedish?
The following function seems really simple, but I keep getting:
NameError: global name 'this_submit' is not defined.
Ideas?
def sort_nodes():
host_list=Popen(hosts_cmd.split(),stdout=PIPE).communicate()[0].strip()
exec_list=Popen(exec_cmd.split(),stdout=PIPE).communicate()[0].strip()
if submit_cmd == '':
submit_list = [x for x in host_list if x not in exec_list]
else:
submit_list=Popen(submit_cmd.split(),stdout=PIPE).communicate()[0].strip()
for host in host_list:
if host in exec_list:
this_exec == 'Exec'
else:
this_exec == ''
if host in submit_list:
this_submit == 'Submit'
else:
this_submit == ''
output="%s,%s,%s\n" % (host,this_submit,this_exec)
ofile.write(output)
the correct syntax is:
this_submit = 'Submit'
and
this_submit = ''
In python the single = is the assignment operator.
== checks if the value of two operands are equal or not, if yes then condition becomes true.
you wrote == instead of =. fix it and everything will be fine.
i have this code:
class Check(webapp.RequestHandler):
def get(self):
user = users.get_current_user()
be = "SELECT * FROM Benutzer ORDER BY date "
c = db.GqlQuery(be)
for x in c:
if x.benutzer == user:
s=1
break
else:
s=2
if s is 0:
self.redirect('/')
to check whether the user is registered or not.
but it gives me an error:
Traceback (most recent call last):
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/__init__.py", line 511, in __call__
handler.get(*groups)
File "/Users/zainab_alhaidary/Desktop/الحمد لله/check.py", line 23, in get
if s is 0:
UnboundLocalError: local variable 's' referenced before assignment
what should i do???
Define s before to assign it a value (also, change the test on s):
user = users.get_current_user()
be = "SELECT * FROM Benutzer ORDER BY date "
c = db.GqlQuery(be)
s=0 # <- init s here
for x in c:
if x.benutzer == user:
s=1
break
else:
s=2
if s == 0: # <- change test on s
self.redirect('/')
Why exactly are you loading all users, then looping through them, just to find one? Use a where clause:
be = "SELECT * FROM Benutzer WHERE benutzer=:1"
c = db.GqlQuery(be, user)
user_from_db = c.get()
if user_from_db is not None: # found someone
dostuff()
else:
self.redirect('/')
You're using 's' before you assign something to it. Add an 's = 0' in the appropriate location.
You want to set s to 0 before the for loop starts. If the query returns zero items, your for loop doesn't loop even once, so s is undefined.
Also, you should use if s == 0: instead of if s is 0:. In CPython, they are both equivalent, but you shouldn't rely on the fact. See: the documentation for PyInt_FromLong and "is" operator behaves unexpectedly with integers.
Your problem is that if c is an empty list then the code in the for loop is never run and s never gets set, hence the error:
UnboundLocalError: local variable 's' referenced before assignment
What the error is telling you that you're referencing - i.e. using - s before it has any value - i.e. before a value has been assigned to it.
To fix this you just ensure s always is assigned a value:
s = 0
for x in c:
if x.benutzer == user:
s = 1
break
else:
s = 2
In the case that c is empty the if statement in the loop never gets executed
you should set s=0 before the for loop
I don't know why you are doing this, but if I understand your code correctly, you have s=1 when x.benutzer == user, and s=2 otherwise (shouldn't this be s=0 if you are going to check against 0?).
for x in c:
if x.benutzer == user:
s=1
break
else:
s=2
if s is 0:
self.redirect('/')
Anyway, here's my solution:
if not any(x.benutzer == user for x in c):
self.redirect('/')