Gladiator
Gladiator

Reputation: 83

Simulate a coin toss experiment - RealPython

Can someone help me explaining the solution for below Realpython assignment task? Solution i found seems confusing.

Write a python script that uses coin toss simulations to determine the answer to this slightly more complex probability puzzle: I keep flipping a fair coin until I've seen it land on both heads and tails at least once each - in other words, after I flip the coin the first time, I continue to flip it until I get a different result. On average, how many times will I have to flip the coin total? Again, the actual probability could be worked out, but the point here is to simulate the event using randint. To get the expected average number of tosses, you should set a variable trials is 10000 and a variable flips is 0 , then add 1 to your flips variable every time a coin toss is made. Then you can print flips / trials at the end of the code to see what the average number of flips was.

    from random import randint
    flips = 0
    trials = 10000
    for i in range(trials):
        first_flip = randint(0, 1)
        while randint(0, 1) == first_flip:
            flips += 1           # Every flip after the first flip.
    print("flips done is {}".format(flips))
    print(flips / trials + 2.0)  # Initial trial and final trial added.

In the above case if the first_flip is 0 and the while loop condition produces 1 at the very first random attempt, the for loop iterates without adding the flips. Also, if the while loop runs when random attempts equals first_flip, within the while loop trail ie, value for "i" in the for loop is not added. In short the final number of flips is more or less than the number of trials.

Can someone help me explaining the logic behind this or a better python script?

Upvotes: 1

Views: 1549

Answers (2)

Hugh Bothwell
Hugh Bothwell

Reputation: 56644

I'd break it down a bit differently.

For each trial, let's just assume the first flip is a 0. (It doesn't matter what it actually was, it makes no difference to the logic - so we'll just assume that's what we got, then we don't actually even have to flip it.) Then we keep flipping until we get a 1.

When we are finished all the trials, we have an unknown number of 0s (plus one 0 per trial which we didn't actually do) plus one 1 per trial. So the total number of flips is {number of 0s we actually flipped} + 2 * {number of trials}, and we stop once we have {number of trials} 1s.

from random import randint

def total_flips(trials):
    zeros = 0
    ones = 0
    while ones < trials:
        if randint(0, 1):
            ones += 1
        else:
            zeros += 1
    return zeros + 2 * trials

trials = 10000
flips = total_flips(trials)
print("Flips done:", flips)
print("Average flips:", flips / trials)

Upvotes: 0

ddg
ddg

Reputation: 1098

The code works mostly how you think. The part you are missing:

if the first_flip is 0 and the while loop condition produces 1 at the very first random attempt, the for loop iterates without adding the flips.

This is solved at the bottom,

print(flips / trials + 2.0)  # Initial trial and final trial added.

They add the 2 'missing' flips per trial here.


If I had written the code, here's how I would do it.

flips = 0
def flip():
    global flips
    flips += 1
    return randint(0,1)

trials = 10000
for i in range(trials):
    first_flip = flip()
    while flip() == first_flip:
        pass

print("flips done is {}".format(flips))
print("average flips", flips / trials)

Upvotes: 2

Related Questions