Alloho
Alloho

Reputation: 11

coin flip simulate in python

I want to simulate flipping a fair coin 500 times. Then I have to create a graph to show the running proportion of heads when flipping a coin with flip number on the x-axis and proportion heads on the y-axis. I wrote the Python code and I got the following error:

Traceback (most recent call last):
File "E:\ProgramsPython\My\bayes\Coin Flip.py", line 22, in <module>
ylist = [coinFlip(x) for x in xlist]
File "E:\ProgramsPython\My\bayes\Coin Flip.py", line 16, in coinFlip
return heads / x
ZeroDivisionError: integer division or modulo by zero

What did I do wrong?  

# -*- coding: cp1251 -*-
import random
import pylab
from matplotlib import mlab
def coinFlip(size):
    heads = 0
    tails = 0

    for x in xrange(size):
        flip = random.randint(0,1)
        if flip == 1: heads += 1
        else: tails += 1



    return heads / x

xmin = 1
xmax = 500
dx = 1
xlist = mlab.frange (xmin, xmax, dx)
ylist = [coinFlip(x) for x in xlist]
pylab.plot(xlist, ylist)
pylab.show()

Upvotes: 0

Views: 15284

Answers (5)

ticktock
ticktock

Reputation: 637

import numpy as np
from matplotlib import pyplot as plt

flips = np.random.binomial(1, 0.5, 500) # flip 1 coin with 0.5 prob of heads 500 times
heads_so_far = flips.cumsum() * 1.0 #lets use float to avoid truncations later
heads_to_count = [heads_so_far[i-1]/i for i in range(1,len(flips)+1)]
x = range(1,len(flips)+1)
plt.plot(x,heads_to_count)
plt.show()

Upvotes: 2

unutbu
unutbu

Reputation: 879103

In [53]: [x for x in xrange(1)]
Out[53]: [0]

x can equal zero. When that happens, (in particular, when coinFlip(1) is called),

heads / x

raises a ZeroDivisionError.


By the way, since you are using matplotlib, you must have NumPy installed. Therefore, you could use express coinFlip like this:

import matplotlib.pyplot as plt
import numpy as np

def coinFlip(size):
    flips = np.random.randint(0, 2, size=size)
    return flips.mean()
coinFlip = np.frompyfunc(coinFlip, 1, 1)

xmin, xmax, dx = 1, 500, 1
x = np.arange(xmin, xmax, dx)
y = coinFlip(x)
plt.plot(x, y)
plt.show()

enter image description here


Or (using @pjs's comment), to see how the proportion of heads changes during a single run of 500 coin flips:

def coinFlip(size):
    xmin, xmax, dx = 1, size, 1
    x = np.arange(xmin, xmax, dx)
    flips = np.random.randint(0, 2, size=size)
    return x, [flips[:i].mean() for i in x]

x, y = coinFlip(500)
plt.plot(x, y)

enter image description here


To plot the x-axis on a log scale:

fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_xscale('log')

enter image description here

Upvotes: 7

raddevus
raddevus

Reputation: 9077

When the line return heads / x is run the last time, then x is 0 thus creating the division by zero error.

Upvotes: 0

willy
willy

Reputation: 1490

You need to divide heads by size

To avoid truncating, it should probably be

     return heads / float(size)

Upvotes: 0

Matt Dodge
Matt Dodge

Reputation: 11142

Well, the error says you are dividing by zero. So there is one line where you divide, it's probably there.

Try changing your return to this (makes more sense anyway in my opinion):

return heads / size

Upvotes: 3

Related Questions