0

I'm trying to create a Martingale betting simulator. My global "running_profit" variable is supposed to be indirectly updated by the "change_running_total" function. The running_total variable is being updated properly, but the running_profit variable, which is affected by the running_total, is not updating.

import random

round_n = 0
bet = 25
starting_funds = 5000
running_total = starting_funds
running_profit = running_total - starting_funds
goal_profit = 5000
wins = 0
losses = 0
rng_v = 0.00


def rng():
    """Generates random number"""
    global rng_v
    rng_v = random.random()


def winloss_generator():
    """Generates win/loss condition"""
    global rng_v
    if rng_v <= .49:
        return 'win'
    else:
        return 'loss'


def increase_winloss():
    """Increases wins or losses variable based on winloss_generator output"""
    global wins
    global losses

    if winloss_generator() == 'win':
        wins += 1
        return 'win'
    elif winloss_generator() == 'loss':
        losses += 1
        return 'loss'
    else:
        print('error')


def increase_round():
    """Increases round number by 1"""
    global round_n
    round_n += 1
    print('round: ', round_n)


def change_running_total():
    """Increases or decreases running_total based on winloss_generator"""
    global running_total
    if winloss_generator() == 'win':
        running_total += bet
    elif winloss_generator() == 'loss':
        running_total -= bet
    else:
        print('error')


def print_current_record():
    """Prints current win/loss record to screen"""
    print('Current Record: ', wins, 'wins, ', losses, 'losses')


def print_winloss():
    """Prints win/loss condition to screen"""
    print(winloss_generator(), 'print_winloss'.upper())


def print_profit():
    """Print running profit to screen"""
    print(running_profit, 'print_profit (variable)'.upper())
    print(running_total - starting_funds, 'print_profit (calculated)'.upper())


def return_current_funds():
    """Returns running total of funds"""
    global running_total
    return running_total


for x in range(5):
    increase_round()
    rng()
    print(rng_v, 'rng_v'.upper())
    print(winloss_generator(), 'winloss_generator'.upper())
    print(increase_winloss(), 'increase winloss'.upper())
    print_winloss()
    change_running_total()
    print(running_total, 'running total'.upper())
    print_profit()
    print()
print_current_record()
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • 1
    Welcome to Stack Overflow! Please take the [tour], read [what's on-topic here](/help/on-topic) and [ask], and condense your code down to a [mre]. We ask for a MRE because (a) it's a waste of time to read through lines after lines of irrelevant code looking for what's wrong, and (b) often, the exercise of creating a MRE helps you isolate and identify the problem and helps you fix the issue yourself. – Pranav Hosangadi Sep 14 '20 at 22:35
  • Variables do not automatically update in Python, you have to reassign them to a new value. – mkrieger1 Sep 14 '20 at 22:35
  • @mkrieger1 the running_profit variable is just a calculation on running_total and starting_funds. I can see that the running_total is being updated, and starting_funds is static, so the running profit calculation should update when the running_total updates, right? – Stephen Williams Sep 14 '20 at 22:48
  • No, that's not how Python works. See https://stackoverflow.com/questions/62042913/why-is-a-variable-not-updating-after-changing-its-dependent-variable – mkrieger1 Sep 14 '20 at 22:50

1 Answers1

0

You declare your variable at the top:

running_profit = running_total - starting_funds

However, this line only runs the one time; you're not setting up some kind of relationship here where it'll automatically get updated whenever you change running_total or starting_funds. If you want to do that, turn it into a function instead:

def running_profit():
    global running_total, starting_funds
    return running_total - starting_funds

Now every time you call running_profit() it'll calculate it based on the current values of those variables.

Side-note, instead of doing all of this with global variables, it'd be a good idea to encapsulate it into a class.

tzaman
  • 46,925
  • 11
  • 90
  • 115
  • The "global" line is not needed in your running_profit function, since neither of those variables are being updated. – SpoonMeiser Sep 14 '20 at 22:55
  • @SpoonMeiser I know, but I prefer to be explicit about it regardless since the function body may change later. Ideally, I'd refactor this whole thing to not use globals but that's out of scope for this answer. – tzaman Sep 14 '20 at 22:56
  • 1
    yes, but you're potentially masking a bug where if a name is _inadvertently_ reused, you clobber data you didn't mean to clobber, and do away with any chance of python reporting a `UnboundLocalError`. This sort of thing is exactly why your advice not to do this with globals is important. – SpoonMeiser Sep 14 '20 at 22:59
  • @tzaman I'm brand new to stackoverflow (as well as python). I don't want to clutter up the comments, but I can't find a messaging system on this site, and I'd like to ask you about your refactoring comment. How would you refactor the whole code base to avoid globals? – Stephen Williams Sep 14 '20 at 23:15
  • @StephenWilliams an approach simple enough to be described in the comments, would be to have your functions calculate numbers, and then `return` them, instead of manipulating globals and not returning anything. – SpoonMeiser Sep 14 '20 at 23:20
  • 1
    @StephenWilliams If this solved your problem please upvote and accept it. For the refactor - try defining a `main` function that drives your code, declare all the variables in there, and then pass them to the functions that need their values, or `return` the updated values to `main` and update them there. – tzaman Sep 15 '20 at 10:40
  • @tzaman I upvoted it yesterday, but I don't have enough reputation to affect the public score. Answer has been accepted. Thank you very much for the help and feedback. I really appreciate the assistance. – Stephen Williams Sep 15 '20 at 15:29