Error: UnboundLocalError: local variable 'attempts' referenced before assignment - python

I am attempting to make a simple guessing game for my class with graphics and I'm trying to make an attempt counter. This is the area where my code is going wrong.
def value():
guess = int(input("Enter your guess: "))
if guess > num:
attempts = attempts + 1
turtle.clearscreen()
interface()
tooHigh()
attempt = turtle.Turtle()
attempt.speed(0)
attempt.color("white")
attempt.penup()
attempt.hideturtle()
attempt.goto(-250 , 200)
attempt.write(guess, font=("Courier", 14, "bold"))
value()
elif guess < num:
attempts = attempts + 1
turtle.clearscreen()
interface()
tooLow()
attempt = turtle.Turtle()
attempt.speed(0)
attempt.color("white")
attempt.penup()
attempt.hideturtle()
attempt.goto(-250 , 200)
attempt.write(guess, font=("Courier", 14, "bold"))
value()
elif guess == num:
attempts = attempts + 1
turtle.clearscreen()
interface()
yes()
attempt = turtle.Turtle()
attempt.speed(0)
attempt.color("pink")
attempt.penup()
attempt.hideturtle()
attempt.goto(-250 , 200)
attempt.write(guess, font=("Courier", 14, "bold", "underline"))
print ("Correct!")
else:
print ("ERROR")
def startScreen():
begin = input("Start the game?: ")
if begin == 'yes':
value()
elif begin == 'instructions':
instructions()
startScreen()
elif begin == 'no':
sys.exit()
else:
print ("Unrecognised answer.")
startScreen()
attempts = 0
num = random.randint(1,1000)
interface()
startScreen()
The error I receive is:
Traceback (most recent call last):
File "D:\Desktop\Python Programs\Game.py", line 154, in <module>
`startScreen()`
File "D:\Desktop\Python Programs\Game.py", line 141, in startScreen
`value()`
File "D:\Desktop\Python Programs\Game.py", line 110, in value
`attempts = attempts + 1`
UnboundLocalError: local variable 'attempts' referenced before assignment
It doesn't seem possible to move attempts into the function as it constantly calls itself, resetting attempts each time.
I am unsure why this is occurring so any help would be greatly appreciated. Thanks!

The reason you are getting this error is because of something called variable scope. You have defined the variable attempts outside of the function value, so the function will not recognize any local variable by the name attempts unless you explicitly put the statement global attempts at the beginning of your function. This will tell the function that you want to use the variable attempts that you defined in your main program. That should look like this:
def value():
global attempts
#function code
Alternatively, you can allow your function value to take an argument, and pass the variable attempts into that. That would look something like this:
def value(attempts):
#function code
#you can use the variable attempts as needed, since you're passing it directly into the function
#call the function however you want
attempts = 0
value(attempts)

In the function, when you access a variable for assignment, it by-default is treated as a local variable. So, to make Python know that the variable that you want to modify is a global variable, you do the following:
def value():
global attempts
# rest of your code

Related

The global isn't working and didn't recognizing variable "text"?

The global isn't working properly and it says that
it does not know what text is, even though it is declared global.
def nguess():
answer = random.randint ( 1, 50 )
def check():
global attempts
attempts = 10
global text
attempts -= 1
guess = int(e.get())
if answer == guess:
text.set("yay you gat it right")
btnc.pack_forget()
elif attempts == 0:
text.set("you are out of attempts")
btnc.pack_forget ()
elif guess > answer:
text.set("incorrect! you have "+ str(attempts) + "attempts remaining. Go higher")
elif guess < answer:
text.set("incorrect! you have "+ str(attempts) + "attempts remaining. Go lower")
return
nw = tk.Toplevel(app)
nw.title("guess the number")
nw.geometry("500x150")
lable = Label(nw, text="guess the number between 1 - 50")
lable.pack()
e = Entry(nw, width = 40, borderwidth = 10)
e.pack()
btnc = Button(nw,text = "Check", command = check)
btnc.pack()
btnq = Button ( nw, text="Quit", command=nw.destroy )
btnq.pack()
text = StringVar()
text.set("you have ten attempts remaining ")
guess_attempts = Label (nw,textvariable = text)
guess_attempts.pack()
Well, what's going on is you're trying to get a variable before initialize it i.e. in check function you're calling a global text variable so what it means is you're bringing whatever text variable stores in global namespace, but the problem is text variable isn't exist in global namespace yet because you've created after calling the check function. Below I show an example:
def test():
global variable
print(variable)
test()
variable = 'Hello'
This will raise an error because of what I just explained, so what you have to do is something like this(based on the example):
def test():
global variable
print(variable)
variable = 'Hello'
test()
In short, initialize the text variable before calling the check function which uses global text

