Level 3 / Project 01 - Package Layout Starter¶
Home: README
Try in Browser: Practice similar concepts online — browser exercises cover Level 2 topics
Before You Start¶
Recall these prerequisites before diving in:
- Can you use try/except to handle a FileNotFoundError?
- Can you import a function from another file? (from mymodule import my_function)
- Can you use pathlib.Path to check if a path is a file or directory?
Estimated time: 30 minutes
Learn Your Way¶
| Read | Build | Watch | Test | Review | Visualize | Try |
|---|---|---|---|---|---|---|
| — | This project | — | — | Flashcards | — | Browser |
Focus¶
- project layout and import boundaries
Why this project exists¶
This project gives you level-appropriate practice in a realistic operations context. Goal: run the baseline, alter behavior, break one assumption, recover safely, and explain the fix.
Run (copy/paste)¶
Use <repo-root> as the folder containing this repository's README.md.
cd <repo-root>/projects/level-3/01-package-layout-starter
python project.py scan .
python project.py validate .
python project.py init .
pytest -q
Expected terminal output¶
Expected artifacts¶
- Package info JSON on stdout
- Passing tests
- Updated
notes.md
Worked Example¶
Here is a similar (but different) problem, solved step by step.
Problem: Write a function that scans a directory and returns a summary of file types.
Step 1: Use pathlib to iterate files.
from pathlib import Path
from collections import Counter
def scan_file_types(directory):
path = Path(directory)
if not path.is_dir():
raise ValueError(f"Not a directory: {directory}")
extensions = Counter()
for item in path.rglob("*"):
if item.is_file():
ext = item.suffix or "(no extension)"
extensions[ext] += 1
return dict(extensions.most_common())
Step 2: Think about the structure. scan_file_types("my_project") returns {".py": 12, ".md": 3, ".txt": 1}.
Step 3: Think about edge cases. Empty directory returns {}. Non-existent directory should raise an error, not silently return empty.
The thought process: Validate input first (is it a directory?). Use pathlib for cross-platform path handling. Use Counter for counting. This is the same approach the package layout scanner uses.
Design First¶
Before writing code, sketch your approach in notes.md:
- What functions or classes do you need?
- What data structures will you use?
- What's the flow from input to output?
- What could go wrong?
Checkpoint: Baseline code runs and all tests pass. Commit your work before continuing.
Alter it (required) — Extension¶
- Try adding support for nested packages — what flag or argument would make sense?
- What other metadata could the scanner generate beyond what it already does?
- Add a useful metric to the report output.
Break it (required) — Core¶
- Try pointing the scanner at something unexpected — what breaks first?
- Can you create a situation where imports get confused?
- What happens when the input is not what the tool expects?
Fix it (required) — Core¶
- Add input validation for the most obvious failure case you found.
- Improve how the tool handles the import issue you discovered.
- Make the tool resilient to permission problems.
Checkpoint: All modifications done, tests still pass. Good time to review your changes.
Explain it (teach-back)¶
- What makes a directory a Python package (hint:
__init__.py)? - What is
__all__and how does it controlfrom package import *? - Why use
@dataclassinstead of writing__init__manually? - What is the difference between a module and a package?
Mastery check¶
You can move on when you can:
- create a Python package from scratch with proper structure,
- explain what __init__.py does and when it is optional (Python 3.3+),
- describe how from package import module resolves the import,
- use dataclasses for structured data instead of plain dicts.
Related Concepts¶
Stuck? Ask AI¶
If you are stuck after trying for 20 minutes, use one of these prompts:
- "I am working on Package Layout Starter. I got this error: [paste error]. Can you explain what this error means without giving me the fix?"
- "I am confused about the difference between a Python module and a package. Can you explain with a simple directory structure example?"
- "Can you explain what
__init__.pydoes and why Python packages need it?"
| ← Prev | Home | Next → |
|---|---|---|