Skip to content

Commit bf49003

Browse files
committed
Audit examples against rationale rubric
1 parent 99d6028 commit bf49003

19 files changed

Lines changed: 311 additions & 147 deletions

src/asset_manifest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# Generated by scripts/fingerprint_assets.py. Do not edit by hand.
22
ASSET_PATHS = {'SITE_CSS': '/site.dc51488c4ed9.css', 'SYNTAX_JS': '/syntax-highlight.3b6c7f730d46.js', 'EDITOR_JS': '/editor.dd81f5171b14.js'}
3-
HTML_CACHE_VERSION = '5cd6e8013a84'
3+
HTML_CACHE_VERSION = '4f2e027de304'

src/example_sources/async-await.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ doc_path = "/library/asyncio-task.html"
1212

1313
Cloudflare Workers handlers are asynchronous, so understanding `await` is practical for fetch calls, bindings, and service interactions even when a small example uses `asyncio.sleep(0)` as a stand-in.
1414

15+
The alternative is ordinary `def` for work that completes immediately. Use async code for I/O-shaped waiting, not as a faster replacement for CPU-bound Python.
16+
1517
:::program
1618
```python
1719
import asyncio
@@ -86,4 +88,5 @@ asyncio.run(main())
8688
- Calling an async function creates a coroutine object.
8789
- `await` yields control until an awaitable completes.
8890
- Workers request handlers are async, so this pattern appears around fetches and bindings.
91+
- Prefer ordinary functions when there is no awaitable work to coordinate.
8992
:::

src/example_sources/async-iteration-and-context.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ see_also = [
1515

1616
These forms appear around network streams, database cursors, locks, and service clients where both iteration and cleanup may wait on I/O.
1717

18+
Use ordinary `for` and `with` when producing the next value or cleaning up does not need to await anything.
19+
1820
The syntax mirrors `for` and `with`, but the protocol methods are asynchronous.
1921

2022
:::program

src/example_sources/booleans.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,5 @@ True
6363
:::note
6464
- Boolean constants are `True` and `False`, with capital letters.
6565
- `and` and `or` short-circuit: Python does not evaluate the right side if the left side already determines the result.
66+
- Prefer truthiness for containers and explicit comparisons when the exact boolean condition matters.
6667
:::

src/example_sources/break-and-continue.md

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,36 +11,36 @@ see_also = [
1111
]
1212
+++
1313

14-
`break` and `continue` control the nearest enclosing loop. They are useful when the loop body discovers a reason to stop early or skip one item.
14+
`break` and `continue` control the nearest enclosing loop. They exist for loops whose body discovers an early stop rule or an item-level skip rule.
1515

16-
Use `continue` for a skip rule: the current item should not run the rest of the body. Use `break` for a stop rule: no later item should be processed.
16+
Use `continue` when the current item should not run the rest of the body. Use `break` when no later item should be processed.
1717

18-
Keep both rules close to the top of the loop when possible. That makes the normal path easier to read.
18+
The alternative is ordinary `if`/`else` nesting. Prefer `break` and `continue` when they keep the normal path flatter and easier to read.
1919

2020
:::program
2121
```python
22-
names = ["Ada", "", "Grace", "stop", "Guido"]
23-
22+
names = ["Ada", "", "Grace"]
2423
for name in names:
2524
if not name:
2625
continue
27-
if name == "stop":
28-
break
2926
print(name)
27+
28+
commands = ["load", "save", "stop", "delete"]
29+
for command in commands:
30+
if command == "stop":
31+
break
32+
print(command)
3033
```
3134
:::
3235

3336
:::cell
3437
`continue` skips the rest of the current iteration. The empty name is ignored, and the loop moves on to the next value.
3538

3639
```python
37-
names = ["Ada", "", "Grace", "stop", "Guido"]
38-
40+
names = ["Ada", "", "Grace"]
3941
for name in names:
4042
if not name:
4143
continue
42-
if name == "stop":
43-
break
4444
print(name)
4545
```
4646

@@ -50,6 +50,23 @@ Grace
5050
```
5151
:::
5252

53+
:::cell
54+
`break` exits the loop immediately. The value after `stop` is never processed because the loop has already ended.
55+
56+
```python
57+
commands = ["load", "save", "stop", "delete"]
58+
for command in commands:
59+
if command == "stop":
60+
break
61+
print(command)
62+
```
63+
64+
```output
65+
load
66+
save
67+
```
68+
:::
69+
5370
:::note
5471
- `continue` skips to the next loop iteration.
5572
- `break` exits the nearest enclosing loop immediately.

src/example_sources/classes.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
slug = "classes"
33
title = "Classes"
44
section = "Classes"
5-
summary = "Classes bundle data and behavior."
5+
summary = "Classes bundle data and behavior into new object types."
66
doc_path = "/tutorial/classes.html"
77
+++
88

