Closing · Lesson 92 of 94

How to keep practicing

Watch this lesson

View full playlist ↗

Read the lesson

What you'll learn

Concept

Skill after a course comes from projects, and projects fail for one reason more than any other: they are too big. The right size for a project is one you can finish in two to four sessions while learning exactly one new thing. Finishing matters more than ambition, because a finished project is something you can show, extend, and learn from, and an abandoned one is none of those. Keep a list, pick the smallest that still excites you, define done before you start, and stop when you reach it.

How to keep practicing: idea list → pick the smallest exciting one → write 'done' in one sentence → build in 2–4 sessions → finish: it runs, it has a README, it is committed → reflect: one thing learned, one thing to do differently
How to keep practicing · Figure 1 · Open for full size

Ideas by level, each finishable in a few sessions and each stretching one skill. Fundamentals: a unit converter with tests, a flash-card quiz that tracks scores in a file, a text adventure with a dictionary of rooms. Beginner: a bookmark manager on sqlite with a CLI, a Markdown-to-HTML converter, a recipe scaler that reads JSON, a folder de-duplicator by content hash. Advanced: a typed and tested API client for a public service you use, a static site generator, a log analyser with generators and Counter, an async link checker for a website. Expert: package and publish one of the above, add a Docker image and CI, contribute a fix to a library you depend on, write a small web service with a real database and a deploy.

Level Project ideas The skill it stretches
Fundamentals unit converter · flash cards with saved scores · text adventure functions, files, dictionaries, loops
Beginner bookmark manager (sqlite + CLI) · Markdown converter · duplicate finder classes, modules, sqlite, pathlib, argparse
Advanced typed API client with tests · static site generator · async link checker typing, pytest, generators, asyncio, httpx
Expert publish a package · dockerized web service · a fix to a dependency packaging, CI, Docker, contributing

Reading code is a practice, not an accident. Once a week, open a well-regarded project on your path and read one module the way the codebase lesson taught: orient, pick one behavior, trace it, draw it. Notice how they name things, how they structure a package, where their tests live, how they handle errors. Steal the habits you like. The standard library itself is excellent reading: pathlib, dataclasses, and functools are written by people who know the language deeply, and they are installed on your machine.

Contributing to open source needs no invitation. Start with the projects you already use: their issue trackers have bugs labeled good first issue, documentation with typos and gaps, and tests that could cover more. Read CONTRIBUTING.md, make the small change in a branch, run their checks, and open a pull request with a clear description. Your first contribution will be a docstring or a test, and that is exactly right; maintainers remember people who make careful small changes and come back. Every contribution is also a code review from someone better than you, which is the fastest feedback there is.

Practice compounds when it is deliberate: regular rather than heroic, so twenty minutes daily beats a monthly weekend; slightly uncomfortable, a step past what you can already do; and reviewed, by a test suite, a linter, a mentor, or a pull request, so mistakes are found. Keep a learning log with one line per session: what you did, what confused you, what you will try next. Read it monthly, and you will see progress that is invisible day to day.

How to keep practicing: practice → compounds → fades
How to keep practicing · Figure 2 · Open for full size

Code

A project picker that sizes ideas to your level and time, and prints a "done" sentence to fill in. Editing the two variables at the top is the whole interface.

# pick_project.py
IDEAS = {
    "fundamentals": [("unit converter with tests", "functions, tests"), ("flash cards with saved scores", "files, dicts"), ("text adventure", "dicts, loops")],
    "beginner": [("bookmark manager: sqlite + CLI", "sqlite, argparse"), ("Markdown to HTML converter", "strings, regex-lite"), ("duplicate file finder", "pathlib, hashing")],
    "advanced": [("typed API client with tests", "typing, httpx, pytest"), ("static site generator", "pathlib, templates"), ("async link checker", "asyncio, httpx")],
    "expert": [("publish a package to PyPI", "packaging, CI"), ("dockerized web service", "Docker, config, logging"), ("fix a bug in a dependency", "reading code, PRs")],
}

level = "advanced"
sessions_available = 3

for i, (idea, skills) in enumerate(IDEAS[level], start=1):
    fits = "fits" if sessions_available >= 2 else "too little time; shrink it"
    print(f"{i}. {idea:<32} stretches: {skills:<24} [{fits}]")
print()
print("Done when: ______________________________ (one sentence, written before you start)")
print(f"Plan: {sessions_available} sessions x ~90 min; commit after each; README before calling it finished")
Output
1. typed API client with tests      stretches: typing, httpx, pytest    [fits]
2. static site generator            stretches: pathlib, templates       [fits]
3. async link checker               stretches: asyncio, httpx           [fits]

Done when: ______________________________ (one sentence, written before you start)
Plan: 3 sessions x ~90 min; commit after each; README before calling it finished

Reading practice, applied to the standard library on your own machine: locate a module and measure it, which is the first step of the orientation method on code written by experts.

# read_stdlib.py
import dataclasses
import functools
import inspect
import pathlib

for module in (pathlib, dataclasses, functools):
    source = inspect.getsource(module)
    docstring = ((module.__doc__ or "").strip().splitlines() or ["(no module docstring)"])[0]
    print(f"{module.__name__:<12} {len(source.splitlines()):>5} lines  | {docstring[:50]}")

print()
print(inspect.getsource(functools.cache).strip().splitlines()[0])
print(inspect.getdoc(functools.cache).splitlines()[0])
Output
pathlib       1307 lines  | Object-oriented filesystem paths.
dataclasses   1813 lines  | (no module docstring)
functools     1165 lines  | functools.py - Tools for working with functions an

def cache(user_function, /):
Simple lightweight unbounded cache.  Sometimes called "memoize".

A learning log that costs one line per session and pays off monthly. Appending is the habit; the summary is the reward.

# learning_log.py
from collections import Counter
from datetime import date
from pathlib import Path

log = Path("learning_log.md")
entries = [
    ("2026-09-01", "typed API client", "confused by Protocol vs ABC", "reread lesson 40"),
    ("2026-09-02", "typed API client", "mypy strict on Optional", "add None checks"),
    ("2026-09-04", "typed API client", "nothing; shipped v0.1", "start async version"),
    ("2026-09-06", "read httpx source", "how transports are swapped", "try MockTransport in my tests"),
]
log.write_text("# Learning log\n\n" + "".join(f"- {d} · {did} · confused: {confused} · next: {nxt}\n" for d, did, confused, nxt in entries), encoding="utf-8")

lines = [ln for ln in log.read_text(encoding="utf-8").splitlines() if ln.startswith("- ")]
projects = Counter(ln.split(" · ")[1] for ln in lines)
print(f"{len(lines)} sessions logged; by project: {dict(projects)}")
print("most recent next step:", lines[-1].split("next: ")[1])
print("today would be entry", len(lines) + 1, "on", date(2026, 9, 9))
Output
4 sessions logged; by project: {'typed API client': 3, 'read httpx source': 1}
most recent next step: try MockTransport in my tests
today would be entry 5 on 2026-09-09

Try it yourself

Write your idea list: at least six projects across two levels, each with a one-sentence "done". Pick one and schedule the first session in your calendar. Choose one open-source project you use, find its contributing guide and one "good first issue" or documentation gap, and make a note of exactly what your first pull request will change. Create learning_log.md and write today's line.

Common mistakes

What's next

You know how to keep improving. Next, how to turn what you have learned into work: a portfolio, a README people trust, and a first production project for a job or a client.

Course overview