Template

Learn Python

Learn Python properly: the language itself, its data model and standard library, and how to write clear, tested, idiomatic Python that I would be happy for someone else to read.

This roadmap takes you from writing your first lines of code to mastering idiomatic, production-grade Python through hands-on project builds. Across ten phases and roughly three to five months at 8 hours per week, you will systematically explore language syntax, structural data models, standard library tools, testing frameworks, and advanced protocols. By the end, you will be able to design, structure, type-check, test, and package robust Python applications and libraries that fully leverage Python's unique data model.

By the end: You will be able to write idiomatic, type-annotated, and thoroughly tested Python libraries and tools, comfortably using the Python data model, decorators, generators, and standard packaging tools.

Starting levelBeginnerStyleBuilding things
8h / week10 phases28 tasks~126h total

This is the map — make this roadmap yours

It shows what this journey generally looks like. Tell Kaidoro your version of the goal and it builds the plan around where you are actually starting, what to do first, the hours you really have, and what you have already finished.

1

Environment Setup and Core Language Mechanics

Establish a modern Python development environment and master foundational syntax, variables, primitive types, and control flow through small interactive tools.

  • Set up modern Python and interactive tooling
    ~3hLearn1 resource

    A reliable local environment with interactive feedback is essential before writing application code.

    You'll learn

    • REPL — Read-Eval-Print Loop for rapid interactive code evaluation
    • sys.version — built-in property exposing the active Python version
    • terminal execution — running scripts using python script.py from the CLI

    Install Python 3.12+, configure a code editor like VS Code or PyCharm, and learn how to run Python scripts both via command line and an interactive REPL like IPython. You will write a script that inspects your runtime environment and prints system details.

    Done when: you can execute a script from your terminal that outputs the Python version, executable path, and current operating system platform.

    How to work through it

    1. Install Python 3.12+ on your system
    2. Configure your text editor with Python language extensions
    3. Install IPython in a terminal for interactive experimentation
    4. Write a script importing sys and platform to print runtime information
  • Build a CLI unit converter with conditional branches
    ~4hBuild

    Writing interactive scripts solidifies your understanding of type coercion and branching control flow.

    You'll learn

    • type casting — converting strings from standard input into numeric types
    • f-strings — formatted string literals for clean text interpolation
    • conditional logic — directing program execution flow based on boolean expressions

    Build a command-line utility that prompts users for values and units (e.g., temperature, distance, weight) and computes conversions. Practice variables, primitive data types (integers, floats, strings, booleans), input parsing, and conditional branching (if/elif/else).

    Done when: the converter handles at least three unit categories, performs valid mathematical conversions with formatted float output, and gracefully rejects invalid input options.

    How to work through it

    1. Create a script handling user prompts via input()
    2. Convert string inputs to float types safely
    3. Implement branching logic with if, elif, and else blocks
    4. Format decimal output using f-strings
  • Build a terminal-based number guessing game with loops
    ~3hBuild

    Loops and loop-control keywords are the core engine of iterative algorithmic logic in Python.

    You'll learn

    • random.randint — standard library function for pseudo-random integers
    • while loop — iterative structure executing while a boolean condition remains true
    • break and continue — statements to interrupt or advance loop iterations

    Create an interactive guessing game where the computer selects a random number and gives directional hints (higher/lower) with a limited attempt counter. Implement while loops, for loops with ranges, loop control statements (break, continue, else-on-loop), and state tracking.

    Done when: the game runs from start to finish, tracks attempts correctly, stops when guesses run out or the number is found, and reports round statistics.

    How to work through it

    1. Import random and use randint to generate target values
    2. Implement a while loop to handle repeated guesses until termination
    3. Use break to exit early on victory and continue to bypass bad inputs
    4. Add an attempt tracking counter and victory/loss summary printouts
2

Core Data Structures and Comprehensions

