Application #4: nbgrader

A tool for creating and grading assignments in Jupyter notebooks

Notebooks are perfect for weaving together instructions, coding exercises, plotting exercises, written responses, etc.

Notebooks are perfect for weaving together instructions, coding exercises, plotting exercises, written responses, etc.

But challenging to use:

  • Maintaining separate instructor and student versions
  • Autograding & manual grading
  • Adding comments & feedback

nbgrader: a tool for creating and grading assignments in Jupyter notebooks

nbgrader: a tool for creating and grading assignments in Jupyter notebooks

{ "nbgrader": { "grade": false, # this is not a test cell "locked": false, # this cell should be editable "solution": true, # this cell will contain a # student's solution "grade_id": "squares", # the name of the cell "schema_version": 1 # the metadata version }, "collapsed": true, "trusted": true }

nbgrader assign

  • Clear the instructor solutions (ClearSolutions preprocessor)
  • Make test cells uneditable (LockCells preprocessor)
  • Clear cell output (ClearOutput preprocessor)
  • ... etc. ...

Instructor Version


In [ ]:
def squares(n):
    """Compute the squares of numbers from 1 to n, such that the 
    ith element of the returned list equals i^2.
    
    """
    ### BEGIN SOLUTION
    if n < 1:
        raise ValueError("n must be greater than or equal to 1")
    return [i ** 2 for i in range(1, n + 1)]
    ### END SOLUTION

Student Version


In [ ]:
def squares(n):
    """Compute the squares of numbers from 1 to n, such that the 
    ith element of the returned list equals i^2.
    
    """
    # YOUR CODE HERE
    raise NotImplementedError()

In [4]:
%%bash

cd course101
nbgrader assign ps1 --force --create --debug


[AssignApp | DEBUG] Searching ['/Users/jhamrick/Dropbox/presentations/2017.08.25-jupytercon/jess/course101', '/Users/jhamrick/.jupyter', '/Users/jhamrick/miniconda3/envs/jupytercon/etc/jupyter', '/usr/local/etc/jupyter', '/etc/jupyter'] for config files
[AssignApp | DEBUG] Looking for jupyter_config in /etc/jupyter
[AssignApp | DEBUG] Looking for jupyter_config in /usr/local/etc/jupyter
[AssignApp | DEBUG] Looking for jupyter_config in /Users/jhamrick/miniconda3/envs/jupytercon/etc/jupyter
[AssignApp | DEBUG] Looking for jupyter_config in /Users/jhamrick/.jupyter
[AssignApp | DEBUG] Looking for jupyter_config in /Users/jhamrick/Dropbox/presentations/2017.08.25-jupytercon/jess/course101
[AssignApp | DEBUG] Looking for nbgrader_config in /etc/jupyter
[AssignApp | DEBUG] Looking for nbgrader_config in /usr/local/etc/jupyter
[AssignApp | DEBUG] Looking for nbgrader_config in /Users/jhamrick/miniconda3/envs/jupytercon/etc/jupyter
[AssignApp | DEBUG] Looking for nbgrader_config in /Users/jhamrick/.jupyter
[AssignApp | DEBUG] Looking for nbgrader_config in /Users/jhamrick/Dropbox/presentations/2017.08.25-jupytercon/jess/course101
[AssignApp | DEBUG] Loaded config file: /Users/jhamrick/Dropbox/presentations/2017.08.25-jupytercon/jess/course101/nbgrader_config.py
[AssignApp | DEBUG] Looking for nbgrader_config in /Users/jhamrick/Dropbox/presentations/2017.08.25-jupytercon/jess/course101
[AssignApp | DEBUG] Loaded config file: /Users/jhamrick/Dropbox/presentations/2017.08.25-jupytercon/jess/course101/nbgrader_config.py
[AssignApp | WARNING] Removing existing assignment: /Users/jhamrick/Dropbox/presentations/2017.08.25-jupytercon/jess/course101/release/ps1
[AssignApp | INFO] Updating/creating assignment 'ps1': {}
[AssignApp | INFO] Converting notebook /Users/jhamrick/Dropbox/presentations/2017.08.25-jupytercon/jess/course101/source/./ps1/problem1.ipynb
[AssignApp | DEBUG] Student: .
[AssignApp | DEBUG] Assignment: ps1
[AssignApp | DEBUG] Notebook: problem1
[AssignApp | DEBUG] Applying preprocessor: IncludeHeaderFooter
[AssignApp | DEBUG] Applying preprocessor: LockCells
[AssignApp | DEBUG] Applying preprocessor: ClearSolutions
[AssignApp | DEBUG] Applying preprocessor: ClearOutput
[AssignApp | DEBUG] Applying preprocessor: CheckCellMetadata
[AssignApp | DEBUG] Applying preprocessor: ComputeChecksums
[AssignApp | DEBUG] Checksum for 'match' is 19f7bfd22d168d3ca40f43b29937860b
[AssignApp | DEBUG] Checksum for 'test_match' is 32177cdb2bd9bcbf40ae05256c0d55fc
[AssignApp | DEBUG] Checksum for 'forward_chain' is ecba59778d96bec84de551d0cf471f82
[AssignApp | DEBUG] Checksum for 'forward_chain_uses_match' is f2ee5a4cf02dd6ae2a9a6ac8f9102671
[AssignApp | DEBUG] Checksum for 'forward_chain_immutable_belief' is 93d43b09acc10499d9a0be24fc434272
[AssignApp | DEBUG] Checksum for 'test_forward_chain' is 82941fc7253fec4c6be9352de7eee17b
[AssignApp | DEBUG] Checksum for 'explain_rules_1' is fad8963e2894e8732648dbe5d399a00e
[AssignApp | DEBUG] Checksum for 'explain_rules_2' is 3fc18f7153981514905b5c6800277ad5
[AssignApp | DEBUG] Checksum for 'explain_rules_3' is 6d5ec2c0951d009f57a984741a457f2b
[AssignApp | DEBUG] Checksum for 'explain_limits' is f9854aba01986aefcc8c82d34b9e49db
[AssignApp | DEBUG] Applying preprocessor: SaveCells
[AssignApp | DEBUG] Removing existing notebook 'problem1' from the database
[AssignApp | DEBUG] Creating notebook 'problem1' in the database
[AssignApp | DEBUG] Notebook kernelspec: {'display_name': 'Python 3', 'language': 'python', 'name': 'python3'}
[AssignApp | DEBUG] Recorded grade cell GradeCell<ps1/problem1/test_match> into the gradebook
[AssignApp | DEBUG] Recorded grade cell GradeCell<ps1/problem1/forward_chain_uses_match> into the gradebook
[AssignApp | DEBUG] Recorded grade cell GradeCell<ps1/problem1/forward_chain_immutable_belief> into the gradebook
[AssignApp | DEBUG] Recorded grade cell GradeCell<ps1/problem1/test_forward_chain> into the gradebook
[AssignApp | DEBUG] Recorded grade cell GradeCell<ps1/problem1/explain_rules_1> into the gradebook
[AssignApp | DEBUG] Recorded grade cell GradeCell<ps1/problem1/explain_rules_2> into the gradebook
[AssignApp | DEBUG] Recorded grade cell GradeCell<ps1/problem1/explain_rules_3> into the gradebook
[AssignApp | DEBUG] Recorded grade cell GradeCell<ps1/problem1/explain_limits> into the gradebook
[AssignApp | DEBUG] Recorded solution cell Notebook<ps1/problem1>/match into the gradebook
[AssignApp | DEBUG] Recorded solution cell Notebook<ps1/problem1>/forward_chain into the gradebook
[AssignApp | DEBUG] Recorded solution cell Notebook<ps1/problem1>/explain_rules_1 into the gradebook
[AssignApp | DEBUG] Recorded solution cell Notebook<ps1/problem1>/explain_rules_2 into the gradebook
[AssignApp | DEBUG] Recorded solution cell Notebook<ps1/problem1>/explain_rules_3 into the gradebook
[AssignApp | DEBUG] Recorded solution cell Notebook<ps1/problem1>/explain_limits into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/print_rules> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/match> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/test_match> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/forward_chain> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/forward_chain_uses_match> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/forward_chain_immutable_belief> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/test_forward_chain> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/rules_1> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/belief_1> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/explain_rules_1> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/rules_2> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/belief_2> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/explain_rules_2> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/belief_3> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/explain_rules_3> into the gradebook
[AssignApp | DEBUG] Recorded source cell SolutionCell<ps1/problem1/explain_limits> into the gradebook
[AssignApp | DEBUG] Applying preprocessor: ClearHiddenTests
[AssignApp | DEBUG] Applying preprocessor: ComputeChecksums
[AssignApp | DEBUG] Checksum for 'match' is 19f7bfd22d168d3ca40f43b29937860b
[AssignApp | DEBUG] Checksum for 'test_match' is 32177cdb2bd9bcbf40ae05256c0d55fc
[AssignApp | DEBUG] Checksum for 'forward_chain' is ecba59778d96bec84de551d0cf471f82
[AssignApp | DEBUG] Checksum for 'forward_chain_uses_match' is f2ee5a4cf02dd6ae2a9a6ac8f9102671
[AssignApp | DEBUG] Checksum for 'forward_chain_immutable_belief' is 93d43b09acc10499d9a0be24fc434272
[AssignApp | DEBUG] Checksum for 'test_forward_chain' is 82941fc7253fec4c6be9352de7eee17b
[AssignApp | DEBUG] Checksum for 'explain_rules_1' is fad8963e2894e8732648dbe5d399a00e
[AssignApp | DEBUG] Checksum for 'explain_rules_2' is 3fc18f7153981514905b5c6800277ad5
[AssignApp | DEBUG] Checksum for 'explain_rules_3' is 6d5ec2c0951d009f57a984741a457f2b
[AssignApp | DEBUG] Checksum for 'explain_limits' is f9854aba01986aefcc8c82d34b9e49db
[AssignApp | DEBUG] Applying preprocessor: CheckCellMetadata
[AssignApp | INFO] Writing 23725 bytes to /Users/jhamrick/Dropbox/presentations/2017.08.25-jupytercon/jess/course101/release/./ps1/problem1.ipynb
[AssignApp | INFO] Setting destination file permissions to 644

Other nbgrader functionality

  • nbgrader autograde
  • Formgrader extension
  • nbgrader feedback