diff --git a/.gitignore b/.gitignore index 8f871d63b..c3d906390 100644 --- a/.gitignore +++ b/.gitignore @@ -79,10 +79,8 @@ nbgrader/docs/source/user_guide/students.csv nbgrader/docs/source/user_guide/assignments.csv nbgrader/docs/source/command_line_tools/nbgrader*.rst nbgrader/docs/source/configuration/config_options.rst -nbgrader/docs/source/user_guide/creating_and_grading_assignments_jlab.rst -nbgrader/docs/source/user_guide/creating_and_grading_assignments_nb.rst -nbgrader/docs/source/user_guide/managing_assignment_files_jlab.rst -nbgrader/docs/source/user_guide/managing_assignment_files_nb.rst +nbgrader/docs/source/user_guide/creating_and_grading_assignments.rst +nbgrader/docs/source/user_guide/managing_assignment_files.rst nbgrader/docs/source/user_guide/managing_assignment_files_manually.rst nbgrader/docs/source/user_guide/managing_the_database.rst nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem1.html diff --git a/README.md b/README.md index c4cf49ea0..8dc8a89b2 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ A system for assigning and grading Jupyter notebooks. The nbgrader toolbar extension for Jupyter notebooks guides the instructor through assignment and grading tasks using the familiar Jupyter notebook interface. -![Creating assignment](nbgrader/docs/source/user_guide/images/classic_notebook/creating_assignment.gif "Creating assignment") +![Creating assignment](nbgrader/docs/source/user_guide/images/creating_assignment.gif "Creating assignment") ### Instructor "formgrader" extension for Jupyter notebooks @@ -24,13 +24,13 @@ the core functionality of nbgrader---generating the student version of an assignment, releasing assignments to students, collecting assignments, autograding submissions, and manually grading submissions. -![Formgrader extension](nbgrader/docs/source/user_guide/images/classic_notebook/formgrader.gif "Formgrader extension") +![Formgrader extension](nbgrader/docs/source/user_guide/images/formgrader.gif "Formgrader extension") ### Student assignment list extension for Jupyter notebooks Using the assignment list extension, students may conveniently view, fetch, submit, and validate their assignments. -![nbgrader assignment list](nbgrader/docs/source/user_guide/images/classic_notebook/student_assignment.gif "nbgrader assignment list") +![nbgrader assignment list](nbgrader/docs/source/user_guide/images/student_assignment.gif "nbgrader assignment list") ### The command line tools of nbgrader diff --git a/nbgrader/docs/source/configuration/jupyterhub_config.rst b/nbgrader/docs/source/configuration/jupyterhub_config.rst index 2aa240b50..f87349b0f 100644 --- a/nbgrader/docs/source/configuration/jupyterhub_config.rst +++ b/nbgrader/docs/source/configuration/jupyterhub_config.rst @@ -3,10 +3,10 @@ Using nbgrader with JupyterHub .. seealso:: - :doc:`/user_guide/creating_and_grading_assignments_jlab` + :doc:`/user_guide/creating_and_grading_assignments` Documentation for ``nbgrader generate_assignment``, ``nbgrader autograde``, ``nbgrader formgrade``, and ``nbgrader generate_feedback``. - :doc:`/user_guide/managing_assignment_files_jlab` + :doc:`/user_guide/managing_assignment_files` Documentation for ``nbgrader release_assignment``, ``nbgrader fetch_assignment``, ``nbgrader submit``, and ``nbgrader collect``. :doc:`nbgrader_config` @@ -26,9 +26,9 @@ the same system. By integrating with JupyterHub, nbgrader streamlines the process of releasing and collecting assignments for the instructor and of fetching and submitting assignments for the student. In addition to using the ``nbgrader release_assignment``, ``nbgrader fetch_assignment``, ``nbgrader submit``, and ``nbgrader -collect`` commands (see :doc:`/user_guide/managing_assignment_files_jlab`) with a +collect`` commands (see :doc:`/user_guide/managing_assignment_files`) with a shared server setup like JupyterHub, the formgrader (see -:doc:`/user_guide/creating_and_grading_assignments_jlab`) can be configured to +:doc:`/user_guide/creating_and_grading_assignments`) can be configured to integrate with JupyterHub so that all grading can occur on the same server. .. warning:: diff --git a/nbgrader/docs/source/configuration/student_version.rst b/nbgrader/docs/source/configuration/student_version.rst index 8769158d8..77777c5a4 100644 --- a/nbgrader/docs/source/configuration/student_version.rst +++ b/nbgrader/docs/source/configuration/student_version.rst @@ -3,7 +3,7 @@ Customizing how the student version of an assignment looks .. seealso:: - :doc:`/user_guide/creating_and_grading_assignments_jlab` + :doc:`/user_guide/creating_and_grading_assignments` Documentation for ``nbgrader generate_assignment``, ``nbgrader autograde``, and ``nbgrader generate_feedback``. :doc:`/command_line_tools/nbgrader-generate-assignment` diff --git a/nbgrader/docs/source/contributor_guide/installation_developer.rst b/nbgrader/docs/source/contributor_guide/installation_developer.rst index d2cc89366..09bc7cd38 100644 --- a/nbgrader/docs/source/contributor_guide/installation_developer.rst +++ b/nbgrader/docs/source/contributor_guide/installation_developer.rst @@ -46,31 +46,3 @@ To install labextensions run:: or in developer mode:: jupyter labextension develop --overwrite . - -Installing classic notebook extensions --------------------------------------- -Previously this was done using the ``nbgrader extension install`` command. -However, moving forward this is done using the ``jupyter nbextension`` and -``jupyter serverextension`` commands. - -The nbextensions are Javascript/HTML/CSS so they require -separate installation and enabling. -The --symlink option is recommended since it updates the extensions -whenever you update the nbgrader repository. -The serverextension is a Python module inside nbgrader, so only an -enable step is needed. -To install and enable all the frontend nbextensions (*assignment list*, -*create assignment*, and *formgrader*) along with the server extensions -(*assignment list* and *formgrader*) run:: - - jupyter nbextension install --symlink --sys-prefix --py nbgrader - jupyter nbextension enable --sys-prefix --py nbgrader - jupyter serverextension enable --sys-prefix --py nbgrader - -To work properly, the *assignment list* and *formgrader* extensions require -both the nbextension and serverextension. The *create assignment* extension -only has an nbextension part. - -Installing Firefox Headless WebDriver -------------------------------------- -To run tests on nbextensions while developing nbgrader and its documentation, the Firefox headless webdriver must be installed. Please `follow the Mozilla installation instructions `_ to get Firefox properly setup on your system. diff --git a/nbgrader/docs/source/contributor_guide/testing.rst b/nbgrader/docs/source/contributor_guide/testing.rst index b75c8a98a..46acbe1f8 100644 --- a/nbgrader/docs/source/contributor_guide/testing.rst +++ b/nbgrader/docs/source/contributor_guide/testing.rst @@ -27,6 +27,9 @@ To run a selective group of tests you can use one of the following commands: | ``python tasks.py tests --group=nbextensions`` | Run tests only for the notebook | | | extensions | +------------------------------------------------+------------------------------------+ +| ``python tasks.py tests --group=labextensions``| Run tests only for the jupyter lab | +| | extensions | ++------------------------------------------------+------------------------------------+ | ``python tasks.py tests --group=docs`` | Build the docs | +------------------------------------------------+------------------------------------+ | ``python tasks.py tests --group=all`` | Same as ``python tasks.py tests`` | diff --git a/nbgrader/docs/source/index.rst b/nbgrader/docs/source/index.rst index 001f581ca..43a041bb5 100644 --- a/nbgrader/docs/source/index.rst +++ b/nbgrader/docs/source/index.rst @@ -18,11 +18,9 @@ For additional resources on using Jupyter in educational contexts, see the `jupy user_guide/highlights user_guide/philosophy - user_guide/creating_and_grading_assignments_jlab - user_guide/creating_and_grading_assignments_nb + user_guide/creating_and_grading_assignments user_guide/managing_the_database - user_guide/managing_assignment_files_jlab - user_guide/managing_assignment_files_nb + user_guide/managing_assignment_files user_guide/managing_assignment_files_manually user_guide/autograding_resources user_guide/faq diff --git a/nbgrader/docs/source/user_guide/advanced.rst b/nbgrader/docs/source/user_guide/advanced.rst index 692e901d9..fbd3b1ca1 100644 --- a/nbgrader/docs/source/user_guide/advanced.rst +++ b/nbgrader/docs/source/user_guide/advanced.rst @@ -21,7 +21,7 @@ Advanced "Assignment List" installation :doc:`installation` General installation instructions. - :doc:`managing_assignment_files_jlab` + :doc:`managing_assignment_files` Details on fetching and submitting assignments using the "Assignment List" plugin. diff --git a/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem1.ipynb b/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem1.ipynb index 3c83c6cb6..19b0e6ec1 100644 --- a/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem1.ipynb +++ b/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem1.ipynb @@ -136,7 +136,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;34m\"\"\"Check that squares returns the correct output for several inputs\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32massert\u001b[0m \u001b[0msquares\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;32massert\u001b[0m \u001b[0msquares\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32massert\u001b[0m \u001b[0msquares\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m9\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m16\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m25\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m36\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m49\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m64\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m81\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32massert\u001b[0m \u001b[0msquares\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m11\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m9\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m16\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m25\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m36\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m49\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m64\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m81\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m121\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "Input \u001b[0;32mIn [4]\u001b[0m, in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;124;03m\"\"\"Check that squares returns the correct output for several inputs\"\"\"\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m squares(\u001b[38;5;241m1\u001b[39m) \u001b[38;5;241m==\u001b[39m [\u001b[38;5;241m1\u001b[39m]\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m squares(\u001b[38;5;241m2\u001b[39m) \u001b[38;5;241m==\u001b[39m [\u001b[38;5;241m1\u001b[39m, \u001b[38;5;241m4\u001b[39m]\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m squares(\u001b[38;5;241m10\u001b[39m) \u001b[38;5;241m==\u001b[39m [\u001b[38;5;241m1\u001b[39m, \u001b[38;5;241m4\u001b[39m, \u001b[38;5;241m9\u001b[39m, \u001b[38;5;241m16\u001b[39m, \u001b[38;5;241m25\u001b[39m, \u001b[38;5;241m36\u001b[39m, \u001b[38;5;241m49\u001b[39m, \u001b[38;5;241m64\u001b[39m, \u001b[38;5;241m81\u001b[39m, \u001b[38;5;241m100\u001b[39m]\n", "\u001b[0;31mAssertionError\u001b[0m: " ] } @@ -274,7 +274,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;34m\"\"\"Check that sum_of_squares returns the correct answer for various inputs.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32massert\u001b[0m \u001b[0msum_of_squares\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;32massert\u001b[0m \u001b[0msum_of_squares\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32massert\u001b[0m \u001b[0msum_of_squares\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m385\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32massert\u001b[0m \u001b[0msum_of_squares\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m11\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m506\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "Input \u001b[0;32mIn [8]\u001b[0m, in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;124;03m\"\"\"Check that sum_of_squares returns the correct answer for various inputs.\"\"\"\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m sum_of_squares(\u001b[38;5;241m1\u001b[39m) \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m sum_of_squares(\u001b[38;5;241m2\u001b[39m) \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m5\u001b[39m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m sum_of_squares(\u001b[38;5;241m10\u001b[39m) \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m385\u001b[39m\n", "\u001b[0;31mAssertionError\u001b[0m: " ] } @@ -384,7 +384,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNotImplementedError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# YOUR CODE HERE\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mNotImplementedError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "Input \u001b[0;32mIn [10]\u001b[0m, in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# YOUR CODE HERE\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mNotImplementedError\u001b[39;00m()\n", "\u001b[0;31mNotImplementedError\u001b[0m: " ] } diff --git a/nbgrader/docs/source/user_guide/creating_and_grading_assignments_jlab.ipynb b/nbgrader/docs/source/user_guide/creating_and_grading_assignments.ipynb similarity index 75% rename from nbgrader/docs/source/user_guide/creating_and_grading_assignments_jlab.ipynb rename to nbgrader/docs/source/user_guide/creating_and_grading_assignments.ipynb index d6a870b8a..198ea9561 100644 --- a/nbgrader/docs/source/user_guide/creating_and_grading_assignments_jlab.ipynb +++ b/nbgrader/docs/source/user_guide/creating_and_grading_assignments.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Creating and grading assignments (Jupyter Lab)" + "# Creating and grading assignments" ] }, { @@ -521,13 +521,31 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[ValidateApp | WARNING] No nbgrader_config.py file found (rerun with --debug to see where nbgrader is looking)\n", + "[ValidateApp | INFO] Validating '[NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/source/ps1/problem1.ipynb'\n", + "[ValidateApp | INFO] Validating '[NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/source/ps1/problem2.ipynb'\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Success! Your notebook passes all the tests.\n", + "Success! Your notebook passes all the tests.\n" + ] + } + ], "source": [ "%%bash\n", "\n", @@ -626,13 +644,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[GenerateAssignmentApp | WARNING] No nbgrader_config.py file found (rerun with --debug to see where nbgrader is looking)\n", + "[GenerateAssignmentApp | INFO] Copying [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/source/./ps1/jupyter.png -> [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/release/./ps1/jupyter.png\n", + "[GenerateAssignmentApp | INFO] Updating/creating assignment 'ps1': {}\n", + "[GenerateAssignmentApp | INFO] Converting notebook [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/source/./ps1/problem1.ipynb\n", + "[GenerateAssignmentApp | INFO] Writing [size] bytes to [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/release/ps1/problem1.ipynb\n", + "[GenerateAssignmentApp | INFO] Converting notebook [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/source/./ps1/problem2.ipynb\n", + "[GenerateAssignmentApp | INFO] Writing [size] bytes to [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/release/ps1/problem2.ipynb\n", + "[GenerateAssignmentApp | INFO] Setting destination file permissions to 644\n" + ] + } + ], "source": [ "%%bash\n", "\n", @@ -674,13 +707,31 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[ValidateApp | WARNING] No nbgrader_config.py file found (rerun with --debug to see where nbgrader is looking)\n", + "[ValidateApp | INFO] Validating '[NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/release/ps1/problem1.ipynb'\n", + "[ValidateApp | INFO] Validating '[NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/release/ps1/problem2.ipynb'\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Success! The notebook does not pass any tests.\n", + "Success! The notebook does not pass any tests.\n" + ] + } + ], "source": [ "%%bash\n", "\n", @@ -707,7 +758,7 @@ "source": [ ".. seealso::\n", "\n", - " :doc:`managing_assignment_files_jlab`\n", + " :doc:`managing_assignment_files`\n", " Guide to releasing and collecting submissions.\n", "\n", " :doc:`/command_line_tools/nbgrader-release-assignment`\n", @@ -727,14 +778,14 @@ "cell_type": "raw", "metadata": {}, "source": [ - "Note: the :doc:`Managing Assignment Files Guide ` goes into greater depth on how to release and collect assignments, and the various options that are available to do you for doing so." + "Note: the :doc:`Managing Assignment Files Guide ` goes into greater depth on how to release and collect assignments, and the various options that are available to do you for doing so." ] }, { "cell_type": "raw", "metadata": {}, "source": [ - "At this point you will be able to take the files in the ``release`` folder and distribute them to students. If you are using nbgrader with JupyterHub, you can do this with either with the formgrader extension or with the ``nbgrader release_assignment`` command (see :doc:`managing_assignment_files_jlab`). Otherwise, you will need to do this manually.\n", + "At this point you will be able to take the files in the ``release`` folder and distribute them to students. If you are using nbgrader with JupyterHub, you can do this with either with the formgrader extension or with the ``nbgrader release_assignment`` command (see :doc:`managing_assignment_files`). Otherwise, you will need to do this manually.\n", "\n", "Similarly, to collect submissions, you can do this either with the formgrader extension or with the ``nbgrader collect`` command. Otherwise, you will need to manually place submitted files into the ``submitted`` directory. As described in :doc:`philosophy`, you need to organize your files in a particular way. For submitted assignments, you should have the submitted versions of students' assignments organized as follows:" ] @@ -853,13 +904,61 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[AutogradeApp | WARNING] No nbgrader_config.py file found (rerun with --debug to see where nbgrader is looking)\n", + "[AutogradeApp | INFO] Copying [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/submitted/bitdiddle/ps1/jupyter.png -> [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/jupyter.png\n", + "[AutogradeApp | INFO] Copying [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/submitted/bitdiddle/ps1/timestamp.txt -> [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/timestamp.txt\n", + "[AutogradeApp | INFO] Creating/updating student with ID 'bitdiddle': {}\n", + "[AutogradeApp | INFO] SubmittedAssignment submitted at [timestamp]\n", + "[AutogradeApp | INFO] Overwriting files with master versions from the source directory\n", + "[AutogradeApp | INFO] Copying [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/source/./ps1/jupyter.png -> [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/jupyter.png\n", + "[AutogradeApp | INFO] Sanitizing [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/submitted/bitdiddle/ps1/problem1.ipynb\n", + "[AutogradeApp | INFO] Converting notebook [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/submitted/bitdiddle/ps1/problem1.ipynb\n", + "[AutogradeApp | WARNING] Attribute 'checksum' for cell correct_squares has changed! (should be: 8f41dd0f9c8fd2da8e8708d73e506b3a, got: 845d4666cabb30b6c75fc534f7375bf5)\n", + "[AutogradeApp | WARNING] Attribute 'checksum' for cell squares_invalid_input has changed! (should be: 23c2b667d3b60eff3be46eb3290a6b4a, got: 123394e73f33a622ec057e2eae51a54a)\n", + "[AutogradeApp | INFO] Writing [size] bytes to [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem1.ipynb\n", + "[AutogradeApp | INFO] Autograding [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem1.ipynb\n", + "[AutogradeApp | INFO] Converting notebook [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem1.ipynb\n", + "[AutogradeApp | INFO] Writing [size] bytes to [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem1.ipynb\n", + "[AutogradeApp | INFO] Sanitizing [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/submitted/bitdiddle/ps1/problem2.ipynb\n", + "[AutogradeApp | INFO] Converting notebook [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/submitted/bitdiddle/ps1/problem2.ipynb\n", + "[AutogradeApp | INFO] Writing [size] bytes to [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem2.ipynb\n", + "[AutogradeApp | INFO] Autograding [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem2.ipynb\n", + "[AutogradeApp | INFO] Converting notebook [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem2.ipynb\n", + "[AutogradeApp | INFO] Writing [size] bytes to [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem2.ipynb\n", + "[AutogradeApp | INFO] Setting destination file permissions to 444\n", + "[AutogradeApp | INFO] Copying [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/submitted/hacker/ps1/jupyter.png -> [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/jupyter.png\n", + "[AutogradeApp | INFO] Copying [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/submitted/hacker/ps1/timestamp.txt -> [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/timestamp.txt\n", + "[AutogradeApp | INFO] Creating/updating student with ID 'hacker': {}\n", + "[AutogradeApp | INFO] SubmittedAssignment submitted at [timestamp]\n", + "[AutogradeApp | INFO] Overwriting files with master versions from the source directory\n", + "[AutogradeApp | INFO] Copying [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/source/./ps1/jupyter.png -> [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/jupyter.png\n", + "[AutogradeApp | INFO] Sanitizing [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/submitted/hacker/ps1/problem1.ipynb\n", + "[AutogradeApp | INFO] Converting notebook [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/submitted/hacker/ps1/problem1.ipynb\n", + "[AutogradeApp | INFO] Writing [size] bytes to [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/problem1.ipynb\n", + "[AutogradeApp | INFO] Autograding [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/problem1.ipynb\n", + "[AutogradeApp | INFO] Converting notebook [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/problem1.ipynb\n", + "[AutogradeApp | INFO] Writing [size] bytes to [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/problem1.ipynb\n", + "[AutogradeApp | INFO] Sanitizing [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/submitted/hacker/ps1/problem2.ipynb\n", + "[AutogradeApp | INFO] Converting notebook [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/submitted/hacker/ps1/problem2.ipynb\n", + "[AutogradeApp | INFO] Writing [size] bytes to [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/problem2.ipynb\n", + "[AutogradeApp | INFO] Autograding [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/problem2.ipynb\n", + "[AutogradeApp | INFO] Converting notebook [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/problem2.ipynb\n", + "[AutogradeApp | INFO] Writing [size] bytes to [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/problem2.ipynb\n", + "[AutogradeApp | INFO] Setting destination file permissions to 444\n" + ] + } + ], "source": [ "%%bash\n", "\n", @@ -1031,13 +1130,35 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[GenerateFeedbackApp | WARNING] No nbgrader_config.py file found (rerun with --debug to see where nbgrader is looking)\n", + "[GenerateFeedbackApp | INFO] Copying [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/jupyter.png -> [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/feedback/bitdiddle/ps1/jupyter.png\n", + "[GenerateFeedbackApp | INFO] Copying [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/timestamp.txt -> [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/feedback/bitdiddle/ps1/timestamp.txt\n", + "[GenerateFeedbackApp | INFO] Converting notebook [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem1.ipynb\n", + "[GenerateFeedbackApp | INFO] Writing [size] bytes to [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/feedback/bitdiddle/ps1/problem1.html\n", + "[GenerateFeedbackApp | INFO] Converting notebook [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/problem2.ipynb\n", + "[GenerateFeedbackApp | INFO] Writing [size] bytes to [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/feedback/bitdiddle/ps1/problem2.html\n", + "[GenerateFeedbackApp | INFO] Setting destination file permissions to 644\n", + "[GenerateFeedbackApp | INFO] Copying [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/jupyter.png -> [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/feedback/hacker/ps1/jupyter.png\n", + "[GenerateFeedbackApp | INFO] Copying [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/timestamp.txt -> [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/feedback/hacker/ps1/timestamp.txt\n", + "[GenerateFeedbackApp | INFO] Converting notebook [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/problem1.ipynb\n", + "[GenerateFeedbackApp | INFO] Writing [size] bytes to [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/feedback/hacker/ps1/problem1.html\n", + "[GenerateFeedbackApp | INFO] Converting notebook [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/autograded/hacker/ps1/problem2.ipynb\n", + "[GenerateFeedbackApp | INFO] Writing [size] bytes to [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/feedback/hacker/ps1/problem2.html\n", + "[GenerateFeedbackApp | INFO] Setting destination file permissions to 644\n" + ] + } + ], "source": [ "%%bash\n", "\n", @@ -1094,13 +1215,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[ExportApp | WARNING] No nbgrader_config.py file found (rerun with --debug to see where nbgrader is looking)\n", + "[ExportApp | INFO] Using exporter: CsvExportPlugin\n", + "[ExportApp | INFO] Exporting grades to grades.csv\n" + ] + } + ], "source": [ "%%bash\n", "\n", @@ -1116,13 +1247,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "assignment,duedate,timestamp,student_id,last_name,first_name,email,raw_score,late_submission_penalty,score,max_score\n", + "ps1,,[timestamp],bitdiddle,,,,1.5,0.0,1.5,13.0\n", + "ps1,,[timestamp],hacker,,,,3.0,0.0,3.0,13.0\n" + ] + } + ], "source": [ "%%bash\n", "\n", diff --git a/nbgrader/docs/source/user_guide/creating_and_grading_assignments_nb.ipynb b/nbgrader/docs/source/user_guide/creating_and_grading_assignments_nb.ipynb deleted file mode 100644 index fc7c12ccb..000000000 --- a/nbgrader/docs/source/user_guide/creating_and_grading_assignments_nb.ipynb +++ /dev/null @@ -1,1174 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Creating and grading assignments (Classic Notebook)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This guide walks an instructor through the workflow for generating an assignment and preparing it for release to students." - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. contents:: Table of Contents\n", - " :depth: 2" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. versionadded:: 0.5.0\n", - "\n", - " Much of the core functionality of nbgrader can now be accessed through the \"formgrader\" extension." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing the formgrader extension" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. seealso::\n", - "\n", - " :doc:`installation`\n", - " Instructions on how to install the formgrader extension." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The formgrader extension provides the core access to nbgrader's instructor tools. After the extension has been installed, you can access it through the tab in the notebook list:\n", - "\n", - "![formgrader tab](images/classic_notebook/formgrader_tab.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Creating a new assignment" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. seealso::\n", - "\n", - " :doc:`managing_the_database`\n", - " Instructions on how to manage assignments in the database from the command line\n", - "\n", - " :doc:`/command_line_tools/nbgrader-db-assignment-add`\n", - " Command line options for ``nbgrader db assignment add``" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the formgrader" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To create a new assignment, open the formgrader extension and click the \"Add new assignment...\" button at the bottom of the page. This will ask you to provide some information such as the name of the assignment and its due date. Then, you can add files to the assignment and edit them by clicking the name of the assignment:\n", - "\n", - "![manage assignments open](images/classic_notebook/manage_assignments1.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the command line" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "If you are not using the formgrader extension, you can add a new assignment simply by creating a folder in your course directory with the name of the assignment. You can specify the assignment metadata (such as the duedate) using the `nbgrader db assignment` command (see :doc:`managing_the_database`)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To simplify this example, two notebooks of the assignment have already been stored in the `source/ps1` folder:\n", - "\n", - "* [source/ps1/problem1.ipynb](source/ps1/problem1.ipynb)\n", - "* [source/ps1/problem2.ipynb](source/ps1/problem2.ipynb)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Developing assignments with the assignment toolbar" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Note**: As you are developing your assignments, you should save them\n", - "into the `source/{assignment_id}/` folder of the nbgrader hierarchy,\n", - "where `assignment_id` is the name of the assignment you are creating\n", - "(e.g. \"ps1\")." - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. seealso::\n", - "\n", - " :doc:`philosophy`\n", - " More details on how the nbgrader hierarchy is structured.\n", - " \n", - " :doc:`/configuration/student_version`\n", - " Instructions for customizing how the student version of the assignment looks.\n", - "\n", - "Before you can begin developing assignments, you will need to actually\n", - "install the nbgrader toolbar. If you do not have it installed, please\n", - "first follow the :doc:`installation instructions `." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Once the toolbar has been installed, you should see it in the drop down \"View -> Cell Toolbar\" menu:\n", - "\n", - "![assignment toolbar](images/classic_notebook/assignment_toolbar.png)\n", - "\n", - "Selecting the \"Create Assignment\" toolbar will create a separate toolbar\n", - "for each cell which by default will be a dropdown menu with the \"-\" item\n", - "selected. For markdown cells, there are two additional options to choose\n", - "from, either \"Manually graded answer\" or \"Read-only\":\n", - "\n", - "![markdown cell](images/classic_notebook/markdown_cell.png)\n", - "\n", - "For code cells, there are four options to choose from, including\n", - "\"Manually graded answer\", \"Autograded answer\", \"Autograder tests\", and\n", - "\"Read-only\":\n", - "\n", - "![code cell](images/classic_notebook/code_cell.png)\n", - "\n", - "The following sections go into detail about the different cell types,\n", - "and show cells that are taken from a complete example of an assignment\n", - "generated with the nbgrader toolbar extension:\n", - "\n", - "- [source/ps1/problem1.ipynb](source/ps1/problem1.html)\n", - "- [source/ps1/problem2.ipynb](source/ps1/problem2.html)" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. _manually-graded-cells-classic-nb:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### \"Manually graded answer\" cells" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you select the \"Manually graded answer\" option (available for both\n", - "markdown and code cells), the nbgrader extension will mark that cell as\n", - "a cell that contains an answer that must be manually graded by a human\n", - "grader. Here is an example of a manually graded answer cell:\n", - "\n", - "![manually graded answer](images/classic_notebook/manually_graded_answer.png)\n", - "\n", - "The most common use case for this type of cell is for written\n", - "free-response answers (for example, which interpret the results of code\n", - "that may have been written and/or executed above)." - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "When you specify a manually graded answer, you must additionally tell nbgrader how many points the answer is worth, and an id for the cell. Additionally, when creating the release version of the assignment (see :ref:`assign-and-release-an-assignment`), the bodies of answer cells will be replaced with a code or text stub indicating to the students that they should put their answer or solution there. Please see :doc:`/configuration/student_version` for details on how to customize this behavior." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "*Note: the blue border only shows up when the nbgrader extension toolbar\n", - "is active; it will not be visible to students.*" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. _manually-graded-task-cells-classic-nb:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### “Manually graded task” cells" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. versionadded:: 0.6.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you select the “Manually graded task” option (available for markdown cells), \n", - "the nbgrader extension will mark that cell as\n", - "a cell that contains the description of a task that students have to perform.\n", - "They must be manually graded by a human\n", - "grader. Here is an example of a manually graded answer cell:\n", - "\n", - "![task cell source](images/classic_notebook/task-cell-source.png)\n", - "\n", - "The difference with a manually graded answer is that the manually graded tasks cells are not edited by the student. A manually or automatically graded cell ask students to perform a task *in* one cell. A manually graded task asks students to perform a task *with* cells.\n", - "\n", - "The common use case for this type of cell is for tasks that require the\n", - "student to create several cells such as \"Process the data and create a plot to illustrate your results.\" \n", - "or to contain notebook-wide tasks such as \"adhere to the PEP8 style convention.\"\n", - "\n", - "*Note: the blue border only shows up when the nbgrader extension toolbar\n", - "is active; it will not be visible to students.*" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. _manually-graded-task-cell-mark-scheme-classic-nb:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### “Manually graded task” cells with mark scheme" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. versionadded:: 0.6.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A mark scheme can be created through the use of a\n", - "special syntax such as ``=== BEGIN MARK SCHEME ===`` and\n", - "``=== END MARK SCHEME ===``. The section of text between the two markers will be removed from the student version,\n", - "but will be visible at the grading stage and in the feedback." - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. _autograded-answer-cells-classic-nb:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### \"Autograded answer\" cells" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you select the \"Autograded answer\" option (available only for code\n", - "cells), the nbgrader extension will mark that cell as a cell that\n", - "contains an answer which will be autograded. Here is an example of an\n", - "autograded graded answer cell:\n", - "\n", - "![autograded answer](images/classic_notebook/autograded_answer.png)" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "As shown in the image above, solutions can be specified inline, through the use of a special syntax such as ``### BEGIN SOLUTION`` and ``### END SOLUTION``. When creating the release version (see :ref:`assign-and-release-an-assignment`), the region between the special syntax lines will be replaced with a code stub. If this special syntax is not used, then the entire contents of the cell will be replaced with the code stub. Please see :doc:`/configuration/student_version` for details on how to customize this behavior." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Unlike manually graded answers, autograded answers aren't worth any\n", - "points: instead, the points for autograded answers are specified for the\n", - "particular tests that grade those answers. See the next section for\n", - "further details.\n", - "\n", - "*Note: the blue border only shows up when the nbgrader extension toolbar\n", - "is active; it will not be visible to students.*" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### \"Autograder tests\" cells" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you select the \"Autograder tests\" option (available only for code\n", - "cells), the nbgrader extension will mark that cell as a cell that\n", - "contains tests to be run during autograding. Here is an example of two\n", - "test cells:\n", - "\n", - "![autograder tests](images/classic_notebook/autograder_tests.png)" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "Test cells should contain ``assert`` statements (or similar). When run through ``nbgrader autograde`` (see :ref:`autograde-assignments`), the cell will pass if no errors are raised, and fail otherwise. You must specify the number of points that each test cell is worth; then, if the tests pass during autograding, students will receive the specified number of points, and otherwise will receive zero points." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The lock icon on the left side of the cell toolbar indicates that the\n", - "tests are \"read-only\". See the next section for further details on what\n", - "this means." - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "For tips on writing autograder tests, see :ref:`autograding-resources`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "*Note: the blue border only shows up when the nbgrader extension toolbar\n", - "is active; it will not be visible to students.*" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. _autograder-tests-cell-hidden-tests-classic-nb:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### \"Autograder tests\" cells with hidden tests" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. versionadded:: 0.5.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Tests in \"Autograder tests\" cells can be hidden through the use of a special syntax such as ``### BEGIN HIDDEN TESTS`` and ``### END HIDDEN TESTS``, for example:\n", - "\n", - "![autograder tests hidden tests](images/classic_notebook/autograder_tests_hidden_tests.png)" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "When creating the release version (see :ref:`assign-and-release-an-assignment`), the region between the special syntax lines will be removed. If this special syntax is not used, then the contents of the cell will remain as is. Please see :doc:`/configuration/student_version` for details on how to customize this behavior.\n", - "\n", - ".. note::\n", - "\n", - " Keep in mind that wrapping all tests (for an \"Autograder tests\" cell) in this special syntax will remove all these tests in\n", - " the release version and the students will only see a blank cell. It is recommended to have at least one or more visible \n", - " tests, or a comment in the cell for the students to see.\n", - "\n", - " These hidden tests are placed back into the \"Autograder tests\" cells when running ``nbgrader autograde``\n", - " (see :ref:`autograde-assignments`)." - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. _read-only-cells-classic-nb:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### \"Read-only\" cells" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you select the \"Read-only\" option (available for both code and\n", - "markdown cells), the nbgrader extension will mark that cell as one that\n", - "cannot be modified. This is indicated by a lock icon on the left side of\n", - "the cell toolbar:\n", - "\n", - "![read only](images/classic_notebook/read_only.png)" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "However, this doesn't actually mean that it is truly read-only when opened in the notebook. Instead, what it means is that during the ``nbgrader generate_assignment`` step (see :ref:`assign-and-release-an-assignment`), the source of these cells will be recorded into the database. Then, during the ``nbgrader autograde`` step (see :ref:`autograde-assignments`), nbgrader will check whether the source of the student's version of the cell has changed. If it has, it will replace the cell's source with the version in the database, thus effectively overwriting any changes the student made.\n", - "\n", - ".. versionadded:: 0.4.0\n", - " Read-only cells (and test cells) are now truly read-only! However, at the moment this functionality will only work on the master version of the notebook (5.0.0.dev)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This functionality is particularly important for test cells, which are\n", - "always marked as read-only. Because the mechanism for autograding is\n", - "that students receive full credit if the tests pass, an easy way to get\n", - "around this would be to simply delete or comment out the tests. This\n", - "read-only functionality will reverse any such changes made by the\n", - "student." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Validating the instructor version" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. seealso::\n", - "\n", - " :doc:`/command_line_tools/nbgrader-validate`\n", - " Command line options for ``nbgrader validate``" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the validate extension" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Ideally, the solutions in the instructor version should be correct and pass all the test cases to ensure that you are giving your students tests that they can actually pass. To verify this is the case, you can use the validate extension:\n", - "\n", - "![validate extension](images/classic_notebook/validate_extension.png)\n", - "\n", - "If your assignment passes all the tests, you'll get a success pop-up:\n", - "\n", - "![validate success](images/classic_notebook/validate_success.png)\n", - "\n", - "If it doesn't pass all the tests, you'll get a message telling you which cells failed:\n", - "\n", - "![validate failed](images/classic_notebook/validate_failed.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the command line" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can also validate assignments on the command line using the `nbgrader validate` command:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "nbgrader validate source/ps1/*.ipynb" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. _assign-and-release-an-assignment-classic-nb:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Generate and release an assignment" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. seealso::\n", - "\n", - " :doc:`/command_line_tools/nbgrader-generate-assignment`\n", - " Command line options for ``nbgrader generate_assignment``\n", - " \n", - " :doc:`philosophy`\n", - " Details about how the directory hierarchy is structured\n", - "\n", - " :doc:`/configuration/config_options`\n", - " Details on ``nbgrader_config.py``" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the formgrader" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "After an assignment has been created with the assignment toolbar, you will want to generate the version that students will receive. You can do this from the formgrader by clicking the \"generate\" button:\n", - "\n", - "![manage assignments generate](images/classic_notebook/manage_assignments2.png)\n", - "\n", - "This should succeed with a pop-up window containing log output:\n", - "\n", - "![generate assignment](images/classic_notebook/generate_assignment.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the command line" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "As described in :doc:`philosophy`, you need to organize your files in a particular way. For releasing assignments, you should have the master copy of your files saved (by default) in the following source directory structure:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```\n", - "{course_directory}/source/{assignment_id}/{notebook_id}.ipynb\n", - "```\n", - "\n", - "Note: The `student_id` is not included here because the source and release versions of the assignment are the same for all students.\n", - "\n", - "After running `nbgrader generate_assignment`, the release version of the notebooks will be:\n", - "\n", - "```\n", - "{course_directory}/release/{assignment_id}/{notebook_id}.ipynb\n", - "```\n", - "\n", - "As a reminder, the instructor is responsible for distributing this release version to their students using their institution's existing student communication and document distribution infrastructure." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When running `nbgrader generate_assignment`, the assignment name (which is \"ps1\") is passed. We also specify a *header* notebook (`source/header.ipynb`) to prepend at the beginning of each notebook in the assignment. By default, this command should be run from the root of the course directory:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "nbgrader generate_assignment \"ps1\" --IncludeHeaderFooter.header=source/header.ipynb --force" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Preview the student version" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "After generating the student version of assignment, you should preview it to make sure that it looks correct. You can do this from the formgrader extension by clicking the \"preview\" button:\n", - "\n", - "![manage assignments preview](images/classic_notebook/manage_assignments3.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Under the hood, there will be a new folder called `release` with the same structure as `source`. The `release` folder contains the actual release version of the assignment files:\n", - "\n", - "* [release/ps1/problem1.ipynb](release/ps1/problem1.ipynb)\n", - "* [release/ps1/problem2.ipynb](release/ps1/problem2.ipynb)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you are working on the command line, you may want to formally verify the student version as well. Ideally, all the tests should fail in the student version if the student hasn't implemented anything. To verify that this is in fact the case, we can use the `nbgrader validate --invert` command:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "nbgrader validate --invert release/ps1/*.ipynb" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If the notebook fails all the test cases, you should see the message \"Success! The notebook does not pass any tests.\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Releasing files to students and collecting submissions" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. seealso::\n", - "\n", - " :doc:`managing_assignment_files_nb`\n", - " Guide to releasing and collecting submissions.\n", - "\n", - " :doc:`/command_line_tools/nbgrader-release-assignment`\n", - " Command line options for ``nbgrader release_assignment``\n", - "\n", - " :doc:`/command_line_tools/nbgrader-collect`\n", - " Command line options for ``nbgrader collect``\n", - " \n", - " :doc:`philosophy`\n", - " Details about how the directory hierarchy is structured\n", - "\n", - " :doc:`/configuration/config_options`\n", - " Details on ``nbgrader_config.py``" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "Note: the :doc:`Managing Assignment Files Guide ` goes into greater depth on how to release and collect assignments, and the various options that are available to do you for doing so." - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "At this point you will be able to take the files in the ``release`` folder and distribute them to students. If you are using nbgrader with JupyterHub, you can do this with either with the formgrader extension or with the ``nbgrader release_assignment`` command (see :doc:`managing_assignment_files_nb`). Otherwise, you will need to do this manually.\n", - "\n", - "Similarly, to collect submissions, you can do this either with the formgrader extension or with the ``nbgrader collect`` command. Otherwise, you will need to manually place submitted files into the ``submitted`` directory. As described in :doc:`philosophy`, you need to organize your files in a particular way. For submitted assignments, you should have the submitted versions of students' assignments organized as follows:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```\n", - "submitted/{student_id}/{assignment_id}/{notebook_id}.ipynb\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Please note**: Students must use version 3 or greater of the IPython/Jupyter notebook for nbgrader to work properly. If they are not using version 3 or greater, it is possible for them to delete cells that contain important metadata for nbgrader. With version 3 or greater, there is a feature in the notebook that prevents cells from being deleted. See [this issue](https://github.com/jupyter/nbgrader/issues/424) for more details.\n", - "\n", - "To ensure that students have a recent enough version of the notebook, you can include a cell such as the following in each notebook of the assignment:\n", - "\n", - "```python\n", - "import IPython\n", - "assert IPython.version_info[0] >= 3, \"Your version of IPython is too old, please update it.\"\n", - "```" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. _autograde-assignments-classic-nb:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Autograde assignments" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. seealso::\n", - "\n", - " :doc:`/command_line_tools/nbgrader-autograde`\n", - " Command line options for ``nbgrader autograde``\n", - " \n", - " :doc:`philosophy`\n", - " Details about how the directory hierarchy is structured\n", - "\n", - " :doc:`/configuration/config_options`\n", - " Details on ``nbgrader_config.py``" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the following example, we have an assignment with two notebooks. There are two submissions of the assignment:\n", - "\n", - "Submission 1:\n", - "\n", - "* [submitted/bitdiddle/ps1/problem1.ipynb](submitted/bitdiddle/ps1/problem1.ipynb)\n", - "* [submitted/bitdiddle/ps1/problem2.ipynb](submitted/bitdiddle/ps1/problem2.ipynb)\n", - "\n", - "Submission 2:\n", - "\n", - "* [submitted/hacker/ps1/problem1.ipynb](submitted/hacker/ps1/problem1.ipynb)\n", - "* [submitted/hacker/ps1/problem2.ipynb](submitted/hacker/ps1/problem2.ipynb)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the formgrader" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can autograde individual submissions from the formgrader directly. To do so, click on the the number of submissions in the \"Manage Assignments\" view:\n", - "\n", - "![manage assignments submission](images/classic_notebook/manage_assignments4.png)\n", - "\n", - "This will take you to a new page where you can see all the submissions. For a particular submission, click the \"autograde\" button to autograde it:\n", - "\n", - "![manage submissions autograde](images/classic_notebook/manage_submissions1.png)\n", - "\n", - "After autograding completes, you will see a pop-up window with log output:\n", - "\n", - "![autograde assignment](images/classic_notebook/autograde_assignment.png)\n", - "\n", - "And back on the submissions screen, you will see that the status of the submission has changed to \"needs manual grading\" and there is now a reported score as well: \n", - "\n", - "![manage submissions manual](images/classic_notebook/manage_submissions2.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the command line" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can run the autograder for all students at once from the command line:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "nbgrader autograde \"ps1\" --force" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When grading the submission for `Bitdiddle`, you'll see some warnings that look like \"Checksum for grade cell correct_squares has changed!\". What's happening here is that nbgrader has recorded what the *original* contents of the grade cell `correct_squares` (when `nbgrader generate_assignment` was run), and is checking the submitted version against this original version. It has found that the submitted version changed (perhaps this student tried to cheat by commenting out the failing tests), and has therefore overwritten the submitted version of the tests with the original version of the tests.\n", - "\n", - "You may also notice that there is a note saying \"ps1 for Bitdiddle is 21503.948203 seconds late\". What is happening here is that nbgrader is detecting a file in Bitdiddle's submission called `timestamp.txt`, reading in that timestamp, and saving it into the database. From there, it can compare the timestamp to the duedate of the problem set, and compute whether the submission is at all late.\n", - "\n", - "Once the autograding is complete, there will be new directories for the autograded versions of the submissions:\n", - "\n", - "```\n", - "autograded/{student_id}/{assignment_id}/{notebook_id}.ipynb\n", - "```\n", - "\n", - "Autograded submission 1:\n", - "\n", - "* [autograded/bitdiddle/ps1/problem1.ipynb](autograded/bitdiddle/ps1/problem1.ipynb)\n", - "* [autograded/bitdiddle/ps1/problem2.ipynb](autograded/bitdiddle/ps1/problem2.ipynb)\n", - "\n", - "Autograded submission 2:\n", - "\n", - "* [autograded/hacker/ps1/problem1.ipynb](autograded/hacker/ps1/problem1.ipynb)\n", - "* [autograded/hacker/ps1/problem2.ipynb](autograded/hacker/ps1/problem2.ipynb)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Manual grading" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. seealso::\n", - "\n", - " :doc:`philosophy`\n", - " More details on how the nbgrader hierarchy is structured.\n", - "\n", - " :doc:`/configuration/config_options`\n", - " Details on ``nbgrader_config.py``" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "After assignments have been autograded, they will saved into an ``autograded`` directory (see :doc:`philosophy` for details):" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "After running `nbgrader autograde`, the autograded version of the\n", - "notebooks will be:\n", - "\n", - " autograded/{student_id}/{assignment_id}/{notebook_id}.ipynb\n", - "\n", - "We can manually grade assignments through the formgrader as well, by clicking on the \"Manual Grading\" navigation button. This will provide you with an interface for hand grading assignments that it finds in the directory listed above. Note that this applies to *all* assignments as well -- as long as the autograder has been run on the assignment, it will be available for manual grading via the formgrader." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Generate feedback on assignments" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. seealso::\n", - "\n", - " :doc:`/command_line_tools/nbgrader-generate-feedback`\n", - " Command line options for ``nbgrader generate_feedback``\n", - " \n", - " :doc:`/command_line_tools/nbgrader-release-feedback`\n", - " Command line options for ``nbgrader release_feedback``\n", - " \n", - " :doc:`philosophy`\n", - " Details about how the directory hierarchy is structured\n", - "\n", - " :doc:`/configuration/config_options`\n", - " Details on ``nbgrader_config.py``" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "As mentioned before, after assignments have been autograded and/or manually graded, they will located in the `autograded` directory (see :doc:`philosophy` for details):" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```\n", - "autograded/{student_id}/{assignment_id}/{notebook_id}.ipynb\n", - "```\n", - "\n", - "Creating feedback for students is divided into two parts:\n", - "\n", - "* generate feedback\n", - "* release feedback\n", - "\n", - "Generating feedback will create HTML files in the local instructor directory. Releasing feedback will copy those HTML files to the nbgrader exchange.\n", - "\n", - "We can generate feedback based on the graded notebooks by running the `nbgrader generate_feedback` command, which will produce HTML versions of these notebooks at the following location:\n", - "\n", - "```\n", - "feedback/{student_id}/{assignment_id}/{notebook_id}.html\n", - "```\n", - "\n", - "The `nbgrader generate_feedback` is available by clicking the Generate Feedback button on either the Manage Assignments view (to generate feedback for all graded submissions), or on the individual student's Manage Submission page (to generate feedback for that specific individual)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can release the generated feedback by running the `nbgrader release_feedback` command, which will send the generated HTML files to the nbgrader exchange.\n", - "\n", - "The `nbgrader release_feedback` is available by clicking the Release Feedback button on either the Manage Assignments view (to release feedback for all generated feedback), or on the individual student's Manage Submission page (to release feedback for that specific individual)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Workflow example: Instructor returning feedback to students" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In some scenarios, you may not want to (or be able to) use the exchange to deliver student feedback. This sections describes a workflow for manually returning generated feedback.\n", - "\n", - "In the following example, we have an assignment with two notebooks. There are two submissions of the assignment that have been graded:\n", - "\n", - "Autograded submission 1:\n", - "\n", - "* [autograded/bitdiddle/ps1/problem1.ipynb](autograded/bitdiddle/ps1/problem1.ipynb)\n", - "* [autograded/bitdiddle/ps1/problem2.ipynb](autograded/bitdiddle/ps1/problem2.ipynb)\n", - "\n", - "Autograded submission 2:\n", - "\n", - "* [autograded/hacker/ps1/problem1.ipynb](autograded/hacker/ps1/problem1.ipynb)\n", - "* [autograded/hacker/ps1/problem2.ipynb](autograded/hacker/ps1/problem2.ipynb)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Generating feedback is fairly straightforward (and as with the other nbgrader commands for instructors, this must be run from the root of the course directory):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "nbgrader generate_feedback \"ps1\" " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Once the feedback has been generated, there will be new directories and HTML files corresponding to each notebook in each submission:\n", - "\n", - "Feedback for submission 1:\n", - "\n", - "* [feedback/bitdiddle/ps1/problem1.html](feedback/bitdiddle/ps1/problem1.html)\n", - "* [feedback/bitdiddle/ps1/problem2.html](feedback/bitdiddle/ps1/problem2.html)\n", - "\n", - "Feedback for submission 2:\n", - "\n", - "* [feedback/hacker/ps1/problem1.html](feedback/hacker/ps1/problem1.html)\n", - "* [feedback/hacker/ps1/problem2.html](feedback/hacker/ps1/problem2.html)\n", - "\n", - "If the exchange is available, one would of course use `nbgrader release_feedback`. However if not available, you can now deliver these generated HTML feedback files via whatever mechanism you wish." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Getting grades from the database" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. versionadded:: 0.4.0\n", - "\n", - ".. seealso::\n", - "\n", - " :doc:`/command_line_tools/nbgrader-export`\n", - " Command line options for ``nbgrader export``\n", - " \n", - " :doc:`/plugins/export-plugin`\n", - " Details on how to write your own custom exporter." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In addition to creating feedback for the students, you may need to upload grades to whatever learning management system your school uses (e.g. Canvas, Blackboard, etc.). nbgrader provides a way to export grades to CSV out of the box, with the `nbgrader export` command:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "nbgrader export" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "After running `nbgrader export`, you will see the grades in a CSV file called `grades.csv`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "cat grades.csv" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "If you need to customize how the grades are exported, you can :doc:`write your own exporter `." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python", - "language": "python", - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 1 -} diff --git a/nbgrader/docs/source/user_guide/faq.rst b/nbgrader/docs/source/user_guide/faq.rst index 497e8b9c9..499dacd61 100644 --- a/nbgrader/docs/source/user_guide/faq.rst +++ b/nbgrader/docs/source/user_guide/faq.rst @@ -74,7 +74,7 @@ database. You can access the timestamps through the API, like so: Note that if you use the release_assignment/fetch_assignment/submit/collect commands (see -:doc:`managing_assignment_files_jlab`), the ``timestamp.txt`` files will be included +:doc:`managing_assignment_files`), the ``timestamp.txt`` files will be included automatically. Do I have to use sqlite for the nbgrader database? diff --git a/nbgrader/docs/source/user_guide/feedback/bitdiddle/ps1/problem1.html b/nbgrader/docs/source/user_guide/feedback/bitdiddle/ps1/problem1.html index e86374c1f..f9638904e 100644 --- a/nbgrader/docs/source/user_guide/feedback/bitdiddle/ps1/problem1.html +++ b/nbgrader/docs/source/user_guide/feedback/bitdiddle/ps1/problem1.html @@ -20,22 +20,22 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight { background: #f8f8f8; } -.highlight .c { color: #408080; font-style: italic } /* Comment */ +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ .highlight .err { border: 1px solid #FF0000 } /* Error */ .highlight .k { color: #008000; font-weight: bold } /* Keyword */ .highlight .o { color: #666666 } /* Operator */ -.highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ -.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #BC7A00 } /* Comment.Preproc */ -.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ -.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ .highlight .gd { color: #A00000 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gr { color: #E40000 } /* Generic.Error */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -.highlight .gi { color: #00A000 } /* Generic.Inserted */ -.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ .highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ @@ -48,15 +48,15 @@ .highlight .kt { color: #B00040 } /* Keyword.Type */ .highlight .m { color: #666666 } /* Literal.Number */ .highlight .s { color: #BA2121 } /* Literal.String */ -.highlight .na { color: #7D9029 } /* Name.Attribute */ +.highlight .na { color: #687822 } /* Name.Attribute */ .highlight .nb { color: #008000 } /* Name.Builtin */ .highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ .highlight .no { color: #880000 } /* Name.Constant */ .highlight .nd { color: #AA22FF } /* Name.Decorator */ -.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ -.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0000FF } /* Name.Function */ -.highlight .nl { color: #A0A000 } /* Name.Label */ +.highlight .nl { color: #767600 } /* Name.Label */ .highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #19177C } /* Name.Variable */ @@ -73,11 +73,11 @@ .highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ .highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ .highlight .s2 { color: #BA2121 } /* Literal.String.Double */ -.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ .highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ -.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ .highlight .sx { color: #008000 } /* Literal.String.Other */ -.highlight .sr { color: #BB6688 } /* Literal.String.Regex */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ .highlight .s1 { color: #BA2121 } /* Literal.String.Single */ .highlight .ss { color: #19177C } /* Literal.String.Symbol */ .highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ @@ -472,12 +472,11 @@

