Spaces:
Running
Running
Merge pull request #13 from marimo-team/001-set
Browse files- probability/00-sets.py +297 -0
probability/00-sets.py
ADDED
@@ -0,0 +1,297 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# /// script
|
2 |
+
# requires-python = ">=3.10"
|
3 |
+
# dependencies = [
|
4 |
+
# "marimo",
|
5 |
+
# ]
|
6 |
+
# ///
|
7 |
+
|
8 |
+
import marimo
|
9 |
+
|
10 |
+
__generated_with = "0.11.0"
|
11 |
+
app = marimo.App()
|
12 |
+
|
13 |
+
|
14 |
+
@app.cell(hide_code=True)
|
15 |
+
def _(mo):
|
16 |
+
mo.md(
|
17 |
+
r"""
|
18 |
+
# Sets
|
19 |
+
|
20 |
+
Probability is the study of "events", assigning numerical values to how likely
|
21 |
+
events are to occur. For example, probability lets us quantify how likely it is for it to rain or shine on a given day.
|
22 |
+
|
23 |
+
|
24 |
+
Typically we reason about _sets_ of events. In mathematics,
|
25 |
+
a set is a collection of elements, with no element included more than once.
|
26 |
+
Elements can be any kind of object.
|
27 |
+
|
28 |
+
For example:
|
29 |
+
|
30 |
+
- ☀️ Weather events: $\{\text{Rain}, \text{Overcast}, \text{Clear}\}$
|
31 |
+
- 🎲 Die rolls: $\{1, 2, 3, 4, 5, 6\}$
|
32 |
+
- 🪙 Pairs of coin flips = $\{ \text{(Heads, Heads)}, \text{(Heads, Tails)}, \text{(Tails, Tails)} \text{(Tails, Heads)}\}$
|
33 |
+
|
34 |
+
Sets are the building blocks of probability, and will arise frequently in our study.
|
35 |
+
"""
|
36 |
+
)
|
37 |
+
return
|
38 |
+
|
39 |
+
|
40 |
+
@app.cell(hide_code=True)
|
41 |
+
def _(mo):
|
42 |
+
mo.md(r"""## Set operations""")
|
43 |
+
return
|
44 |
+
|
45 |
+
|
46 |
+
@app.cell(hide_code=True)
|
47 |
+
def _(mo):
|
48 |
+
mo.md(r"""In Python, sets are made with the `set` function:""")
|
49 |
+
return
|
50 |
+
|
51 |
+
|
52 |
+
@app.cell
|
53 |
+
def _():
|
54 |
+
A = set([2, 3, 5, 7])
|
55 |
+
A
|
56 |
+
return (A,)
|
57 |
+
|
58 |
+
|
59 |
+
@app.cell
|
60 |
+
def _():
|
61 |
+
B = set([0, 1, 2, 3, 5, 8])
|
62 |
+
B
|
63 |
+
return (B,)
|
64 |
+
|
65 |
+
|
66 |
+
@app.cell(hide_code=True)
|
67 |
+
def _(mo):
|
68 |
+
mo.md(
|
69 |
+
r"""
|
70 |
+
Below we explain common operations on sets.
|
71 |
+
|
72 |
+
_**Try it!** Try modifying the definitions of `A` and `B` above, and see how the results change below._
|
73 |
+
|
74 |
+
The **union** $A \cup B$ of sets $A$ and $B$ is the set of elements in $A$, $B$, or both.
|
75 |
+
"""
|
76 |
+
)
|
77 |
+
return
|
78 |
+
|
79 |
+
|
80 |
+
@app.cell
|
81 |
+
def _(A, B):
|
82 |
+
A | B
|
83 |
+
return
|
84 |
+
|
85 |
+
|
86 |
+
@app.cell(hide_code=True)
|
87 |
+
def _(mo):
|
88 |
+
mo.md(r"""The **intersection** $A \cap B$ is the set of elements in both $A$ and $B$""")
|
89 |
+
return
|
90 |
+
|
91 |
+
|
92 |
+
@app.cell
|
93 |
+
def _(A, B):
|
94 |
+
A & B
|
95 |
+
return
|
96 |
+
|
97 |
+
|
98 |
+
@app.cell(hide_code=True)
|
99 |
+
def _(mo):
|
100 |
+
mo.md(r"""The **difference** $A \setminus B$ is the set of elements in $A$ that are not in $B$.""")
|
101 |
+
return
|
102 |
+
|
103 |
+
|
104 |
+
@app.cell
|
105 |
+
def _(A, B):
|
106 |
+
A - B
|
107 |
+
return
|
108 |
+
|
109 |
+
|
110 |
+
@app.cell(hide_code=True)
|
111 |
+
def _(mo):
|
112 |
+
mo.md(
|
113 |
+
"""
|
114 |
+
### 🎬 An interactive example
|
115 |
+
|
116 |
+
Here's a simple example that classifies TV shows into sets by genre, and uses these sets to recommend shows to a user based on their preferences.
|
117 |
+
"""
|
118 |
+
)
|
119 |
+
return
|
120 |
+
|
121 |
+
|
122 |
+
@app.cell(hide_code=True)
|
123 |
+
def _(mo):
|
124 |
+
viewer_type = mo.ui.radio(
|
125 |
+
options={
|
126 |
+
"I like action and drama!": "New Viewer",
|
127 |
+
"I only like action shows": "Action Fan",
|
128 |
+
"I only like dramas": "Drama Fan",
|
129 |
+
},
|
130 |
+
value="I like action and drama!",
|
131 |
+
label="Which genre do you prefer?",
|
132 |
+
)
|
133 |
+
return (viewer_type,)
|
134 |
+
|
135 |
+
|
136 |
+
@app.cell(hide_code=True)
|
137 |
+
def _(viewer_type):
|
138 |
+
viewer_type
|
139 |
+
return
|
140 |
+
|
141 |
+
|
142 |
+
@app.cell
|
143 |
+
def _():
|
144 |
+
action_shows = {"Stranger Things", "The Witcher", "Money Heist"}
|
145 |
+
drama_shows = {"The Crown", "Money Heist", "Bridgerton"}
|
146 |
+
return action_shows, drama_shows
|
147 |
+
|
148 |
+
|
149 |
+
@app.cell
|
150 |
+
def _(action_shows, drama_shows):
|
151 |
+
recommendations = {
|
152 |
+
"New Viewer": action_shows | drama_shows, # Union for new viewers
|
153 |
+
"Action Fan": action_shows - drama_shows, # Unique action shows
|
154 |
+
"Drama Fan": drama_shows - action_shows, # Unique drama shows
|
155 |
+
}
|
156 |
+
return (recommendations,)
|
157 |
+
|
158 |
+
|
159 |
+
@app.cell(hide_code=True)
|
160 |
+
def _(mo, recommendations, viewer_type):
|
161 |
+
result = recommendations[viewer_type.value]
|
162 |
+
|
163 |
+
explanation = {
|
164 |
+
"New Viewer": "You get everything to explore!",
|
165 |
+
"Action Fan": "Pure action, no drama!",
|
166 |
+
"Drama Fan": "Drama-focused selections!",
|
167 |
+
}
|
168 |
+
|
169 |
+
mo.md(f"""
|
170 |
+
**🎬 Recommended shows.** Based on your preference for **{viewer_type.value}**,
|
171 |
+
we recommend:
|
172 |
+
|
173 |
+
{", ".join(result)}
|
174 |
+
|
175 |
+
**Why these shows?**
|
176 |
+
{explanation[viewer_type.value]}
|
177 |
+
""")
|
178 |
+
return explanation, result
|
179 |
+
|
180 |
+
|
181 |
+
@app.cell(hide_code=True)
|
182 |
+
def _(mo):
|
183 |
+
mo.md("""
|
184 |
+
### Exercise
|
185 |
+
|
186 |
+
Given these sets:
|
187 |
+
|
188 |
+
- A = {🎮, 📱, 💻}
|
189 |
+
|
190 |
+
- B = {📱, 💻, 🖨️}
|
191 |
+
|
192 |
+
- C = {💻, 🖨️, ⌨️}
|
193 |
+
|
194 |
+
Can you:
|
195 |
+
|
196 |
+
1. Find all elements that are in A or B
|
197 |
+
|
198 |
+
2. Find elements common to all three sets
|
199 |
+
|
200 |
+
3. Find elements in A that aren't in C
|
201 |
+
|
202 |
+
<details>
|
203 |
+
|
204 |
+
<summary>Check your answers!</summary>
|
205 |
+
|
206 |
+
1. A ∪ B = {🎮, 📱, 💻, 🖨️}<br>
|
207 |
+
2. A ∩ B ∩ C = {💻}<br>
|
208 |
+
3. A - C = {🎮, 📱}
|
209 |
+
|
210 |
+
</details>
|
211 |
+
""")
|
212 |
+
return
|
213 |
+
|
214 |
+
|
215 |
+
@app.cell(hide_code=True)
|
216 |
+
def _(mo):
|
217 |
+
mo.md(
|
218 |
+
r"""
|
219 |
+
## 🧮 Set properties
|
220 |
+
|
221 |
+
Here are some important properties of the set operations:
|
222 |
+
|
223 |
+
1. **Commutative**: $A \cup B = B \cup A$
|
224 |
+
2. **Associative**: $(A \cup B) \cup C = A \cup (B \cup C)$
|
225 |
+
3. **Distributive**: $A \cup (B \cap C) = (A \cup B) \cap (A \cup C)$
|
226 |
+
"""
|
227 |
+
)
|
228 |
+
return
|
229 |
+
|
230 |
+
|
231 |
+
@app.cell(hide_code=True)
|
232 |
+
def _(mo):
|
233 |
+
mo.md(
|
234 |
+
r"""
|
235 |
+
## Set builder notation
|
236 |
+
|
237 |
+
To compactly describe the elements in a set, we can use **set builder notation**, which specifies conditions that must be true for elements to be in the set.
|
238 |
+
|
239 |
+
For example, here is how to specify the set of positive numbers less than 10:
|
240 |
+
|
241 |
+
\[
|
242 |
+
\{x \mid 0 < x < 10 \}
|
243 |
+
\]
|
244 |
+
|
245 |
+
The predicate to the right of the vertical bar $\mid$ specifies conditions that must be true for an element to be in the set; the expression to the left of $\mid$ specifies the value being included.
|
246 |
+
|
247 |
+
In Python, set builder notation is called a "set comprehension."
|
248 |
+
"""
|
249 |
+
)
|
250 |
+
return
|
251 |
+
|
252 |
+
|
253 |
+
@app.cell
|
254 |
+
def _():
|
255 |
+
def predicate(x):
|
256 |
+
return x > 0 and x < 10
|
257 |
+
return (predicate,)
|
258 |
+
|
259 |
+
|
260 |
+
@app.cell
|
261 |
+
def _(predicate):
|
262 |
+
set(x for x in range(100) if predicate(x))
|
263 |
+
return
|
264 |
+
|
265 |
+
|
266 |
+
@app.cell(hide_code=True)
|
267 |
+
def _(mo):
|
268 |
+
mo.md("""**Try it!** Try modifying the `predicate` function above and see how the set changes.""")
|
269 |
+
return
|
270 |
+
|
271 |
+
|
272 |
+
@app.cell(hide_code=True)
|
273 |
+
def _(mo):
|
274 |
+
mo.md("""
|
275 |
+
## Summary
|
276 |
+
|
277 |
+
You've learned:
|
278 |
+
|
279 |
+
- Basic set operations
|
280 |
+
- Set properties
|
281 |
+
- Real-world applications
|
282 |
+
|
283 |
+
In the next lesson, we'll define probability from the ground up, using sets.
|
284 |
+
|
285 |
+
Remember: In probability, every event is a set, and every set can be an event!
|
286 |
+
""")
|
287 |
+
return
|
288 |
+
|
289 |
+
|
290 |
+
@app.cell
|
291 |
+
def _():
|
292 |
+
import marimo as mo
|
293 |
+
return (mo,)
|
294 |
+
|
295 |
+
|
296 |
+
if __name__ == "__main__":
|
297 |
+
app.run()
|