Skip to content

birsi/python-training

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🎓 Python Training

Hands-on Python exercises that check themselves with pytest — designed to be worked through with Claude Code acting as your personal tutor and reviewer.

Python Exercises Tutor License: MIT

Every exercise ships with a locked test file. When pytest passes, you've solved it.


⚙️ How it works

  1. 📝 Each directory in exercises/ is a self-contained lesson with tasks marked # TODO: your code here in the main .py file.
  2. 🔴 A fresh exercise fails at test timeAttributeError: module 'basics' has no attribute 'greet' literally names what you still need to build.
  3. 🟢 You write code, re-run the test, and work from missing-attribute errors to failing assertions to green.
  4. 🤖 Claude reviews your work: not just "do the tests pass", but whether it's idiomatic Python.
# check a single exercise (do this constantly while working)
pytest exercises/stage1/01_basics/

# run everything (only clean once ALL exercises are solved)
pytest exercises/

Note

The test_*.py file in each exercise is the spec — don't modify it. Unlike Go or TypeScript, Python has no compiler to pin function signatures ahead of time — that's what mypy --strict is for (see Ground rules). A fresh exercise file has no stub at all, just the # TODO comment, so tests fail one at a time with a clear AttributeError naming exactly what's missing.

🚀 Setup

Requires Python 3.12+.

git clone <this-repo>
cd python-training
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements-dev.txt
pytest solutions/   # sanity check: everything green

🤖 Training with Claude Code

This repo ships with a CLAUDE.md that turns Claude Code into a Python tutor. Start a session in the repo root:

claude

Then drive the training conversationally:

💬 You say 🤖 Claude does
"Where should I start?" / "What's next?" Checks your progress across all exercises and points you at the right one
"Explain task 8.2, I don't get it" Teaches the concept with fresh examples — without handing you the answer
"I'm stuck on task 11.3" Gives escalating hints, smallest first
"Review exercise 6" Runs the tests (+ mypy --strict, ruff), reads your code, gives feedback
"Show me the solution for task 9.4" Only then reveals the reference solution

Claude is instructed to never solve exercises for you unless you explicitly ask.

You can of course also train without Claude — solve the TODOs, run the tests, and compare against solutions/ yourself.

📚 Curriculum

The three stages mirror how Python proficiency develops for someone who already thinks in a statically-typed language: first the mechanics (values, functions, collections — and where Python quietly diverges from Go/TS), then Python's way of modeling (classes, dataclasses, structural typing, exceptions), then its power features (generics, concurrency, boundaries).

Each exercise comes with official reading — read it up front or in parallel, then let the tests check your understanding. All links go to docs.python.org (the CPython project's own documentation) or peps.python.org for the handful of features defined by a PEP rather than a docs page. Before Stage 1, skim the Python Tutorial once — everything below builds on it.

🌱 Stage 1 — Foundations: values, functions, and Python's data structures

The mechanics you need for everything else — including the traps that bite people coming from a language with a compiler and real pointers: Python has no zero values, mutable default arguments are shared across calls, and "pass by reference vs. value" is really "mutable vs. immutable type."

Exercise Topics 📖 Official reading
01_basics Type-hinted variables, f-strings, the UPPER_CASE constant convention, no automatic zero values, / vs // division Tutorial: An Informal Introduction to Python · Language Reference: Assignment statements
02_functions Default parameters, *args/**kwargs, closures (nonlocal), functions as values Tutorial: More Control Flow Tools — defining functions
03_collections List/dict/set comprehensions, dict.get as the comma-ok idiom, the list-sharing mutation trap Tutorial: Data Structures · Library: dict
04_mutability is vs ==, the mutable-default-argument footgun, shallow vs. deep copy, mutable vs. immutable pass semantics Library: copy — shallow and deep copy · Glossary: mutable · Programming FAQ (search "changing list")

🧩 Stage 2 — Modeling: classes, dataclasses, and errors as exceptions

How Python structures programs without Go's implicit-everything-by-value structs or TS's nominal implements. Plain classes first, then @dataclass for the ergonomic case, then typing.Protocol — Python's structural typing, the closest thing to Go's implicit interface satisfaction — and finally exceptions, which replace (value, error) returns entirely.

Exercise Topics 📖 Official reading
05_classes __init__, __repr__/__eq__ (no free structural equality), class vs. instance attributes, composition Tutorial: Classes · Language Reference: Data model (dunder methods)
06_dataclasses @dataclass, frozen=True, @property, mutating methods Library: dataclasses
07_protocols typing.Protocol structural typing, __str__, isinstance narrowing over object Library: typing.Protocol · Glossary: duck-typing
08_exceptions Raising ValueError, custom exception classes, raise ... from ... chaining, a retry() helper Tutorial: Errors and Exceptions · Library: Built-in Exceptions

🔮 Stage 3 — Power features: generics, concurrency, boundaries

Python's answers to Go's headline features. Generics first (PEP 695's native [T] syntax), then concurrency in two steps — shared memory with threading.Lock (10), then asyncio's cooperative, message-passing style via Queue/gather (11) — and finally JSON, where untyped outside data enters your typed world.

Exercise Topics 📖 Official reading
09_generics PEP 695 generic functions/classes (def first[T](...), class Stack[T]), bounded type parameters PEP 695 — Type Parameter Syntax · What's New in Python 3.12 (generic syntax section)
10_threading threading.Thread + join-all, threading.Lock-guarded shared state, disjoint-index parallelism Library: threading
11_asyncio asyncio.Queue producer/consumer, asyncio.gather fan-in, asyncio.wait_for timeouts Library: Coroutines and Tasks (gather, wait_for) · Queues
12_json Dataclass ⇄ JSON via json.dumps/json.loads, omitempty-style filtering, unknown-shape JSON via dict[str, Any] Library: json

Tip

Work through the exercises in order — concepts are deliberately reused: mutability rules (03, 04) explain why frozen dataclasses matter (06), structural typing (07) is what makes the generic Stack[T] (09) easy to reason about, and the Lock discipline from threading (10) motivates why asyncio (11) sidesteps locks entirely by being single-threaded.

📏 Ground rules

  • 🎨 Run ruff format — formatting is not a matter of taste. (ruff format --check . must print nothing.)
  • 🔎 Run ruff check — catches unused imports, shadowing, and other lint issues.
  • 🏷️ Full type hints, checked with mypy --strict. No untyped defs, no unannotated Any.
  • 🔒 Don't touch the test_*.py files. They're the spec.
  • 🚫 No bare except:. Catch specific exception types — swallowing everything hides bugs.

🙈 Solutions

Reference solutions live in solutions/, mirroring the exercise structure. Spoilers! Try the exercise, ask Claude for hints, and only then compare.

🗂️ Project layout

exercises/            ← your workspace: 12 exercises across 3 stages
solutions/             ← reference solutions (same layout, same tests)
CLAUDE.md              ← tutor instructions for Claude Code
Makefile               ← check-solutions / check-all / fmt / lint / typecheck
pyproject.toml         ← pytest / mypy / ruff configuration
requirements-dev.txt   ← pytest, mypy, ruff

🤝 Contributing

Found a bug, an unclear task, or an idea for a new exercise? Suggestions are welcome — open an issue or start a discussion, and PRs are always welcome too.


Made for learning. Fork it, train with it, share it. 🚀

Looking for the same course for Go or TypeScript? → go-training · typescript-training

About

Hands-on Python exercises that check themselves with pytest — designed to be worked through with Claude Code as your tutor.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages