Help with coin flip

Hi I have a question regarding the code below. I define the variable money before I define the function, nevertheless, when I don’t define money INSIDE the function, I get an error that money is referenced before assignment.

On the other hand I define num also before the function and not inside the function. This does not cause the above mentioned error. Do you have any idea why? I think this is because I do not do arithmetics on this num variable. But I still don’t understand why this is the reason for the error.

import random

money = 100
num = random.randint(0,10)
print(num)

heads = num<= 5
tails = num>5


def coin_flipping(guess, amount):
  money = 100
  if guess == True:
    money += amount
  else:
    money -= amount
  print(money)
  
  if num <= 5:
    print('heads')
  else:
    print('tails')

coin_flipping(heads,50)

hi @ajax6191459755
you will notice that when you are sharing code you would want to make it easy for other codecademy forums users to read it, you can do it like this:
at the top of the editing box are a line of icons, in order to put your code in

an environment like this

use the: </> button.
this makes it a lot easier for other users to help you.

about your code. I’m not quite sure what is the reason for this error, but I have a feeling it has to do with num being a permanent variable (you are not trying to change it inside the function). and money being a non permanent variable. so I think you should look this concept up and for now just in order for you code to work :wink:, stick to assigning money inside the function.
good luck, and happy coding!

1 Like

Aha! Didn’t know that, so edited my post. Thx for the tip.

Yes, that’s also what I thought. It’s just strange you can call a variable inside the function if you define it beforehand, but you cannot perform arithmetics on it. Otherwise you need to define it inside the function again.

1 Like

I think you should look it up, cause it does seem a bit strange. I’m not sure that is what’s causing it but maybe.

I’ve run into this problem too and am not sure why it is like this. I did find a way around it though…
You can make the function create a new variable equal to the old one and perform your operation, then after the function make the old variable be equal to the new one.


value = 3

def calculation():
new_value = value + 3

calculation()
value = new_value




This should set value = 6
Hopefully that was helpful :)

@ajax6191459755, it is the way that Python handles local (within the function) and global (outside the function) variables. Python wants you to easily be able to reference global variables inside a function — if you don’t plan on reassigning the value.

Once you assign value to a variable within a function, Python automatically classifies it as a local variable, unless explicitly told not to. This prevents the numerous (and potentially dangerous) unexpected consequences that come from modifying globals within your functions. Although it wouldn’t be a big deal in your program here, it would cause you headaches in the future on a larger program. There are numerous discussions online (including this one) if you are interested in understanding more.

3 Likes

I’m going to post a way to deal with this and leave the research to the reader. Python looks at variables in four (4) ways: Local, Enclosed, Global, Built-in (LEGB); this can help with Internet keyword searches.

"""local-vs_global.py"""

money = 100

def local():
    print(money, 'printing from local()')

def change_money():
    global money 
    print(money, 'printing from change_money()')
    money = 50
    print(money, 'printing from change_money()')

print(money, 'printing from global')
local()
change_money()
print(money, 'printing from global')
1 Like

@harrjt:

Yes, you can do this. However, I would strongly discourage anyone from using the global and nonlocal keywords until they have been programming for a few years and thoroughly understand what they are dealing with. That is precisely why I did not mention the use of global in my answer, and probably why Codecademy doesn’t include it in their curriculum.

Although it works great in a small script like this, as a program gets larger it will almost inevitably cause issues with both:

  • Unexpected side-effects
    • Python docs on why you have to explicitly call global:

…requiring global for assigned variables provides a bar against unintended side-effects.

  • Thread safety issues
    • Python docs on ways to write functions with output parameters:

1.By returning a tuple of the results […] This is almost always the clearest solution.
2. By using global variables. This isn’t thread-safe, and is not recommended. (emphasis added)
3. By passing a mutable (changeable in-place) object […]
4. By passing in a dictionary that gets mutated […]
5. Or bundle up values in a class instance […] There’s almost never a good reason to get this complicated.
Your best choice is to return a tuple containing the multiple results. (emphasis added)

Also, it’s worth noting that using the global keyword from early on encourages lazy coding habits and discourages the use of local variables and data structures that are potentially more appropriate.

1 Like