MUSA Graderv0.1.0

MUSA 5500 · Geospatial Data Science in Python

MUSA Grader

Semi-automatic grading for Jupyter Notebook assignments. It automates what can be tested objectively, flags anything ambiguous, and keeps human review quick. Every deduction traces back to a deterministic test, a structural check, a notebook result or a person's decision.

The grader screens submissions. It does not set marks on its own.

The grader can clear a submission, but it never marks one down by itself. Any submission that comes back below full marks goes to a person, and the deduction stands only if that person agrees. The time saved comes from the submissions the grader clears. Where the grader is unsure, nobody relies on it.

What it does#

Three assignments, three ways to grade#

What the grader can check depends on the dataset. Each of the three assignments gives it a different situation:

Assignment 1: The Donut EffectAssignment 2: Exploratory VisualizationAssignment 3: Evictions and the NDVI
DatasetOne Zillow file, downloaded by each studentThe student's own choice, never handed inOne zip, distributed with the assignment
Answer key?No. Zillow revises the file monthlyNo. Every student uses a different datasetYes. Everyone runs the same five files
What is gradedWhether each step worked, checked against the student's own dataWhether the student can produce the required elementsWhether each result is correct
Evidence fromThe grading run's own executionThe outputs saved in the notebookBoth, combined

See Assignments for how each one is graded and where its 100 points go.

Student data#

  • Grading runs entirely on the instructor's or TA's machine. Submissions are never uploaded anywhere.
  • The Streamlit UI binds to localhost, and notebooks run in a Docker container with no network access.
  • Failure patterns are reproduced in tests/ with synthetic fixtures. No student file, name or identifier appears in the repository.
  • Optional LLM grading of written answers is off by default. When it is on, names, emails and ID numbers are redacted before any text leaves the machine.

Architecture at a glance#

Streamlit UI→GradingService→executor→assignment grader→rubric engine→results store

The UI contains no grading logic. It calls grader.service.GradingService and displays what comes back, and the CLI works the same way. You can drive the grader from your own Python code in a few lines:

from grader import GraderSettings, GradingService

service = GradingService.from_rubric_path(
    "rubrics/hw1.yaml",
    GraderSettings(shared_data_paths=["examples/data/zillow_zhvi.csv"]),
)
session = service.run(service.load_submissions("examples/submissions").candidates)
print(session.summary())