Dorian’s Math

PRACTICE / PROBABILITY STATISTICS

Counting and chance in Python

Indexing, recursion, and the matching and birthday problems, in the CS61A style.

Fill in the blank

What would Python display? Indexing

What would Python display?

>>> v = [3, 1, 4, 1, 5, 9]
>>> v[1]
Your answer

Use an integer, decimal, or fraction such as 1/2. An exact value is expected.

Hints
1

Python numbers positions from 0, not from 1.

2

v[0] is 3. Which entry comes next?

Reference solution

1. Python positions start at 0, so v[1] is the second entry. In R, v[1] would be the first entry, 3.

Source: Adapted from Blitzstein & Hwang, Introduction to Probability, §1.8 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied

Single choice

What would Python display? No recycling

What happens here?

>>> v = [3, 1, 4]
>>> v + 3
Your answer

Choose one answer.

Hints
1

+ between two lists joins them. Is 3 a list?

2

Python does not repeat a shorter value to fit a longer one.

Reference solution

Python raises TypeError: can only concatenate list (not "int") to list. For lists, + means concatenation, and it needs a list on both sides. Write [x + 3 for x in v] to add 3 to each entry, which gives [6, 4, 7].

Source: Adapted from Blitzstein & Hwang, Introduction to Probability, §1.8 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied

Python

Binomial coefficients by recursion

Complete choose(n, k) recursively, using Pascal’s rule (nk)=(n−1k−1)+(n−1k)\binom{n}{k}=\binom{n-1}{k-1}+\binom{n-1}{k}. Do not use math.comb or factorials. Return 0 when k<0k<0 or k>nk>n.

Your answer

Python function exercise. Tab moves focus; use the indent buttons for selected lines.

Public tests

1. Small case

>>> choose(5, 2)
10

2. Middle of a row

>>> choose(10, 5)
252

3. Choose none or all

>>> choose(4, 0)
1
>>> choose(4, 4)
1

4. Too many

>>> choose(3, 5)
0
Hints
1

There are two base cases: impossible choices, and choosing none or all.

2

If kk is 0 or equal to nn, there is exactly one way.

3

Otherwise, return the sum of two smaller choose calls.

Reference solution
def choose(n, k):
    if k < 0 or k > n:
        return 0
    if k == 0 or k == n:
        return 1
    return choose(n - 1, k - 1) + choose(n - 1, k)

The first base case handles impossible requests; the second is the edge of Pascal’s triangle. Each recursive call lowers nn, so the recursion ends. It makes many repeated calls, which is fine for small nn and a good reason to meet memoization later.

Source: Adapted from Blitzstein & Hwang, Introduction to Probability, §1.8 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied

Fill in the blank

What would Python display? Adding truth values

What would Python display?

>>> deck = [2, 1, 3, 4]
>>> sum([card == position for position, card in enumerate(deck, start=1)])
Your answer

Use an integer, decimal, or fraction such as 1/2. An exact value is expected.

Hints
1

The list inside is [False, False, True, True].

2

In arithmetic, True counts as 1 and False as 0.

Reference solution

2. Cards 3 and 4 are in their own positions, so the list is [False, False, True, True], and its sum counts the True values.

Source: Adapted from Blitzstein & Hwang, Introduction to Probability, §1.8 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied

Python

Count the matches

Complete count_fixed_points(deck). deck lists the cards in the order they are turned over; card ii matches when it is turned over iith. Return the number of matches.

Your answer

Python function exercise. Tab moves focus; use the indent buttons for selected lines.

Public tests

1. Every card matches

>>> count_fixed_points([1, 2, 3])
3

2. One match

>>> count_fixed_points([2, 1, 3])
1

3. No matches

>>> count_fixed_points([3, 1, 2])
0
>>> count_fixed_points([2, 1])
0

4. Empty deck

>>> count_fixed_points([])
0
Hints
1

enumerate(deck, start=1) gives each position together with its card.

2

Compare each card with its position, then add up the results.

Reference solution
def count_fixed_points(deck):
    return sum(card == position for position, card in enumerate(deck, start=1))

Each comparison is True or False, which sum counts as 1 or 0. An empty deck has no matches, so the sum is 0.

Source: Adapted from Blitzstein & Hwang, Introduction to Probability, §1.8 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied

Python

How many people are needed?

birthday_match(k, days) is provided. Complete people_needed(p, days): return the smallest number of people k≥1k\ge1 for which birthday_match(k, days) is at least p. This is what R’s qbirthday computes. Assume 0<p≤10<p\le1.

Your answer

Python function exercise. Tab moves focus; use the indent buttons for selected lines.

Public tests

1. Even odds

>>> people_needed(0.5)
23

2. Ninety percent

>>> people_needed(0.9)
41

3. Ninety-nine percent

>>> people_needed(0.99)
57

4. A shorter year

>>> people_needed(0.5, days=2)
2
Hints
1

Start with one person and add people until the probability is large enough.

2

A while loop fits: keep going while birthday_match(k, days) < p.

Reference solution
def people_needed(p, days=365):
    k = 1
    while birthday_match(k, days) < p:
        k += 1
    return k

The loop always stops: with days + 1 people a shared birthday is certain, so the probability reaches 1.

Source: Adapted from Blitzstein & Hwang, Introduction to Probability, §1.8 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied

Read as Markdown ↗Read alongside: Counting and chance in Python: simulating the matching and birthday problems