MUSA Graderv0.1.0

API reference · assignments/base.py · 297 lines

assignments.base

Assignment grader base class and registry.

An assignment module maps rubric ids to check methods. Every check receives the same context and returns one RubricItemResult carrying a score, a status, a confidence and the evidence behind it (design.md §24).

Summary

NameKindDescription
GradingContextclassEverything a check may look at.
AssignmentGraderclassBase grader: dispatches rubric ids to check_<rubric_id> methods.
register()functionClass decorator: register an AssignmentGrader subclass under its assignment_id.
get_grader()functionReturn the grader for a rubric, falling back to the generic base.
registered_assignments()function

Classes

class GradingContext #[source]

dataclass

Everything a check may look at.

Fields

NameTypeDefaultNotes
student_idstrrequired
rubricRubricrequired
analysisNotebookAnalysisrequired
executionExecutionRecordrequired
probedict[str, Any] | NoneNone
workdirPath | NoneNone
discovery_warningslist[str]field(default_factory=list)
qualitative_graderAny | NoneNone
settingsdict[str, Any]field(default_factory=dict)
cachedict[str, Any]field(default_factory=dict)Scratch space for work shared between checks on one submission — e.g. HW2 reads the executed notebook once and grades seven items from it.

Properties

property probe_ok: bool #[source]

No description.

class AssignmentGrader(rubric: Rubric) #[source]

Base grader: dispatches rubric ids to check_<rubric_id> methods.

Class attributes

NameTypeDefaultNotes
assignment_id'base'

Methods

probe_config() -> dict[str, Any] #[source]

Config handed to the in-kernel probe (hidden tests included).

hidden_test_specs() -> list[dict[str, Any]] #[source]

Only selectors and call inputs — expected values stay on the host.

Two call styles: scalar_args passes literal arguments, group_frame asks the probe to build a DataFrame from interpolated anchor points and pass that. Either way the container is told what to call the function with, never what it should return.

grade(ctx: GradingContext) -> list[RubricItemResult] #[source]

Run every rubric item's check_<id> method and return one result per item.

A missing check returns manual_review; a check that raises returns manual_review with confidence 0 and the error in its evidence, so a broken check never loses a submission.

result(item: RubricItem, score: float, status: str, confidence: float = 1.0, feedback: str = '', evidence: dict[str, Any] | None = None) -> RubricItemResult #[source]

Build a RubricItemResult, rounding the score to the rubric's score_rounding increment and clamping it to [0, points].

no_probe_result(item: RubricItem, ctx: GradingContext) -> RubricItemResult #[source]

Shared response when the kernel never reported its namespace.

Rubric checks 2

Each check_<rubric_id> method grades the rubric item with that id and returns one RubricItemResult.

check_unimplemented(ctx: GradingContext, item: RubricItem) -> RubricItemResult #[source]

No description.

check_notebook_execution(ctx: GradingContext, item: RubricItem) -> RubricItemResult #[source]

Shared execution check (design.md §19). Never an automatic zero.

Functions

register(cls: type[AssignmentGrader]) -> type[AssignmentGrader] #[source]

Class decorator: register an AssignmentGrader subclass under its assignment_id.

get_grader(rubric: Rubric) -> AssignmentGrader #[source]

Return the grader for a rubric, falling back to the generic base.

registered_assignments() -> list[str] #[source]

No description.