Home > Back-end >  Python Randint function w/ repetition
Python Randint function w/ repetition

Time:12-04

I'm working with a simple function

def D6_roll():
    from random import randint
    return randint(1, 6)

I wanted to see the distribution of results after 1, 10, & 10,000 rolls, so I built this out

def D6_roll():
    from random import randint
    if randint(1, 6) == 1:
        return "1"
    elif randint(1, 6) == 2:
        return "2"
    elif randint(1, 6) == 3:
        return "3"
    elif randint(1, 6) == 4:
        return "4"
    elif randint(1, 6) == 5:
        return "5"
    else:
        return "6"

num_rolls = int(input("Please input roll sample size: "))
tally1 = 0
tally2 = 0
tally3 = 0
tally4 = 0
tally5 = 0
tally6 = 0
total = 0

for trial in range(num_rolls):
    total = total   int(D6_roll())
    
    if D6_roll() == "1":
        tally1 = tally1   1

    elif D6_roll() == "2":
        tally2 = tally2   1

    elif D6_roll() == "3":
        tally3 = tally3   1

    elif D6_roll() == "4":
        tally4 = tally4   1
        
    elif D6_roll() == "5":
        tally5 = tally5   1
        
    else:
        tally6 = tally6   1

print(f"1 was rolled {tally1}x")
print(f"2 was rolled {tally2}x")
print(f"3 was rolled {tally3}x")
print(f"4 was rolled {tally4}x")
print(f"5 was rolled {tally5}x")
print(f"6 was rolled {tally6}x")

Now here's where things get weird and why I've come seeking help...

If you look at

   for trial in range(num_rolls):
        total = total   int(D6_roll())

And then compare it to this line

sum_of_rolls = (1 * tally1)   (2 * tally2)   (3 * tally3)   (4 * tally4)   (5 * tally5)   (6 * tally6)

Shouldn't the total = sum_of_rolls? If not, why? I'm at a loss trying to explain my observed results. To anyone who made it this far, thank you in advance for helping a coding newb!

full code at https://github.com/thesageRR3/Python/blob/main/D6_Roll.py

CodePudding user response:

The answer to your question is that D6_roll() is producing a new random integer on each roll, so the D6_roll() summed into total does not match the one that you added into your tally. As a suggestion, use a dictionary:

from random import randint
num_rolls = 100
result = {i : 0 for i in range(1, 7)}
total = 0
for trial in range(num_rolls):
    roll = randint(1, 6)
    total  = roll
    result[roll]  = 1
print(total, sum(key * value for key, value in result.items()))

Notice here that roll is stored and referenced both by total and result, rather than calling randint(1, 6) in both places, which has the potential for the two values to be different.

CodePudding user response:

Each time you call D6_roll() as a condition you get a new roll. If you want to get only one roll per cycle, you should store the result in a variable and then use that variable, something like:

for trial in range(num_rolls):
    roll = int(D6_roll())
    total = total   roll
    if roll == 1:
        tally1 = tally1   1
    elif roll == 2:
        tally2 = tally2   1
...

CodePudding user response:

There is a big problem with the code you've implemented - namely, you are calling the random.randint function multiple times within D6_roll, and then you are calling D6_roll multiple times in your for loop. It is important that you only roll the dice one time in your code, otherwise it will give you unanticipated results.

To fix this, the first step is to fix D6_roll:

def D6_roll():
    from random import randint
    roll = randint(1, 6)
    return str(roll)

This will roll the dice a single time and return the result as a string.

The second step is to change inside the for loop:

for trial in range(num_rolls):
    roll = D6_roll()
    total  = int(roll)

    if roll == "1":
        tally1  = 1
    elif roll == "2":
        tally2  = 1
    ...

This will roll the dice exactly once then use it to perform your calculations. After you fix these two things, your sum_of_rolls function should equal total.

CodePudding user response:

from random import randint

def D6_roll():
    return randint(1, 6)

def roll(n = 10):
    d = {1:0, 2:0, 3:0, 4:0, 5:0, 6:0}
    for i in range(n):
        d[D6_roll()]  = 1
    return d

roll(100)
Out[1]: {1: 23, 2: 18, 3: 13, 4: 19, 5: 11, 6: 16}

roll(1000)
Out[2]: {1: 153, 2: 167, 3: 161, 4: 166, 5: 172, 6: 181}

roll(10000)
Out[3]: {1: 1682, 2: 1705, 3: 1677, 4: 1602, 5: 1717, 6: 1617}

You can check whether the number of rolls are the same: ie

sum(roll(20).values())
Out[5]: 20  ## Gives you 20 as expected
         
  • Related