0

I'm building an application that allows for user tracking of basketball scores. For example, if a team shoots a free throw, they press a 'Free Throw' button under the scoring team's header and one point is added to the displayed score. I'm using Python 3.x and want to know if I can write function arguments that will be specified as either the home or the away score variable and then have the specified score be updated. Currently, I have separate functions for each type of score for each team, meaning I essentially have duplicate code minus the differences in 'home' and 'away'. Both home and away score are saved as globals due to requirements for interfacing with other software. Am I stuck with 6 total functions, or can I write 3 and just specify which global I want updated when I call the function? Sample non working code attached

global away_score
away_score = 0

global home_score
home_score = 0

def plus_one(inc_score, inc_frame):
    inc_score += 1
    inc_frame.config(text = inc_score) # this is for interfacing with tkinter
  • Note that the `inc_score` inside `plus_one` is a local variable created inside the function, and thus only in scope inside there. It does not refer to the parameter `inc_score`, whose value you would pass as an argument when calling `plus_one`. – Jethro Cao Oct 17 '19 at 03:49
  • send score to function as argument and send it back using `return`. Use `return inc_score` in `plus_one` and then `home_score = plus_one(home_score, ...)` and the same `away_score = plus_one(away_score, ...)` – furas Oct 17 '19 at 03:51
  • BTW: variable created outside functions are global - so you don't have to use your `global`. We use `global` inside function to inform funtion that it has to use external/global variable instead of creating local one. – furas Oct 17 '19 at 03:56

3 Answers3

2

Since you are using tkinter, probably the best way to deal with this is leveraging tkinter variables, in this case a IntVar:

import tkinter as tk

root = tk.Tk()

away_score = tk.IntVar(value=0)
home_score = tk.IntVar(value=0)

def plus_one(inc_score, inc_frame):
    inc_score.set(inc_score.get()+1)
    inc_frame.config(text = inc_score.get())

away_but = tk.Button(root,text=0)
away_but.config(command=lambda: plus_one(away_score,away_but))
away_but.pack()

root.mainloop()
Henry Yik
  • 22,275
  • 4
  • 18
  • 40
1

It's better to not use global variables and refactors your code to use local ones and dictionary or object to store scores. But as for your question, you could write something like this:

away_score = 0
home_score = 0


def plus_one(inc_frame, add_to_away: bool = False):
    global home_score
    global away_score
    if add_to_away:
        away_score += 1
        inc_score = away_score
    else:
        home_score += 1
        inc_score = home_score
    # inc_frame.config(text = inc_score) # this is for interfacing with tkinter


if __name__ == '__main__':
    plus_one(None, add_to_away=False)
    print(f"home: {home_score}, away: {away_score}")
    plus_one(None, add_to_away=True)
    print(f"home: {home_score}, away: {away_score}")
    plus_one(None, add_to_away=True)
    print(f"home: {home_score}, away: {away_score}")
Denis Yakovlev
  • 487
  • 3
  • 12
0

While you can modify global variables by name, this is generally not something you should do.

However, if you really need to make those variables globals (and not, for example, entries in a dictionary or properties of a class) and you really don't want to write multiple update functions, there is a solution.

As per this answer, you can modify the dictionary returned by globals, which updates the module namespace.

some_variable = None

def update(var, value):
    globals()[var] = value

update('some_variable', 'some value')

print(some_variable) # Output: "some value"

But if it is at all possible, you should avoid doing this—there are many better ways to write code, and this also leaves room for more exciting mistakes.

away_score = 10
update('away_scoer', away_score + 1) # npote the typo
print(away_score) # It's still 10, but there was no error in Python.

update('update', print) # now updating prints instead
update('away_score', 11) # Prints "away_score 11"
print(away_score) # still 10

update('print', function_that_melts_your_computer) # probably a bad idea

It also has more mundane downsides, like making your editor unhappy and ruining code completion in some places.

jirassimok
  • 3,850
  • 2
  • 14
  • 23