3

Write a program to simulate tossing a fair coin for 100 times and count the number of heads. Repeat this simulation 10**5 times to obtain a distribution of the head count.

I wrote below code to count number of heads 100 times, and outer loop should repeat my function 100K times to obtain distribution of the head:

import random
def coinToss():
    return random.randint(0, 1)

recordList = []

for j in range(10**5):

    for i in range(100):
        flip = coinToss()
        if (flip == 0):
            recordList.append(0)

    print(str(recordList.count(0)))

but each time I run my program, instead of getting a list of 100K heads probability, I get no#s higher, can anyone tell me what I doing wrong ?

42

89

136

....

392

442

491

Community
  • 1
  • 1

4 Answers4

4

Here's a version with numpy that allows you to more elegantly produce random numbers, as you can also specify a size attribute.

import numpy as np


n_sim = 10
n_flip = 100

sims = np.empty(n_sim)
for j in xrange(n_sim):
    flips = np.random.randint(0, 2, n_flip)
    sims[j] = np.sum(flips)
rammelmueller
  • 855
  • 10
  • 24
2

Since the original problem asks for a distribution of head counts, you need to keep track of two lists: one for the number of heads per 100-toss trial, and one for the number of heads in the current 100-toss trial.

import random
def coinToss():
    return random.randint(0, 1)

experiments = [] # Number of heads per 100-toss experiment

for j in range(10**5):
    cnt = [] # Number of heads in current 100-toss experiment
    for i in range(100):
        flip = coinToss()
        if (flip == 0):
            cnt.append(0)
    experiments.append(cnt.count(0))
    print(str(cnt.count(0)))

However, I would strongly suggest doing this in something like numpy which will greatly improve performance. You can do this is one line with numpy:

import numpy as np
experiments = np.random.binomial(n=100, p=0.5, size=10**5)

You can then analyze/plot the distribution of head counts with whatever tools you want (e.g. numpy, matplotlib).

Brenden Petersen
  • 1,678
  • 7
  • 10
  • I like your answer, can you implement the code snipet that you used numpy, in my code, cause I am new to python and I don't know where to bring changes to my code and add `experiments` – Hashmatullah Noorzai Oct 10 '17 at 16:19
  • 2
    The numpy code snippet is actually a replacement for your entire code block. Check out the docs for [`numpy.random.binomial`](https://docs.scipy.org/doc/numpy-dev/reference/generated/numpy.random.binomial.html). So, the number of heads in each 100-toss trial for all 10^5 experiments is stored in the variable `experiments`. The only difference is that its datatype is a `numpy.ndarray` instead of `list`. You can convert it to list with `experiments = list(experiments)`. – Brenden Petersen Oct 10 '17 at 16:22
1

You might notice that your number of heads is ~50 more each time. This is because you don't reset the record counter to [] each time you loop. If you add "recordList = []" straight after your print statement and with the same indentation, it will basically fix your code.

Another nifty way to do this would be to wrap the 100 coin flips experiment in a function and then call the function 10**5 times. You could also use list comprehension to make everything nice and concise:

import random

def hundred_flips():
    result = sum([random.randint(0, 1) for i in range(100)])
    return result

all_results = [hundred_flips() for i in range(10**5)]
0

You can simulate a matrix with all your coin flips and then do your calculations on the matrix.

from numpy import mean, std
from numpy.random import rand
N_flip = int(1e5)
N_trials = int(1e2)
coin_flips = rand(N_flip, N_trials) > 0.5
p = mean(coin_flips, axis=0) # Vector of length N_trials with estimated probabilites
print('Mean: %3.2f%%, Std: %3.2f%%' % (mean(p)*100, std(p)*100))
wpof
  • 11
  • 1