1,105,286 Community Members

Coin Toss Simulation - Real Python

Member Avatar
flebber
Junior Poster in Training
71 posts since Aug 2009
Reputation Points: 12 [?]
Q&As Helped to Solve: 4 [?]
Skill Endorsements: 1 [?]
 
0
 

Hi

I was doing an exercise in the Real Python book. It gave a task of simulating a coin toss "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? "

So created the code:

from __future__ import division
from random import randint

flips = 0
trials = 10000

for trial in range(0, trials):

    first_flip = randint(0,1)
    while randint(0,1) == first_flip:
        flips += 1
    flips += 1

print "Average = ", flips / trials

So this produces an average of 2 which I thought would be right considering a coin is 2 sided.

However the solution is different:

from __future__ import division
from random import randint

flips = 0
trials = 10000

for trial in range(0, trials):
    flips += 1 # first flip
    if randint(0, 1) == 0: # flipped tails on first flip
        while randint(0, 1) == 0: # keep flipping tails
            flips += 1
        flips += 1 # finally flipped heads
    else: # otherwise, flipped heads on first flip
        while randint(0, 1) == 1: # keep flipping heads
            flips += 1
        flips += 1 # finally flipped tails

print flips / trials

And this produces an answer of 3.

The only difference I can see is that in my code I don't care whether its head or tails just measure whether its the same as the first flip.

Why are the averages different?

Member Avatar
pyTony
pyMod
6,103 posts since Apr 2010
Reputation Points: 818 [?]
Q&As Helped to Solve: 1,056 [?]
Skill Endorsements: 42 [?]
Moderator
Featured
 
0
 

The number of flips on average is first_flip + flips + final_flip = flips + 2:

from __future__ import division
from random import randint

flips = 0
trials = 10000

for trial in range(trials):
    first_flip = randint(0, 1)
    while randint(0, 1) == first_flip:
        flips += 1 # flips between

print flips / trials + 2.0 # always the first and last flip also

""" Output:
3.0075
"""

The exact theoretical answer would be counted

print sum((1.0/2)**n for n in range(10000)) + 1

as there is the first try and 0...infinity throws after first, continuation chance always halfing. (10000 arbitrary "big enough" number for the number to reduce to almost zero)

Member Avatar
flebber
Junior Poster in Training
71 posts since Aug 2009
Reputation Points: 12 [?]
Q&As Helped to Solve: 4 [?]
Skill Endorsements: 1 [?]
 
0
 

Thanks

while randint(0, 1) == first_flip:

makes much more sense thanks. And i forgot to add the first and last flip. It's good too see I wasn't too far out of the ballpark. When I saw the other solution was so different I thought I had stuffed it.

You
This article has been dead for over three months: Start a new discussion instead
Post:
Start New Discussion
View similar articles that have also been tagged: