The use of Jupyter Notebook in teaching is common place, but not during exams. Exams should be constructively aligned with assignments. We tackle this problem by deploying a scalable and reconfigurable JupyterHub with nbgrader. We take into consideration the requirements for students, instructors and sysadmins and present our solutions for conducting exams for large groups of students.
We deploy JupyterHub on two different servers: a grading server that is used for managing assigments with nbgrader, serves as a NFS server for exchange and student home directories, and supports multiple classes and graders; and an exam server that runs on Kubernetes, deployed using Zero to JupyterHub (Z2JH), and is used by students during the exam. Our Kubernetes cluster runs locally on the OpenStack infrastructure of our department and is deployed using Kubespray.
Our setup comes with the following advantages:
Additonally to adapting the JupyterHub for exams, we also customize the Jupyter Notebook using nbextensions. On the student side we restrict the notebook to prevent students from deleting and adding cells or notebooks. A customizable IPython kernel is used to assure students can only use specific imports. To assert that the exam has not been tampered with after submission, we generate a hashcode of the notebook and let the students sign a sheet containing the hashcode.
For grading the exams we use nbgrader. To give instructors more options for questions, we added a multiple and single choice cell. This cell is based on a markdown cell and fully integrated into nbgrader. Another feature we add is a per question grading view and a way to export grades, release feedback to and import submissions from our LMS (Ilias).