Project 1 Studio:
Plan Before You Code

COMP 536 • In-class lab structure (Feb 2, 2026)

Dr. Anna Rosen

2026-02-02

The point of today

You are not “behind” if you haven’t coded yet.

You are behind if you don’t have a plan.

The point of today (continued)

Today’s goal is to produce a small plan you can implement with confidence:

  • a map of the repo you will build
  • pseudocode for the Star class and its derived quantities
  • a validation plan (python run.py validate)
  • a test plan (python run.py test)

Laptops open — but not for coding (yet)

You’ll need your laptop to read the assignment and the paper.

For the first half of class, your laptop is for:

  • the Project 1 page
  • the Tout et al. PDF
  • your notes

Not for writing Python.

Today’s focus: star.py (plus zams.py scaffolding)

Project 1 has a lot in it. If you try to do everything at once, you’ll end up with tangled code and no evidence.

Today we focus on the newest idea for many of you: a class with a clean contract.

Your goal is to be able to say:

“If I give Star(mass, Z), I know exactly what attributes exist, what units they have, and how I will validate them.”

The Commandments (translated for today)

We are practicing four habits:

  1. Think before you type: write the plan on paper first.
  2. Write down the contract: inputs, outputs, units, valid ranges.
  3. Assume your code is wrong: plan validation before implementation.
  4. Test requirements: write tests that check behavior, not “it runs”.

What is a spec?

A spec (specification) is the authoritative description of what your code must do.

For Project 1, your specs include:

  • the assignment page (the reproducibility contract, required functions, required figures)
  • the paper (equations, tables, valid ranges, and model assumptions)

If you can’t point to a line in a spec, you’re guessing.

Must-haves (realistic for today)

By the end of class, you must have:

  1. A written contract and pseudocode for Star
  2. A written plan for zams.luminosity() and zams.radius() (signatures + input checks + where coefficients will live; solar \(Z\) / column 1 first)

These two are the non-negotiables.

Timeline (75 minutes, with checkpoints)

0–15: Slide walkthrough (what we’re doing and why)

15–35: star.py planning (contract + pseudocode + failure modes)

35–55: zams.py planning (equations + coefficient locations; solar \(Z\) / column 1 first)

55–65: Validation + tests plan (3 validation checks + 2 “first tests”)

65–75: Finalize your worksheet + checkoff

Checkpoints (I will come around)

Today, the work product is your plan quality.

When I stop by, be ready to show me:

  1. Where the spec lives (equation # / table # / valid ranges)
  2. Your Star contract (inputs/outputs/units + 3 failure modes)
  3. Your Star pseudocode (including derived quantities)

If you can’t show these, you haven’t started yet — even if you already wrote code.

End-of-class checkoff

  • In the last 10 minutes, I will check off your planning sheet.

  • I’m not grading you on “how much code you wrote today.”

  • I’m checking that you have a plan that can actually guide correct implementation.

“Solar \(Z\) first” (column 1 mindset)

Start with \(Z = 0.02\) (solar). In the Tout fits this is the simplest path:

  • it reduces the metallicity-dependent coefficient polynomials to their first column at \(Z = Z_\odot\)
  • it makes debugging much easier because you can validate anchors immediately

Then, once solar passes, add the full \(Z\) dependence.

Pseudocode is not busywork

Pseudocode is how you catch misunderstandings early:

  • where do you check valid mass ranges?
  • what is the log base?
  • what is the return shape for arrays?
  • what happens at piecewise boundaries?

If you can’t write pseudocode, you’re not ready to code.

Write a trace

… when something feels “mysterious”

A trace is a written step-by-step record of how one specific input produces an output.

Use a trace when you suspect a transcription or interpretation error. For example:

  • pick one input (like \(M = 1.0\), \(Z = 0.02\))
  • write the intermediate values you compute (not just the final answer)
  • compare each step against your formulas and units

Good traces for today

  • A Star trace: compute \(T_\mathrm{eff}\), then \(t_\mathrm{MS}\), then \(t_\mathrm{KH}\) for one mass
  • A zams trace (optional): compute one numerator/denominator term at a time for one mass

Traces make “paper \(\to\) code” bugs visible and implementation straightforward.

When you get stuck

Stop typing. Say this out loud:

“I think the bug is because , and I expect to see if I check ___.”

Then run one targeted check.

That is debugging.

Why we’re doing this

  • “Specs-first” means you write down what correct means before you code (equations, tables, valid ranges, and the run.py contract).

  • This prevents the classic failure mode: lots of code quickly, then you discover a hidden assumption was wrong (units, \(\log_{10}\), piecewise ranges).

  • Specs-first forces clean structure: one source of truth, no duplicated formulas/constants, and modules you can actually test.

  • It also makes grading fair: I can run it, audit it, and see evidence (validation + tests), not just output that “looks plausible.”