Skip to content

Commit 17727c5

Browse files
committed
Add probability of OR notebook with an interactive visualization
1 parent 90cc7e2 commit 17727c5

File tree

1 file changed

+349
-0
lines changed

1 file changed

+349
-0
lines changed
Lines changed: 349 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,349 @@
1+
# /// script
2+
# requires-python = ">=3.10"
3+
# dependencies = [
4+
# "marimo",
5+
# "matplotlib",
6+
# "matplotlib-venn"
7+
# ]
8+
# ///
9+
10+
import marimo
11+
12+
__generated_with = "0.11.2"
13+
app = marimo.App()
14+
15+
16+
@app.cell
17+
def _():
18+
import marimo as mo
19+
return (mo,)
20+
21+
22+
@app.cell
23+
def _():
24+
import matplotlib.pyplot as plt
25+
from matplotlib_venn import venn2
26+
import numpy as np
27+
return np, plt, venn2
28+
29+
30+
@app.cell(hide_code=True)
31+
def _(mo):
32+
mo.md(
33+
r"""
34+
# Probability of Or
35+
36+
When calculating the probability of either one event _or_ another occurring, we need to be careful about how we combine probabilities. The method depends on whether the events can happen together[<sup>1</sup>](https://chrispiech.github.io/probabilityForComputerScientists/en/part1/prob_or/).
37+
38+
Let's explore how to calculate $P(E \cup F)$ or $P(E \text{ or } F)$ in different scenarios.
39+
"""
40+
)
41+
return
42+
43+
44+
@app.cell(hide_code=True)
45+
def _(mo):
46+
mo.md(
47+
r"""
48+
## Mutually Exclusive Events
49+
50+
Two events $E$ and $F$ are **mutually exclusive** if they cannot occur simultaneously.
51+
In set notation, this means:
52+
53+
$E \cap F = \emptyset$
54+
55+
For example:
56+
57+
- Rolling an even number (2,4,6) vs rolling an odd number (1,3,5)
58+
- Drawing a heart vs drawing a spade from a deck
59+
- Passing vs failing a test
60+
61+
Here's a Python function to check if two sets of outcomes are mutually exclusive:
62+
"""
63+
)
64+
return
65+
66+
67+
@app.cell
68+
def _():
69+
def are_mutually_exclusive(event1, event2):
70+
return len(event1.intersection(event2)) == 0
71+
72+
# Example with dice rolls
73+
even_numbers = {2, 4, 6}
74+
odd_numbers = {1, 3, 5}
75+
prime_numbers = {2, 3, 5, 7}
76+
return are_mutually_exclusive, even_numbers, odd_numbers, prime_numbers
77+
78+
79+
@app.cell
80+
def _(are_mutually_exclusive, even_numbers, odd_numbers):
81+
are_mutually_exclusive(even_numbers, odd_numbers)
82+
return
83+
84+
85+
@app.cell
86+
def _(are_mutually_exclusive, even_numbers, prime_numbers):
87+
are_mutually_exclusive(even_numbers, prime_numbers)
88+
return
89+
90+
91+
@app.cell(hide_code=True)
92+
def _(mo):
93+
mo.md(
94+
r"""
95+
## Or with Mutually Exclusive Events
96+
97+
For mutually exclusive events, the probability of either event occurring is simply the sum of their individual probabilities:
98+
99+
$P(E \cup F) = P(E) + P(F)$
100+
101+
This extends to multiple events. For $n$ mutually exclusive events $E_1, E_2, \ldots, E_n$:
102+
103+
$P(E_1 \cup E_2 \cup \cdots \cup E_n) = \sum_{i=1}^n P(E_i)$
104+
105+
Let's implement this calculation:
106+
"""
107+
)
108+
return
109+
110+
111+
@app.cell
112+
def _():
113+
def prob_union_mutually_exclusive(probabilities):
114+
return sum(probabilities)
115+
116+
# Example: Rolling a die
117+
# P(even) = P(2) + P(4) + P(6)
118+
p_even_mutually_exclusive = prob_union_mutually_exclusive([1/6, 1/6, 1/6])
119+
print(f"P(rolling an even number) = {p_even_mutually_exclusive}")
120+
121+
# P(prime) = P(2) + P(3) + P(5)
122+
p_prime_mutually_exclusive = prob_union_mutually_exclusive([1/6, 1/6, 1/6])
123+
print(f"P(rolling a prime number) = {p_prime_mutually_exclusive}")
124+
return (
125+
p_even_mutually_exclusive,
126+
p_prime_mutually_exclusive,
127+
prob_union_mutually_exclusive,
128+
)
129+
130+
131+
@app.cell(hide_code=True)
132+
def _(mo):
133+
mo.md(
134+
r"""
135+
## Or with Non-Mutually Exclusive Events
136+
137+
When events can occur together, we need to use the **inclusion-exclusion principle**:
138+
139+
$P(E \cup F) = P(E) + P(F) - P(E \cap F)$
140+
141+
Why subtract $P(E \cap F)$? Because when we add $P(E)$ and $P(F)$, we count the overlap twice!
142+
143+
For example, consider calculating $P(\text{prime or even})$ when rolling a die:
144+
- Prime numbers: {2, 3, 5}
145+
- Even numbers: {2, 4, 6}
146+
- The number 2 is counted twice unless we subtract its probability
147+
148+
Here's how to implement this calculation:
149+
"""
150+
)
151+
return
152+
153+
154+
@app.cell
155+
def _():
156+
def prob_union_general(p_a, p_b, p_intersection):
157+
"""Calculate probability of union for any two events"""
158+
return p_a + p_b - p_intersection
159+
160+
# Example: Rolling a die
161+
# P(prime or even)
162+
p_prime_general = 3/6 # P(prime) = P(2,3,5)
163+
p_even_general = 3/6 # P(even) = P(2,4,6)
164+
p_intersection = 1/6 # P(intersection) = P(2)
165+
166+
result = prob_union_general(p_prime_general, p_even_general, p_intersection)
167+
print(f"P(prime or even) = {p_prime_general} + {p_even_general} - {p_intersection} = {result}")
168+
return (
169+
p_even_general,
170+
p_intersection,
171+
p_prime_general,
172+
prob_union_general,
173+
result,
174+
)
175+
176+
177+
@app.cell(hide_code=True)
178+
def _(mo):
179+
mo.md(
180+
r"""
181+
### Extension to Three Events
182+
183+
For three events, the inclusion-exclusion principle becomes:
184+
185+
$P(E_1 \cup E_2 \cup E_3) = P(E_1) + P(E_2) + P(E_3)$
186+
$- P(E_1 \cap E_2) - P(E_1 \cap E_3) - P(E_2 \cap E_3)$
187+
$+ P(E_1 \cap E_2 \cap E_3)$
188+
189+
The pattern is:
190+
191+
1. Add individual probabilities
192+
2. Subtract probabilities of pairs
193+
3. Add probability of triple intersection
194+
"""
195+
)
196+
return
197+
198+
199+
@app.cell(hide_code=True)
200+
def _(mo):
201+
mo.md(r"""### Interactive example:""")
202+
return
203+
204+
205+
@app.cell
206+
def _(event_type):
207+
event_type
208+
return
209+
210+
211+
@app.cell(hide_code=True)
212+
def _(mo):
213+
# Create a dropdown to select the type of events to visualize
214+
event_type = mo.ui.dropdown(
215+
options=[
216+
"Mutually Exclusive Events (Rolling Odd vs Even)",
217+
"Non-Mutually Exclusive Events (Prime vs Even)",
218+
"Three Events (Less than 3, Even, Prime)"
219+
],
220+
value="Mutually Exclusive Events (Rolling Odd vs Even)",
221+
label="Select Event Type"
222+
)
223+
return (event_type,)
224+
225+
226+
@app.cell(hide_code=True)
227+
def _(event_type, mo, plt, venn2):
228+
# Define the events and their probabilities
229+
events_data = {
230+
"Mutually Exclusive Events (Rolling Odd vs Even)": {
231+
"sets": (round(3/6, 2), round(3/6, 2), 0), # (odd, even, intersection)
232+
"labels": ("Odd\n{1,3,5}", "Even\n{2,4,6}"),
233+
"title": "Mutually Exclusive Events: Odd vs Even Numbers",
234+
"explanation": r"""
235+
### Mutually Exclusive Events
236+
237+
$P(\text{Odd}) = \frac{3}{6} = 0.5$
238+
$P(\text{Even}) = \frac{3}{6} = 0.5$
239+
$P(\text{Odd} \cap \text{Even}) = 0$
240+
241+
$P(\text{Odd} \cup \text{Even}) = P(\text{Odd}) + P(\text{Even}) = 1$
242+
243+
These events are mutually exclusive because a number cannot be both odd and even.
244+
"""
245+
},
246+
"Non-Mutually Exclusive Events (Prime vs Even)": {
247+
"sets": (round(2/6, 2), round(2/6, 2), round(1/6, 2)), # (prime-only, even-only, intersection)
248+
"labels": ("Prime\n{3,5}", "Even\n{4,6}"),
249+
"title": "Non-Mutually Exclusive: Prime vs Even Numbers",
250+
"explanation": r"""
251+
### Non-Mutually Exclusive Events
252+
253+
$P(\text{Prime}) = \frac{3}{6} = 0.5$ (2,3,5)
254+
$P(\text{Even}) = \frac{3}{6} = 0.5$ (2,4,6)
255+
$P(\text{Prime} \cap \text{Even}) = \frac{1}{6}$ (2)
256+
257+
$P(\text{Prime} \cup \text{Even}) = \frac{3}{6} + \frac{3}{6} - \frac{1}{6} = \frac{5}{6}$
258+
259+
These events overlap because 2 is both prime and even.
260+
"""
261+
},
262+
"Three Events (Less than 3, Even, Prime)": {
263+
"sets": (round(1/6, 2), round(2/6, 2), round(1/6, 2)), # (less than 3, even, intersection)
264+
"labels": ("<3\n{1,2}", "Even\n{2,4,6}"),
265+
"title": "Complex Example: Numbers < 3 and Even Numbers",
266+
"explanation": r"""
267+
### Complex Event Interaction
268+
269+
$P(x < 3) = \frac{2}{6}$ (1,2)
270+
$P(\text{Even}) = \frac{3}{6}$ (2,4,6)
271+
$P(x < 3 \cap \text{Even}) = \frac{1}{6}$ (2)
272+
273+
$P(x < 3 \cup \text{Even}) = \frac{2}{6} + \frac{3}{6} - \frac{1}{6} = \frac{4}{6}$
274+
275+
The number 2 belongs to both sets, requiring the inclusion-exclusion principle.
276+
"""
277+
}
278+
}
279+
280+
# Get data for selected event type
281+
data = events_data[event_type.value]
282+
283+
# Create visualization
284+
plt.figure(figsize=(10, 5))
285+
v = venn2(subsets=data["sets"],
286+
set_labels=data["labels"])
287+
plt.title(data["title"])
288+
289+
# Display explanation alongside visualization
290+
mo.hstack([
291+
plt.gcf(),
292+
mo.md(data["explanation"])
293+
])
294+
return data, events_data, v
295+
296+
297+
@app.cell(hide_code=True)
298+
def _(mo):
299+
mo.md(
300+
r"""
301+
## 🤔 Test Your Understanding
302+
303+
Consider rolling a six-sided die. Which of these statements are true?
304+
305+
<details>
306+
<summary>1. P(even or less than 3) = P(even) + P(less than 3)</summary>
307+
308+
❌ Incorrect! These events are not mutually exclusive (2 is both even and less than 3).
309+
We need to use the inclusion-exclusion principle.
310+
</details>
311+
312+
<details>
313+
<summary>2. P(even or greater than 4) = 4/6</summary>
314+
315+
✅ Correct! {2,4,6} ∪ {5,6} = {2,4,5,6}, so probability is 4/6.
316+
</details>
317+
318+
<details>
319+
<summary>3. P(prime or odd) = 5/6</summary>
320+
321+
✅ Correct! {2,3,5} ∪ {1,3,5} = {1,2,3,5}, so probability is 5/6.
322+
</details>
323+
"""
324+
)
325+
return
326+
327+
328+
@app.cell(hide_code=True)
329+
def _(mo):
330+
mo.md(
331+
"""
332+
## Summary
333+
334+
You've learned:
335+
336+
- How to identify mutually exclusive events
337+
- The addition rule for mutually exclusive events
338+
- The inclusion-exclusion principle for overlapping events
339+
- How to extend these concepts to multiple events
340+
341+
In the next lesson, we'll explore **conditional probability** - how the probability
342+
of one event changes when we know another event has occurred.
343+
"""
344+
)
345+
return
346+
347+
348+
if __name__ == "__main__":
349+
app.run()

0 commit comments

Comments
 (0)