You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/lessons-learned.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -112,7 +112,7 @@ git diff --check
112
112
-**Lines must terminate AT elements, not in their gaps or interiors.** A 1.5px gap between a tree edge and a leaf dot reads as "the tree is disconnected" (the `exception-group-peel` bug). A line endpoint 2px inside a circle reads as "the arrow pierces the node" (the `context-bowtie` bug). When connecting to a dot, end the line at the dot's centre and let the dot draw on top — the visual termination is the circumference, with zero gap or overshoot.
113
113
-**Journey pages render section figures inline.**`SECTION_FIGURES` lives in `src/marginalia.py` (single source of truth, keyed by section title) and `render_for_section(title)` is invoked from `render_journey_page` between each section's meta and its example list. The same paint code that produces the `/prototyping/journey-figures-gestalt` review page renders on production journey pages; drift between the two is structurally impossible. Contract 10 asserts every section in `JOURNEYS` has a figure and every figure name resolves.
114
114
-**An explicit comparison loop should iterate over the topic's whole spectrum.** When a cell teaches by doing `for label, value in [(...), (...)]: print(...)`, the bracketed list IS the lesson. Two items is a binary contrast; three items reads as a progression. The strings example presented English (pure ASCII, 1 byte/char) against Thai (3 bytes/char) but skipped the Latin-extended middle (French `café`: 4 code points, 5 bytes — `é` is 2 UTF-8 bytes). Adding the middle row turned the cell from "ASCII vs non-Latin" into "1-byte / 2-byte / 3-byte progression." The rule is narrow — most examples spread categories across cells, which is also a valid pattern — but when a comparison loop exists, fill it with the topic's actual spectrum, not just the endpoints.
115
-
-**Quality debt must be tracked, not normalized away.**`docs/example-quality-rubric.md` sets a 9.0 target and `scripts/check_quality_scores.py` enforces the score registry: pages below the hard minimum need a concrete improvement backlog entry, and Hello World is the only standing waiver because first examples are traditionally tiny. A score below target is allowed only when the remaining work is named.
115
+
-**Quality debt must be tracked, not normalized away.**`docs/example-quality-rubric.md` sets a 9.0 target and `scripts/check_quality_scores.py` enforces the score registry: pages below the hard minimum need a concrete improvement backlog entry, stale backlog entries fail once a page clears the gate, and Hello World is the only standing waiver because first examples are traditionally tiny. A score below target is allowed only when the remaining work is named.
116
116
-**No-figure decisions need a registry.** Some examples should not have figures, but that cannot be an invisible omission. `scripts/check_no_figure_rationales.py` validates `no_figure_rationales` so future constraint-shaped pages can opt out explicitly instead of shipping weak diagrams.
117
117
-**Journey sections need outcome contracts.**`scripts/check_journey_outcomes.py` ties each journey section to learner outcomes and support examples so journey pages stay mental maps rather than catalog slices.
118
-
-**Deployment smoke belongs beside CI.**`scripts/smoke_deployment.py` checks rendered Worker pages, runtime-boundary pages, journey pages, and prototype review pagesfor HTTP failures and exception markers. Build success is not enough; the deployed Worker must render.
118
+
-**Deployment smoke belongs beside CI.**`scripts/smoke_deployment.py` checks rendered Worker pages, runtime-boundary pages, journey pages, prototype review pages, and representative Dynamic Worker POST runs for HTTP failures, exception markers, and stale edited-code output. Build success is not enough; the deployed Worker must render and execute edited examples.
Copy file name to clipboardExpand all lines: src/example_sources/collections-module.md
+38-10Lines changed: 38 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,13 +4,19 @@ title = "Collections Module"
4
4
section = "Collections"
5
5
summary = "collections provides specialized containers for common data shapes."
6
6
doc_path = "/library/collections.html"
7
+
see_also = [
8
+
"dicts",
9
+
"lists",
10
+
"tuples",
11
+
"sets",
12
+
]
7
13
+++
8
14
9
-
collections provides specialized containers for common data shapes. It exists to make a common boundary explicit instead of leaving the behavior implicit in a larger program.
15
+
`collections` provides specialized containers for common shapes that would otherwise require repetitive plumbing. Use it when the shape has a name: counting, grouping, queueing, or lightweight records.
10
16
11
-
Use it when the problem shape matches the example, and prefer simpler neighboring tools when the extra machinery would hide the intent. The notes call out the boundary so the feature stays practical rather than decorative.
17
+
These types are not replacements for `list`, `dict`, `tuple`, and `set`. They are small standard-library tools for cases where an ordinary container would hide the intent behind manual bookkeeping.
12
18
13
-
The example is small, deterministic, and focused on the semantic point. The complete source is editable below, while the walkthrough pairs the source with its output.
19
+
The examples below map each type to the question it answers.
14
20
15
21
:::program
16
22
```python
@@ -34,18 +40,42 @@ print(Point(2, 3).x)
34
40
:::
35
41
36
42
:::cell
37
-
Use `Counter` when counting is the data shape.
43
+
Use `Counter` when the question is "how many times did each value appear?"
38
44
39
45
```python
40
-
from collections import Counter, defaultdict, deque, namedtuple
46
+
from collections import Counter
41
47
42
48
counts = Counter("banana")
43
49
print(counts.most_common(2))
50
+
```
51
+
52
+
```output
53
+
[('a', 3), ('n', 2)]
54
+
```
55
+
:::
56
+
57
+
:::cell
58
+
Use `defaultdict(list)` when each key gathers multiple values and the missing-key case should create an empty list automatically.
59
+
60
+
```python
61
+
from collections import defaultdict
44
62
45
63
groups = defaultdict(list)
46
64
for name, team in [("Ada", "red"), ("Grace", "blue"), ("Lin", "red")]:
47
65
groups[team].append(name)
48
66
print(dict(groups))
67
+
```
68
+
69
+
```output
70
+
{'red': ['Ada', 'Lin'], 'blue': ['Grace']}
71
+
```
72
+
:::
73
+
74
+
:::cell
75
+
Use `deque` for queue operations at both ends, and `namedtuple` when a tiny immutable record needs names as well as positions.
76
+
77
+
```python
78
+
from collections import deque, namedtuple
49
79
50
80
queue = deque(["first"])
51
81
queue.append("second")
@@ -56,15 +86,13 @@ print(Point(2, 3).x)
56
86
```
57
87
58
88
```output
59
-
[('a', 3), ('n', 2)]
60
-
{'red': ['Ada', 'Lin'], 'blue': ['Grace']}
61
89
first
62
90
2
63
91
```
64
92
:::
65
93
66
94
:::note
67
-
-Use `Counter`when counting is the data shape.
68
-
-Use `defaultdict` when grouping values by key.
69
-
-Use `deque` for efficient queue operations and `namedtuple` for lightweight named records.
95
+
-`Counter`counts, `defaultdict` groups, `deque` queues, and `namedtuple` names record fields.
96
+
-Prefer the built-in containers until a specialized shape makes the code clearer.
97
+
-For new structured records with defaults and methods, consider `dataclasses` instead of `namedtuple`.
0 commit comments