Part A (2 points)--------------------------------------------------------------------------- AssertionError Traceback (most recent call last) -<ipython-input-4-f3fef5b9ed4e> in <module> - 1 """Check that squares returns the correct output for several inputs""" -----> 2 assert squares(1) == [1] - 3 assert squares(2) == [1, 4] - 4 assert squares(10) == [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] - 5 assert squares(11) == [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121] +Input In [4], in <cell line: 2>() + 1 """Check that squares returns the correct output for several inputs""" +----> 2 assert squares(1) == [1] + 3 assert squares(2) == [1, 4] + 4 assert squares(10) == [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] AssertionError: @@ -627,12 +626,11 @@

Part B (1 point)--------------------------------------------------------------------------- AssertionError Traceback (most recent call last) -<ipython-input-8-1a00eaa7c988> in <module> - 1 """Check that sum_of_squares returns the correct answer for various inputs.""" -----> 2 assert sum_of_squares(1) == 1 - 3 assert sum_of_squares(2) == 5 - 4 assert sum_of_squares(10) == 385 - 5 assert sum_of_squares(11) == 506 +Input In [8], in <cell line: 2>() + 1 """Check that sum_of_squares returns the correct answer for various inputs.""" +----> 2 assert sum_of_squares(1) == 1 + 3 assert sum_of_squares(2) == 5 + 4 assert sum_of_squares(10) == 385 AssertionError: @@ -742,9 +740,9 @@

