1

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
3
  • what are the values of variable used in function, like die1, die2 etc Commented Nov 12, 2019 at 5:50
  • A simple debugging way would be to check if any of the conditional statements are getting executed or not. Commented Nov 12, 2019 at 5:55
  • i'm trying to make a dice game. if all dice have the same value they fall under pattern 1 which would give user 100 points. pattern 2 is if dice sum is odd number. pattern 3 is if 3/5 dice have the same value. pattern 4 is if dice have different values. pattern 5 is anything that doesn't fall under any previous patterns. hope I explained it good :) Commented Nov 12, 2019 at 5:57

3 Answers 3

1

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]))
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the explanation :) . How would I make my function so that it'll change the pattern value?
@Mark No worries. Added an edit that expands on the answer! :)
Thanks I'm still very new to coding and this is actually my first project that I'm doing. I'm still trying to fully understand your code but you've been a great help :)
0

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.

4 Comments

Good explanation on scope! :) This leaves patternDef as a local that never gets returned though.
That might happen. Looking at the code initially I had assumed that patternDef was another global variable. I agree, the code in your answer makes much more sense :)
Even if patternDef was a global variable, it wouldn't get written without global patternDef (or nonlocal patternDef in the case patterns() was an inner function, but that's beside the point).
Agreed. My apologies. I'll remove the code, but keep the variable scope explanation just in case :)
0

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()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.