Work deeply with Python's core collection types—lists, tuples, dictionaries, and sets—and master idiomatic idioms like comprehensions and structural unpacking.

  • Implement an in-memory inventory tracker using collections
    ~4hBuild1 resource

    Dictionaries and lists form the foundational data storage layer for almost all Python data pipelines.

    You'll learn

    • list mutability — in-place modification of ordered sequences
    • dictionary hashing — key-value mappings with O(1) lookup performance
    • dict.get() — accessing dictionary values with safe default fallbacks

    Build an inventory management CLI that stores item records using dictionaries nested inside lists. Practice indexing, slicing, inserting, updating, removing, and iterating over collection items using standard dictionary and list methods.

    Done when: the script supports adding items, updating stock counts, deleting entries, and displaying formatted table summaries.

    How to work through it

    1. Design the data structure using dictionaries for item entities and lists for collections
    2. Implement CRUD (create, read, update, delete) functions over the data structure
    3. Use dictionary methods like .get(), .keys(), and .items()
    4. Print formatted tabular data using string alignment methods
  • Build a text analysis tool using sets and comprehensions
    ~5hBuild

    Comprehensions and set mathematics allow you to write concise, highly efficient, and idiomatic data transformations.

    You'll learn

    • list comprehension — compact syntax for generating new lists from iterables
    • dict comprehension — expression-based construction of dictionaries
    • set operations — union, intersection, and difference operations on unique collections

    Build a script that parses raw text documents, computes word frequency distributions, identifies unique vocabulary across multiple files using set operations (unions, intersections, differences), and filters datasets using list and dict comprehensions.

    Done when: the program accepts text files, computes word frequency counts, and outputs set comparisons between documents using list/dict comprehensions.

    How to work through it

    1. Read raw text and normalize case and punctuation
    2. Generate unique token sets and perform set intersections and differences
    3. Build word count mappings using dictionary comprehensions
    4. Filter low-frequency words with nested list comprehensions
  • Build a data restructuring pipeline using sequence unpacking
    ~4hBuild

    Idiomatic iteration patterns eliminate off-by-one errors and replace manual index arithmetic with clean expressions.

    You'll learn

    • extended iterable unpacking — extracting head, middle, and tail items with * syntax
    • zip() — aggregating elements from multiple iterables into tuples
    • enumerate() — yielding index and value pairs during iteration

    Create a data transform script that processes raw nested tuples and lists from simulated legacy data. Apply tuple unpacking, extended unpacking (*rest), zip(), enumerate(), and sorted() with custom key functions to output clean structured records.

    Done when: the script processes heterogeneous nested tuples and produces sorted, uniformly structured summaries without using manual index counters.

    How to work through it

    1. Construct sample nested tuple data structures representing raw database rows
    2. Use tuple unpacking and starred expressions (*rest) to extract fields
    3. Iterate across parallel sequences using zip() and enumerate()
    4. Sort structured records with sorted() using lambda key functions
3

Modular Functions, Scopes, and Standard Libraries

Transition from scripts to modular software design by mastering function signatures, scope rules, module structures, and standard library tools.

  • Build a flexible calculation engine using advanced function arguments
    ~4hBuild

    Clean API design in Python relies heavily on precise argument positioning and explicit keyword boundaries.

    You'll learn

    • positional-only parameters — arguments enforced before the / delimiter
    • keyword-only parameters — arguments required by name after the * delimiter
    • LEGB rule — Local, Enclosing, Global, Built-in variable resolution scopes

    Write a multi-purpose calculation module that uses positional-only arguments, keyword-only arguments, default values, and arbitrary argument lists (*args, **kwargs). Enforce strict parameter signatures to prevent invalid usage.

    Done when: the module exposes functions that strictly differentiate positional from keyword arguments, correctly handles arbitrary arguments, and includes full docstrings.

    How to work through it

    1. Define functions with positional-only syntax (/) and keyword-only syntax (*)
    2. Implement variadic functions capturing *args and **kwargs
    3. Handle default parameter pitfalls (avoiding mutable defaults)
    4. Write comprehensive docstrings adhering to PEP 257 standards
  • Refactor logic into a multi-file Python package
    ~4hBuild1 resource

    Understanding Python's import system and module resolution is essential for building scalable applications.

    You'll learn

    • __init__.py — file marking directory as an importable Python package
    • __main__.py — entrypoint executed when a module is run with the -m flag
    • sys.path — list of directories Python searches when resolving imports

    Organize your converter, inventory, and calculation tools into a well-structured Python package containing multiple modules, proper __init__.py exports, and a central __main__.py entrypoint. Run the package directly using python -m.

    Done when: you can execute the entire toolkit from the CLI using python -m mytoolkit with cleanly resolved relative and absolute imports.

    How to work through it

    1. Create a directory structure with package root, submodules, and __init__.py
    2. Configure relative imports within submodules
    3. Create a __main__.py file to make the package directory executable
    4. Verify execution via python -m without import errors
  • Build a benchmark tool using itertools and collections modules
    ~5hBuild

    The standard library collections and itertools provide highly optimized C-level abstractions for common data manipulation tasks.

    You'll learn

    • collections.defaultdict — dictionary subclass calling a factory function for missing keys
    • collections.Counter — dict subclass designed specifically for counting hashable objects
    • itertools.groupby — iterator generating consecutive keys and groups from an iterable

    Build a statistical analysis script that processes sequences using standard library modules including collections (defaultdict, Counter, deque, namedtuple) and itertools (chain, cycle, groupby, islice). Benchmark the performance against pure list implementations.

    Done when: the tool runs data aggregation benchmarks using both pure lists and specialized collections, printing execution time comparisons and memory summaries.

    How to work through it

    1. Implement frequency counters with collections.Counter and groupings with defaultdict
    2. Create sliding windows and combined streams using itertools
    3. Use time.perf_counter() to measure runtime performance
    4. Present comparative timing metrics in a formatted terminal table
4

Object-Oriented Programming and the Python Data Model

Learn object-oriented design in Python by implementing classes, inheritance, encapsulation, dataclasses, and core dunder (special) methods.

  • Build a banking domain model with encapsulation and properties
    ~5hBuild

    Pythonic OOP avoids unnecessary getters and setters in favor of clean properties and explicit dunder methods.

    You'll learn

    • @property — decorator enabling getter, setter, and deleter methods with attribute syntax
    • __repr__ vs __str__ — developer representation vs user-facing string formatting
    • @classmethod — method receiving the class object (cls) rather than instance (self)

    Model a banking domain with classes for accounts, transactions, and customers. Implement state encapsulation with private attributes, dynamic properties (@property and setter), custom string representations (repr and str), and class methods.

    Done when: the domain model prevents negative balances via property setters, maintains valid transaction ledgers, and prints descriptive debug representations via repr.

    How to work through it

    1. Define Account and Transaction classes with __init__ initialization
    2. Implement @property and @balance.setter with validation logic
    3. Define __str__ for user-friendly printing and __repr__ for unambiguous debugging
    4. Add @classmethod factory constructors for creating accounts from raw data
  • Implement a custom Vector class supporting arithmetic protocols
    ~5hBuild1 resource

    Implementing arithmetic protocols makes your custom types behave like first-class native Python objects.

    You'll learn

    • operator overloading — defining operator behavior on custom objects using dunder methods
    • __rmul__ — right-hand (reflected) multiplication protocol method
    • NotImplemented — singleton returned when a type does not support an operation with another

    Create a 2D/3D Vector mathematical class that implements arithmetic and comparison dunder methods. Support addition (+), subtraction (-), scalar multiplication (*), equality (==), and truth-value testing (bool).

    Done when: your custom Vector class allows intuitive mathematical expressions (v3 = v1 + v2 * 3), checks equality accurately, and handles type mismatch errors gracefully.

    How to work through it

    1. Implement __add__, __sub__, and __mul__ with type checking
    2. Add __rmul__ to support reverse scalar multiplication (e.g., 3 * v)
    3. Implement __eq__ and __abs__ for magnitude calculations
    4. Implement __bool__ to evaluate vector magnitude against zero
  • Build a card deck simulator implementing the Sequence protocol
    ~4hBuild

    Python relies on duck typing and protocols: satisfying minimal dunder methods gives full access to language features without explicit inheritance.

    You'll learn

    • Sequence protocol — emulating read-only sequences with __len__ and __getitem__
    • dataclasses.dataclass — decorator generating boilerplate __init__ and comparison methods
    • duck typing — polymorphism based on object capabilities rather than class hierarchy

    Implement a custom Deck class that implements __len__ and __getitem__. Demonstrate how implementing these two methods automatically gives your object iteration, slicing, containment checks (in), and compatibility with random.choice.

    Done when: the Deck instance supports slicing (deck[0:5]), reverse iteration (reversed(deck)), random picking via random.choice, and sorting using dataclass card representations.

    How to work through it

    1. Define a Card dataclass using @dataclass with rank and suit
    2. Create a Deck class implementing __len__ and __getitem__
    3. Test slicing, indexing, and iteration on the deck instance
    4. Pass the deck to standard functions like random.choice() and sorted()
5

File Operations, Serialization, and Context Managers

Work with local file systems using modern pathlib, parse common structured data formats (JSON, CSV), and build custom context managers using the `with` statement.

  • Build a file organizer utility using pathlib
    ~4hBuild1 resource

    Modern pathlib provides an intuitive object-oriented interface for cross-platform filesystem operations.

    You'll learn

    • pathlib.Path — object-oriented representation of filesystem paths
    • Path.rglob — recursive pattern matching over directory structures
    • cross-platform compatibility — handling path separators consistently across OS platforms

    Create a command-line utility that inspects a target directory, categorizes files by extension and modification dates, creates sorted subfolders, and moves items safely. Use pathlib.Path exclusively instead of legacy os.path methods.

    Done when: the script cleanly inspects nested directories using pathlib globbing, handles filename collisions, and organizes files into categorized subdirectories.

    How to work through it

    1. Use Path.cwd() and Path.glob() / rglob() to discover files
    2. Extract file stems, suffixes, and metadata via Path methods
    3. Safely construct new directory trees using Path.mkdir(parents=True, exist_ok=True)
    4. Move files with Path.rename() or shutil
  • Build a JSON and CSV data migration tool
    ~4hBuild

    Real-world Python applications constantly serialize and deserialize structured data between formats.

    You'll learn

    • json.loads / json.dumps — serializing and deserializing JSON strings
    • csv.DictReader / csv.DictWriter — mapping rows to dictionaries for tabular data
    • encoding parameters — specifying explicit UTF-8 encoding in open()

    Build a data migration script that reads complex nested JSON configuration files, validates the schema, transforms fields, and writes normalized tabular records into CSV files using csv.DictWriter, and vice versa using csv.DictReader.

    Done when: the migration tool converts nested JSON payloads to normalized CSV spreadsheets and reconstructs the JSON structure back without data loss.

    How to work through it

    1. Read and parse JSON files using json.load() with custom deserializers
    2. Flatten nested dictionaries into flat records for tabular storage
    3. Write records using csv.DictWriter with specified fieldnames
    4. Implement reverse transformation using csv.DictReader and json.dump()
  • Create custom context managers for resource handling
    ~5hBuild

    Context managers guarantee deterministic resource acquisition and cleanup, preventing resource leaks.

    You'll learn

    • __enter__ and __exit__ — dunder methods defining context management lifecycle
    • contextlib.contextmanager — decorator converting generator functions into context managers
    • atomic operations — patterns ensuring file modifications succeed completely or not at all

    Create custom context managers using both the class-based protocol (__enter__ and __exit__) and the generator-based contextlib.contextmanager decorator. Build managers for timing code blocks, temporarily redirecting standard output, and handling atomic file writes.

    Done when: your atomic file writer context manager ensures that files are only modified if the inner block finishes without raising an exception.

    How to work through it

    1. Build a class-based Timer context manager implementing __enter__ and __exit__
    2. Handle exception propagation and suppression logic within __exit__
    3. Implement an AtomicFileWriter using contextlib.contextmanager and temporary files
    4. Verify that errors during writes leave original target files untouched
6

Error Handling, Logging, and Testing with Pytest

Master robust defensive programming by creating custom exception hierarchies, setting up structured logging, and writing automated test suites with pytest.

  • Build a custom exception hierarchy with structured logging
    ~4hBuild1 resource

    Production Python applications require structured log streams and explicit error types rather than raw prints and blanket try/except blocks.

    You'll learn

    • exception chaining — preserving original traceback using the 'raise ... from err' syntax
    • logging handlers — routing log records to console, files, or rotating storage
    • custom exceptions — application-specific exception types for distinct error domains

    Refactor an existing file parsing project to replace generic print statements with structured logging using the logging module. Design a domain-specific hierarchy of custom Exception classes that capture structured error details.

    Done when: all application events are output through configured loggers (with levels, timestamps, and formatting) and invalid states trigger custom exceptions caught cleanly by top-level handlers.

    How to work through it

    1. Define custom exception classes inheriting from Exception
    2. Configure logging with logging.basicConfig, formatters, and RotatingFileHandler
    3. Use logger.info, logger.warning, and logger.exception with stack traces
    4. Catch specific custom exceptions and preserve error context with 'from err'
  • Write comprehensive unit tests with pytest fixtures and parametrization
    ~5hBuild1 resource

    Pytest is the standard testing tool in the Python ecosystem due to its clean syntax and powerful fixture architecture.

    You'll learn

    • pytest fixtures — dependency injection mechanism for test resources
    • pytest.mark.parametrize — running a single test function across multiple input matrices
    • assert introspection — automatic detailed failure reports on assertion failure

    Install pytest and write a thorough automated test suite for your domain models and parser tools. Utilize pytest fixtures for test setup/teardown and @pytest.mark.parametrize to run tests over dozens of input/expected-output combinations.

    Done when: the test suite executes with 100% pass rate, contains parametrized test cases, and runs fixtures with clean teardowns.

    How to work through it

    1. Install pytest and configure pytest.ini / pyproject.toml
    2. Write unit tests using simple assert statements
    3. Create reusable test data fixtures with @pytest.fixture and yield teardown
    4. Parametrize edge-case test matrices using @pytest.mark.parametrize
  • Mock external dependencies and measure test coverage
    ~4hBuild

    Mocking isolates unit tests from external instability, ensuring fast and deterministic test runs.

    You'll learn

    • tmp_path — built-in pytest fixture providing unique temporary directory Path objects
    • unittest.mock.patch — replacing target objects with Mock instances during tests
    • branch coverage — verifying all execution branches in conditional logic are tested

    Extend your test suite to test code interacting with files and network calls without touching real external resources. Use unittest.mock.patch and pytest's monkeypatch / tmp_path fixtures, then measure test coverage using pytest-cov.

    Done when: the test suite achieves over 90% branch coverage reported via pytest-cov with zero network or real filesystem dependencies.

    How to work through it

    1. Use tmp_path fixture to test filesystem interactions in isolated sandbox directories
    2. Mock external function calls using unittest.mock.patch and MagicMock
    3. Assert mock call counts and received arguments
    4. Generate an HTML coverage report using pytest --cov
7

Advanced Idioms: Generators, Iterators, and Decorators

Deepen your Python mastery by writing custom iterators, memory-efficient generator pipelines, and reusable function and class decorators.

  • Build a streaming log processor with generator pipelines
    ~4hBuild

    Generators enable lazy evaluation, allowing Python programs to process massive data streams without loading them into RAM.

    You'll learn

    • yield keyword — pausing function execution and producing a value to the caller
    • generator pipeline — composing multiple generator functions in series
    • lazy evaluation — delaying expression evaluation until value is requested

    Create a log analysis tool capable of processing multi-gigabyte log files with near-zero memory consumption. Chain generator functions using yield statements to filter, map, parse, and aggregate lines sequentially.

    Done when: the streaming pipeline parses and filters large files in constant O(1) memory space, verified by memory profiling.

    How to work through it

    1. Write generator functions yielding parsed lines with yield statements
    2. Chain generator filters into a processing pipeline
    3. Use generator expressions for inline data transformations
    4. Track memory usage before and after using sys.getsizeof or tracemalloc
  • Implement custom function decorators with functools.wraps
    ~5hBuild

    Decorators are Python's primary metaprogramming tool for cleanly injecting cross-cutting concerns.

    You'll learn

    • decorator pattern — higher-order function modifying the behavior of wrapped functions
    • functools.wraps — preserving original function name, docstrings, and signature
    • decorator factory — outer function returning a decorator parameterized by arguments

    Build a collection of utility decorators: @timer for execution timing, @retry(times=3) with configurable arguments, @rate_limit, and @cache_lru memoization. Preserve function metadata using functools.wraps.

    Done when: the decorators can wrap arbitrary functions with varying signatures, handle arguments correctly, and preserve the original function's __name__ and docstrings.

    How to work through it

    1. Write a simple decorator wrapping functions with inner wrapper functions
    2. Apply functools.wraps to maintain introspection metadata
    3. Create decorator factories that accept configuration parameters (e.g., retry count)
    4. Test decorators against both positional and keyword argument functions
  • Build a class-level validation decorator and descriptor
    ~5hBuild

    Descriptors power Python's internal mechanics for properties, methods, and ORMs.

    You'll learn

    • descriptor protocol — objects defining __get__, __set__, or __delete__ methods
    • __set_name__ — hook automatically assigning descriptor instance attribute names
    • class decorator — function receiving a class and returning a modified class

    Implement custom descriptor classes that enforce type and range validation on class attributes (e.g., IntegerField, StringField). Compare descriptor behavior with property decorators and write a class decorator that auto-applies descriptors.

    Done when: any invalid attribute assignment on decorated classes immediately raises a descriptive ValidationError managed by your custom descriptors.

    How to work through it

    1. Implement __get__, __set__, and __set_name__ in a Validator descriptor class
    2. Integrate descriptors into a sample entity model
    3. Create a class decorator that inspects class attributes and binds descriptors
    4. Write unit tests verifying validation rejection on bad assignment
8

Type Hinting and Static Analysis

Adopt modern Python static typing by annotating codebases with typing constructs, Generics, Protocols, and enforcing strict checks using Mypy.

  • Add static type annotations to an existing codebase
    ~4hBuild1 resource

    Type hints make code self-documenting, catch subtle bugs before runtime, and enhance IDE autocompletion.

    You'll learn

    • type hints — annotations declaring expected types for variables and functions
    • mypy — static type checker analyzing Python code without executing it
    • Union and Optional — typing constructs allowing multiple types or None values

    Annotate functions and classes using primitive types, collections (list[str], dict[str, int]), Optional, Union (and the | union syntax), and callable signatures. Configure Mypy and resolve initial type errors.

    Done when: Mypy passes on the annotated codebase under standard configuration with zero type errors reported.

    How to work through it

    1. Install mypy and configure a mypy.ini / pyproject.toml configuration file
    2. Annotate function parameter types and return types across modules
    3. Use modern union syntax (int | str) and Optional types
    4. Run mypy . and resolve detected type mismatches
  • Implement Generics and structural subtyping with typing.Protocol
    ~5hBuild

    Protocols provide static duck typing, allowing compile-time type verification without rigid class inheritance hierarchies.

    You'll learn

    • typing.Protocol — static duck typing mechanism defining required interface methods
    • TypeVar — variable standing in for an unknown type in generic functions and classes
    • mypy --strict — strictest static type validation mode enforcing exhaustive annotations

    Design generic data structures using TypeVar / Generic (e.g., a custom Stack or Repository) and decouple components by defining structural interfaces using typing.Protocol instead of concrete base classes.

    Done when: Mypy verifies type safety across generic classes and confirms that duck-typed objects satisfy declared Protocol definitions under --strict mode.

    How to work through it

    1. Define generic classes using TypeVar and Generic (or PEP 695 type parameters)
    2. Define a Serializable or Renderable Protocol using typing.Protocol
    3. Create independent classes satisfying the protocol without subclassing it
    4. Verify complete type conformance with mypy --strict
9

Concurrency: Threads, Processes, and Asyncio

Understand Python's concurrency landscape, the Global Interpreter Lock (GIL), and when to use multithreading, multiprocessing, or asynchronous I/O.

  • Build a concurrent web scraper using ThreadPoolExecutor and ProcessPoolExecutor
    ~5hBuild

    Choosing between threads and processes requires understanding whether your bottlenecks are I/O bound or CPU bound in the presence of the GIL.

    You'll learn

    • GIL (Global Interpreter Lock) — mutex preventing multiple native threads from executing Python bytecode simultaneously
    • ThreadPoolExecutor — managing pools of worker threads for I/O concurrency
    • ProcessPoolExecutor — bypassing the GIL by spawning distinct Python OS processes

    Create a script that compares concurrent execution models. Fetch multiple web endpoints concurrently using concurrent.futures.ThreadPoolExecutor (I/O bound), then perform CPU-intensive hashing calculations across multiple cores using ProcessPoolExecutor.

    Done when: the script benchmarks serial vs multi-threaded I/O fetching and serial vs multi-process CPU processing, demonstrating expected speedups.

    How to work through it

    1. Implement sequential download and processing baselines
    2. Wrap I/O operations inside ThreadPoolExecutor and map tasks
    3. Wrap CPU-bound hashing calculations inside ProcessPoolExecutor
    4. Measure and explain the performance differences and CPU core utilization
  • Build an asynchronous rate-limited API client with asyncio and httpx
    ~5hBuild1 resource

    Asyncio provides high-throughput cooperative multitasking for modern network services.

    You'll learn

    • async / await — syntax for writing non-blocking asynchronous coroutines
    • event loop — central execution mechanism scheduling and running asynchronous tasks
    • asyncio.Semaphore — concurrency synchronization primitive limiting concurrent coroutines

    Build an asynchronous client that queries a REST API for hundreds of resources. Use asyncio, async/await, asyncio.Semaphore for concurrency rate limiting, and asyncio.gather for coordinating parallel tasks.

    Done when: the client executes 100+ asynchronous requests within strict concurrency limits (e.g., max 5 concurrent requests) and handles timeouts and failures gracefully.

    How to work through it

    1. Write asynchronous functions using async def and await syntax
    2. Execute concurrent coroutines using asyncio.gather()
    3. Limit simultaneous outbound connections using asyncio.Semaphore
    4. Implement graceful exception handling and timeout cancellations using asyncio.wait_for
10

Packaging, Tooling, and Capstone Project

Synthesize all skills by building, styling, typing, testing, and packaging an idiomatic, production-grade CLI application configured with modern pyproject.toml standards.

  • Configure modern project tooling with Ruff and pyproject.toml
    ~3hBuild

    Standardized configuration in pyproject.toml and automated formatters guarantee that your code adheres to community standards (PEP 8) effortlessly.

    You'll learn

    • pyproject.toml — unified configuration file for Python build tools and linters
    • ruff — extremely fast Python linter and code formatter written in Rust
    • PEP 8 — official style guide for Python code

    Initialize a clean project layout according to PEP 621 / PEP 518 standards using pyproject.toml. Configure ruff for ultra-fast linting and code formatting, configure Mypy with strict settings, and set up Git pre-commit hooks.

    Done when: running a single command runs formatting, linting, and type checking across your codebase with zero warnings.

    How to work through it

    1. Create a pyproject.toml with project metadata and dependencies
    2. Configure ruff for code style linting and formatting rules
    3. Set up strict type checking rules in pyproject.toml
    4. Verify automated checking runs cleanly across the repository
  • Build the capstone project: an idiomatic CLI data processing tool
    ~8hBuild

    Integrating all language features into a coherent project proves your ability to build complete, maintainable Python applications.

    You'll learn

    • argparse — standard library module for writing user-friendly CLI interfaces
    • domain-driven structure — organizing code by business concepts rather than technical layers
    • error boundaries — isolating subsystem failures from crashing the main CLI loop

    Design and build a complete CLI tool (such as an automated markdown link validator and static asset analyzer). It must feature clean modular architecture, custom data structures implementing dunder protocols, async fetching, custom exceptions, robust logging, and full type annotations.

    Done when: the CLI tool runs smoothly from terminal commands with flags, parses local and remote inputs asynchronously, logs cleanly, and handles all runtime failures gracefully.

    How to work through it

    1. Design the application architecture using clean domain models and protocols
    2. Build the CLI interface using argparse or click
    3. Integrate async network fetching with semaphore concurrency control
    4. Add detailed logging and domain-specific error handling
  • Complete test suite, documentation, and package distribution build
    ~6hReview1 resource

    A Python project is complete when it is tested, documented, and reliably installable by others.

    You'll learn

    • wheel (.whl) — standard built-package format for distributing Python software
    • python -m build — standard tool for building PEP 517 packages
    • virtual environments (venv) — isolated directory trees for managing dependencies

    Write a complete pytest suite covering the capstone application with fixtures, mocks, and parametrization (>90% coverage). Add comprehensive docstrings and build an installable .whl distribution package using the build tool.

    Done when: the test suite passes with 90%+ coverage, Mypy passes in strict mode, and you can install your package into a clean virtual environment using pip install dist/*.whl and run the CLI command successfully.

    How to work through it

    1. Write comprehensive pytest test cases for all modules with mocking
    2. Verify >90% code coverage and strict Mypy conformance
    3. Build source distributions and wheels using python -m build
    4. Test installation of the wheel in an isolated clean virtual environment

How the plan fits together

10 phases in 9 stages. Anything on the same row can be worked on at the same time.

An arrow points from a phase to the work it unlocks: before starting any phase, every phase with an arrow into it has to be finished first.

STARTSTAGE 2STAGE 3STAGE 4STAGE 5STAGE 6STAGE 7STAGE 8STAGE 91Environment Setup and CoreLanguage Mechanics3 tasks · ~10h2Core Data Structures andComprehensions3 tasks · ~13h3Modular Functions, Scopes,and Standard Libraries3 tasks · ~13h4Object-OrientedProgramming and the PythonData Model3 tasks · ~14h5File Operations,Serialization, and ContextManagers3 tasks · ~13h6Error Handling, Logging,and Testing with Pytest3 tasks · ~13h7Advanced Idioms:Generators, Iterators, andDecorators3 tasks · ~14h8Type Hinting and StaticAnalysis2 tasks · ~9h9Concurrency: Threads,Processes, and Asyncio2 tasks · ~10h10Packaging, Tooling, andCapstone Project3 tasks · ~17h
Solid arrow
Must be finished before the phase it points to
Dashed arrow
Same rule, but the prerequisite sits more than one stage back

Resources

14 in this plan's library, beyond the links on individual tasks.

Core Documentation and Books

Primary references, official documentation, and deep dives.

  • Fluent Python (2nd Edition)

    Use for an in-depth dive into idiomatic Python, covering data models, protocols, type hints, and modern concurrency.

    oreilly.com · O'Reilly Media · Book · $60–$80

  • Mypy Documentation

    Use to configure static analysis, strict verification flags, and gradual typing across your codebases.

    mypy.readthedocs.io · Mypy core development team · Documentation · Free

  • PEP 8 – Style Guide for Python Code

    Use as the foundational standard for consistent code formatting and naming conventions across the Python ecosystem.

    peps.python.org · Python Software Foundation · Style Guide · Free

  • pytest Documentation

    Use to master idiomatic Python testing conventions, fixture dependency injection, and test parametrization.

    docs.pytest.org · pytest development team · Documentation · Free

  • Python 3 Module of the Week (PyMOTW-3)

    Consult this library tour to see clear, practical code examples for standard library modules like itertools, collections, and functools.

    pymotw.com · Doug Hellmann · Reference Guide · Free · Intermediate

  • Python Distilled

    Use to understand Python runtime mechanics, function call frames, generators, and I/O abstractions without outdated patterns.

    pearson.com · Addison-Wesley Professional · Book · $30–$40

  • Python Packaging User Guide (PyPUG)

    Use to learn modern package structuring, pyproject.toml configuration, distribution building, and publishing.

    packaging.python.org · Python Packaging Authority (PyPA) · Documentation · Free

  • Python Testing with pytest, Second Edition

    A structured guide to mastering test parameterization, custom fixtures, mocking, and organizing test suites.

    pragprog.com · The Pragmatic Bookshelf · Book · ~$32 for ebook · Intermediate

  • Ruff Documentation

    Use to set up high-performance linting, automatic import sorting, and code formatting enforcing PEP 8.

    docs.astral.sh · Astral Software · Documentation · Free

  • The Python Data Model Reference

    Use to learn dunder methods and master how user-defined classes integrate directly with core Python syntax.

    docs.python.org · Python Software Foundation · Documentation · Free

  • The Python Discourse Forum (discuss.python.org)

    Use to participate in core language discussions, packaging standard evolutions, and PEP feedback with maintainers.

    discuss.python.org · Python Software Foundation · Community Forum · Free

  • The Python Tutorial

    Use as the authoritative introductory reference for core control flow, built-in sequences, mapping types, and standard library conventions.

    docs.python.org · Python Software Foundation · Documentation · Free

  • The Python typing Standard Library Documentation

    Use to implement static type hints, generic types, parameter specs, and structural subtyping protocols.

    Python Software Foundation · Documentation · Free

Community and Standards

Python enhancement proposals (PEPs) and community forums.

  • PEP 484 – Type Hints

    Read this PEP to understand the design philosophy, constraints, and intentions behind static type annotations in Python.

    peps.python.org · Python Software Foundation · Specification · Free · Intermediate