NotebookGrader uses the same format as nbgrader, except that test cells have to begin with a comment with the following format (you can change the number of points and the description):

# Tests 10 points: Tests for something. ...

Here is a sample test.

The prefix # Tests *n* points has to appear exactly in that format, with *n* being the number of points of the tests cell.
The comment is useful to the students: it tells them how many points the cell is worth!

At this time, NotebookGrader supports the following Python modules:

array, base64, binascii, bisect, calendar, cmath, collections, copy, datetime, decimal, enum, fractions, functools, graphlib, hashlib, heapq, hmac, itertools, json, math, matplotlib, numbers, numpy, operator, pandas, PIL, pytorch, random, re, requests, scipy, secrets, statistics, string, struct, time, types, zipfile, zoneinfo

If you need additional modules, please contact info@notebookgrader.com.

Note: Modules cannot be imported in solution cells; they must be imported in read-ony or test cells. This prevents students from importing their own modules.

A notebook consists of four types of cells: markdown (text), read-only code, solution cells, and test cells.

Markdown cells contain text, and they are read-only, in the sense that during grading, their content is replaced with the content in the source notebook provided by the instructor. You can use markdown cells, among other things, to describe the problem to be solved.

A solution cell is a cell where students can write their solution to the problems. A cell is a solution cell if somewhere in it appears the string ### BEGIN SOLUTION.

Typically, a solution cells contains one or more regions delimitated by ### BEGIN SOLUTION and ### END SOLUTION; each of these regions is then replaced by a ### YOUR SOLUTION HERE line in the student's notebook. Note that solution cells cannot contain import statements. You will need to import any modules in other cells (read-only or test cells).

Example: if this is the cell in the source notebook:

def factorial(n): ### BEGIN SOLUTION return 1 if n < 2 else n * factorial(n - 1) ### END SOLUTION def fibonacci(n): ### BEGIN SOLUTION if n < 3: return 1 f1, f2 = 1, 1 for _ in range(n - 2): f1, f2 = f2, f1 + f2 return f2 ### END SOLUTION

The cell becomes, in the student notebook:

def factorial(n): ### YOUR SOLUTION HERE def fibonacci(n): ### YOUR SOLUTION HERE

Note that students can write their solution anywhere in the cell. This enables them to more easily define auxiliary functions.

A test cell is a cell that starts with the comment # Tests *n* Points, where *n* is the number of points a student receives if the execution of the cell raises no errors.
Test cells can contain both tests that are visible to students, and *hidden tests,* which are used during grading, but that are not included in the notebooks given to the students. Hidden tests are used to ensure the students don't hard-code the values expected by the tests. Hidden tests are included in regions delimited by ### BEGIN HIDDEN TESTS and ### END HIDDEN TESTS

# Tests 10 points: Fibonacci assert fibonacci(4) == 3 ### BEGIN HIDDEN TESTS assert fibonacci(15) == 610 ### END HIDDEN TESTS

Then the student's version of the notebook will contain the following two cells:

# Tests 10 points. assert fibonacci(4) == 3

where the hidden test is not present.

The Fibonacci name is used as the name of the test in reporting statistics.

Please look for the presence of the additional markdown cell in the student version of the notebook: its presence ensures that NotebookGrader has properly recognized the tests.

All other cells are read-only code cells. If students modify them, their modifications are discarded before grading.

Students can only write code in the solution cells. Any other cell modifications, and any cell insertions/deletions, are discarded. If a student modifies a notebook and deletes or reorders the original cells, the notebook cannot be graded, and the student will receive no credit for it.