Initialising a new project
- With uv (recommended)
- Manual setup
uv scaffolds a complete project in one command and is dramatically faster than pip for everything it does.uv init creates:pyproject.toml and uv.lock automatically — no manual editing needed.Managing multiple Python versions
Different projects often need different Python versions.uv handles this transparently:
uv writes the pinned version to .python-version. Commit this file so every contributor uses the same interpreter.
If you work with many Python versions regularly, pyenv is an alternative that works independently of uv.
Running scripts
Always run scripts from the project root directory using the-m flag. This guarantees that your package is on sys.path and that relative paths in your code resolve correctly.
If you double-click a
.py file or run python src/weather_analysis/main.py from the wrong directory, your imports will likely fail. The -m flag plus running from the project root is the single habit that prevents 90% of path errors.Adding a new feature — end-to-end workflow
Here is the workflow you will follow every time you add a new capability to your project:1
Create a new module
Add a new file for the feature’s logic. Keep it focused — one clear responsibility per file.
2
Write the functions and add a test
Create the corresponding test file immediately — not after everything is working.Run the tests:
3
Import the new module in main.py
Wire the new feature into your entry point once you are satisfied with the tests.
4
Update pyproject.toml if you added a dependency
If the new feature uses a third-party package, record it properly:Never assume a package is “already there”. Document every dependency you use.
Updating dependencies
- With uv
- With pip
Reading error tracebacks effectively
Python tracebacks look intimidating but follow a consistent pattern. Read them from the bottom up — the last line is the actual error, and the lines above it are the call stack that led there.- What is the error type? (
ZeroDivisionError,KeyError,TypeError…) - What is the error message? (often tells you exactly what went wrong)
- Which file and line number is at the bottom of the stack? (that is where to fix it)
- Work upward through the call stack to understand why the bad value arrived there
Debugging workflow
Quick debugging with print statements
For simple problems,print is fast and requires no setup:
print debugging before committing. Use the logging module for persistent diagnostic output instead:
VS Code debugger
For harder bugs, the VS Code debugger lets you pause execution and inspect any variable without modifying your code.1
Set a breakpoint
Click in the gutter (left of the line numbers) on the line where you want execution to pause. A red dot appears.
2
Start the debugger
Press F5, or open the Run & Debug panel (Ctrl+Shift+D / ⇧⌘D) and click Run and Debug. Choose Python File.
3
Inspect variables
When execution pauses at your breakpoint, hover over any variable to see its value, or expand the Variables panel on the left. Use the toolbar buttons to step over, step into, or continue.
.vscode/launch.json to configure the debugger for your project:
Keeping pyproject.toml tidy
Your pyproject.toml is the source of truth for your project. Keep it honest:
Weather Data Analysis Project
Apply everything you have learned by building a real weather analysis tool