Use python3 as the canonical command name course-wide (#104)
CI / check (pull_request) Successful in 7s

Most current systems (default Debian/Ubuntu, recent macOS) install Python
only as `python3`, with no bare `python` on PATH, so learners who copied
`python cli.py ...` into their host shell hit "command not found".

Convert host-shell `python <cmd>` -> `python3 <cmd>` across module/lab
READMEs, lab `.py` docstrings & usage strings, blog posts, lab prompt and
instruction files, the M04 verify.sh message, and the M10/M24 lab patches.
Module 01's convention note (and its blog/02 mirror) is rewritten so
`python3` is canonical and `python` is the documented fallback.

Stop-lines respected: Docker image tags (`python:3.12-slim`), `.venv/.../python`
and `...\.venv\Scripts\python.exe` paths, the M20 `"command": "python"`
teaching example and surrounding venv prose, container-internal invocations
(M16/M18 Dockerfiles, M16 README `docker run` examples), and CI-workflow
`run:` steps fed by `actions/setup-python` / `image: python:3.12` are left
as `python` on purpose.

pip was left out of scope: most occurrences are prose or CI/container-internal,
and `pip3` does not fix the PEP 668 externally-managed-environment refusal that
the course already addresses with venvs. The M01 note is worded to stay
consistent with bare `pip` (use whichever pip pairs with your Python).

Build (tools/build_wiki.py) and tools/check.sh both pass.

Closes #104

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GAEzanEoGJT5o1VizQar47
This commit is contained in:
2026-06-23 20:18:04 -04:00
parent 7f439212ac
commit 3221f7abe8
102 changed files with 380 additions and 378 deletions
+9 -9
View File
@@ -79,9 +79,9 @@ Let it edit `tasks.py` and `cli.py` freely. This is a multi-file change: exactly
```bash
git diff # read what it actually changed
python cli.py add "ship module 6" --priority high
python cli.py add "water plants" --priority low
python cli.py list # see if priorities work and sort
python3 cli.py add "ship module 6" --priority high
python3 cli.py add "water plants" --priority low
python3 cli.py list # see if priorities work and sort
git add .
git commit -m "Add task priorities (experiment)"
```
@@ -90,7 +90,7 @@ The payoff: prove the isolation. Switch back to `main` and watch the whole featu
```bash
git switch main
python cli.py list # no priorities: main is exactly as you left it
python3 cli.py list # no priorities: main is exactly as you left it
```
Sit with that for a second. Your bold change exists *only* on the branch. `main` never saw it. That's the entire point of the module in two commands.
@@ -103,7 +103,7 @@ Sit with that for a second. Your bold change exists *only* on the branch. `main`
git switch main
git merge experiment/priorities # likely a fast-forward: main slides up to the branch
git log --oneline --graph # straight line = fast-forward
python cli.py list # the feature is now on main
python3 cli.py list # the feature is now on main
git branch -d experiment/priorities # branch did its job; -d is the safe delete
```
@@ -127,9 +127,9 @@ Most merges just work; Git is genuinely good at combining changes that touch *di
```python
<<<<<<< HEAD
print("usage: python cli.py [add <title> | list | done <index> | purge]")
print("usage: python3 cli.py [add <title> | list | done <index> | purge]")
=======
print("usage: python cli.py [add <title> | list | done <index> | stats]")
print("usage: python3 cli.py [add <title> | list | done <index> | stats]")
>>>>>>> feature/stats
```
@@ -149,8 +149,8 @@ It resolves silently and the merge lands. And here is the only part that's still
```bash
git diff HEAD~1 # what the merge actually changed; confirm no markers, both commands present
python cli.py # run it: see the merged usage string
python cli.py stats && python cli.py purge # both actually work
python3 cli.py # run it: see the merged usage string
python3 cli.py stats && python3 cli.py purge # both actually work
```
That `git diff` after *every* merge is the whole skill now. Not "edit the markers by hand," which the AI did for you before you could blink, but "know a conflict can happen and check the silent resolution," because a resolution that runs cleanly can still be wrong and it won't leave an error behind to warn you. (And if your AI's edits didn't happen to collide (they're nondeterministic), the course ships a little `make-conflict.sh` helper that manufactures one deterministically so you can still see the markers at least once.)