Created
March 10, 2013 13:02
-
-
Save widdowquinn/5128493 to your computer and use it in GitHub Desktop.
Python code to illustrate the Tuesday Boy paradox ("I have two children. One is a boy born on a Tuesday. What is the probability I have two boys") for a blog post. This time, unlike paradox.py, parents with one child of either sex are free to choose which child they tell you about, and rephrase the question accordingly.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# boy-girl.py | |
# | |
# Python code to illustrate the Tuesday Boy paradox ("I have two children. | |
# One is a boy born on a Tuesday. What is the probability I have two boys") | |
# for a blog post. | |
# | |
# This time, unlike paradox.py, we're not assuming that there is preselection | |
# for telling you that one of the children is a boy, or a boy born on a Tuesday. | |
# This radically alters the solution of the problem. | |
# | |
# Again, this has general implications for what we can reasonably infer | |
# from experiments where we did not design the experiment to answer a | |
# specific question. | |
# | |
# (c) L.Pritchard 2013 | |
import collections | |
import random | |
sexes = ['B', 'G'] | |
days = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'] | |
# 1) We look at 10000 random parents, whose children are, on the whole, evenly | |
# distributed between the sexes. We keep a tally of the sex ratios of the | |
# children, and the distribution of each family type (boy/girl, boy/boy, etc.) | |
# Also, any selected parent has a random choice of which child to refer to in | |
# their question, and we record the counts of each type of family that answer | |
# each question. | |
families = collections.defaultdict(int) | |
sexcount = collections.defaultdict(int) | |
question_is_boys = collections.defaultdict(int) | |
question_is_girls = collections.defaultdict(int) | |
question_not_boys = collections.defaultdict(int) | |
question_not_girls = collections.defaultdict(int) | |
runs = 10000 | |
for i in range(runs): | |
children = (random.choice(sexes), random.choice(sexes)) | |
families[children] += 1 | |
for child in children: | |
sexcount[child] += 1 | |
# The parent looks at their children, picks one, and asks the question: | |
# "I have one <sex>. What is the probability that I have two <sex>?" | |
qsex = random.choice(children) | |
if qsex == 'B': | |
question_is_boys[children] += 1 | |
if qsex == 'G': | |
question_is_girls[children] += 1 | |
# The parent looks at their children, notes that they don't have two of one | |
# sex, and asks: "I do not have two <sex>. What is the probability that I | |
# have two <other sex>?" | |
if children != ('B', 'B') and children != ('G', 'G'): | |
d = random.choice([question_not_boys, question_not_girls]) | |
d[children] += 1 | |
elif children != ('B', 'B'): | |
question_not_boys[children] += 1 | |
elif children != ('G', 'G'): | |
question_not_girls[children] += 1 | |
print "\nCounts of each kind of family:" | |
for k, v in families.items(): | |
print k, v | |
print "\nCounts of each child's sex:" | |
for k, v in sexcount.items(): | |
print k, v | |
print "\nFamilies that ask '...I have one boy...?'" | |
for k, v in question_is_boys.items(): | |
print k, v | |
print "\nFamilies that ask '...I have one girl...?'" | |
for k, v in question_is_girls.items(): | |
print k, v | |
print "\nFamilies that ask '...I do not have two boys...?'" | |
for k, v in question_not_boys.items(): | |
print k, v | |
print "\nFamilies that ask '...I do not have two girls...?'" | |
for k, v in question_not_girls.items(): | |
print k, v | |
# 2) We look at 100000 random parents, whose children are, on the whole, evenly | |
# distributed between the sexes, and days of birth. We keep a tally of the sex | |
# ratios of the children/birth days, and the distribution of each family type | |
# Also, any selected parent has a random choice of which child to refer to in | |
# their question, and we record the counts of each type of family that ask the | |
# question "I have two children. One is a boy born on a Tuesday. What is the | |
# probability that I have two boys?" | |
print "Tuesday Boy\n-----------" | |
families = collections.defaultdict(int) | |
childcount = collections.defaultdict(int) | |
question_families = collections.defaultdict(int) | |
runs = 100000 | |
for i in range(runs): | |
children = ((random.choice(sexes), random.choice(days)), | |
(random.choice(sexes), random.choice(days))) | |
families[children] += 1 | |
for child in children: | |
childcount[child] += 1 | |
# The parent looks at their children, picks one, and asks the question: | |
# "I have one <sex> born on <day>. What is the probability that I have | |
# two <sex>?" | |
child = random.choice(children) | |
if child == ('B', 'Tu'): # This is the only way the Tuesday Boy Q is asked | |
question_families[children] += 1 | |
# Uncomment if you want to see all the families. There are lots | |
#print families | |
#print childcount | |
print '\nFamilies who asked about Tuesday Boy:' | |
for k, v in question_families.items(): | |
print k, v | |
print "\nTotal number of families who asked about Tuesday Boy:" | |
print sum([v for v in question_families.values()]) | |
print "\nTwo-boy families who asked about Tuesday Boy:" | |
tb_families = [(children, count) for children, count in \ | |
question_families.items() \ | |
if children[0][0] == 'B' and children[1][0] == 'B'] | |
print sum([count for children, count in tb_families]) | |
for k, v in tb_families: | |
print k, v |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment