PRACTICE / PROBABILITY STATISTICS
Conditional probability in Python
Comparisons, predicates, the Monty Hall problem, and updating on evidence, in the CS61A style.
What would Python display? Comparing a list
What would Python display?
>>> child1 = [1, 2, 1]
>>> child1 == 1Hints
Python’s == compares the whole left value with the whole right value.
Is a list ever equal to a number?
Reference solution
False. Python compares the list [1, 2, 1] as a whole with the number 1, and they are not equal. Nothing is compared entry by entry, unlike R, where child1 == 1 gives TRUE FALSE TRUE. Write [c == 1 for c in child1] to get [True, False, True].
Source: Adapted from Blitzstein & Hwang, Introduction to Probability, Chapter 2 and §2.10 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied
What would Python display? Counting with and
What would Python display?
>>> pairs = [(1, 1), (1, 2), (2, 1), (1, 1)]
>>> sum([c1 == 1 and c2 == 1 for c1, c2 in pairs])Hints
The comprehension is [True, False, False, True].
sum counts each True as 1.
Reference solution
2. Only the first and last pairs have both children equal to 1, so the list is [True, False, False, True], and its sum is 2. This is for = both girls.
Source: Adapted from Blitzstein & Hwang, Introduction to Probability, Chapter 2 and §2.10 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied
Estimate a conditional probability
Complete conditional_frequency(outcomes, a, b). a and b are predicates, functions that take one outcome and return True or False. Return : the number of outcomes where both hold, divided by the number where b holds. Return None if b never holds.
Public tests
1. Elder child is a girl
>>> families = [(1, 1), (1, 2), (2, 1), (2, 2)]
>>> both_girls = lambda f: f == (1, 1)
>>> conditional_frequency(families, both_girls, lambda f: f[0] == 1)
0.5
2. At least one girl
>>> families = [(1, 1), (1, 2), (2, 1), (2, 2)]
>>> both_girls = lambda f: f == (1, 1)
>>> round(conditional_frequency(families, both_girls, lambda f: 1 in f), 3)
0.333
3. B never happens
>>> families = [(1, 1), (1, 2), (2, 1), (2, 2)]
>>> both_girls = lambda f: f == (1, 1)
>>> conditional_frequency(families, both_girls, lambda f: False) is None
True
4. Other outcomes
>>> rolls = [1, 2, 3, 4, 5, 6]
>>> conditional_frequency(rolls, lambda r: r == 6, lambda r: r % 2 == 0)
0.3333333333333333
Output and test details
Hints
Count with sum(1 for o in outcomes if b(o)).
Count the same way, requiring a(o) and b(o).
Check for before dividing.
Reference solution
def conditional_frequency(outcomes, a, b):
n_b = sum(1 for o in outcomes if b(o))
n_ab = sum(1 for o in outcomes if a(o) and b(o))
return None if n_b == 0 else n_ab / n_b
The function knows nothing about children or dice. It only calls the predicates it is given, which is what lets one definition answer every question in the note.
Source: Adapted from Blitzstein & Hwang, Introduction to Probability, Chapter 2 and §2.10 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied
Which door does Monty open?
Complete monty_opens(chosen, car) for doors 1, 2, and 3. Monty never opens the player’s door or the car’s door. When two doors are allowed (the player picked the car), return the lower-numbered one, so the result is always predictable.
Public tests
1. Only one door allowed
>>> monty_opens(1, 2)
3
>>> monty_opens(2, 1)
3
>>> monty_opens(3, 1)
2
2. Player picked the car
>>> monty_opens(1, 1)
2
>>> monty_opens(2, 2)
1
>>> monty_opens(3, 3)
1
Output and test details
Hints
Consider each door in (1, 2, 3) and keep the ones that are neither chosen nor car.
min of the allowed doors gives the lower-numbered one.
Reference solution
def monty_opens(chosen, car):
return min(door for door in (1, 2, 3) if door != chosen and door != car)
When chosen != car, exactly one door is allowed; when they are equal, two are, and min picks the lower. In the real game Monty chooses at random in that case, which the simulation in the note adds back.
Source: Adapted from Blitzstein & Hwang, Introduction to Probability, Chapter 2 and §2.10 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied
The chance of winning by switching
You pick door 1, Monty opens a door with a goat behind it, and you always switch. What is the probability that you win the car? Answer as a fraction.
Hints
Switching wins exactly when your first pick was wrong.
Your first pick is wrong with probability .
Reference solution
. If your first pick is the car (probability ), switching loses. If your first pick is a goat (probability ), Monty must open the other goat door, so the door you switch to has the car. The simulation in the note gives .
Source: Adapted from Blitzstein & Hwang, Introduction to Probability, Chapter 2 and §2.10 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied
Update a probability on evidence
Complete bayes_update(prior, p_evidence_if_a, p_evidence_if_not_a). Given , , and , return using Bayes’ rule with the law of total probability. The tests pass Fraction values so the answers are exact. Assume .
Public tests
1. Monday: at least one girl
>>> bayes_update(Fraction(1, 4), 1, Fraction(2, 3))
Fraction(1, 3)
2. Tuesday: the elder is a girl
>>> bayes_update(Fraction(1, 3), 1, Fraction(1, 2))
Fraction(1, 2)
3. Evidence that rules out not-A
>>> bayes_update(Fraction(1, 100), 1, 0)
Fraction(1, 1)
4. Evidence that says nothing
>>> bayes_update(Fraction(1, 5), Fraction(1, 2), Fraction(1, 2))
Fraction(1, 5)
Output and test details
Hints
The numerator is .
The denominator adds to the numerator.
Reference solution
def bayes_update(prior, p_evidence_if_a, p_evidence_if_not_a):
numerator = p_evidence_if_a * prior
return numerator / (numerator + p_evidence_if_not_a * (1 - prior))
Because the result is again a probability for , it can be passed straight back in as the next prior: that is sequential updating. Evidence equally likely under and not leaves the prior unchanged.
Source: Adapted from Blitzstein & Hwang, Introduction to Probability, Chapter 2 and §2.10 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied
Practice is kept only while this page is open.