Repository: jupyter/nbgrader

Issue:
Error generating assignment and managing students
Firstly, I apologize if this is not the proper place to report issues like this.  I am exploring nbgrader, and have had some trouble getting it to work.

I have installed nbgrader on a local Jupyterhub installation and have been working through the example notebooks.

I had to create a `~/.jupyter/nbgrader_config.py` file that has the following contents:
```
c = get_config()
c.CourseDirectory.root = '~/Jupyter/ChEn6703_test_nbgrader'
```
(note that I used the full path above, but replaced the prefix with `~` for security reasons)

There are a few strange things going on though:

## Problems with student entries
1. When I go to the `Manage Students` section of nbgrader, it doesn't show any students.
1. When I do `nbgrader db student list --log-level='DEBUG'` I get something which is inconsistent with the empty list in the `Manage Students` dialog.
```
[DbStudentListApp | DEBUG] Searching ['~/Jupyter/ChEn6703_test_nbgrader', '~/.jupyter', '/usr/etc/jupyter', '/usr/local/etc/jupyter', '/etc/jupyter'] for config files
[DbStudentListApp | DEBUG] Looking for jupyter_config in /etc/jupyter
[DbStudentListApp | DEBUG] Looking for jupyter_config in /usr/local/etc/jupyter
[DbStudentListApp | DEBUG] Looking for jupyter_config in /usr/etc/jupyter
[DbStudentListApp | DEBUG] Looking for jupyter_config in ~/.jupyter
[DbStudentListApp | DEBUG] Looking for jupyter_config in ~/Jupyter/ChEn6703_test_nbgrader
[DbStudentListApp | DEBUG] Looking for nbgrader_config in /etc/jupyter
[DbStudentListApp | DEBUG] Looking for nbgrader_config in /usr/local/etc/jupyter
[DbStudentListApp | DEBUG] Looking for nbgrader_config in /usr/etc/jupyter
[DbStudentListApp | DEBUG] Looking for nbgrader_config in ~/.jupyter
[DbStudentListApp | DEBUG] Loaded config file: ~/.jupyter/nbgrader_config.py
[DbStudentListApp | DEBUG] Looking for nbgrader_config in ~/Jupyter/ChEn6703_test_nbgrader
[DbStudentListApp | DEBUG] Loaded config file: ~/Jupyter/ChEn6703_test_nbgrader/nbgrader_conf
ig.py
[DbStudentListApp | DEBUG] Looking for nbgrader_config in ~/Jupyter/ChEn6703_test_nbgrader
[DbStudentListApp | DEBUG] Loaded config file: ~/Jupyter/ChEn6703_test_nbgrader/nbgrader_conf
ig.py
There are 1 students in the database:
1 (Flinstone, Fred) -- None
```
3. If I manually enter a student in the `Manage Students` dialog, the student shows up and then disappears.

## Problems when generating the assignment
When I go to `Manage Assignments` and click on the `Generate` icon for the example `ps1` assignment, I get:
```
[INFO] Copying ~/Jupyter/ChEn6703_test_nbgrader/source/./ps1/jupyter.png -> ~/Jupyter/ChEn6703_test_nbgrader/release/./ps1/jupyter.png
[INFO] Updating/creating assignment 'ps1': {}
[INFO] Converting notebook ~/Jupyter/ChEn6703_test_nbgrader/source/./ps1/problem1.ipynb
[ERROR] There was an error processing assignment: ~/Jupyter/ChEn6703_test_nbgrader/source/./ps1
[ERROR] Traceback (most recent call last):
      File "/usr/local/lib/python3.5/dist-packages/nbgrader/converters/base.py", line 288, in convert_notebooks
        self.convert_single_notebook(notebook_filename)
      File "/usr/local/lib/python3.5/dist-packages/nbgrader/converters/base.py", line 244, in convert_single_notebook
        output, resources = self.exporter.from_filename(notebook_filename, resources=resources)
      File "/usr/local/lib/python3.5/dist-packages/nbconvert/exporters/exporter.py", line 172, in from_filename
        return self.from_file(f, resources=resources, **kw)
      File "/usr/local/lib/python3.5/dist-packages/nbconvert/exporters/exporter.py", line 190, in from_file
        return self.from_notebook_node(nbformat.read(file_stream, as_version=4), resources=resources, **kw)
      File "/usr/local/lib/python3.5/dist-packages/nbconvert/exporters/notebook.py", line 31, in from_notebook_node
        nb_copy, resources = super(NotebookExporter, self).from_notebook_node(nb, resources, **kw)
      File "/usr/local/lib/python3.5/dist-packages/nbconvert/exporters/exporter.py", line 132, in from_notebook_node
        nb_copy, resources = self._preprocess(nb_copy, resources)
      File "/usr/local/lib/python3.5/dist-packages/nbconvert/exporters/exporter.py", line 309, in _preprocess
        nbc, resc = preprocessor(nbc, resc)
      File "/usr/local/lib/python3.5/dist-packages/nbconvert/preprocessors/base.py", line 47, in __call__
        return self.preprocess(nb,resources)
      File "/usr/local/lib/python3.5/dist-packages/nbgrader/preprocessors/headerfooter.py", line 23, in preprocess
        with open(self.header, 'r') as fh:
    FileNotFoundError: [Errno 2] No such file or directory: 'source/header.ipynb'
    
[WARNING] Removing failed assignment: ~/Jupyter/ChEn6703_test_nbgrader/release/ps1
[ERROR] There was an error processing assignment 'ps1' for student '.'
[ERROR] Please see the the above traceback for details on the specific errors on the above failures.
Traceback
```
I have tried regenerating the entire class and this issue persists.

If I try the command line approach: `nbgrader assign source/ps1/` I get:
```
[AssignApp | ERROR] No notebooks were matched by ~/Jupyter/ChEn6703_test_nbgrader/source/./s
```
Note the `source/./s` which seems problematic.

Any ideas on this?

Discussion:
jhamrick: Turns out this fix is not actually correct, though. That's what I get for submitting a PR without running all the tests locally...

Patch:
diff --git a/nbgrader/api.py b/nbgrader/api.py
index cb9b552b..6c79aabc 100644
--- a/nbgrader/api.py
+++ b/nbgrader/api.py
@@ -2318,7 +2318,8 @@ class Gradebook(object):
             A list of dictionaries, one per student
 
         """
-        if len(self.assignments) > 0:
+        total_score, = self.db.query(func.sum(Assignment.max_score)).one()
+        if len(self.assignments) > 0 and total_score > 0:
             # subquery the scores
             scores = self.db.query(
                 Student.id,
@@ -2332,7 +2333,7 @@ class Gradebook(object):
             students = self.db.query(
                 Student.id, Student.first_name, Student.last_name,
                 Student.email, _scores,
-                func.sum(GradeCell.max_score)
+                func.sum(Assignment.max_score)
             ).outerjoin(scores, Student.id == scores.c.id)\
              .group_by(
                  Student.id, Student.first_name, Student.last_name,


Test patch:
diff --git a/nbgrader/tests/api/test_gradebook.py b/nbgrader/tests/api/test_gradebook.py
index 361a4def..69c181d1 100644
--- a/nbgrader/tests/api/test_gradebook.py
+++ b/nbgrader/tests/api/test_gradebook.py
@@ -728,6 +728,12 @@ def test_student_dicts(assignment):
     assert a == b
 
 
+def test_student_dicts_zero_points(gradebook):
+    gradebook.add_assignment("ps1")
+    s = gradebook.add_student("1234")
+    assert gradebook.student_dicts() == [s.to_dict()]
+
+
 def test_notebook_submission_dicts(assignment):
     assignment.add_student('hacker123')
     assignment.add_student('bitdiddle')