Project 1 Starter Code

COMP 536 | Short Projects

Author

Anna Rosen

This page provides the starter scaffold for Project 1. Copy these files into your repo and fill in the implementations.

Quick Start

From your repo root:

python run.py test          # Run pytest
python run.py validate      # Run numerical checks
python run.py make-figures  # Generate plots

If those run cleanly, you’re most of the way to a good grade.

Repo Structure

project-1/
├── run.py                  # CLI entry point (required)
├── constants.py            # Physical constants (CGS)
├── zams.py                 # ZAMS L(M) and R(M) functions
├── star.py                 # Star class
├── stellar_population.py   # StellarPopulation class
├── astro_plot.py           # Plotting functions
├── tests/                  # Your pytest tests
├── outputs/
│   └── figures/            # Generated plots (not committed)
├── research_memo.pdf
├── growth_memo.pdf
├── README.md
└── requirements.txt

Docstring Convention

Use numpy-style docstrings for all functions and classes. See examples in the Python Fundamentals module.


run.py

"""COMP 536 Project 1 — Command-line interface.

This file dispatches to your implementation modules.
Keep it simple: real logic belongs in your modules, not here.
"""
import argparse
import subprocess
import sys
from pathlib import Path


def main():
    # ------------------------------------
    # 1. Set up argument parsing
    # ------------------------------------
    # argparse validates input and auto-generates --help
    parser = argparse.ArgumentParser(
        description="COMP 536 Project 1: ZAMS stellar models"
    )
    parser.add_argument(
        "command",
        choices=["test", "validate", "make-figures"],
        help="test | validate | make-figures"
    )
    args = parser.parse_args()

    # ------------------------------------
    # 2. Ensure output directories exist
    # ------------------------------------
    Path("outputs/figures").mkdir(parents=True, exist_ok=True)

    # ------------------------------------
    # 3. Dispatch to the appropriate action
    # ------------------------------------
    if args.command == "test":
        # Run pytest and exit with its return code
        sys.exit(subprocess.call(["pytest", "-v"]))

    elif args.command == "validate":
        # TODO: Import your modules and run validation checks
        # Example:
        #   from zams import luminosity, radius
        #   from star import Star
        #   ... check values against anchor points ...
        raise NotImplementedError("Implement your validation checks")

    elif args.command == "make-figures":
        # TODO: Import your plotting module and generate figures
        # Example:
        #   from astro_plot import plot_mass_luminosity, plot_hr_diagram
        #   plot_mass_luminosity("outputs/figures/luminosity_vs_mass.png")
        raise NotImplementedError("Implement your figure generation")


if __name__ == "__main__":
    main()

constants.py

"""Physical constants in CGS units.

Document each constant with units and source in your README.
"""

# --------------------------------------
# Solar reference values
# --------------------------------------
MSUN = None  # Solar mass [g]
RSUN = None  # Solar radius [cm]
LSUN = None  # Solar luminosity [erg/s]
TSUN = None  # Solar effective temperature [K]

# --------------------------------------
# Fundamental constants
# --------------------------------------
G = None        # Gravitational constant [cm^3 g^-1 s^-2]
SIGMA_SB = None # Stefan-Boltzmann constant [erg cm^-2 s^-1 K^-4]

# --------------------------------------
# Time conversions
# --------------------------------------
YEAR = None  # Seconds per year
MYR = None   # Seconds per megayear (10^6 yr)
GYR = None   # Seconds per gigayear (10^9 yr)

zams.py

"""ZAMS functions from Tout et al. (1996)."""

def luminosity(mass, Z=0.02):
    raise NotImplementedError

def radius(mass, Z=0.02):
    raise NotImplementedError

star.py

"""Star class for individual ZAMS stars."""
from zams import luminosity, radius

class Star:
    def __init__(self, mass, Z=0.02):
        raise NotImplementedError

stellar_population.py

"""StellarPopulation class for vectorized operations."""
from zams import luminosity, radius

class StellarPopulation:
    def __init__(self, masses, Z=0.02):
        raise NotImplementedError

astro_plot.py

"""Plotting functions for ZAMS stellar models."""
import matplotlib.pyplot as plt
import numpy as np

# Required functions (you design the signatures):
# - Mass-luminosity plot
# - Mass-radius plot
# - HR diagram (log L vs log T_eff, T inverted)
# - Timescales plot (2-panel: t_KH and t_MS vs mass)
# - Multi-Z versions of the above

tests/test_zams.py

"""Example test file — pytest discovers test_* functions automatically."""
import pytest

def test_example():
    # Replace with real tests
    assert True

What to Do Next

  1. Fill in constants.py with values from authoritative sources
  2. Implement luminosity() and radius() in zams.py using Tout et al. (1996)
  3. Build out Star and StellarPopulation classes
  4. Write tests as you go — run python run.py test often
  5. Run python run.py validate to check against anchor values
  6. Generate figures with python run.py make-figures

See the full assignment for requirements, equations, and grading rubric.