import random import math def stdDev(values): mean = float(sum(values))/len(values) diffsum = 0.0 for item in values: diff = item - mean diffsum = diffsum + diff*diff return math.sqrt(diffsum/len(values)) # simulate flipping a coin numFlips times. # return tuple (number of heads, number of tails) # def doNCoinFlips(numFlips): numHeads = 0 flipNum = 0 while flipNum < numFlips: value = random.randint(1,2) if value == 1: numHeads = numHeads + 1 flipNum = flipNum + 1 return (numHeads, numFlips-numHeads) # Do numTrials coin flip simulations with numCoins each time. # For each trial compute ratio of number of heads to number of trials. # Compute average and standard deviation of the ratios over all trials. # Print summary and # return tuple (average heads/tails ratio, standard devation of ratio) # def doCoinFlipTrials(numTrials, numCoins): headTailRatios = [] headTailDiffs = [] for trial in range(numTrials): nHeads, nTails = doNCoinFlips(numCoins) #print("Trial #{}: numHeads = {}, numTails = {}".format(trial, nHeads, nTails)) # NOTE: This code *can* crash - it's unlikely but nTails can, of course, be 0 headTailRatios.append(float(nHeads)/nTails) ratiosAvg = sum(headTailRatios)/len(headTailRatios) ratiosStdDev = stdDev(headTailRatios) print("# of flips = {}: avg head/tail ratio: {} (SD: {})".format(numCoins, ratiosAvg, ratiosStdDev)) return (numCoins, ratiosAvg, ratiosStdDev) # Execute doCoinFlipTrials for different numbers of coins (and given number of trials), # starting with minCoins and increasing by factor until number exceeds maxCoins. # Return list of results returned by the calls to doCoinFlipTrials. # Thus, results will be of form [(minCoins, ..ratio.., ...std...), (factor*minCoins, ..ratio.., ...std..), ...] # def doCoinFlipExperiment(minCoins, maxCoins, factor, numTrials=20): numCoins = minCoins results = [] while numCoins <= maxCoins: results.append(doCoinFlipTrials(numTrials, numCoins )) numCoins = numCoins * factor return results # Uncomment section below if you have pylab import pylab # results = doCoinFlipExperiment(16, 2**20, 2) # plotResults(results) # pylab.show() # # # Create figure with two subplots, one showing avg. head/tail ratios for different numbers of # coin flips, the other showing standard deviation of head/tail ratios. # def plotResults(results): numFlips, ratios, ratioSDs = tuple(zip(*results)) pylab.figure(1) pylab.clf() pylab.subplot(121) pylab.title("Head/tail ratios") pylab.xlabel("Number of flips") pylab.ylabel("Average head/tail ratio") pylab.semilogx() pylab.plot(numFlips, ratios, 'ro-') pylab.subplot(122) pylab.title("Std dev. of h/t ratios") pylab.xlabel("Number of flips") pylab.ylabel("Standard deviation") pylab.semilogx() pylab.plot(numFlips, ratioSDs, 'ro-')