Skip to content

Instantly share code, notes, and snippets.

@widdowquinn
Created March 10, 2013 13:02
Show Gist options
  • Save widdowquinn/5128493 to your computer and use it in GitHub Desktop.
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.
# 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