Part D (2 points)--------------------------------------------------------------------------- NotImplementedError Traceback (most recent call last) -<ipython-input-10-15b94d1fa268> in <module> - 1 # YOUR CODE HERE -----> 2 raise NotImplementedError() +Input In [10], in <cell line: 2>() + 1 # YOUR CODE HERE +----> 2 raise NotImplementedError() NotImplementedError: diff --git a/nbgrader/docs/source/user_guide/feedback/bitdiddle/ps1/problem2.html b/nbgrader/docs/source/user_guide/feedback/bitdiddle/ps1/problem2.html index 195768faa..3539525aa 100644 --- a/nbgrader/docs/source/user_guide/feedback/bitdiddle/ps1/problem2.html +++ b/nbgrader/docs/source/user_guide/feedback/bitdiddle/ps1/problem2.html @@ -20,22 +20,22 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight { background: #f8f8f8; } -.highlight .c { color: #408080; font-style: italic } /* Comment */ +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ .highlight .err { border: 1px solid #FF0000 } /* Error */ .highlight .k { color: #008000; font-weight: bold } /* Keyword */ .highlight .o { color: #666666 } /* Operator */ -.highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ -.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #BC7A00 } /* Comment.Preproc */ -.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ -.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ .highlight .gd { color: #A00000 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gr { color: #E40000 } /* Generic.Error */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -.highlight .gi { color: #00A000 } /* Generic.Inserted */ -.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ .highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ @@ -48,15 +48,15 @@ .highlight .kt { color: #B00040 } /* Keyword.Type */ .highlight .m { color: #666666 } /* Literal.Number */ .highlight .s { color: #BA2121 } /* Literal.String */ -.highlight .na { color: #7D9029 } /* Name.Attribute */ +.highlight .na { color: #687822 } /* Name.Attribute */ .highlight .nb { color: #008000 } /* Name.Builtin */ .highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ .highlight .no { color: #880000 } /* Name.Constant */ .highlight .nd { color: #AA22FF } /* Name.Decorator */ -.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ -.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0000FF } /* Name.Function */ -.highlight .nl { color: #A0A000 } /* Name.Label */ +.highlight .nl { color: #767600 } /* Name.Label */ .highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #19177C } /* Name.Variable */ @@ -73,11 +73,11 @@ .highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ .highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ .highlight .s2 { color: #BA2121 } /* Literal.String.Double */ -.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ .highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ -.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ .highlight .sx { color: #008000 } /* Literal.String.Other */ -.highlight .sr { color: #BB6688 } /* Literal.String.Regex */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ .highlight .s1 { color: #BA2121 } /* Literal.String.Single */ .highlight .ss { color: #19177C } /* Literal.String.Symbol */ .highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ diff --git a/nbgrader/docs/source/user_guide/feedback/hacker/ps1/problem1.html b/nbgrader/docs/source/user_guide/feedback/hacker/ps1/problem1.html index 7ab52111d..c8c2f775a 100644 --- a/nbgrader/docs/source/user_guide/feedback/hacker/ps1/problem1.html +++ b/nbgrader/docs/source/user_guide/feedback/hacker/ps1/problem1.html @@ -20,22 +20,22 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight { background: #f8f8f8; } -.highlight .c { color: #408080; font-style: italic } /* Comment */ +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ .highlight .err { border: 1px solid #FF0000 } /* Error */ .highlight .k { color: #008000; font-weight: bold } /* Keyword */ .highlight .o { color: #666666 } /* Operator */ -.highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ -.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #BC7A00 } /* Comment.Preproc */ -.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ -.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ .highlight .gd { color: #A00000 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gr { color: #E40000 } /* Generic.Error */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -.highlight .gi { color: #00A000 } /* Generic.Inserted */ -.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ .highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ @@ -48,15 +48,15 @@ .highlight .kt { color: #B00040 } /* Keyword.Type */ .highlight .m { color: #666666 } /* Literal.Number */ .highlight .s { color: #BA2121 } /* Literal.String */ -.highlight .na { color: #7D9029 } /* Name.Attribute */ +.highlight .na { color: #687822 } /* Name.Attribute */ .highlight .nb { color: #008000 } /* Name.Builtin */ .highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ .highlight .no { color: #880000 } /* Name.Constant */ .highlight .nd { color: #AA22FF } /* Name.Decorator */ -.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ -.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0000FF } /* Name.Function */ -.highlight .nl { color: #A0A000 } /* Name.Label */ +.highlight .nl { color: #767600 } /* Name.Label */ .highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #19177C } /* Name.Variable */ @@ -73,11 +73,11 @@ .highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ .highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ .highlight .s2 { color: #BA2121 } /* Literal.String.Double */ -.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ .highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ -.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ .highlight .sx { color: #008000 } /* Literal.String.Other */ -.highlight .sr { color: #BB6688 } /* Literal.String.Regex */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ .highlight .s1 { color: #BA2121 } /* Literal.String.Single */ .highlight .ss { color: #19177C } /* Literal.String.Symbol */ .highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ diff --git a/nbgrader/docs/source/user_guide/feedback/hacker/ps1/problem2.html b/nbgrader/docs/source/user_guide/feedback/hacker/ps1/problem2.html index 04743c74a..1fa256ce3 100644 --- a/nbgrader/docs/source/user_guide/feedback/hacker/ps1/problem2.html +++ b/nbgrader/docs/source/user_guide/feedback/hacker/ps1/problem2.html @@ -20,22 +20,22 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight { background: #f8f8f8; } -.highlight .c { color: #408080; font-style: italic } /* Comment */ +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ .highlight .err { border: 1px solid #FF0000 } /* Error */ .highlight .k { color: #008000; font-weight: bold } /* Keyword */ .highlight .o { color: #666666 } /* Operator */ -.highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ -.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #BC7A00 } /* Comment.Preproc */ -.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ -.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ .highlight .gd { color: #A00000 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gr { color: #E40000 } /* Generic.Error */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -.highlight .gi { color: #00A000 } /* Generic.Inserted */ -.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ .highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ @@ -48,15 +48,15 @@ .highlight .kt { color: #B00040 } /* Keyword.Type */ .highlight .m { color: #666666 } /* Literal.Number */ .highlight .s { color: #BA2121 } /* Literal.String */ -.highlight .na { color: #7D9029 } /* Name.Attribute */ +.highlight .na { color: #687822 } /* Name.Attribute */ .highlight .nb { color: #008000 } /* Name.Builtin */ .highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ .highlight .no { color: #880000 } /* Name.Constant */ .highlight .nd { color: #AA22FF } /* Name.Decorator */ -.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ -.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0000FF } /* Name.Function */ -.highlight .nl { color: #A0A000 } /* Name.Label */ +.highlight .nl { color: #767600 } /* Name.Label */ .highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #19177C } /* Name.Variable */ @@ -73,11 +73,11 @@ .highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ .highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ .highlight .s2 { color: #BA2121 } /* Literal.String.Double */ -.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ .highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ -.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ .highlight .sx { color: #008000 } /* Literal.String.Other */ -.highlight .sr { color: #BB6688 } /* Literal.String.Regex */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ .highlight .s1 { color: #BA2121 } /* Literal.String.Single */ .highlight .ss { color: #19177C } /* Literal.String.Symbol */ .highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ diff --git a/nbgrader/docs/source/user_guide/highlights.rst b/nbgrader/docs/source/user_guide/highlights.rst index 2b8c45b44..1b97c8748 100644 --- a/nbgrader/docs/source/user_guide/highlights.rst +++ b/nbgrader/docs/source/user_guide/highlights.rst @@ -82,7 +82,7 @@ Using the **assignment list extension**, students may conveniently view, fetch, submit, and validate their assignments. This is also where they recieve and review any feedback on those submissions: -.. image:: images/classic_notebook/student_assignment.gif +.. image:: images/student_assignment.gif :alt: nbgrader assignment list @@ -97,7 +97,7 @@ The **nbgrader toolbar extension** for Jupyter notebooks guides the instructor through assignment and grading tasks using the familiar Jupyter notebook interface. For example, creating an assignment has the following workflow: -.. image:: images/classic_notebook/creating_assignment.gif +.. image:: images/creating_assignment.gif :alt: Creating assignment Instructor "formgrader" extension for Jupyter notebooks @@ -108,7 +108,7 @@ the core functionality of nbgrader---generating the student version of an assignment, releasing assignments to students, collecting assignments, autograding submissions, and manually grading submissions. -.. image:: images/classic_notebook/formgrader.gif +.. image:: images/formgrader.gif :alt: Formgrader extension diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_downloaded.png b/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_downloaded.png deleted file mode 100644 index 9361a446f..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_downloaded.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_downloaded_expanded.png b/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_downloaded_expanded.png deleted file mode 100644 index 17a36131c..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_downloaded_expanded.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_released.png b/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_released.png deleted file mode 100644 index c84913db3..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_released.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_submit_error.jpg b/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_submit_error.jpg deleted file mode 100644 index 12cdb3639..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_submit_error.jpg and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_submitted.png b/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_submitted.png deleted file mode 100644 index a1c8ac39e..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_submitted.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_submitted_again.png b/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_submitted_again.png deleted file mode 100644 index 885e424a2..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_submitted_again.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_validate_failed.png b/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_validate_failed.png deleted file mode 100644 index bc439c05b..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_validate_failed.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_validate_succeeded.png b/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_validate_succeeded.png deleted file mode 100644 index 4cecab762..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_list_validate_succeeded.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_toolbar.png b/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_toolbar.png deleted file mode 100644 index 455125921..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/assignment_toolbar.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/autograde_assignment.png b/nbgrader/docs/source/user_guide/images/classic_notebook/autograde_assignment.png deleted file mode 100644 index 036c60f35..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/autograde_assignment.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/autograded_answer.png b/nbgrader/docs/source/user_guide/images/classic_notebook/autograded_answer.png deleted file mode 100644 index 0e551e703..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/autograded_answer.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/autograder_tests.png b/nbgrader/docs/source/user_guide/images/classic_notebook/autograder_tests.png deleted file mode 100644 index 1a65cdc21..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/autograder_tests.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/autograder_tests_hidden_tests.png b/nbgrader/docs/source/user_guide/images/classic_notebook/autograder_tests_hidden_tests.png deleted file mode 100644 index 9c50dadac..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/autograder_tests_hidden_tests.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/code_cell.png b/nbgrader/docs/source/user_guide/images/classic_notebook/code_cell.png deleted file mode 100644 index 0a709c636..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/code_cell.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/collect_assignment.png b/nbgrader/docs/source/user_guide/images/classic_notebook/collect_assignment.png deleted file mode 100644 index da3e53741..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/collect_assignment.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/creating_assignment.gif b/nbgrader/docs/source/user_guide/images/classic_notebook/creating_assignment.gif deleted file mode 100644 index 2e1fb01d8..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/creating_assignment.gif and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/formgrader.gif b/nbgrader/docs/source/user_guide/images/classic_notebook/formgrader.gif deleted file mode 100644 index 61d2858c1..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/formgrader.gif and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/formgrader_tab.png b/nbgrader/docs/source/user_guide/images/classic_notebook/formgrader_tab.png deleted file mode 100644 index b055380c6..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/formgrader_tab.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/generate_assignment.png b/nbgrader/docs/source/user_guide/images/classic_notebook/generate_assignment.png deleted file mode 100644 index e4d839db4..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/generate_assignment.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments1.png b/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments1.png deleted file mode 100644 index e16b9357d..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments1.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments2.png b/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments2.png deleted file mode 100644 index 7a8f6cb35..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments2.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments3.png b/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments3.png deleted file mode 100644 index e046c2023..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments3.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments4.png b/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments4.png deleted file mode 100644 index 75d16bd94..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments4.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments5.png b/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments5.png deleted file mode 100644 index 42902ebb3..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments5.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments6.png b/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments6.png deleted file mode 100644 index a407e3aa1..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments6.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments7.png b/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments7.png deleted file mode 100644 index 3c065396a..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments7.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments8.png b/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments8.png deleted file mode 100644 index 1b83f73df..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_assignments8.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_submissions1.png b/nbgrader/docs/source/user_guide/images/classic_notebook/manage_submissions1.png deleted file mode 100644 index df736fed3..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_submissions1.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_submissions2.png b/nbgrader/docs/source/user_guide/images/classic_notebook/manage_submissions2.png deleted file mode 100644 index f6080f108..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/manage_submissions2.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/manually_graded_answer.png b/nbgrader/docs/source/user_guide/images/classic_notebook/manually_graded_answer.png deleted file mode 100644 index a822557dc..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/manually_graded_answer.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/markdown_cell.png b/nbgrader/docs/source/user_guide/images/classic_notebook/markdown_cell.png deleted file mode 100644 index 35c31a2b8..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/markdown_cell.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/read_only.png b/nbgrader/docs/source/user_guide/images/classic_notebook/read_only.png deleted file mode 100644 index 4203a4067..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/read_only.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/release_assignment.png b/nbgrader/docs/source/user_guide/images/classic_notebook/release_assignment.png deleted file mode 100644 index 75de8a2d0..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/release_assignment.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/student_assignment.gif b/nbgrader/docs/source/user_guide/images/classic_notebook/student_assignment.gif deleted file mode 100644 index 9e6ba7c3c..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/student_assignment.gif and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/task-cell-source.png b/nbgrader/docs/source/user_guide/images/classic_notebook/task-cell-source.png deleted file mode 100644 index 61a44eb10..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/task-cell-source.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/validate_extension.png b/nbgrader/docs/source/user_guide/images/classic_notebook/validate_extension.png deleted file mode 100644 index 232f0e36c..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/validate_extension.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/validate_failed.png b/nbgrader/docs/source/user_guide/images/classic_notebook/validate_failed.png deleted file mode 100644 index cdb236b4e..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/validate_failed.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/classic_notebook/validate_success.png b/nbgrader/docs/source/user_guide/images/classic_notebook/validate_success.png deleted file mode 100644 index 712f9a8e7..000000000 Binary files a/nbgrader/docs/source/user_guide/images/classic_notebook/validate_success.png and /dev/null differ diff --git a/nbgrader/docs/source/user_guide/images/creating_assignment.gif b/nbgrader/docs/source/user_guide/images/creating_assignment.gif new file mode 100644 index 000000000..70460a82c Binary files /dev/null and b/nbgrader/docs/source/user_guide/images/creating_assignment.gif differ diff --git a/nbgrader/docs/source/user_guide/images/formgrader.gif b/nbgrader/docs/source/user_guide/images/formgrader.gif new file mode 100644 index 000000000..fd6771a31 Binary files /dev/null and b/nbgrader/docs/source/user_guide/images/formgrader.gif differ diff --git a/nbgrader/docs/source/user_guide/images/student_assignment.gif b/nbgrader/docs/source/user_guide/images/student_assignment.gif new file mode 100644 index 000000000..a786a9159 Binary files /dev/null and b/nbgrader/docs/source/user_guide/images/student_assignment.gif differ diff --git a/nbgrader/docs/source/user_guide/installation.rst b/nbgrader/docs/source/user_guide/installation.rst index 86cdf58e9..394482cfa 100644 --- a/nbgrader/docs/source/user_guide/installation.rst +++ b/nbgrader/docs/source/user_guide/installation.rst @@ -16,13 +16,13 @@ Or, if you use `Anaconda `__:: nbgrader extensions in Jupyter Lab ----------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Extensions will be automatically installed after the installation of nbgrader. The installation will activated 4 server extensions (formgrader, assignment_list, course_list and validate_assignment) -and 1 labextension composed of 5 plugins (formgrader, assignment_list, course_list, validate_assignment and create_assignment). +and 5 labextensions (formgrader, assignment_list, course_list, validate_assignment and create_assignment). The server extensions can be disabled individually by running:: @@ -31,7 +31,7 @@ The server extensions can be disabled individually by running:: jupyter server extension disable nbgrader.server_extensions.course_list jupyter server extension disable nbgrader.server_extensions.validate_assignment -To disable the whole labextension run:: +To disable all the labextensions run:: jupyter labextension disable nbgrader @@ -51,70 +51,32 @@ or enabled:: jupyter labextension enable nbgrader/create-assignment jupyter labextension enable nbgrader/validate-assignment -nbgrader extensions in classic Notebook ---------------------------------------- - -**Take note:** If you install nbgrader via `Anaconda -`__ the nbgrader extensions will be -installed and enabled for you upon installation. See the `Installation -options`_ and `Disabling extensions`_ sections below for more information on -changing the default installation option ``--sys-prefix`` or disabling one or -more extensions. - -Installing and activating extensions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can install the nbgrader extensions for Jupyter notebook. Previously -this was done using the ``nbgrader extension install`` command. However, moving -forward this is done using the ``jupyter nbextension`` and ``jupyter -serverextension`` commands. - -To install and enable all nbextensions (**assignment list**, **create -assignment**, **formgrader**, and **validate**) run:: - - jupyter nbextension install --sys-prefix --py nbgrader --overwrite - jupyter nbextension enable --sys-prefix --py nbgrader - jupyter serverextension enable --sys-prefix --py nbgrader - -To work properly, the **assignment list**, **formgrader**, and **validate** -extensions require both the nbextension and serverextension. The **create -assignment** extension only has an nbextension part. +To work properly, the **assignment list**, **formgrader**, **course list** and **validate assignment** +extensions require both the labextension and server extension. The **create +assignment** extension only has an labextension part. Installation options ~~~~~~~~~~~~~~~~~~~~ -When installed/enabled with the ``--sys-prefix`` option, the nbextensions and -serverextension will be installed and enabled for anyone using the particular +When installed/enabled with the ``--sys-prefix`` option, the +server extension will be installed and enabled for anyone using the particular Python installation or conda environment where nbgrader is installed. If that Python installation is available system-wide, all users will immediately be able to use the nbgrader extensions. There are a number of ways you may need to customize the installation: -- To install or enable the nbextensions/serverextension for just the +- To install or enable the labextensions/server extension for just the current user, run the above commands with ``--user`` instead of ``--sys-prefix``:: - jupyter nbextension install --user --py nbgrader --overwrite - jupyter nbextension enable --user --py nbgrader - jupyter serverextension enable --user --py nbgrader + jupyter labextension enable --level=user nbgrader + jupyter server extension enable --user --py nbgrader -- To install or enable the nbextensions/serverextension for all +- To install or enable the labextensions/server extension for all Python installations on the system, run the above commands with ``--system`` instead of ``--sys-prefix``:: - jupyter nbextension install --system --py nbgrader --overwrite - jupyter nbextension enable --system --py nbgrader - jupyter serverextension enable --system --py nbgrader - -- You can also use the ``--overwrite`` option along with the ``jupyter - nbextension install`` command to overwrite existing nbgrader extension - installation files, typically used when updating nbgrader, for - example:: - - jupyter nbextension install --sys-prefix --overwrite --py nbgrader - -Previous versions of nbgrader required each user on a system to enable the -nbextensions; this is no longer needed if the ``--sys-prefix`` option is used -for a system-wide python or the ``--system`` option is used. + jupyter labextension enable --level=system nbgrader + jupyter server extension enable --system --py nbgrader Disabling extensions ~~~~~~~~~~~~~~~~~~~~ @@ -123,47 +85,47 @@ You may want to only install one of the nbgrader extensions. To do this, follow the above steps to install everything and then disable the extension you don't need. For example, to disable the Assignment List extension:: - jupyter nbextension disable --sys-prefix assignment_list/main --section=tree - jupyter serverextension disable --sys-prefix nbgrader.server_extensions.assignment_list + jupyter labextension disable --level=sys_prefix nbgrader/assignment_list + jupyter server extension disable --sys-prefix nbgrader.server_extensions.assignment_list or to disable the Create Assignment extension:: - jupyter nbextension disable --sys-prefix create_assignment/main + jupyter labextension disable --level=sys_prefix nbgrader/create_assignment or to disable the Formgrader extension:: - jupyter nbextension disable --sys-prefix formgrader/main --section=tree - jupyter serverextension disable --sys-prefix nbgrader.server_extensions.formgrader + jupyter labextension disable --level=sys_prefix nbgrader/formgrader + jupyter server extension disable --sys-prefix nbgrader.server_extensions.formgrader or to disable the Course List extension:: - jupyter nbextension disable --sys-prefix course_list/main --section=tree - jupyter serverextension disable --sys-prefix nbgrader.server_extensions.course_list + jupyter labextension disable --level=sys_prefix nbgrader/course_list + jupyter server extension disable --sys-prefix nbgrader.server_extensions.course_list For example lets assume you have installed nbgrader via `Anaconda -`__ (meaning all extensions are installed +`__ (meaning all serverextensions are installed and enabled with the ``--sys-prefix`` flag, i.e. anyone using the particular Python installation or conda environment where nbgrader is installed). But you only want the *create assignment* extension available to a specific user and not everyone else. First you will need to disable the *create assignment* extension for everyone else:: - jupyter nbextension disable --sys-prefix create_assignment/main + jupyter labextension disable nbgrader/create_assignment Log in with the specific user and then enable the *create assignment* extension only for that user:: - jupyter nbextension enable --user create_assignment/main + jupyter labextension enable --level=user nbgrader/create_assignment -Finally to see all installed nbextensions/server extensions, run:: +Finally to see all installed labextensions/server extensions, run:: - jupyter nbextension list - jupyter serverextension list + jupyter labextension list + jupyter server extension list For further documentation on these commands run:: - jupyter nbextension --help-all - jupyter serverextension --help-all + jupyter labextension --help-all + jupyter server extension --help-all For advanced instructions on installing the *assignment list* extension please see the :ref:`advanced installation instructions`. diff --git a/nbgrader/docs/source/user_guide/managing_assignment_files_jlab.ipynb b/nbgrader/docs/source/user_guide/managing_assignment_files.ipynb similarity index 77% rename from nbgrader/docs/source/user_guide/managing_assignment_files_jlab.ipynb rename to nbgrader/docs/source/user_guide/managing_assignment_files.ipynb index 319a876b7..49a0b52d9 100644 --- a/nbgrader/docs/source/user_guide/managing_assignment_files_jlab.ipynb +++ b/nbgrader/docs/source/user_guide/managing_assignment_files.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Exchanging assignment files (Jupyter Lab)" + "# Exchanging assignment files" ] }, { @@ -42,13 +42,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Writing nbgrader_config.py\n" + ] + } + ], "source": [ "%%file nbgrader_config.py\n", "\n", @@ -67,7 +75,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "vscode": { "languageId": "python" @@ -98,7 +106,7 @@ "source": [ ".. seealso::\n", "\n", - " :doc:`creating_and_grading_assignments_jlab`\n", + " :doc:`creating_and_grading_assignments`\n", " Details on generating assignments\n", "\n", " :doc:`/command_line_tools/nbgrader-release-assignment`\n", @@ -155,13 +163,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[ReleaseAssignmentApp | INFO] Source: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/release/./ps1\n", + "[ReleaseAssignmentApp | INFO] Destination: /tmp/exchange/example_course/outbound/ps1\n", + "[ReleaseAssignmentApp | INFO] Released as: example_course ps1\n" + ] + } + ], "source": [ "%%bash\n", "\n", @@ -177,13 +195,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[ListApp | INFO] Released assignments:\n", + "[ListApp | INFO] example_course ps1\n" + ] + } + ], "source": [ "%%bash\n", "\n", @@ -236,7 +263,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": { "vscode": { "languageId": "python" @@ -262,13 +289,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Writing /tmp/student_home/nbgrader_config.py\n" + ] + } + ], "source": [ "%%file /tmp/student_home/nbgrader_config.py\n", "\n", @@ -351,13 +386,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[ListApp | INFO] Released assignments:\n", + "[ListApp | INFO] example_course ps1\n" + ] + } + ], "source": [ "%%bash\n", "export HOME=/tmp/student_home && cd $HOME\n", @@ -374,13 +418,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[FetchAssignmentApp | INFO] Source: /tmp/exchange/example_course/outbound/ps1\n", + "[FetchAssignmentApp | INFO] Destination: /tmp/student_home/ps1\n", + "[FetchAssignmentApp | INFO] Fetched as: example_course ps1\n" + ] + } + ], "source": [ "%%bash\n", "export HOME=/tmp/student_home && cd $HOME\n", @@ -397,13 +451,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "total ##\n", + "-rw-r--r-- 1 nb_user nb_group [size] [date] [time] jupyter.png\n", + "-rw-r--r-- 1 nb_user nb_group [size] [date] [time] problem1.ipynb\n", + "-rw-r--r-- 1 nb_user nb_group [size] [date] [time] problem2.ipynb\n" + ] + } + ], "source": [ "%%bash\n", "\n", @@ -531,13 +596,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "c = get_config()\n", + "c.Exchange.root = '/tmp/exchange'\n", + "c.CourseDirectory.course_id = \"example_course\"\n" + ] + } + ], "source": [ "%%bash\n", "\n", @@ -553,13 +629,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[SubmitApp | INFO] Source: /tmp/student_home/ps1\n", + "[SubmitApp | INFO] Destination: /tmp/exchange/example_course/inbound/nb_user+ps1+[timestamp] UTC+[random string]\n", + "[SubmitApp | INFO] Submitted as: example_course ps1 [timestamp] UTC\n" + ] + } + ], "source": [ "%%bash\n", "export HOME=/tmp/student_home && cd $HOME\n", @@ -576,13 +662,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "total ##\n", + "-rw-rw-r-- 1 nb_user nb_group [size] [date] [time] nbgrader_config.py\n", + "drwxr-xr-x 1 nb_user nb_group [size] [date] [time] ps1\n" + ] + } + ], "source": [ "%%bash\n", "export HOME=/tmp/student_home && cd $HOME\n", @@ -599,13 +695,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[ListApp | INFO] Submitted assignments:\n", + "[ListApp | INFO] example_course nb_user ps1 [timestamp] UTC (no feedback available)\n" + ] + } + ], "source": [ "%%bash\n", "export HOME=/tmp/student_home && cd $HOME\n", @@ -622,13 +727,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[SubmitApp | INFO] Source: /tmp/student_home/ps1\n", + "[SubmitApp | INFO] Destination: /tmp/exchange/example_course/inbound/nb_user+ps1+[timestamp] UTC+[random string]\n", + "[SubmitApp | INFO] Submitted as: example_course ps1 [timestamp] UTC\n" + ] + } + ], "source": [ "%%bash\n", "export HOME=/tmp/student_home && cd $HOME\n", @@ -645,13 +760,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[ListApp | INFO] Submitted assignments:\n", + "[ListApp | INFO] example_course nb_user ps1 [timestamp] UTC (no feedback available)\n", + "[ListApp | INFO] example_course nb_user ps1 [timestamp] UTC (no feedback available)\n" + ] + } + ], "source": [ "%%bash\n", "export HOME=/tmp/student_home && cd $HOME\n", @@ -675,13 +800,30 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[SubmitApp | INFO] Source: /tmp/student_home/ps1\n", + "[SubmitApp | INFO] Destination: /tmp/exchange/example_course/inbound/nb_user+ps1+[timestamp] UTC+[random string]\n", + "[SubmitApp | WARNING] Possible missing notebooks and/or extra notebooks submitted for assignment ps1:\n", + " Expected:\n", + " \tproblem1.ipynb: MISSING\n", + " \tproblem2.ipynb: FOUND\n", + " Submitted:\n", + " \tmyproblem1.ipynb: EXTRA\n", + " \tproblem2.ipynb: OK\n", + "[SubmitApp | INFO] Submitted as: example_course ps1 [timestamp] UTC\n" + ] + } + ], "source": [ "%%bash\n", "export HOME=/tmp/student_home && cd $HOME\n", @@ -708,13 +850,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting /tmp/student_home/nbgrader_config.py\n" + ] + } + ], "source": [ "%%file /tmp/student_home/nbgrader_config.py\n", "\n", @@ -726,7 +876,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": { "tags": [ "raises-exception" @@ -735,7 +885,24 @@ "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[SubmitApp | INFO] Source: /tmp/student_home/ps1\n", + "[SubmitApp | INFO] Destination: /tmp/exchange/example_course/inbound/nb_user+ps1+[timestamp] UTC+[random string]\n", + "[SubmitApp | CRITICAL] Assignment ps1 not submitted. There are missing notebooks for the submission:\n", + " Expected:\n", + " \tproblem1.ipynb: MISSING\n", + " \tproblem2.ipynb: FOUND\n", + " Submitted:\n", + " \tmyproblem1.ipynb: EXTRA\n", + " \tproblem2.ipynb: OK\n", + "[SubmitApp | ERROR] nbgrader submit failed\n" + ] + } + ], "source": [ "%%bash\n", "export HOME=/tmp/student_home && cd $HOME\n", @@ -756,7 +923,7 @@ "source": [ ".. seealso::\n", "\n", - " :doc:`creating_and_grading_assignments_jlab`\n", + " :doc:`creating_and_grading_assignments`\n", " Details on grading assignments after they have been collected\n", "\n", " :doc:`/command_line_tools/nbgrader-collect`\n", @@ -781,13 +948,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "c = get_config()\n", + "\n", + "c.CourseDirectory.course_id = \"example_course\"\n", + "c.Exchange.root = \"/tmp/exchange\"\n" + ] + } + ], "source": [ "%%bash\n", "\n", @@ -834,13 +1013,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[ListApp | INFO] Submitted assignments:\n", + "[ListApp | INFO] example_course nb_user ps1 [timestamp] UTC (no feedback available)\n", + "[ListApp | INFO] example_course nb_user ps1 [timestamp] UTC (no feedback available)\n", + "[ListApp | INFO] example_course nb_user ps1 [timestamp] UTC (no feedback available)\n" + ] + } + ], "source": [ "%%bash\n", "\n", @@ -856,13 +1046,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[CollectApp | INFO] Processing 1 submissions of 'ps1' for course 'example_course'\n", + "[CollectApp | INFO] Collecting submission: nb_user ps1\n" + ] + } + ], "source": [ "%%bash\n", "\n", @@ -878,13 +1077,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "total ##\n", + "drwxrwxr-x 1 nb_user nb_group [size] [date] [time] bitdiddle\n", + "drwxrwxr-x 1 nb_user nb_group [size] [date] [time] hacker\n", + "drwxrwxr-x 1 nb_user nb_group [size] [date] [time] nb_user\n" + ] + } + ], "source": [ "%%bash\n", "\n", diff --git a/nbgrader/docs/source/user_guide/managing_assignment_files_manually.ipynb b/nbgrader/docs/source/user_guide/managing_assignment_files_manually.ipynb index 0978c6ce6..0ca98be97 100644 --- a/nbgrader/docs/source/user_guide/managing_assignment_files_manually.ipynb +++ b/nbgrader/docs/source/user_guide/managing_assignment_files_manually.ipynb @@ -183,7 +183,8 @@ "output_type": "stream", "text": [ "total ##\n", - "-rw-r--r-- 1 nb_user nb_group [size] [date] [time] notebooks.zip\n", + "-rw-rw-r-- 1 nb_user nb_group [size] [date] [time] jupyter.png\n", + "-rw-rw-r-- 1 nb_user nb_group [size] [date] [time] notebooks.zip\n", "-rw------- 1 nb_user nb_group [size] [date] [time] ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n" ] } @@ -256,7 +257,8 @@ "output_type": "stream", "text": [ "total ##\n", - "-rw-r--r-- 1 nb_user nb_group [size] [date] [time] notebooks.zip\n", + "-rw-rw-r-- 1 nb_user nb_group [size] [date] [time] jupyter.png\n", + "-rw-rw-r-- 1 nb_user nb_group [size] [date] [time] notebooks.zip\n", "-rw------- 1 nb_user nb_group [size] [date] [time] ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n" ] } @@ -352,11 +354,15 @@ "[ZipCollectApp | INFO] Using file extractor: ExtractorPlugin\n", "[ZipCollectApp | INFO] Using file collector: FileNameCollectorPlugin\n", "[ZipCollectApp | WARNING] Directory not found. Creating: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted\n", - "[ZipCollectApp | INFO] Copying from: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/archive/ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n", - "[ZipCollectApp | INFO] Copying to: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n", + "[ZipCollectApp | INFO] Copying from: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/archive/jupyter.png\n", + "[ZipCollectApp | INFO] Copying to: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/jupyter.png\n", "[ZipCollectApp | INFO] Extracting from: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/archive/notebooks.zip\n", "[ZipCollectApp | INFO] Extracting to: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/notebooks\n", + "[ZipCollectApp | INFO] Copying from: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/archive/ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n", + "[ZipCollectApp | INFO] Copying to: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n", "[ZipCollectApp | INFO] Start collecting files...\n", + "[ZipCollectApp | INFO] Parsing file: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/jupyter.png\n", + "[ZipCollectApp | WARNING] Skipped submission with no match information provided: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/jupyter.png\n", "[ZipCollectApp | INFO] Parsing file: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/notebooks/ps1_bitdiddle_attempt_2016-01-30-15-30-10_jupyter.png\n", "[ZipCollectApp | WARNING] Skipped submission with no match information provided: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/notebooks/ps1_bitdiddle_attempt_2016-01-30-15-30-10_jupyter.png\n", "[ZipCollectApp | INFO] Parsing file: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/notebooks/ps1_bitdiddle_attempt_2016-01-30-15-30-10_problem1.ipynb\n", @@ -367,7 +373,7 @@ "[ZipCollectApp | WARNING] Skipped notebook with invalid name 'myproblem1.ipynb'\n", "[ZipCollectApp | INFO] Parsing file: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/notebooks/ps1_hacker_attempt_2016-01-30-16-30-10_problem2.ipynb\n", "[ZipCollectApp | INFO] Parsing file: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n", - "[ZipCollectApp | WARNING] 4 files collected, 3 files skipped\n", + "[ZipCollectApp | WARNING] 4 files collected, 4 files skipped\n", "[ZipCollectApp | INFO] Start transfering files...\n", "[ZipCollectApp | WARNING] Directory not found. Creating: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/submitted_zip/bitdiddle/ps1\n", "[ZipCollectApp | INFO] Copying from: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/notebooks/ps1_bitdiddle_attempt_2016-01-30-15-30-10_problem1.ipynb\n", @@ -407,7 +413,8 @@ "output_type": "stream", "text": [ "total ##\n", - "drwxr-xr-x 1 nb_user nb_group [size] [date] [time] notebooks\n", + "-rw-rw-r-- 1 nb_user nb_group [size] [date] [time] jupyter.png\n", + "drwxrwxr-x 1 nb_user nb_group [size] [date] [time] notebooks\n", "-rw------- 1 nb_user nb_group [size] [date] [time] ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n", "total ##\n", "-rw-rw-r-- 1 nb_user nb_group [size] [date] [time] ps1_bitdiddle_attempt_2016-01-30-15-30-10_jupyter.png\n", @@ -445,8 +452,8 @@ "output_type": "stream", "text": [ "total ##\n", - "drwxr-xr-x 1 nb_user nb_group [size] [date] [time] bitdiddle\n", - "drwxr-xr-x 1 nb_user nb_group [size] [date] [time] hacker\n" + "drwxrwxr-x 1 nb_user nb_group [size] [date] [time] bitdiddle\n", + "drwxrwxr-x 1 nb_user nb_group [size] [date] [time] hacker\n" ] } ], @@ -468,7 +475,7 @@ "total ##\n", "-rw------- 1 nb_user nb_group [size] [date] [time] problem1.ipynb\n", "-rw-rw-r-- 1 nb_user nb_group [size] [date] [time] problem2.ipynb\n", - "-rw-r--r-- 1 nb_user nb_group [size] [date] [time] timestamp.txt\n" + "-rw-rw-r-- 1 nb_user nb_group [size] [date] [time] timestamp.txt\n" ] } ], @@ -564,11 +571,15 @@ "[ZipCollectApp | INFO] Using file extractor: ExtractorPlugin\n", "[ZipCollectApp | INFO] Using file collector: CustomPlugin\n", "[ZipCollectApp | WARNING] Clearing existing files in [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted\n", - "[ZipCollectApp | INFO] Copying from: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/archive/ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n", - "[ZipCollectApp | INFO] Copying to: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n", + "[ZipCollectApp | INFO] Copying from: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/archive/jupyter.png\n", + "[ZipCollectApp | INFO] Copying to: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/jupyter.png\n", "[ZipCollectApp | INFO] Extracting from: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/archive/notebooks.zip\n", "[ZipCollectApp | INFO] Extracting to: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/notebooks\n", + "[ZipCollectApp | INFO] Copying from: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/archive/ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n", + "[ZipCollectApp | INFO] Copying to: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n", "[ZipCollectApp | INFO] Start collecting files...\n", + "[ZipCollectApp | INFO] Parsing file: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/jupyter.png\n", + "[ZipCollectApp | WARNING] Skipped submission with no match information provided: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/jupyter.png\n", "[ZipCollectApp | INFO] Parsing file: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/notebooks/ps1_bitdiddle_attempt_2016-01-30-15-30-10_jupyter.png\n", "[ZipCollectApp | WARNING] Skipped submission with no match information provided: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/notebooks/ps1_bitdiddle_attempt_2016-01-30-15-30-10_jupyter.png\n", "[ZipCollectApp | INFO] Parsing file: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/notebooks/ps1_bitdiddle_attempt_2016-01-30-15-30-10_problem1.ipynb\n", @@ -579,7 +590,7 @@ "[ZipCollectApp | WARNING] Skipped notebook with invalid name 'myproblem1.ipynb'\n", "[ZipCollectApp | INFO] Parsing file: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/notebooks/ps1_hacker_attempt_2016-01-30-16-30-10_problem2.ipynb\n", "[ZipCollectApp | INFO] Parsing file: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n", - "[ZipCollectApp | WARNING] 4 files collected, 3 files skipped\n", + "[ZipCollectApp | WARNING] 4 files collected, 4 files skipped\n", "[ZipCollectApp | INFO] Start transfering files...\n", "[ZipCollectApp | WARNING] Clearing existing files in [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/submitted_zip/bitdiddle/ps1\n", "[ZipCollectApp | INFO] Copying from: [NB_GRADER_ROOT]/nbgrader/docs/source/user_guide/downloaded/ps1/extracted/notebooks/ps1_bitdiddle_attempt_2016-01-30-15-30-10_problem1.ipynb\n", diff --git a/nbgrader/docs/source/user_guide/managing_assignment_files_nb.ipynb b/nbgrader/docs/source/user_guide/managing_assignment_files_nb.ipynb deleted file mode 100644 index fd61b9b5c..000000000 --- a/nbgrader/docs/source/user_guide/managing_assignment_files_nb.ipynb +++ /dev/null @@ -1,901 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Exchanging assignment files (classic Notebook)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Distributing assignments to students and collecting them can be a logistical nightmare. If you are running nbgrader on a server, some of this pain can be relieved by relying on nbgrader's built-in functionality for releasing and collecting assignments on the instructor's side, and fetching and submitting assignments on the student's side. \n", - "\n", - "This page describes the built-in implementation of an **exchange directory** coupled with instructor and student interfaces - both integrated in the Jupyter interface and via the command line. Since nbgrader 0.7.0, the exchange is modular, and a different implementation could be used (with the same user interface as below)." - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. contents:: Table of Contents\n", - " :depth: 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Setting up the exchange" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "After an assignment has been created using `nbgrader generate_assignment`, the instructor must actually release that assignment to students. If the class is being taught on a single filesystem, then the instructor may use `nbgrader release_assignment` to copy the assignment files to a shared location on the filesystem for students to then download.\n", - "\n", - "First, we must specify a few configuration options. To do this, we'll create a `nbgrader_config.py` file that will get automatically loaded when we run `nbgrader`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%file nbgrader_config.py\n", - "\n", - "c = get_config()\n", - "\n", - "c.CourseDirectory.course_id = \"example_course\"\n", - "c.Exchange.root = \"/tmp/exchange\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the config file, we've specified the \"exchange\" directory to be `/tmp/exchange`. This directory must exist before running `nbgrader`, and it *must* be readable and writable by all users, so we'll first create it and configure the appropriate permissions:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "# remove existing directory, so we can start fresh for demo purposes\n", - "rm -rf /tmp/exchange\n", - "\n", - "# create the exchange directory, with write permissions for everyone\n", - "mkdir /tmp/exchange\n", - "chmod ugo+rw /tmp/exchange" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Releasing assignments" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. seealso::\n", - "\n", - " :doc:`creating_and_grading_assignments_nb`\n", - " Details on generating assignments\n", - "\n", - " :doc:`/command_line_tools/nbgrader-release-assignment`\n", - " Command line options for ``nbgrader release_assignment``\n", - "\n", - " :doc:`/command_line_tools/nbgrader-list`\n", - " Command line options for ``nbgrader list``\n", - "\n", - " :doc:`philosophy`\n", - " More details on how the nbgrader hierarchy is structured.\n", - "\n", - " :doc:`/configuration/config_options`\n", - " Details on ``nbgrader_config.py``" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the formgrader" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Using the formgrader extension, you may release assignments by clicking on the \"release\" button:\n", - "\n", - "![manage assignments release](images/classic_notebook/manage_assignments5.png)\n", - "\n", - "**Note** that for the \"release\" button to become available, the `course_id` option must be set in `nbgrader_config.py`.\n", - "Once completed, you will see a pop-up window with log output:\n", - "\n", - "![release assignment](images/classic_notebook/release_assignment.png)\n", - "\n", - "If you decide you want to \"un-release\" an assignment, you may do so by clicking again on the \"release\" button (which is now an \"x\"). **However, note that students who have already downloaded the assignment will still have access to their downloaded copy. Unreleasing an assignment only prevents more students from downloading it.**\n", - "\n", - "![manage assignments un-release](images/classic_notebook/manage_assignments6.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the command line" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now that we have the directory created, we can actually run `nbgrader release_assignment` (and as with the other nbgrader commands for instructors, this must be run from the root of the course directory):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "nbgrader release_assignment \"ps1\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, you can verify that the assignment has been appropriately released by running the `nbgrader list` command:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "nbgrader list" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that there should only ever be *one* instructor who runs the `nbgrader release_assignment` and `nbgrader collect` commands (and there should probably only be one instructor -- the same instructor -- who runs `nbgrader generate_assignment`, `nbgrader autograde` and the formgrader as well). However this does not mean that only one instructor can do the grading, it just means that only one instructor manages the assignment files. Other instructors can still perform grading by accessing the notebook where the formgrader is running." - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. _fetching-assignments-classic-nb:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Fetching assignments" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. seealso::\n", - "\n", - " :doc:`/command_line_tools/nbgrader-fetch-assignment`\n", - " Command line options for ``nbgrader fetch_assignment``\n", - "\n", - " :doc:`/command_line_tools/nbgrader-list`\n", - " Command line options for ``nbgrader list``\n", - "\n", - " :doc:`/configuration/config_options`\n", - " Details on ``nbgrader_config.py``" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "From the student's perspective, they can list what assignments have been released, and then fetch a copy of the assignment to work on. First, we'll create a temporary directory to represent the student's home directory:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "# remove the fake student home directory if it exists, for demo purposes\n", - "rm -rf /tmp/student_home\n", - "\n", - "# create the fake student home directory and switch to it\n", - "mkdir /tmp/student_home" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you are not using the default exchange directory (as is the case here), you will additionally need to provide your students with a configuration file that sets the appropriate directory for them:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%file /tmp/student_home/nbgrader_config.py\n", - "\n", - "c = get_config()\n", - "c.Exchange.root = '/tmp/exchange'\n", - "c.CourseDirectory.course_id = \"example_course\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the notebook dashboard" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. warning::\n", - "\n", - " The \"Assignment List\" extension is not fully compatible with multiple\n", - " courses on the same server. Please see :ref:`multiple-classes` for details.\n", - "\n", - "Alternatively, students can fetch assignments using the assignment list notebook server extension. You must have installed the extension by following the instructions :doc:`here `, after which you should see an \"Assignments\" tab in dashboard:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "![assignment list released](images/classic_notebook/assignment_list_released.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The image above shows that there has been one assignment released (\"ps1\") for the class \"example_course\". To get this assignment, students can click the \"Fetch\" button (analogous to running `nbgrader fetch_assignment ps1 --course example_course`. **Note: this assumes nbgrader is always run from the root of the notebook server, which on JupyterHub is most likely the root of the user's home directory.**\n", - "\n", - "After the assignment is fetched, it will appear in the list of \"Downloaded assignments\":\n", - "\n", - "![assignment list downloaded](images/classic_notebook/assignment_list_downloaded.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Students can click on the name of the assignment to expand it and see all the notebooks in the assignment:\n", - "\n", - "![assignment list downloaded expanded](images/classic_notebook/assignment_list_downloaded_expanded.png)\n", - "\n", - "Clicking on a particular notebook will open it in a new tab in the browser." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the command line" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "From the student's perspective, they can see what assignments have been released using `nbgrader list`, and passing the name of the class:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "export HOME=/tmp/student_home && cd $HOME\n", - "\n", - "nbgrader list" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "They can then fetch an assignment for that class using `nbgrader fetch_assignment` and passing the name of the class and the name of the assignment:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "export HOME=/tmp/student_home && cd $HOME\n", - "\n", - "nbgrader fetch_assignment \"ps1\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that running `nbgrader fetch_assignment` copies the assignment files from the exchange directory to the local directory, and therefore can be used from any directory:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "ls -l \"/tmp/student_home/ps1\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Additionally, the `nbgrader fetch_assignment` (as well as `nbgrader submit`) command also does not rely on having access to the nbgrader database -- the database is only used by instructors." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Submitting assignments" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. seealso::\n", - "\n", - " :doc:`/command_line_tools/nbgrader-submit`\n", - " Command line options for ``nbgrader submit``\n", - "\n", - " :doc:`/command_line_tools/nbgrader-list`\n", - " Command line options for ``nbgrader list``\n", - "\n", - " :doc:`/configuration/config_options`\n", - " Details on ``nbgrader_config.py``" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the notebook dashboard" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. warning::\n", - "\n", - " The \"Assignment List\" extension is not fully compatible with multiple\n", - " courses on the same server. Please see :ref:`multiple-classes` for details.\n", - "\n", - "Alternatively, students can submit assignments using the assignment list notebook server extension. You must have installed the extension by following the instructions `here `__. Students must have also downloaded the assignments (see :ref:`fetching-assignments`)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "After students have worked on the assignment for a while, but before submitting, they can validate that their notebooks pass the tests by clicking the \"Validate\" button (analogous to running `nbgrader validate`). If any tests fail, they will see a warning:\n", - "\n", - "![assignment list validate failed](images/classic_notebook/assignment_list_validate_failed.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If there are no errors, they will see that the validation passes:\n", - "\n", - "![assignment list validate succeeded](images/classic_notebook/assignment_list_validate_succeeded.png)" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. note::\n", - "\n", - " If the notebook has been released with hidden tests removed from the source version\n", - " (see :ref:`autograder-tests-cell-hidden-tests`) then this validation is only done against the tests the students can\n", - " see in the release version." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Once students have validated all the notebooks, they can click the \"Submit\" button to submit the assignment (analogous to running `nbgrader submit ps1 --course example_course`). Afterwards, it will show up in the list of submitted assignments (and also still in the list of downloaded assignments):\n", - "\n", - "![assignment list submitted](images/classic_notebook/assignment_list_submitted.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Students may submit an assignment as many times as they'd like. All copies of a submission will show up in the submitted assignments list, and when the instructor collects the assignments, they will get the most recent version of the assignment:\n", - "\n", - "![assignment list submitted again](images/classic_notebook/assignment_list_submitted_again.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Similarly, if the ``strict`` option (in the student's ``nbgrader_config.py`` file) is set to ``True``, the students will not be able to submit an assignment with missing notebooks (for a given assignment):\n", - "\n", - "![assignment list submit error](images/classic_notebook/assignment_list_submit_error.jpg)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the command line" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First, as a reminder, here is what the student's `nbgrader_config.py` file looks like:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "cat /tmp/student_home/nbgrader_config.py" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "After working on an assignment, the student can submit their version for grading using `nbgrader submit` and passing the name of the assignment and the name of the class:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "export HOME=/tmp/student_home && cd $HOME\n", - "\n", - "nbgrader submit \"ps1\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that \"the name of the assignment\" really corresponds to \"the name of a folder\". It just happens that, in our current directory, there is a folder called \"ps1\":" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "export HOME=/tmp/student_home && cd $HOME\n", - "\n", - "ls -l \"/tmp/student_home\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Students can see what assignments they have submitted using `nbgrader list --inbound`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "export HOME=/tmp/student_home && cd $HOME\n", - "\n", - "nbgrader list --inbound" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Importantly, students can run `nbgrader submit` as many times as they want, and all submitted copies of the assignment will be preserved:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "export HOME=/tmp/student_home && cd $HOME\n", - "\n", - "nbgrader submit \"ps1\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can see all versions that have been submitted by again running `nbgrader list --inbound`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "export HOME=/tmp/student_home && cd $HOME\n", - "\n", - "nbgrader list --inbound" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that the `nbgrader submit` (as well as `nbgrader fetch_assignment`) command also does not rely on having access to the nbgrader database -- the database is only used by instructors." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "``nbgrader`` requires that the submitted notebook names match the released notebook names for each assignment. For example if a student were to rename one of the given assignment notebooks:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "export HOME=/tmp/student_home && cd $HOME\n", - "\n", - "# assume the student renamed the assignment file\n", - "mv ps1/problem1.ipynb ps1/myproblem1.ipynb\n", - "\n", - "nbgrader submit \"ps1\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "By default this assignment will still be submitted however only the \"FOUND\" notebooks (for the given assignment) can be ``autograded`` and will appear on the ``formgrade`` extension. \"EXTRA\" notebooks will not be ``autograded`` and will not appear on the ``formgrade`` extension." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To ensure that students cannot submit an assignment with missing notebooks (for a given assignment) the ``strict`` option, in the student's ``nbgrader_config.py`` file, can be set to ``True``:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%file /tmp/student_home/nbgrader_config.py\n", - "\n", - "c = get_config()\n", - "c.Exchange.root = '/tmp/exchange'\n", - "c.CourseDirectory.course_id = \"example_course\"\n", - "c.ExchangeSubmit.strict = True" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "raises-exception" - ], - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "export HOME=/tmp/student_home && cd $HOME\n", - "\n", - "nbgrader submit \"ps1\" || true" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Collecting assignments" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - ".. seealso::\n", - "\n", - " :doc:`creating_and_grading_assignments_nb`\n", - " Details on grading assignments after they have been collected\n", - "\n", - " :doc:`/command_line_tools/nbgrader-collect`\n", - " Command line options for ``nbgrader collect``\n", - "\n", - " :doc:`/command_line_tools/nbgrader-list`\n", - " Command line options for ``nbgrader list``\n", - "\n", - " :doc:`philosophy`\n", - " More details on how the nbgrader hierarchy is structured.\n", - "\n", - " :doc:`/configuration/config_options`\n", - " Details on ``nbgrader_config.py``" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First, as a reminder, here is what the instructor's `nbgrader_config.py` file looks like:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "cat nbgrader_config.py" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the formgrader" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "From the formgrader extension, we can collect submissions by clicking on the \"collect\" button:\n", - "\n", - "![manage assignments collect](images/classic_notebook/manage_assignments7.png)\n", - "\n", - "As with releasing, this will display a pop-up window when the operation is complete, telling you how many submissions were collected:\n", - "\n", - "![collect assignment](images/classic_notebook/collect_assignment.png)\n", - "\n", - "From here, you can click on the number of submissions to grade the collected submissions:\n", - "\n", - "![manage assignments grade collected](images/classic_notebook/manage_assignments8.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### From the command line" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "After students have submitted their assignments, the instructor can view what has been submitted with `nbgrader list --inbound`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "nbgrader list --inbound" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The instructor can then collect all submitted assignments with `nbgrader collect` and passing the name of the assignment (and as with the other nbgrader commands for instructors, this must be run from the root of the course directory):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "nbgrader collect \"ps1\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This will copy the student submissions to the `submitted` folder in a way that is automatically compatible with `nbgrader autograde`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "ls -l submitted" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that there should only ever be *one* instructor who runs the `nbgrader release_assignment` and `nbgrader collect` commands (and there should probably only be one instructor -- the same instructor -- who runs `nbgrader generate_assignment`, `nbgrader autograde` and the formgrader as well). However this does not mean that only one instructor can do the grading, it just means that only one instructor manages the assignment files. Other instructors can still perform grading by accessing the notebook server running the formgrader." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python", - "language": "python", - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -}