2
def q1():
  type = str(input("Does your powers work with heat or cold or both? "))
  key = 0
  if type == "H":
    name1 = "Fire"
    key = 1
    q2a()

  if type == "C":
    name1 = "Ice"
    key = 1
    q2b()

  if type == "B":
    name1 = "Both"
    key = 1
    q3()

  elif key == 0:
    print("Oops, please enter H, C or B")
    q1()

def q2():
  print(name1)

I'm creating a code to generate a superhero name based on values inputted by the user. My question is, if one variable gets a value assigned to it, why doesn't the variable retain the value if the same variable is used in a separate function?

chowman01
  • 21
  • 1

3 Answers3

1

The variable name1 is a local variable in a function. You will need to use global to make it accessible as a global variable outside the function.

name1 = 'blank'

def q1():
  global name1
  type = str(input("Does your powers work with heat or cold or both? "))
  key = 0
  if type == "H":
    name1 = "Fire"
    key = 1
    q2()   #I edited this

  if type == "C":
    name1 = "Ice"
    key = 1
    q2()   #I edited this

  if type == "B":
    name1 = "Both"
    key = 1
    q2()   #I edited this

  elif key == 0:
    print("Oops, please enter H, C or B")
    q1()

def q2():
    print(name1)

q1()

Output is

Does your powers work with heat or cold or both? C
Ice

Edit: Thanks @rudolfovic that global variable is discouraged, see post Why are global variables evil?

So alternatively you could call the next function with the required value as a parameter

def q1():
  type = str(input("Does your powers work with heat or cold or both? "))
  key = 0
  if type == "H":
    name1 = "Fire"
    key = 1
    q2(name1)   #call next function with desired value

  if type == "C":
    name1 = "Ice"
    key = 1
    q2(name1)   #call next function with desired value

  if type == "B":
    name1 = "Both"
    key = 1
    q2(name1)   #call next function with desired value

  elif key == 0:
    print("Oops, please enter H, C or B")
    q1()

def q2(name1):
    print(name1)

q1()

Output

Does your powers work with heat or cold or both? H
Fire
blackraven
  • 5,284
  • 7
  • 19
  • 45
0

You could use global but it would be an anti-pattern. Instead return the value at the end of your function and then print(q1()). No need for q2 at all:

def q1():
  type = str(input("Does your powers work with heat or cold or both? "))
 
  if type == "H":
    return 'Fire'

  if type == "C":
    return 'Water'

  if type == "B":
    return "Both"

  print("Oops, please enter H, C or B")
  return q1()

name = q1()
print(name)
Jasmijn
  • 9,370
  • 2
  • 29
  • 43
rudolfovic
  • 3,163
  • 2
  • 14
  • 38
0

I think that there are some problems to be addressed and not all of them are about code.

If question is asked: "Does your powers work with heat or cold or both? " how one will know that 'F', 'C' or 'B' is expected? Why not accept 'heat', 'cold', 'both' as an answers?

This chain of if-s is very hard to maintain or change. Simpler approach would be creating mapping for powers (note my doubts about necessity of it expressed earlier):

powers_mapping = {'H': 'Fire',
                  'C': 'Ice',
                  'B': 'Both',
                 }

Now one can write simple validation function to get power from user. In order to have control over program flow instead of printing it returns validated value:

def validate(question, **kwargs):
    while (answer := input(question).upper()) not in kwargs:
        print(f'Expected one of {", ".join(kwargs)} but you entered {answer!r}')
    return kwargs[answer]

Now it can be used like:

print(validate('Enter your power ...', **powers_mapping))

The advantage of this approach is that if need to update/change/add powers then you do it in power_mapping and everything works just fine.

I put ... in question to user. It should be replaced with values from mapping and not entered manually (one possibility is combination of f-string and power_mappings.values()).

validate function is general enough that it can be used to verify other mappings as well (weapons?). If this is not needed one can omit **kwargs and access powers_mapping directly.

It should be also noted that 3.8 <= Python is required due to walrus operator.

Aivar Paalberg
  • 4,645
  • 4
  • 16
  • 17