API reference · grader/notebook.py · 425 lines
grader.notebook
Static analysis of a student notebook (design.md §23, structural grading).
Everything here works without executing anything, so it still produces evidence when a notebook fails to run.
Summary
| Name | Kind | Description |
|---|---|---|
NotebookAnalysis | class | Static facts about a notebook. |
empty_analysis() | function | Placeholder used when no notebook was submitted at all. |
read_notebook() | function | |
analyze_notebook() | function | |
extract_markdown_responses() | function | Find the most substantial free-text markdown answer in the notebook. |
render_cells() | function | Flatten a notebook into a read-only structure for the UI (design.md §13). |
Constants
| Name | Value | Notes |
|---|---|---|
ABSOLUTE_PATH_RE | re.compile('(?P<quote>[\'"])(?P<path>(?:[A-Za-z]:[\\\\/]|/(?:Users|home|mnt|Volumes|var|tmp)/|~[\\\\/])[^\'"]{2,200})(?P=quote)') | /Users/..., C:\Users\..., ~/Desktop/... inside a string literal. |
DATA_SUFFIXES | ('.csv', '.tsv', '.json', '.geojson', '.xlsx', '.xls', '.parquet', '.shp', '.gpkg', '.tif', '.txt', '.zip', '.gz') | Any string literal that looks like a data file the notebook wants to open. |
READ_FUNCS | {'read_csv', 'read_excel', 'read_json', 'read_parquet', 'read_file', 'read_table', 'read_html', 'read_feather', 'read_stata'} | |
PLOT_HINTS | ('plt.', 'sns.', '.plot(', '.plot.', 'plotly', 'altair', 'alt.Chart', 'figure(', 'subplots(', 'hvplot') | |
IPYTHON_LINE_PREFIXES | ('%', '!', '?') | IPython syntax that is not Python. |
IMPORT_RE | re.compile('^[ \\t]*(?:from[ \\t]+([\\w.]+)[ \\t]+import\\b|import[ \\t]+([^\\n#]+))', re.M) | |
READ_CALL_RE | re.compile('\\b(read_(?:csv|excel|json|parquet|file|table|html|feather|stata))[ \\t]*\\([ \\t]*(?:[rRbBuUfF]*([\'\\"])([^\'\\"\\n]{1,300})\… | |
STRING_LITERAL_RE | re.compile('([\'\\"])([^\'\\"\\n]{1,300})\\1') | |
INSTRUCTION_RE | re.compile('\\b(in (?:a|one) (?:short |brief )?(?:paragraph|sentence)|describe|explain|discuss|interpret the|comment on|write (?:a|your)|an… | Phrasing that belongs to the assignment prompt rather than a student answer. |
Classes
Static facts about a notebook.
Fields
| Name | Type | Default | Notes |
|---|---|---|---|
path | str | required | |
valid | bool | True | |
parse_error | str | None | None | |
n_cells | int | 0 | |
n_code_cells | int | 0 | |
n_markdown_cells | int | 0 | |
code_source | str | '' | |
code_cells | list[str] | field(default_factory=list) | |
markdown_cells | list[str] | field(default_factory=list) | |
imports | set[str] | field(default_factory=set) | |
functions | list[dict[str, Any]] | field(default_factory=list) | |
absolute_paths | list[str] | field(default_factory=list) | |
read_calls | list[str] | field(default_factory=list) | |
referenced_files | list[str] | field(default_factory=list) | |
data_path_literals | list[str] | field(default_factory=list) | Every data-file-looking string literal, wherever it appears — students often assign the path to a variable before reading it. |
plot_calls | int | 0 | |
has_syntax_error | bool | False | |
unparsed_cells | list[int] | field(default_factory=list) | Cells that could not be parsed; the rest of the notebook is still analysed. |
stored_outputs | dict[str, int] | field(default_factory=dict) | |
stored_errors | list[dict[str, Any]] | field(default_factory=list) |
Methods
Functions
- empty_analysis(path: str = '') -> NotebookAnalysis #[source]
Placeholder used when no notebook was submitted at all.
- analyze_notebook(path: str | Path) -> NotebookAnalysis #[source]
No description.
- extract_markdown_responses(analysis: NotebookAnalysis, heading_hints: list[str] | None = None, min_words: int = 30) -> dict[str, Any] #[source]
Find the most substantial free-text markdown answer in the notebook.