'''
Calculating the average number of children in a Chinese family
(without regulation) for educational purposes.
Kristjan Kannike
Created: 2006-02-10
Changed: 2007-05-17
Calculate the average number of children in a Chinese family without any
regulations, if they want to have at least one boy, and the biologically
possible maximum number of children is given.
'''
import random
def happens(prob):
'''Probability -> Does the event happen?'''
return random.random() <= prob
def children(pBoy, pAnotherIfBoyAlready, nMax):
'''(pBoy, pAnotherIfBoyAlready, nMax) -> (boys, girls)
in a family, where
pBoy -- probability of the birth of a boy;
pAnotherIfBoyAlready -- probability of the birth of another child in case
the family already has a boy;
nMax -- the (biologically) maximum number of children.'''
boys = 0
girls = 0
pAnother = 1 # Probability that another child is born
for i in range(0, nMax):
if boys != 0:
pAnother = pAnotherIfBoyAlready
if happens(pAnother): # Does the family have another child?
if happens(pBoy):
boys += 1
else:
girls +=1
else: # No more children
return (boys, girls)
return (boys, girls)
def average(ls):
'''List -> average of the list'''
return round(float(sum(ls)) / len(ls), 3) # float to assure real division
def averageChildren(pBoy= 0.5, pAnotherIfBoyAlready=0.6, nMax=10, \
nTrials = 10000):
'''(pBoy, pAnotherIfBoyAlready, nMax, nTrials) -> (boysAverage, girlsAverage, childrenAverage)
in a family, where
pBoy -- probability of the birth of a boy;
pAnotherIfBoyAlready -- probability of the birth of another child in case
the family already has a boy;
nMax -- the (biologically) maximum number of children;
nTrials -- the number of families considered.'''
trials = [children(pBoy, pAnotherIfBoyAlready,nMax) for i in range(0, \
nTrials)]
boysAverage = average([boys for (boys, girls) in trials])
girlsAverage = average([girls for (boys, girls) in trials])
childrenAverage = boysAverage + girlsAverage
return (boysAverage, girlsAverage, childrenAverage)