How to add counters to User-Defined Functions in Python? - python

>>> Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Maximillian\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:\Python-koding\steinsakspapir.py", line 64, in scissors
botwin += 1
UnboundLocalError: local variable 'botwin' referenced before assignment
-Tried to remove botwin and youwin from rest of the code
-Tried to use youwin = youwin + 1
def scissors():
bot = random.randint(1,3)
user = 3
if user == bot:
printfuver = ("Stalemate, booth players choose scissors")
printfu = Label(lowerframe, text=printfuver, fg="blue")
printfu.pack()
if user == 3 and bot == 1:
printfuver = ("Rock crushes scissors, bot win! ")
printfu = Label(lowerframe, text=printfuver, fg="red")
printfu.pack()
botwin += 1
if user == 3 and bot == 2:
printfuver = ("Scissors cut paper, you win! ")
printfu = Label(lowerframe, text=printfuver, fg="green")
printfu.pack()
youwin += 1
Simply want botwin to increase with a value of 1 after each time the fuction is ran.
thanks in advance

Aside from the indentation error in your code, this is probably a scope issue. Check to make sure you have botwin = 0 or something like it somewhere in your code. If that code is in a function or otherwise out of global scope, put it at the top of your code. Then, in all functions that reference it, put global botwin at the beginning of your function as explained here.
I hope this helps you.

Related

I am trying to code blackjack for fun and i get this error local variable 'first_hit' referenced before assignment on line: 32

I am coding in codesters/python bc thats what my school is teaching me on and im trying to code in the hit button. I originally had it where there were no if statements but i realized i might need to hit 2 times i tried this and i get the error message "local variable 'first_hit' referenced before assignment on line: 32"
if first_hit == True:
This happens when i click the hit button the first time
first_hit = True
def click(hit_button):
if first_hit == True:
player3 = random.choice(cards)
player3disp = codesters.Display(player3, 50, -150)
player_total = player1 + player2 + player3
playertotaldisp.update(player_total)
first_hit = False
stage.wait(1)
elif first_hit == False:
player4 = random.choice(cards)
player4disp = codesters.Display(player4, 150, -150)
player_total = player1 + player2 + player3 + player4
playertotaldisp.update(player_total)
hit_button.event_click(click)
Normally a variable will be local meaning that once you are in a new scope (In this case your function) Python won't "see" the variable.
To make your variable accessible from all scopes you use global first_hit before the first reference.
Since you'll often start to get problems finding new names for variables when you use global variables, it is often a good idea to put things that will reference each other in a class.

unresolved NameError while writing Blackjack gameflow

I am currently writing a game of Blackjack using python 2.7. as part of the app's gameflow I have defined a new function called player_turn(), in which I required a user input that would result in different scenarios depending on the input ("hit" would give the player another card, and "hold" would end the player's turn and pass it on to the dealer. otherwise would result in a customized error)
def player_turn():
if sum(player_card_numbers) < 21:
user_decision = input('would you like to hit or hold?')
if user_decision == 'hit':
player_cards.append(deck.draw())
print player_cards, dealer_cards
player_turn()
elif user_decision == 'hold':
print "Dealer's turn!"
dealer_turn()
else:
print "player must choose 'hit' or 'hold'"
player_turn()
elif sum(player_card_numbers) == 21:
print "Blackjack!"
dealer_turn()
else:
print "Player Burnt! \nDealer's turn!"
dealer_turn()
It is worth mentioning that the code was originally written in python 3.7, and was changed later on. the code worked perfectly with 3.7.
Now I get this error:
NameError: name 'hit' is not defined
I would love some advice on how to solve this issue, as well as an explanation on why this would happen. :)
The problem is this line:
user_decision = input('would you like to hit or hold?')
In Python2, input() has an eval() nature to it, so it's evaling your answer: hit
>>> user_decision = input('would you like to hit or hold?')
would you like to hit or hold?hit
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'hit' is not defined
>>>
The coding standard for Python 2 is to not use input() but rather use raw_input() instead:
>>> user_decision = raw_input('would you like to hit or hold?')
would you like to hit or hold?hit
>>> user_decision
'hit'
>>>
In Python 3, the input() function is equivalent to raw_input() in Python 2.

python calling definition by variable name

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?

I'm writing the follow python script as a way to implement a slot machine type game using random numbers

