Reputation: 21
Why does my function not change the value of a variable in python?
pattern = 0
def patterns(pattern):
if die1 == die2 == die3 == die4 == die5:
pattern = 1
patternDef = "all values being the same (100 points)?"
elif diceSum % 2 == 1:
pattern = 2
patternDef = "a prime number sum (sum of" + str(diceSum) + "is a prime number) (50 points)"
elif count == 3:
pattern = 3
patternDef = "3 values being the same (30 points)?"
elif count == 0:
pattern = 4
patternDef = " all different values (25 points)?"
else:
pattern = 5
patterns(pattern)
print(pattern)
OUTPUT:
0
Upvotes: 1
Views: 1458
Reputation: 248
Do not forget about the global operator. This code allows you to change the value of pattern without calling pattern = patterns ()
later:
pattern = 0
def patterns(pattern):
global pattern
if die1 == die2 == die3 == die4 == die5:
pattern = 1
patternDef = "all values being the same (100 points)?"
elif diceSum % 2 == 1:
pattern = 2
patternDef = "a prime number sum (sum of" + str(diceSum) + "is a prime number) (50 points)"
elif count == 3:
pattern = 3
patternDef = "3 values being the same (30 points)?"
elif count == 0:
pattern = 4
patternDef = " all different values (25 points)?"
else:
pattern = 5
patterns()
Upvotes: 0
Reputation: 6033
To improve upon the previous answer, there is something called as variable scope in each programming language.
The scope of a variable is the extent upto which the variable will be stored in memory. Once the variable goes out of scope, it's value is discarded and the memory is freed up.
In your case, the confusion occurs as you have labelled both the global variable and the function argument as pattern
.
But since the scope of the function argument extends only upto the function body, the value is discarded once the program control exits from the function as mentioned in the previous answer.
Upvotes: 0
Reputation: 168824
Because pattern
is a local variable (as it's a function argument), and modifications to it won't persist when the function exits.
One way to fix this would be to pass pattern
around as a global variable (as you're implicitly doing with die1..5
, diceSum
and count
), but better would be to just pass in the dice values as arguments, compute the intermediaries in this scoring function and return the values. I'm returning 2-tuples of pattern "id" and explanation, but you could probably want to extend these to 3-tuples of id/explanation/score too.
def patterns(die1, die2, die3, die4, die5):
total = die1 + die2 + die3 + die4 + die5
count = len({die1, die2, die3, die4, die5}) # count unique values
if die1 == die2 == die3 == die4 == die5:
return (1, "all values being the same (100 points)?")
elif total % 2 == 1:
return (2, "a prime number sum (sum of %s is a prime number) (50 points)" % total)
elif count == 3:
return (3, "3 values being the same (30 points)?")
elif count == 5:
return (4, "all different values (25 points)?")
else:
return (5, "mysterious pattern #5")
# ...
pattern_id, pattern_explanation = patterns(1, 3, 6, 4, 5)
A further refactoring would allow for any number of dice, by passing them in as a list:
def patterns(dice):
total = sum(dice) # total of dice
count = len({die1, die2, die3, die4, die5}) # count unique values
if count == 1:
return (1, "all values being the same (100 points)?")
elif total % 2 == 1:
return (2, "a prime number sum (sum of %s is a prime number) (50 points)" % total)
elif count == 3:
return (3, "3 values being the same (30 points)?")
elif count == len(dice):
return (4, "all different values (25 points)?")
else:
return (5, "mysterious pattern #5")
# ...
print(patterns([1, 3, 3, 6, 2, 4, 5, 5, 1, 5, 1]))
Upvotes: 1