How can i fix this with threading or multithreading - python

So in short im making a python game using Tkinter for some GUI, Thats not the problem.
when im running the code its freesing for 10 second. tell me how i can fix this using threading.
sorry i cant write a question properly
def timepas():
global time0
global money
global total_money
global Invests
global Invests_money
global stopInvest
global countlocal
while stopInvest:
countlocal = countlocal + 1
Invests_money = Invests * 2
money = money + Invests_money
print(money)
time.sleep(1)
if countlocal == count:
stopInvest = False
continue
def work_money():
global money
money += 1
def BankAcc():
global money
messagebox.showinfo("Your Bank Account", "You have $:" + str(total_money))
def Inves():
global Invests
global money
if money >= 10:
Invests = Invests + 1
money = money - 10
def stop_investing():
global count
global countlocal
global total_money
global money
count = 10
countlocal
total_money = total_money + money

Related

How do I create a variable that can be changed by calling a function in Python but also saves the data of the past changes?

For example, let's say I'm trying to create a wallet system in python where money can be add to and taken out of. I try this code here:
balance = 0
def addmoney(x):
x += balance
addmoney(10000)
print(balance)
but it just gave me 0.
so then I tried this:
def addmoney(x):
balance = 0
balance += x
And I realized that this would set the money back to 0 every time the user adds money, which I didn't want. Is there a solution to this?
You could declare the balance variable as global inside the function.
balance = 0
def addmoney(x):
global balance
balance += x
addmoney(10000)
print(balance)
This is usually do with OOP:
class BankAccount:
def __init__(self, owner, balance, currency):
self.owner = owner
self.balance = balance
self.currency = currency
def print_balance(self):
print("Your current balance is:")
print(self.balance)
def make_deposit(self, amount):
if amount > 0:
self.balance += amount
else:
print("Please enter a valid amount.")
def make_withdrawal(self, amount):
if self.balance - amount >= 0:
self.balance -= amount
else:
print("You don't have enough funds to make this withdrawal.")
To call the function:
my_savings_account = BankAccount("Pepita Perez", 45600, "USD")
my_savings_account.print_balance()
my_savings_account.make_deposit(5000)
my_savings_account.make_withdrawal(200)
my_savings_account.print_balance()
In Python, you must use the global keyword when accessing global variables from within a function. See here.
One way to keep track of the changes is to store the previous values in a list outside the function. Again, using the global keyword
Also your logic for the balance is backwards. You should be adding x to the balance.
balance = 0
historyLst = []
def addmoney(x):
global balance
global historyLst
historyLst.append(balance)
balance += x
addmoney(10000)
print(balance)

Variable doesn't add itself to previous amount

In this code I tried to make that when you type "work", you get any number from 1 to 50 and it adds itself to the total balance (5 times). But when I do this, the previous amount of the variable resets to the new amount.
import random
balance = 0
def work(balance):
earned_money = random.randint(1, 50)
balance += earned_money
print(balance)
for x in range(5):
user_input = input()
if user_input == "work":
work(balance)
Even though the global keyword solves your problem, depending on who you ask, global variables are considered bad practice in Python. I try to avoid them unless there's absolutely no other way, and in this case, it's quite easy to come up with a solution that doesn't need globals:
import random
balance = 0
def work(balance):
earned_money = random.randint(1, 50)
return balance + earned_money
for x in range(5):
user_input = input()
if user_input == "work":
balance = work(balance)
print(balance)
I recommend learning more about variable scope.
Here is working code. You need to declare it as global.
import random
balance = 0
def work():
global balance
earned_money = random.randint(1, 50)
balance += earned_money
print(balance)
for x in range(5):
user_input = input()
if user_input == "work":
work()
The outer balance variable is in global scoping whereas the balance variable inside function is in local scoping.
If you want to make local scope variable global then you need to use global keyword inside your function.
import random
balance = 0
def work():
global balance # This makes balance variable global.
earned_money = random.randint(1, 50)
balance += earned_money
print(balance)
for x in range(5):
user_input = input()
if user_input == "work":
work()

UnboundLocalError: local variable 'money' referenced before assignment [duplicate]