9-
Classes define new object types by bundling data with behavior. They are useful when several values and operations belong together.
9+
Classes define new object types by bundling data with behavior. They are useful when several values and operations belong together and should travel as one object.
1010

11-
`__init__` initializes each instance, and methods receive the instance as `self`. Assigning `self.value` stores state on that particular object.
11+
The alternative is often a dictionary plus separate functions. That is fine for loose data, but a class gives the data a stable API and keeps behavior next to the state it changes.
1212

13-
Separate instances keep separate state. Mutating one `Counter` does not change another because each object has its own attributes.
13+
`__init__` initializes each instance, and methods receive the instance as `self`. Separate instances keep separate state because each object has its own attributes.
1414

1515
:::program
1616
```python
@@ -25,6 +25,8 @@ class Counter:
2525
first = Counter()
2626
second = Counter(10)
2727

28+
print(first.value)
29+
print(second.value)
2830
print(first.increment())
2931
print(second.increment(5))
3032
```
@@ -77,5 +79,6 @@ print(second.increment(5))
7779
:::note
7880
- `self` is the instance the method is operating on.
7981
- `__init__` initializes each new object.
82+
- Use classes when behavior belongs with state; use dictionaries for looser structured data.
8083
- Instance attributes belong to one object, not to the class as a whole.
8184
:::

src/example_sources/enums.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,5 @@ False
6767
- Enums make states and choices explicit.
6868
- Members have names and values.
6969
- Comparing enum members avoids string typo bugs.
70+
- Prefer raw strings for open-ended text; prefer enums for a closed set of named choices.
7071
:::

src/example_sources/exception-groups.md

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,22 @@ see_also = [
1111
]
1212
+++
1313

14-
`ExceptionGroup` represents several unrelated exceptions raised together. `except*` handles the matching members of the group and lets other members continue separately.
14+
`ExceptionGroup` represents several unrelated exceptions raised together. `except*` exists for code that may receive multiple failures at once, especially concurrent work.
1515

16-
This syntax is most useful with concurrent code, where several tasks can fail before the caller regains control.
16+
Use ordinary `except` for one exception. Use `except*` only when the value being handled is an exception group and each matching subgroup needs its own handling.
1717

18-
Use ordinary `except` for one exception. Use `except*` only when the value being handled is an exception group.
18+
Each `except*` clause receives a smaller exception group containing the matching exceptions.
1919

2020
:::program
2121
```python
22+
errors = ExceptionGroup(
23+
"batch failed",
24+
[ValueError("bad port"), TypeError("bad mode")],
25+
)
26+
print(len(errors.exceptions))
27+
2228
try:
23-
raise ExceptionGroup(
24-
"batch failed",
25-
[ValueError("bad port"), TypeError("bad mode")],
26-
)
29+
raise errors
2730
except* ValueError as group:
2831
print(type(group).__name__)
2932
print(group.exceptions[0])
@@ -33,14 +36,27 @@ except* TypeError as group:
3336
:::
3437

3538
:::cell
36-
`ExceptionGroup` bundles several exception objects. `except* ValueError` receives a group containing only the matching `ValueError` members.
39+
An exception group bundles several exception objects. This is different from an ordinary exception because more than one failure is present.
40+
41+
```python
42+
errors = ExceptionGroup(
43+
"batch failed",
44+
[ValueError("bad port"), TypeError("bad mode")],
45+
)
46+
print(len(errors.exceptions))
47+
```
48+
49+
```output
50+
2
51+
```
52+
:::
53+
54+
:::cell
55+
`except*` handles matching members of the group. The `ValueError` handler sees the value error, and the `TypeError` handler sees the type error.
3756

3857
```python
3958
try:
40-
raise ExceptionGroup(
41-
"batch failed",
42-
[ValueError("bad port"), TypeError("bad mode")],
43-
)
59+
raise errors
4460
except* ValueError as group:
4561
print(type(group).__name__)
4662
print(group.exceptions[0])

src/example_sources/exceptions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Exceptions represent errors or unusual conditions that interrupt normal control
1010

1111
Keep the successful path separate from the recovery path. `else` runs only when no exception was raised, while `finally` runs either way for cleanup or bookkeeping.
1212

13+
Use exceptions when an operation cannot produce a valid result. Prefer ordinary conditionals for expected branches that are not errors.
14+
1315
Catch specific exceptions whenever possible. A broad catch can hide programming mistakes, while a targeted `ValueError` handler documents exactly what failure is expected.
1416

1517
:::program

src/example_sources/generators.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,5 @@ for value in countdown(3):
6767
- Generator functions are a concise way to create custom iterators.
6868
- Values are produced on demand.
6969
- A generator is consumed as you iterate over it.
70+
- Prefer a list when you need to reuse stored results; prefer a generator when values can be streamed once.
7071
:::

0 commit comments

Comments
 (0)