Search code examples
pythonvariablestkinterreturndefinition

How to update a variable after it's returned in a function without repetition


i am making a game(cookieclicker to be exact) im running of a problem of repetition so I fixed it but theirs still a problem of var not being returned, i cant seem to find a way to do it without involving repetition, here the code( just a cut of my code, which i added useful stuff like print button ) and ill tell you what I mean:

import tkinter as tk
root = tk.Tk()

def printt():
    print(amountc, amountg, amountt)

def defamountx(amount, priceconstant, cpsconstant, Name, Button, refresh):
    global cpsall
    old_price = round(priceconstant * 1.15 ** amount)
    if refresh is False:
        amount += 1
    price = round(priceconstant * 1.15 ** amount)
    cps = amount * cpsconstant
    Button["text"] = f"{Name}\n🍪{price}"
    shoptxt["text"] = f"↓Shop↓, {cpsall} c/s"
    print(amount)
    return amount, price, cps
amountc=0
amountg=0
amountt=0
cpsall = 0

shoptxt = tk.Label(root, height=1, width=40)
shoptxt.pack()

clickerbn = tk.Button(root, command=lambda: defamountx(amountc, 5, 0.1, "Clicker", clickerbn, False), width=30, height=2)
amountc, pricec, cpsc = defamountx(amountc, 5, 0.1, "Clicker", clickerbn, True)

grandmabn = tk.Button(root, command=lambda: defamountx(amountg, 75, 1, "Grandma", grandmabn, False), width=30, height=2)
amountg, priceg, cpsg = defamountx(amountg, 75, 1, "Grandma", grandmabn, True)

treebn = tk.Button(root, command=lambda: defamountx(amountt, 500, 5, "Cookie Tree", treebn, False), width=30, height=2)
amountt, pricet, cpst = defamountx(amountt, 500, 5, "Cookie Tree", treebn, True)

printbn = tk.Button(root, command=printt, width=30, height=2, text='print')
printbn.pack()



shoptxt["text"] = f"↓Shop↓, {cpsall} c/s"
buttons = [clickerbn, grandmabn, treebn]
for stf in buttons:
    stf.pack()

root.mainloop()

ok so the idea behind defamountx is that i can change the outcome from what i choose like if the price is 1000 i can just put defamountx(amountx, 1000, cpsconstant_x, "Name of thing", bn, False) but defamountx isnt returning the amount, price, and cps since it isnt really updating the amount and etch vars, since when i say amountc, pricec, cpsc = defamountx(amountc, 5, 0.1, "Clicker", clickerbn, True)

which yes that updates the var but it runs the first thing in the code and I wanna make it run every time u do the button now I was thinking to add a def like def c: amountc, pricec, cpsc = defamountx(amountc, 5, 0.1, "Clicker", clickerbn, False) which might work but that really kinda defeated the whole purpose of the thing not being repetitive

so please if someone knows a way to do it without repetition and make it return my var, than please do please inform me

i was expecting that the def defamountx would just return the vars to the code without any problem, but i need to do def c: amountc, pricec, cpsc = defamountx(amountc, 5, 0.1, "Clicker", clickerbn, False) which is the only thing i can think of but that will involve repetition..


Solution

  • From your description, it is very difficult to understand what you are trying to achieve.

    Here is a code that removes the need to call defamountx twice. It does this by creating a function that will instantiate your button with the correct values and behavior

    Note: Your code did not work because you thought that you could pass any variable to a function and change its value inside it (amountc, amountg, amountt). This is not the case: it does not work for integer, floats, strings but it works for mutable object instances (see https://stackoverflow.com/a/986145/19209968 for more detail)

    To fix this, I have created a dictionary with as key the name of the cookie maker, and as value the current amount.

    import tkinter as tk
    
    root = tk.Tk()
    
    amount_per_type = {
        "Clicker": 0,
        "Grandma": 0,
        "Cookie Tree":0
    }
    
    cpsall = 0
    
    shoptxt = tk.Label(root, height=1, width=40)
    shoptxt["text"] = f"↓Shop↓, {cpsall} c/s"
    shoptxt.pack()
    
    
    def create_button(price_constant, cps_constant, name):
    
        def update_values():
            global cpsall
            print(amount_per_type[name])
            amount_per_type[name]+=1
            price = round(price_constant * (1.15 ** amount_per_type[name]))
            cpsall+=cps_constant
    
            shoptxt["text"] = f"↓Shop↓, {cpsall} c/s"
            button["text"] = f"{name}\n{price}"
    
    
        button = tk.Button(root, command=update_values)
        button["text"] = f"{name}\n{price_constant}"
        
        return button
    
    buttons = [
        create_button(5, 0.1, "Clicker"),
        create_button(75, 1, "Grandma"),
        create_button(500, 5, "Cookie Tree"),
    ]
    
    for stf in buttons:
        stf.pack()
        
    root.mainloop()