This question already has answers here:
Using global variables in a function
(25 answers)
Closed 5 years ago.
I'm trying to get rid of a error in python but so far every method i've tried hasn't worked. Any help would be greatly appreciated.
The code:
from sense_hat import SenseHat
import random
from guizero import App, PushButton,Text
import time
import pygame.mixer
from pygame.mixer import Sound
pygame.mixer.init()
sense = SenseHat()
app = App(title="Fruity Fruit Machine", bgcolor="yellow")
mario = Sound("SuperMarioBros.ogg")
money = 30.00
casino = 100.00
global money
global casino
def machine():
sense.clear(0,0,0)
images = ["apple.png", "orange.png", "lemon.png"]
fruit = []
money = money - 1.00
for i in range(3):
img = random.choice(images)
fruit.append(img)
sense.load_image(img)
time.sleep(3)
sense.clear(0,0,0)
if all_same(fruit) == True:
sense.show_message("You won £20!")
casino = casino - 20.00
money = money + 20.00
display_casino()
dispaly_money()
dc = "Casino money: " + casino
cm.set(dc)
md = "Your money: " + money
m.set(md)
else:
sense.show_message("You got 30p!")
money = money + 00.30
casino = casino + 00.70
display_casino()
display_money()
dc = "Casino money: " + casino
cm.set(dc)
md = "Your money: " + money
m.set(md)
def play_mario():
mario.play()
def all_same(items):
return all(x == items[0] for x in items)
button = PushButton(app, command=machine, text="SPIN")
button2 = PushButton(app, command=play_mario, text="Play Music")
cm = Text(app, text="",align="left")
m = Text(app, text="",align="right")
The error is: UnboundLocalError: local variable 'money' referenced before assignment. Python also sometimes comes up with a syntax warning: SyntaxWarning: name 'casino' is assigned to before global declaration
Try moving the global declarations inside your function:
from sense_hat import SenseHat
import random
from guizero import App, PushButton,Text
import time
import pygame.mixer
from pygame.mixer import Sound
pygame.mixer.init()
sense = SenseHat()
app = App(title="Fruity Fruit Machine", bgcolor="yellow")
mario = Sound("SuperMarioBros.ogg")
money = 30.00
casino = 100.00
def machine():
global money
global casino
sense.clear(0,0,0)
images = ["apple.png", "orange.png", "lemon.png"]
fruit = []
money = money - 1.00
for i in range(3):
img = random.choice(images)
fruit.append(img)
sense.load_image(img)
time.sleep(3)
sense.clear(0,0,0)
if all_same(fruit) == True:
sense.show_message("You won £20!")
casino = casino - 20.00
money = money + 20.00
display_casino()
dispaly_money()
dc = "Casino money: " + casino
cm.set(dc)
md = "Your money: " + money
m.set(md)
else:
sense.show_message("You got 30p!")
money = money + 00.30
You need to put global money and global casino within machine. Putting it outside a function does nothing. For an explanation of why, take a look at this answer.

Tkinter update label when variable changes

I am working on a code that is a clicker game. I have done 90% myself as I have never used Tkinter module before so was a learning project really, anyway to the problem:
I have just sorted the auto clicking function and a label in the window attached to a variable (the amount of cash), at the moment I have the label at a .pack(), and set so it creates a new label after every second. Obviously this will create confusion and isn't what you would expect from a game, so I wondered if there was a way to either:
1) Make the label update every time the variable (Amount of cash) updates (This would be Ideal if you can help me with this)
2)Delete the label with a line of code and then put the new label in with the current variables number (Not as good as the first, but would still be great to have this one if the first isn't possible)
Here is the code so far:
import time
from tkinter import *
root=Tk()
CPS=0
cash=0
mult=1
def blankLine():
for i in range(16):
print ("")
def infoprint():
print("Cash =",cash)
print("")
print("Each click is worth",mult,"cash")
print("")
print("CPS =",CPS)
blankLine()
def CashASecond():
global root
global cash
global CPS
cash += CPS
root.after(1000, CashASecond)
CashASecond()
def CashLabel():
label1=Label(root,text=cash)
label1.pack()
root.after(1000, CashLabel)
CashLabel()
def ManualClicker():
global cash
global mult
cash += 1*(mult)
infoprint()
ManualClickerButton=Button(root,text="Click",command=ManualClicker)
ManualClickerButton.pack()
class upgrades():
def DoubleManualClicker():
global cash
global mult
if cash < 1000:
print("Not enough cash, sorry")
elif cash>= 1000:
print ("Double clicks purchased!")
mult *= 2
cash = cash - 1,000
DoubleManualClickerButton=Button(root,text="Purchase double clicks",command=DoubleManualClicker)
DoubleManualClickerButton.pack()
DoubleManualClickerLabel=Label(root,text="Each click is worth twice as much, costs 1,000 \n")
DoubleManualClickerLabel.pack()
def clicker():
global cash
global mult
global CPS
if cash < 25:
print("Not enough cash, sorry")
elif cash >=25:
CPS += 1
print("CPS is now",CPS)
cash = cash - 25
ClickerButton=Button(root,text="Purchase auto clicker", command=clicker)
ClickerButton.pack()
ClickerLabel=Label(root,text="+1 CPS, costs 25 \n")
ClickerLabel.pack()
def SingleMachine():
global cash
global mult
global CPS
if cash < 50:
print("Not enough cash, sorry")
elif cash >= 50:
CPS += 3
print("CPS is now",CPS)
cash = cash - 50
SingleMachineButton=Button(root,text="Purcahse Single Cash Printer",command=SingleMachine)
SingleMachineButton.pack()
SingleMachineLabel=Label(root,text="+3 CPS, costs 50 \n")
SingleMachineLabel.pack()
def LoftOfCashPrinter():
global cash
global mult
global CPS
if cash < 100:
print("Not enough cash, sorry")
elif cash >= 100:
CPS += 5
print("CPS is now",CPS)
cash=cash-100
LoftOfCashPrinterButton=Button(root,text="Purchase a loft of cash printers",command=LoftOfCashPrinter)
LoftOfCashPrinterButton.pack()
loftlabel=Label(root,text="+7 CPS, costs 100 \n")
loftlabel.pack()
root.title("Cash Clicker! ALPHA! By George Hill")
root.geometry("500x900+900+0")
root.mainloop()
Thanks in advance :)
I had this problem before and the way I managed to fix this was to use events and bindings. Note that I am using classes and Application. e.g.
def Click(self, event):
self.Label['text'] = ....
....
self.Buy = Button(....)
self.Buy.grid(....)
self.Buy.bind('<Button>', self.Click)
self.Label = Label(....)
self.Label.grid(....)
I understand this code is very basic (it won't work) and the use of .... is to show where the use of variables and the like will be used. This is written purely to show you how to bind widgets.

NameError: global name 'numKilos' is not defined

def inputKilos():
while True:
numKilos = float(raw_input("Enter a number of Kilometers. Enter 0 to end program. "))
if numKilos == 0:
break
else:
convert_kilos(numKilos)
return
def convert_kilos(numKilos):
numMiles = numKilos * 0.6214
print_output()
return
def print_output():
print numKilos, "kilometers eqauls", numMiles, "miles."
def main():
inputKilos()
main()
When I try to run the program it says "NameError: global name 'numKilos' is not defined" I don't know why it says numKilos isn't defined. numKilos is equal to the number that the user enters.
numKilos is a local variable in both inputKilos and convert_kilos, but not print_output. Local variables can only be accessed from within that function.
To pass variables around, use return <value> to return a value from the function, then collect it by using result = function(), or do the reverse by passing values into functions (like you did with convert_kilos.
Those are local variables not global.
You can try this:
#!/usr/bin/python
def inputKilos():
while True:
numKilos = float(raw_input("Enter a number of Kilometers. Enter 0 to end program. "))
if numKilos == 0:
break
else:
miles = convert_kilos(numKilos)
print_output(numKilos,miles)
return
def convert_kilos(numKilos):
numMiles = numKilos * 0.6214
return numMiles
def print_output(numKilos,numMiles):
print numKilos, "kilometers eqauls", numMiles, "miles."
inputKilos()
Or using global keyword:
#!/usr/bin/python
numKilos=0
numMiles=0
def inputKilos():
while True:
global numKilos
numKilos = float(raw_input("Enter a number of Kilometers. Enter 0 to end program. "))
if numKilos == 0:
break
else:
convert_kilos(numKilos)
print_output
def convert_kilos(numKilos):
global numKilos
global numMiles
numMiles = numKilos * 0.6214
def print_output:
global numKilos
global numMiles
print numKilos, "kilometers eqauls", numMiles, "miles."
inputKilos()
Here's a refactored version:
MILES_PER_KM = 0.621371
def get_float(prompt=''):
while True:
try:
return float(raw_input(prompt))
except ValueError:
pass
def main():
while True:
kms = get_float('Enter a distance in kms (or 0 to exit): ')
if kms:
miles = MILES_PER_KM * kms
print ' {} kilometers is {} miles.'.format(kms, miles)
else:
break
if __name__=='__main__':
main()

Categories