from getch import getch, pause
from random import randint
def wheel_spin():
tokens = 100
while tokens > 0:
num_input= getch()
if num_input == ' ':
print "You Hit Space Bar"
draw1 = randint(1,6)
draw2 = randint(1,6)
draw3 = randint(1,6)
print draw1 , draw2 ,draw3
winning(draw1,draw2,draw3)
tokens -= 1
#pause()
def winning(draw1,draw2,draw3):
if draw1 == draw2 or draw2 == draw3:
print "YOU WIN"
tokens += 10
else:
pass
wheel_spin()
The code works fine and generates random numbers but when it comes to the "winning" function where it is supposed to reward the player for getting two of the same numbers it doesn't work I get the following error
YOU WIN Traceback (most recent call last): File "Exercise 36
Designing and Debugging.py", line 59, in
wheel_spin() File "Exercise 36 Designing and Debugging.py", line 31, in wheel_spin
winning(draw1,draw2,draw3) File "Exercise 36 Designing and Debugging.py", line 51, in winning
tokens += 10 UnboundLocalError: local variable 'tokens' referenced before assignment
Any help will be greatly appreciated
tokens is undefined in the winning method. It's declared in the spin_wheel and is scope-limited to only that method. You either want to pass it in or make it global.
tokens = 10
def spin_wheel():
global tokens
...
def winning():
global tokens
...

Python: Returning a list doesn't work

I am trying to make a program that can add/delete/show students in a class, and the 5 classes are 5 lists in a list.
Help is greatly appreciated.
When I run this code:
global classes
def intro():
print("Welcome to Powerschool v2.0!")
print("Actions:")
print("1. Add Student")
print("2. Delete Student")
print("3. Show Students in a Class")
print("4. Show All Students")
x = int(input())
while x<1 or x>4:
print ("Please choose an action, 1-4.")
x = int(input())
if x == 1:
action1()
elif x == 2:
action2()
elif x == 3:
action3()
elif x == 4:
action4()
classes = [[],[],[],[],[]]
return classes
def action1():
print("Which Class? 1-5")
a = int(input())
print("Please enter the student's name.")
z = input()
classes[a-1].append(z)
again()
def action2():
print ("Which Class? 1-5")
print ("Which student?")
again()
def action3():
print ("Which Class? 1-5")
y = int(input())
if y == 1:
print (classes[0])
elif y == 2:
print (classes[1])
elif y == 3:
print (classes[2])
elif y == 4:
print (classes[3])
elif y == 5:
print (classes[4])
again()
def action4():
print (classes)
again()
def again():
print("Would you like to do something else? y/n")
h = input()
if h == "y":
intro()
else:
quit
def main():
intro()
main()
My error is:
Traceback (most recent call last):
File "C:\Documents and Settings\user1\My Documents\Downloads\az_studenttracker.py", line 67, in <module>
main()
File "C:\Documents and Settings\user1\My Documents\Downloads\az_studenttracker.py", line 65, in main
intro()
File "C:\Documents and Settings\user1\My Documents\Downloads\az_studenttracker.py", line 19, in intro
action1()
File "C:\Documents and Settings\user1\My Documents\Downloads\az_studenttracker.py", line 33, in action1
classes[a-1].append(z)
NameError: name 'classes' is not defined
I did return classes at the end of intro() but I see that doesn't work.
I followed some suggestions, and nothing really happened :/
You're defining classes in your intro method, and, even though it's returning it, your action1 method doesn't see any variable named classes anywhere.
Relevant answer on Python scope and relevant documentation.
return doesn't do what you think it does. return statements are a way of passing execution control back up a context (For example, from intro() to main()), with the ability to send back some information for the higher context to use. Although you're passing classes back to main(), you never do anything with it at that context so it goes away.
One way to solve the problem would be to declare classes as a global variable. This is the easiest thing to do, but isn't generally good design. You could do this either by using the global keyword before declaring the local variable classes in intro() (See this question for guidance on global), or by declaring classes outside any of your functions.
Another solution would be to pass classes as a parameter to your action functions.
In either case, you would need to declare classes before any calls to your action functions.
This is because classes is out of scope for the second two methods. Therefore, you have two options:
Option 1
Pass classes to the methods action1(), action2(), etc like so:
def action1(classes)
...and the when you call it:
action1(classes) //with the classes var you just made
Option 2 (recommended)
Simply put the classes var outside your methods or declare it global like so:
global classes = [[],[],[],[],[]]
...right before:
def intro()
In general, you should read up on how return works; it is not necessary in the code you wrote
classes only exists in intro():, you would have to declare it as a global variable to access it in other functions or declare it outside the function.
classes = [[],[],[],[],[]] # can be accessed by action3() ,action4()
def intro():

Categories