Skip to content

About

A hands-on Python curriculum grown out of two class exercises: 16 progressive lessons, 40 graded problems with solutions, and 3 complete projects. 292 tests, mypy --strict clean, every program runs.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Python_educator

Learn Python the way it is actually written — one file that runs, lints and type-checks.

CI Python Ruff mypy Tests License Lessons Exercises

16 progressive lessons · 40 graded exercises with solutions · 3 build-it-yourself projects

Every one of the 60 programs here runs, passes ruff, and type-checks under mypy --strict.


Where this came from

This repository started as two files from a class — a function that counts repeats, and one that filters a list of films by genre. They are still here, unedited, in coursework/.

Everything else is the distance travelled from them: what those two exercises turn into once you know about type hints, Counter, dataclasses, generators, context managers and a test suite. The starting line is kept on purpose, because deleting it would make the distance impossible to measure.


Quick start

git clone https://github.com/limonuser/Python_educator.git
cd Python_educator

python -m pip install -e ".[dev]"   # pytest, ruff, mypy

make            # lint + type-check + test + run everything
make lesson-09  # run one lesson
make test       # just the tests

Every file is standalone, so you never actually need make:

python lessons/09-dicts-and-sets/mappings.py

No Python yet? See docs/SETUP.md — Linux, macOS and Windows.


The curriculum

Work top to bottom. Each lesson assumes the one above it and nothing else.

Part I — The Language Floor

# Lesson You will learn Key file
01 Hello, World How Python runs a file, bytecode and __pycache__, and what if __name__ == "__main__" actually prevents hello.py
02 Variables & Types Names are references, not boxes; is vs ==, interning, float imprecision, unbounded int variables.py
03 Operators / vs // vs %, flooring toward negative infinity, chained comparison, truthiness, the walrus operators.py
04 Control Flow if/elif, match/case and its capture-vs-compare trap, when if x: is the wrong test control.py
05 Loops enumerate, zip(strict=), what for/else really means, mutating a list while iterating it loops.py
06 Functions The mutable default argument trap, *args/**kwargs, keyword-only params, closures and late binding functions.py

Part II — Data Structures

# Lesson You will learn Key file
07 Lists & Tuples Slicing, shallow vs deep copy and the aliasing bug it hides, sorting with key=, stability sequences.py
08 Strings Immutability, why += in a loop is O(n²), f-string format specs, str vs bytes strings.py
09 Dicts & Sets get/setdefault, defaultdict, Counter, hashability, O(1) vs O(n) membership measured mappings.py
10 Comprehensions List/dict/set forms, nested-for ordering, generator expressions, when not to use one comprehensions.py
11 Iterators & Generators The iterator protocol, yield, generator exhaustion, itertools, memory measured with getsizeof generators.py

Part III — Building Things

# Lesson You will learn Key file
12 Classes & Objects __repr__ vs __str__, __eq__ with __hash__, @property, dataclasses, the class-attribute trap classes.py
13 Errors & Exceptions What else and finally are for, why bare except is never right, raise … from, EAFP vs LBYL errors.py
14 Modules & Packages A real package (textkit/), __all__, relative imports, why module code runs once, circular imports main.py + textkit/
15 Files & Context Managers with and what it guarantees, writing your own, pathlib, json, csv, always encoding="utf-8" fileio.py
16 Testing & Typing pytest, raises, parametrize, fixtures; annotations aren't enforced — mypy is what enforces them demo.py

Practice

Forty problems, sorted by difficulty. Every one ships with a full solution — in a separate file, so looking is a decision rather than an accident.

Tier Problems Sample
Beginner 15 FizzBuzz, prime sieve, digit sum, palindrome, GCD/LCM, char frequency
Intermediate 15 Binary search, Caesar cipher, anagrams, Roman numerals, RLE, base conversion
Advanced 10 LRU cache, hash table, BST, binary heap, decorators, context managers, JSON parser
cd practice/beginner
python 01_fizzbuzz.py

The advanced tier is covered by the test suite:

python -m pytest tests/test_practice_advanced.py -v

Projects

Three complete programs. Each one is argparse-driven, fully typed, raises its own exception types rather than leaking tracebacks, and runs a self-contained demonstration when you give it no arguments.

Project What it is Lines Pulls in
01 — Calculator Infix expression evaluator: tokenizer → shunting-yard → RPN. Never calls eval() 485 parsing, custom exceptions, argparse
02 — Todo CLI Task manager with JSON persistence, subcommands, and stable IDs 555 dataclasses, enums, pathlib, json
03 — Word Frequency Streaming text analyzer with a histogram and hapax count 392 Counter, re, generators
python projects/01-calculator/calc.py "5 + (1 + 2) * 4 - 3"     # 14
python projects/02-todo-cli/todo.py add "learn generators"
python projects/03-word-frequency/wordfreq.py book.txt -n 25

Quality bar

Four checks, enforced by CI on Python 3.11, 3.12 and 3.13:

python -m ruff check .            # lint
python -m ruff format --check .   # formatting
python -m mypy .                  # types, --strict
python -m pytest                  # 292 tests
  • Every function is annotated. mypy --strict passes on all 70 modules — no Any leaking out, no untyped defs, no silent # type: ignore.
  • 292 tests, all passing. Not smoke tests: the calculator's error paths, the todo store's disk round-trip, the LRU cache's eviction order, and the JSON parser checked against json.loads.
  • Every program runs. CI executes all 60 of them and fails on a non-zero exit.
  • coursework/ is exempt and stays that way — those two files are a record, not a target. CI still runs them, so they have to keep working.

Repository layout

Python_educator/
├── coursework/           the two original class exercises, unedited
├── lessons/              16 lessons, each a folder you can cd into
│   ├── 01-hello-world/       README.md + hello.py
│   ├── ...
│   └── 14-modules-and-packages/   README.md + main.py + textkit/
├── practice/             40 problems with full solutions
│   ├── beginner/             15 · loops, arithmetic, strings, lists
│   ├── intermediate/         15 · algorithms, parsing, bit work
│   └── advanced/             10 · data structures built from scratch
├── projects/             3 complete programs
├── tests/                292 pytest tests over the projects and advanced tier
├── docs/                 setup · cheatsheet · gotchas · style · roadmap
├── .github/workflows/    CI on 3.11 / 3.12 / 3.13
├── pyproject.toml        ruff + mypy + pytest config
└── Makefile              make check runs the whole bar

Reference material

Document Contents
docs/SETUP.md Getting Python and a virtualenv on any OS; what each tool flag buys you
docs/CHEATSHEET.md f-string specs, str/list/dict/set methods, itertools, dunders, truthiness
docs/GOTCHAS.md Fifteen Python traps, each with a wrong/right pair and the reason
docs/STYLE_GUIDE.md The conventions every file here follows
docs/ROADMAP.md Where this curriculum goes next

How to actually learn from this

  1. Read the lesson README first. It frames the problem before showing code.
  2. Type the example out. Do not copy-paste.
  3. Break it deliberately. Drop the encoding=, mutate the list you are iterating, give a function a mutable default. Watch what happens — and what doesn't warn you.
  4. Do the exercises before reading the solutions. A solution you read is worth about a tenth of one you wrote.
  5. Run mypy on your own answer. It finds the bug your test forgot.

License

MIT — use it, fork it, teach with it.

About

A hands-on Python curriculum grown out of two class exercises: 16 progressive lessons, 40 graded problems with solutions, and 3 complete projects. 292 tests, mypy --strict clean, every program runs.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages