Lab Reference Index
Labs are the hands-on portion of each session. Each lab has a tiny, specific objective. Labs are embedded in the session doc — this page is an index for quick lookup.
Labs are designed to be completed in under 20 minutes. The rest of the session is
spent reading, quizzing, and reviewing the commit.
Lab Objectives by Session
| # | Lab Objective | Files Touched | Status |
|---|---|---|---|
| 01 | Write a file that prints several values, stores them in well-named variables, and confirms their types with type(). | hello.py, docs/sessions/session-01/index.html |
Available |
| 02 | Practice arithmetic, string combination with f-strings, explicit conversions, and comparisons that produce booleans. | operators.py, docs/sessions/session-02/index.html |
Available |
| 03 | Write a series of conditionals classifying a country by population and region, combining and/or/not correctly. | conditionals.py, docs/sessions/session-03/index.html |
Available |
| 04 | Iterate over a list with a for loop, repeat with range(), write a while loop, and use break and continue meaningfully. | loops.py, docs/sessions/session-04/index.html |
Available |
| 05 | Create a single Python file that defines one country as a dictionary, reads its values two different ways, and prints the results. | country.py, docs/sessions/session-05/index.html |
Available |
| 06 | Store three countries as a list of dictionaries, iterate over it, and prove the mutating vs non-mutating distinction. | countries.py, docs/sessions/session-06/index.html |
Available |
| 07 | Rewrite loop-based transforms and filters from Session 06 as list comprehensions, and combine both in one line. | filters.py, docs/sessions/session-07/index.html |
Available |
| 08 | Write reusable functions for formatting and sorting countries, including one lambda used with sorted(). | functions_lab.py, docs/sessions/session-08/index.html |
Available |
| 09 | Practice unpacking, *rest collection, and write functions using *args and **kwargs, including spreading a dict into a call. | unpacking_lab.py, docs/sessions/session-09/index.html |
Available |
| 10 | Split your country data into its own module, import it two different ways, and add a __main__ guard. | country_data.py, explorer.py, docs/sessions/session-10/index.html |
Available |
| 11 | Write a safe country lookup function that handles missing keys and invalid input using try/except, else, and finally, plus a function that raises its own exception. | errors_lab.py, docs/sessions/session-11/index.html |
Available |
| 12 | Define an empty Country class, create two separate instances, and prove they are independent objects — no meaningful behavior yet. | country_class.py, docs/sessions/session-12/index.html |
Available |
| 13 | Give Country a real constructor with name, region, and population, create multiple independent instances, and prove attributes are mutable. | country_init.py, docs/sessions/session-13/index.html |
Available |
| 14 | Add a summary method and a mutating grow_population method to Country, then prove the dot-call is equivalent to calling through the class directly. | country_methods.py, docs/sessions/session-14/index.html |
Available |
| 15 | Rewrite Country construction to always use keyword arguments, add a default population, and demonstrate why reading global state is risky. | construction_lab.py, docs/sessions/session-15/index.html |
Available |
| 16 | Build a CountryExplorer class that composes a list of Country instances and offers collection-level operations by delegating to each one. | explorer_composed.py, docs/sessions/session-16/index.html |
Available |
| 17 | Add conditional logic to CountryExplorer that handles an empty collection gracefully, using truthy checks and a ternary expression. | conditional_lab.py, docs/sessions/session-17/index.html |
Available |
| 18 | Build a from_dict classmethod on Country, convert a batch of raw records with a comprehension, and gracefully skip a malformed one. | build_list_lab.py, docs/sessions/session-18/index.html |
Available |
| 19 | Prove the default identity-based equality, implement a custom __eq__, and demonstrate is None as the idiomatic check. | identity_lab.py, docs/sessions/session-19/index.html |
Available |
| 20 | Identify and annotate which attributes across the project so far are state versus fixed identity, and observe uncontrolled mutation firsthand. | state_concept.py, docs/sessions/session-20/index.html |
Available |
| 21 | Add set_population, set_capital, and add_country as controlled, validating state-change methods, replacing direct attribute assignment. | controlled_state.py, docs/sessions/session-21/index.html |
Available |
| 22 | Build an interactive text menu that reads and validates user input, then applies it through the controlled state methods from Session 21. | input_lab.py, docs/sessions/session-22/index.html |
Available |
| 23 | Add print-based and logging-based traces to set_population, plus an update counter, and observe both in action. | tracing_lab.py, docs/sessions/session-23/index.html |
Available |
| 24 | Build a shared validators module with thorough name and population validation, and wire it into the Session 22 menu. | validators.py, menu.py, docs/sessions/session-24/index.html |
Available |
| 25 | Demonstrate mutation vs reassignment across functions, then refactor scattered menu state into one owning class passed explicitly. | state_passing_lab.py, docs/sessions/session-25/index.html |
Available |
| 26 | Identify and eliminate redundant stored state in CountryExplorer by converting it to @property-based computed values. | computed_lab.py, docs/sessions/session-26/index.html |
Available |
| 27 | Write a mock country dataset with 10 records mirroring the eventual real API shape, and build the full explorer entirely offline from it. | mock_countries.py, explore_offline.py, docs/sessions/session-27/index.html |
Available |
| 28 | Build a CountryRepository wrapping the mock data from Session 27, and connect it to a CountryExplorer built entirely through the repository's interface. | repository_lab.py, docs/sessions/session-28/index.html |
Available |
| 29 | Write the mock data to a real JSON file, read it back with graceful error handling, and point CountryRepository at it. | json_lab.py, countries.json, docs/sessions/session-29/index.html |
Available |
| 30 | Convert Country to a dataclass, prove type hints are not enforced, and add explicit contract validation for raw records loaded from JSON. | contracts_lab.py, docs/sessions/session-30/index.html |
Available |
| 31 | Write plain assert-based checks (no pytest yet) for the highest-value, most logic-bearing parts of the project, and consciously identify what NOT to test. | manual_tests.py, docs/sessions/session-31/index.html |
Available |
| 32 | Set up a proper project structure with a tests/ directory, convert Session 31's manual tests to pytest, and run the suite. | country.py, tests/test_country.py, docs/sessions/session-32/index.html |
Available |
| 33 | Write a systematic test suite covering normal, edge, and boundary cases for find_by_region, from_dict, and set_population, using parametrization. | country.py, tests/test_return_values.py, docs/sessions/session-33/index.html |
Available |
| 34 | Add CountryExplorer to country.py, then test state changes using fixtures, before/after checks, and a multi-step sequence. | country.py, tests/test_state_changes.py, docs/sessions/session-34/index.html |
Available |
| 35 | Build a complete, isolated test suite for CountryRepository and validate_country_record using small, purpose-built fake datasets. | country.py, tests/test_repository.py, docs/sessions/session-35/index.html |
Available |
| 36 | Reorganize country.py into a country_explorer/ package with focused submodules, update all imports, and confirm the full test suite still passes. | country_explorer/__init__.py, country_explorer/models.py, country_explorer/repository.py, country_explorer/validators.py, country.py, tests/*.py, docs/sessions/session-36/index.html |
Available |
| 37 | Extract a shared, documented, tested format_population function, and identify (without necessarily extracting) a case of premature abstraction. | country_explorer/formatting.py, country_explorer/models.py, tests/test_formatting.py, docs/sessions/session-37/index.html |
Available |
| 38 | Build a thoroughly tested search.py utility module, and use it from both CountryExplorer and CountryRepository. | country_explorer/search.py, country_explorer/models.py, country_explorer/repository.py, tests/test_search.py, tests/test_search_integration.py, docs/sessions/session-38/index.html |
Available |
| 39 | Build the layered App / MenuSection / CountryExplorer structure, deliberately experience the deep-reference threading problem, and document it clearly. | prop_drilling_lab.py, docs/sessions/session-39/index.html |
Available |
| 40 | Write a real architecture review document covering at least two decisions (one resolved, one open), and confirm the full test suite still passes. | ARCHITECTURE.md, docs/sessions/session-40/index.html |
Available |
| 41 | Rebuild CountryRepository to read from a real file path using with, correct modes, and encoding-aware error handling, with zero changes to its existing methods. | file_io_lab.py, load_log.txt, docs/sessions/session-41/index.html |
Available |
| 42 | Call the real REST Countries API, adapt its shape to our contract, and construct a working CountryRepository from genuinely live data. | real_api_lab.py, docs/sessions/session-42/index.html |
Available |
| 43 | Build a fully robust country-loading function combining timeouts, specific exception handling, and explicit loading/success/error feedback. | robust_loading_lab.py, docs/sessions/session-43/index.html |
Available |
| 44 | Run the complete final test suite, trace the full architecture end to end in writing, and add a final whole-project retrospective to ARCHITECTURE.md. | capstone_trace.py, ARCHITECTURE.md, docs/sessions/session-44/index.html |
Available |
| 45 | Write a timing decorator and a validation decorator from scratch, applying both to functions from the Country Explorer project, using functools.wraps correctly. | decorators_lab.py, docs/sessions/session-45/index.html |
Available |
| 46 | Write a generator function for lazily processing countries, and a custom context manager for timing a block of code. | generators_lab.py, docs/sessions/session-46/index.html |
Available |
| 47 | Create a virtual environment for the Country Explorer project, install its real dependencies, and produce a requirements.txt that could recreate the setup on any machine. | env/, requirements.txt, docs/sessions/session-47/index.html |
Available |