Your First Python Project
Project structure, your first script, and notebooks in a managed environment — every tool from this course, working together.
Module 8 · OverviewTwo parts
Part A — this deck
- A standard project layout:
src,data,notebooks,output,tests - Writing and running
hello.pywithuv run - Notebooks inside the managed environment
- How notebooks display output — with and without
print()
≈ 40 min, including a checkpoint exercise
Part B — next deck
- A taste of Python:
print(), arithmetic, NumPy, pandas - Charts with matplotlib and seaborn
- Exporting notebooks to HTML and PDF
- The final hands-on lab
≈ 90 min, including the lab
Companion notebook: module-08a-first-project.ipynb — worked examples and self-checking exercises.
The big pictureEverything you’ve built, working together
C:\actuarial_workModule 1
Modules 2–3
Module 4
Module 5
Module 6
Module 7
Today the tools fade into the background, and Python takes center stage.
Project Structure
A place for everything, and everything in its place.
StructureA standard layout
actuarial_intro\
├── .venv\ managed by uv — never touch
├── .vscode\ editor config (Module 7)
├── data\
│ └── raw\ inputs, read-only, not in Git
├── notebooks\ exploration & reports
├── output\ charts, exports — regenerable
├── src\ reusable Python code
├── tests\ checks that code is right
├── .gitignore
├── .python-version
├── pyproject.toml
├── README.md
└── uv.lock
| Folder | Rule of thumb |
|---|---|
data\raw | Never edited by hand or by code. The source of truth. |
src | Scripts and functions you trust and reuse |
notebooks | Numbered: 01_load.ipynb, 02_explore.ipynb… |
output | Anything code produces. Safe to delete and rebuild. |
tests | Automated checks (future courses) |
StructureWhy bother?
Raw data stays raw
You can always rerun from the original extract. No “which version of the CSV did I clean?”.
Code is separate from results
Delete output\, rerun, and get the same numbers. That’s reproducibility.
Others can find things
A colleague — or a reviewer — opens any project and knows where to look.
This is the same discipline as a well-built Excel model: separate input, calculation, and output tabs — enforced by folders instead of goodwill.
StructureCreating it
cd C:\actuarial_work
uv init actuarial_intro --python 3.12
cd actuarial_intro
mkproj . # your Module 3 script!
mkdir data\raw
No mkproj? Plain PowerShell does it too:
mkdir src, data\raw, notebooks, output, tests
Git doesn’t track empty folders. Drop an empty placeholder file in any folder you want to keep:
ni tests\.gitkeep, output\.gitkeep
uv init made a main.py at the top level. We’ll keep code in src\, so delete it: rm main.py
Your First Script
hello.py, run the uv way.
hello.pyWrite it, run it
In VS Code: right-click src → New File… → hello.py
"""hello.py — my first Python script."""
name = "Actuarial Student"
years_to_exam = 0.5
print(f"Hello, {name}!")
print("Weeks until exam:", years_to_exam * 52)
In the terminal (Ctrl+`), from the project root:
PS C:\actuarial_work\actuarial_intro> uv run python src/hello.py
Hello, Actuarial Student!
Weeks until exam: 26.0
Forward slash in src/hello.py — works on every OS (Module 1). The ▷ button in VS Code does the same, using the .venv interpreter.
hello.pyWhat just happened?
.venv matches uv.lock.venv starts"""…"""on line 1 is a docstring — a description of the filename = …creates a variable: a label attached to a valuef"…{name}…"is an f-string: values dropped into textprint()writes to the terminal
A script runs fresh, top to bottom, every time. That makes it predictable — the opposite of a notebook’s hidden state.
Notebooks in the Managed Environment
Two front-ends, one environment.
NotebooksScripts or notebooks?
Script (.py) | Notebook (.ipynb) | |
|---|---|---|
| Runs | Top to bottom, every time | Cell by cell, in any order |
| Best for | Repeatable jobs, reusable functions | Exploring data, explaining results |
| Output | Terminal text, files | Rich tables and charts, saved inline |
| In Git | Clean, readable diffs | JSON — noisier diffs |
| Lives in | src\ | notebooks\ |
Explore in a notebook; once something works, move it into a script.
NotebooksTwo ways to open one — same environment
Jupyter Lab in the browser
uv add --dev jupyterlab
uv run jupyter lab
Navigate to notebooks\ → New → Notebook.
VS Code
- Ctrl+Shift+P → Create: New Jupyter Notebook
- Select Kernel → Python Environments →
.venv - Save as
notebooks\01_hello.ipynb
Needs ipykernel in the environment — jupyterlab brings it along.
Either way, the kernel is the project’s .venv Python, so the notebook sees exactly the packages in uv.lock.
NotebooksGotcha: where is “here”?
Relative paths start from the current working directory (Module 1) — and it differs:
| Running… | CWD is… | Data path |
|---|---|---|
a script via uv run from the root | project root | data/raw/x.csv |
a notebook in notebooks\ | notebooks\ | ../data/raw/x.csv |
Check any time:
from pathlib import Path
Path.cwd()
# WindowsPath('C:/actuarial_work/actuarial_intro/notebooks')
A robust habit in notebooks:
DATA = Path("..") / "data" / "raw"
df = pd.read_csv(DATA / "policies.csv")
DisplayOutput with and without print()
- The last expression in a cell is displayed automatically, with an
Out[n]label print()output appears with noOutlabel — and works anywhere in the cell- Only the last bare expression shows — cell 3 hides
rate * 2 - An assignment (cell 4) displays nothing
And yes, 0.15000000000000002 — computers store decimals in binary. Round for display: round(rate * 3, 4).
DisplayRich display for tables and charts
| age | qx | |
|---|---|---|
| 0 | 30 | 0.0008 |
| 1 | 40 | 0.0016 |
| Want… | Use |
|---|---|
| A formatted table | End the cell with df |
| Several tables from one cell | display(df.head())display(df.describe()) |
| Plain text (as a script would print) | print(df) |
To hide an unwanted Out | End the line with ; |
display() is built into Jupyter — no import needed. In a .py script, only print() shows anything.
Checkpoint · 15 minScaffold, script, notebook
- Create
actuarial_introwithuv initand the standard folders - Write
src\hello.py; run it withuv run python src/hello.py uv add --dev jupyterlab; createnotebooks\01_hello.ipynbusing the.venvkernel- Reproduce the display examples: bare expression,
print(), two expressions in one cell, a semicolon - Print
Path.cwd()from both the notebook and the script. Explain the difference.
Keep this project — Part B builds on it, and the final lab commits it to Git.
Stretch: git init (if uv didn’t), extend .gitignore from Module 5, and make a first commit now.
A Taste of Python
Arithmetic, NumPy, pandas, and charts — then publish your notebook and commit the finished project.