Python Random Project

This is a random code which is similar to my own project code.
When i run it it says UnboundLocalError: local variable 'score' referenced before assignment. Can anyone fix it.
score = 0
def Random_Thing():
Random_Text = input("Random Text")
if Random_Text == "Hello":
score = score + 1
print(score)
def Random_Thing_2():
Random_Text_2 = input("Random Text 2")
if Random_Text_2 == "Hello2":
score = score + 1
print(score)
Random_Thing()
Random_Thing_2()
print(score)
When you define score = 0 at the top, it is in the global scope for the file. By default, functions have only read access to global variables. You cannot change them. Therefore print(score) would work inside a function. But score=score+1 would not.
If you want to change global variable(s) from inside a function, do global var1, var2... at the begining of the function. For your code, you need to do
def Random_Thing():
global score
#your code
def Random_Thing_2():
global score
#your code

'function' object is not subscriptable error message

I am new to python and I am trying to make a basic text game with an inventory system. It was all going perfectly until I realised I needed the whole inv system as a function instead, and that's where the problems started.
gloinv = ["apple (food) 5", "health (healthpotion) 10", "sword (weapon) 5"]
hunger = 5
health = 10
fighting = False
enemyLife = 0
def get_num(x):
return (int(''.join(ele for ele in x if ele.isdigit())))
def inv():
global gloinv
global inv
print(gloinv)
while True:
item = input("which item would you like to select? ")
select = inv[int(item)-1]
print("you have selected '", select,"'")
use = input("type 'use' to use it or 'back' to select another. ")
if use == "use":
if "(food)" in select:
y = (int(''.join(ele for ele in select if ele.isdigit())))
print("you have eaten", (select.split(' ', 1)[0] ), "your hunger is now", hunger + y)
inv.remove(select)
print(inv)
gloinv = inv
break
elif "(healthpotion)" in select:
y = (int(''.join(ele for ele in inv[int(item)-1] if ele.isdigit())))
print("you have drunk", (inv[int(item)-1].split(' ', 1)[0] ), "your health is now", health + y)
health = health + y
inv.remove(inv[int(item)-1])
print(inv)
gloinv = inv
break
elif "weapon" in inv[int(item)-1]:
if fighting == True:
enemyLife - get_num(inv[int(item)-1])
elif fighting == True:
print("you can't use a weapon here")
break
elif use == "back":
print(inv)
inv()
print(gloinv)
print(hunger)
print(health)
I've tried to adapt to some problems but when I run this it comes up with;
Traceback (most recent call last):
File "C:\Users\Jenson\Desktop\Python\inv.py", line 47, in <module>
inv()
File "C:\Users\Jenson\Desktop\Python\inv.py", line 19, in inv
select = inv[int(item)-1]
TypeError: 'function' object is not subscriptable
enter code here
>>>
I have looked on other questions on this site but they are too confusing for me and tailored to different code doing different things.
Thanks for the answers but I found the solution doing some testing of my own. What I did wrong was label the function (inv) the same thing as the variable (inv) I solved it by naming the variable vInv instead so python wouldn't confuse the two.
Use parentheses (()) and not brackets ([]) when making a function call.
On line 19, you are doing the following:
select = inv[int(item)-1]
First of all; it's not clear what the purpose of this is. Please double check it. If you want to call the inv function, you need to call it with parentheses () and add the method parameters to the function declaration. Right now you're treating a function as a list, and using int(item)-1 as the index of that list. Hence the error.

TicTacToe project in Python 2: I am trying to avoid using global variables and return variables instead

