Cells¶
Solution stripping, marker validation, grading cell injection, and notebook post-processing.
mograder.grading.cells
¶
Notebook cell manipulation: marker validation, solution stripping, grading cell injection, and mark/feedback parsing.
validate_markers(lines, filepath)
¶
Check that all solution and hidden-test markers are properly paired.
Returns a list of error messages (empty if valid).
Source code in src/mograder/grading/cells.py
strip_solutions(lines)
¶
Remove solution blocks from source lines.
Lines between BEGIN SOLUTION / END SOLUTION are replaced with
# YOUR CODE HERE and pass at the correct indentation.
The pass ensures empty function bodies remain syntactically valid.
When a return statement after END SOLUTION references simple
variable names that are only defined inside the removed solution block,
sentinel assignments (name = ...) are inserted before the
placeholder so the return does not raise :class:NameError.
Source code in src/mograder/grading/cells.py
count_markers(lines)
¶
count_hidden_markers(lines)
¶
strip_hidden_tests(lines)
¶
Remove hidden test blocks from source lines.
Lines between BEGIN HIDDEN TESTS / END HIDDEN TESTS are replaced with
a single # HIDDEN TESTS placeholder comment at the correct indentation.
Source code in src/mograder/grading/cells.py
extract_hidden_tests(lines)
¶
Extract hidden test blocks as (indent, lines) tuples.
Each tuple contains the indentation prefix and the list of lines (with their original indentation) from one hidden-test block. Used during autograde to reinject hidden tests into submitted notebooks.
Source code in src/mograder/grading/cells.py
convert_markdown_cells(lines)
¶
Convert stripped markdown answer cells to editable mo.md() blocks.
After strip_solutions(), markdown answer cells look like::
response_text = "placeholder text"
# YOUR CODE HERE
pass
mo.md(response_text)
This function converts them to::
mo.md(r\"\"\"
placeholder text
\"\"\")
so that students see a clean editable markdown cell instead of ugly placeholder code.
Source code in src/mograder/grading/cells.py
build_submit_cell(server_url, assignment_name)
¶
Build a submit cell that uses mograder.remote.submit().
Returns source text for two marimo cells (username input + submit action).
Source code in src/mograder/grading/cells.py
process_file(source, output_dir, dry_run=False, validate_only=False, submit_url=None)
¶
Process a single notebook file. Returns True on success.
Source code in src/mograder/grading/cells.py
build_release_zip(release_dir)
¶
Create a zip of student-facing release files, excluding artifacts.
Returns None (and removes any stale zip) when the directory contains only a single file — a zip that wraps one file adds no value.
Uses a fixed timestamp so the zip is reproducible across runs.
Source code in src/mograder/grading/cells.py
extract_marking_scale(source_lines)
¶
Extract the Marking Scale admonition from a source notebook.
Looks for /// details | Marking Scale ... /// block in markdown cells.
Returns the markdown content (without the admonition wrapper), or None.
Source code in src/mograder/grading/cells.py
parse_marks_metadata(source_lines)
¶
Extract marks metadata from a notebook.
Reads _marks = {...} from the MARKS_MARKER cell. All question marks
(both auto-checked and manual) must be listed in this single dict.
Returns None if no MARKS_MARKER cell found.
Source code in src/mograder/grading/cells.py
parse_auto_marks(source_lines)
¶
Extract auto-scored marks from a verification cell with marks data.
Looks for _mograder_marks and _mograder_checks in the verification
cell and computes sum of marks for PASS checks. Supports both 4-tuple
format (label, status, earned_weight, total_weight) (fractional) and
legacy 2-tuple format (label, status) (binary).
Returns None if no marks data found in the verification cell.
Source code in src/mograder/grading/cells.py
has_grading_cells(source_lines)
¶
Detect if grading cells are already injected.
inject_grading_cells(source_lines, checks, cell_errors=0, marks=None, source_check_keys=None)
¶
Insert verification summary + marker feedback cells before if __name__.
Returns modified source lines. Idempotent: if grading cells already exist, returns the input unchanged.
When marks is provided, the verification cell includes a marks column
and the feedback cell is pre-configured for manual-only grading.
source_check_keys, if given, determines which marks-dict keys are
auto-graded (have a check() call in the source notebook). When omitted,
keys are inferred from the student's executed checks — which may be
incomplete if mo.stop guards prevented some checks from running.
Source code in src/mograder/grading/cells.py
parse_marker_feedback(source_lines)
¶
Extract _mark and _feedback from a graded notebook.
Looks for the MOGRADER: MARKER FEEDBACK marker and parses the variable assignments that follow it.
Returns (mark, feedback) where mark is None if not yet graded.
Source code in src/mograder/grading/cells.py
write_marker_feedback(file_path, mark, feedback)
¶
Write _mark and _feedback values into a graded notebook.
The file must contain a MOGRADER: MARKER FEEDBACK marker cell.
Always writes _feedback as a triple-quoted string.
Raises ValueError if the feedback marker is not found.