''' 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)