I am working on a project, and I have no idea how to avoid using global variables. I have a list of functions that perform bits and pieces but I am not able to pass variables between them!
Here is my current code:
===================
def player_names_input():
global player_A_name,player_B_name
player_A_name = raw_input("Please enter name for Player A : ")
player_B_name = raw_input("Please enter name for Player B : ")
def coin_flip():
global player_A_name,player_B_name,start_player,end_player,game_state
game_state = "running"
import random
print "\nFlipping a coin to see who starts first..."
random_int = random.randint(0, 1)
if random_int == 0:
coin = 'Heads'
start_player = player_A_name
end_player = player_B_name
else:
coin = 'Tails'
start_player = player_B_name
end_player = player_A_name
print '\nCoin flip --> ',coin
print '\nStarting player --> ',start_player
print '\nStarting player gets "X"'
player_names_input()
coin_flip()
Here is my failed attempt to use return instead of global:
=========================================================
def player_names_input():
player_A_name = raw_input("Please enter name for Player A : ")
player_B_name = raw_input("Please enter name for Player B : ")
return player_A_name,player_B_name
def coin_flip(player_A_name,player_B_name):
game_state = "running"
import random
print "\nFlipping a coin to see who starts first..."
random_int = random.randint(0, 1)
if random_int == 0:
coin = 'Heads'
start_player = player_A_name
end_player = player_B_name
else:
coin = 'Tails'
start_player = player_B_name
end_player = player_A_name
print '\nCoin flip --> ',coin
print '\nStarting player --> ',start_player
print '\nStarting player gets "X"'
player_names_input()
coin_flip(player_A_name,player_B_name)
1- Please help make my second code run, I really wanna avoid global variables as everyone recommends.
2- Please critique my code, I am in the beginning and I am trying to learn writing good code (not just code). How bad is my attempt?
Since you have defined player_names_input() to return a 2-tuple (the two values, player_A_name and player_B_name), you could just assign them like so in the scope you are using that function,
player_A_name, player_B_name = player_names_input()
Now, when this is called:
coin_flip(player_A_name, player_B_name)
The two variables will be available for use.
You may want to consider wrapping the actual main program in a main method like
def main():
player_A_name, player_B_name = player_names_input()
coin_flip(player_A_name, player_B_name)
And call that if that file was directly executed - this is done by checking the magic __name__ variable to equal to the string '__main__', so add this too to the end of your program file.
if __name__ == '__main__':
main()

How can I reduce number of trys left in a game?

I am trying to limit the amount of tries a person has when attempting to guess the random number. I get this error code when I run the program and can't figure out what to do next.
Traceback (most recent call last):
File "C:/Python27/coding/Guess.py", line 34, in <module>
main()
File "C:/Python27/coding/Guess.py", line 24, in main
trys(userGuess)
File "C:/Python27/coding/Guess.py", line 29, in trys
trysLeft -= 1
UnboundLocalError: local variable 'trysLeft' referenced before assignment
The code:
import random
def main():
print "Guess a number between 1 and 100."
randomNumber = random.randint(1,100)
found = False
trysLeft = 5
while not found:
userGuess = input("Your guess: ")
if userGuess == randomNumber:
print "You got it!"
found = True
elif userGuess > randomNumber:
trys()
print "Guess lower!"
else:
trys()
print "Guess higher!"
def trys():
trysLeft -= 1
print "You have %d trys left." %trysLeft
if __name__ == "__main__":
main()
You have 3 options to fix this:
Put trysLeft in a global (not a good idea)
Add function trys() to your class and reference it as self.trysLeft
Pass the variable into the trys() function.
You need to pass trysLeft to the function for it to see it ...
def trys(trysLeft):
trysLeft -= 1
print "You have %d trys left." %trysLeft
return trysLeft
and then when you call trys ...
trysLeft = trys(trysLeft)
The problem is that you're assigning trysLeft in the function, so it assumes it has local (rather than global) scope. But you actually want to assign the global variable, so you need to declare that trysLeft has global scope. Change your trys() function to the following:
def trys():
global trysLeft
trysLeft -= 1
print "You have %d trys left." %trysLeft
For more information, see the FAQ
FWIW, the correct way to solve this would be to pass a variable to your function rather than use globals, but that's outside the scope of your question.
def trys(self):
self.trysLeft-=1
Should do it!
Self is referring to the instance of the class that you are currently in.
Similar to this in java and Me in vba.

Categories

Resources