Ejemplo n.º 1
0
def test_average_notebook_score(assignment: Gradebook) -> None:
    assert assignment.average_notebook_score('p1', 'foo') == 0
    assert assignment.average_notebook_code_score('p1', 'foo') == 0
    assert assignment.average_notebook_written_score('p1', 'foo') == 0

    assignment.add_student('hacker123')
    assignment.add_student('bitdiddle')
    assignment.add_submission('foo', 'hacker123')
    assignment.add_submission('foo', 'bitdiddle')

    assert assignment.average_notebook_score('p1', 'foo') == 0.0
    assert assignment.average_notebook_code_score('p1', 'foo') == 0.0
    assert assignment.average_notebook_written_score('p1', 'foo') == 0.0

    g1 = assignment.find_grade("test1", "p1", "foo", "hacker123")
    g2 = assignment.find_grade("test2", "p1", "foo", "hacker123")
    g3 = assignment.find_grade("test1", "p1", "foo", "bitdiddle")
    g4 = assignment.find_grade("test2", "p1", "foo", "bitdiddle")

    g1.manual_score = 0.5
    g2.manual_score = 2
    g3.manual_score = 1
    g4.manual_score = 1
    assignment.db.commit()

    assert assignment.average_notebook_score('p1', 'foo') == 2.25
    assert assignment.average_notebook_code_score('p1', 'foo') == 0.75
    assert assignment.average_notebook_written_score('p1', 'foo') == 1.5
Ejemplo n.º 2
0
def gradebook(request, tempdir):
    # create a "class files" directory
    origdir = os.getcwd()
    os.mkdir("class_files")
    os.chdir("class_files")

    # copy files from the user guide
    source_path = os.path.join(os.path.dirname(__file__), "..", "..", "..", "docs", "source", "user_guide", "source")
    submitted_path = os.path.join(os.path.dirname(__file__), "..", "..", "..", "docs", "source", "user_guide", "submitted")

    shutil.copytree(os.path.join(os.path.dirname(__file__), source_path), "source")
    shutil.copytree(os.path.join(os.path.dirname(__file__), submitted_path), "submitted")

    # create the gradebook
    gb = Gradebook("sqlite:///gradebook.db")
    gb.add_assignment("Problem Set 1")
    gb.add_student("Bitdiddle", first_name="Ben", last_name="B")
    gb.add_student("Hacker", first_name="Alyssa", last_name="H")
    gb.add_student("Reasoner", first_name="Louis", last_name="R")

    # run nbgrader assign
    run_command([
        "nbgrader", "assign", "Problem Set 1",
        "--IncludeHeaderFooter.header=source/header.ipynb"
    ])

    # run the autograder
    run_command(["nbgrader", "autograde", "Problem Set 1"])

    def fin():
        os.chdir(origdir)
        shutil.rmtree("class_files")
    request.addfinalizer(fin)

    return gb
Ejemplo n.º 3
0
 def _setup_db(self):
     dbpath = self._init_db()
     gb = Gradebook(dbpath)
     gb.add_assignment("ps1", duedate="2015-02-02 14:58:23.948203 PST")
     gb.add_student("foo")
     gb.add_student("bar")
     return dbpath
Ejemplo n.º 4
0
    def init_assignment(self, assignment_id, student_id):
        super(AutogradeApp, self).init_assignment(assignment_id, student_id)

        # try to get the student from the database, and throw an error if it
        # doesn't exist
        gb = Gradebook(self.db_url)
        try:
            gb.find_student(student_id)
        except MissingEntry:
            if self.create_student:
                self.log.warning("Creating student with ID '%s'", student_id)
                gb.add_student(student_id)
            else:
                self.fail("No student with ID '%s' exists in the database", student_id)

        # try to read in a timestamp from file
        src_path = self._format_source(assignment_id, student_id)
        timestamp = self._get_existing_timestamp(src_path)
        if timestamp:
            submission = gb.update_or_create_submission(
                assignment_id, student_id, timestamp=timestamp)
            self.log.info("%s submitted at %s", submission, timestamp)

            # if the submission is late, print out how many seconds late it is
            if timestamp and submission.total_seconds_late > 0:
                self.log.warning("%s is %s seconds late", submission, submission.total_seconds_late)

        else:
            submission = gb.update_or_create_submission(assignment_id, student_id)

        # copy files over from the source directory
        self.log.info("Overwriting files with master versions from the source directory")
        dest_path = self._format_dest(assignment_id, student_id)
        source_path = self.directory_structure.format(
            nbgrader_step=self.source_directory,
            student_id='.',
            assignment_id=assignment_id)
        source_files = utils.find_all_files(source_path, self.ignore + ["*.ipynb"])

        # copy them to the build directory
        for filename in source_files:
            dest = os.path.join(dest_path, os.path.relpath(filename, source_path))
            ensure_dir_exists(os.path.dirname(dest))
            if not os.path.normpath(dest) == os.path.normpath(filename):
                self.log.info("Linking %s -> %s", filename, dest)
                link_or_copy(filename, dest)

        # ignore notebooks that aren't in the database
        notebooks = []
        for notebook in self.notebooks:
            notebook_id = os.path.splitext(os.path.basename(notebook))[0]
            try:
                gb.find_notebook(notebook_id, assignment_id)
            except MissingEntry:
                self.log.warning("Skipping unknown notebook: %s", notebook)
                continue
            else:
                notebooks.append(notebook)
        self.notebooks = notebooks
Ejemplo n.º 5
0
def assignmentWithSubmissionNoMarks(assignmentWithTask: Gradebook) -> Gradebook:
    assignmentWithTask.add_student('hacker123')
    assignmentWithTask.add_student('bitdiddle')
    assignmentWithTask.add_student('louisreasoner')
    s1 = assignmentWithTask.add_submission('foo', 'hacker123')
    s2 = assignmentWithTask.add_submission('foo', 'bitdiddle')
    s1.flagged = True
    s2.flagged = False
    assignmentWithTask.db.commit()
    return assignmentWithTask
    def test_remove_student_db(self, tmpdir_factory):
        self._mock_remove_student()
        tmp_dir = tmpdir_factory.mktemp(self.course_id)
        os.chdir(tmp_dir)
        self._add_empty_gradebook(tmp_dir)
        gb = Gradebook('sqlite:///gradebook.db', course_id=self.course_id)
        gb.add_student(self.student_id)

        # test valid
        cm.main(['remove_students', self.course_id, self.student_id])
        assert len(gb.students) == 0
Ejemplo n.º 7
0
    def test_add_extra_notebooks_with_submissions(self, db):
        """Is an error thrown when new notebooks are added and there are existing submissions?"""
        gb = Gradebook(db)
        assignment = gb.add_assignment("ps1")

        self._copy_file("files/test.ipynb", "source/ps1/test.ipynb")
        run_command('nbgrader assign ps1 --db="{}"'.format(db))

        gb.db.refresh(assignment)
        assert len(assignment.notebooks) == 1

        gb.add_student("hacker123")
        gb.add_submission("ps1", "hacker123")

        self._copy_file("files/test.ipynb", "source/ps1/test2.ipynb")
        run_command('nbgrader assign ps1 --db="{}" --force'.format(db), retcode=1)
Ejemplo n.º 8
0
    def test_remove_extra_notebooks_with_submissions(self, db):
        """Is an error thrown when notebooks are removed and there are existing submissions?"""
        gb = Gradebook(db)
        assignment = gb.add_assignment("ps1")

        self._copy_file("files/test.ipynb", "source/ps1/test.ipynb")
        self._copy_file("files/test.ipynb", "source/ps1/test2.ipynb")
        run_command(["nbgrader", "assign", "ps1", "--db", db])

        gb.db.refresh(assignment)
        assert len(assignment.notebooks) == 2

        gb.add_student("hacker123")
        gb.add_submission("ps1", "hacker123")

        os.remove("source/ps1/test2.ipynb")
        run_command(["nbgrader", "assign", "ps1", "--db", db, "--force"], retcode=1)
    def test_add_extra_notebooks_with_submissions(self, db):
        """Is an error thrown when new notebooks are added and there are existing submissions?"""
        gb = Gradebook(db)
        assignment = gb.add_assignment("ps1")

        self._copy_file("files/test.ipynb", "source/ps1/test.ipynb")
        run_command(["nbgrader", "assign", "ps1", "--db", db])

        gb.db.refresh(assignment)
        assert len(assignment.notebooks) == 1

        gb.add_student("hacker123")
        gb.add_submission("ps1", "hacker123")

        self._copy_file("files/test.ipynb", "source/ps1/test2.ipynb")
        run_command(["nbgrader", "assign", "ps1", "--db", db, "--force"],
                    retcode=1)
Ejemplo n.º 10
0
def class_files(request, tempdir):
    # copy files from the user guide
    source_path = os.path.join(os.path.dirname(__file__), "..", "..", "..", "docs", "source", "user_guide", "source")
    shutil.copytree(os.path.join(os.path.dirname(__file__), source_path), "source")

    # create a fake ps1
    os.mkdir(os.path.join("source", "ps1"))
    with open(os.path.join("source", "ps1", "problem 1.ipynb"), "w") as fh:
        write_nb(new_notebook(), fh, 4)

    # create the gradebook
    gb = Gradebook("sqlite:///gradebook.db")
    gb.add_assignment("Problem Set 1")
    gb.add_assignment("ps1")
    gb.add_student("Bitdiddle", first_name="Ben", last_name="B")
    gb.add_student("Hacker", first_name="Alyssa", last_name="H")
    gb.add_student("Reasoner", first_name="Louis", last_name="R")

    return tempdir
Ejemplo n.º 11
0
def gradebook(request, tempdir):
    # create a "class files" directory
    origdir = os.getcwd()
    os.mkdir("class_files")
    os.chdir("class_files")

    # copy files from the user guide
    source_path = os.path.join(os.path.dirname(__file__), "..", "..", "..",
                               "docs", "source", "user_guide", "source")
    submitted_path = os.path.join(os.path.dirname(__file__), "..", "..", "..",
                                  "docs", "source", "user_guide", "submitted")

    shutil.copytree(os.path.join(os.path.dirname(__file__), source_path),
                    "source")
    shutil.copytree(os.path.join(os.path.dirname(__file__), submitted_path),
                    "submitted")

    # create the gradebook
    gb = Gradebook("sqlite:///gradebook.db")
    gb.add_assignment("Problem Set 1")
    gb.add_student("Bitdiddle", first_name="Ben", last_name="B")
    gb.add_student("Hacker", first_name="Alyssa", last_name="H")
    gb.add_student("Reasoner", first_name="Louis", last_name="R")

    # run nbgrader assign
    run_command([
        "nbgrader", "assign", "Problem Set 1",
        "--IncludeHeaderFooter.header=source/header.ipynb"
    ])

    # run the autograder
    run_command(["nbgrader", "autograde", "Problem Set 1"])

    def fin():
        os.chdir(origdir)
        shutil.rmtree("class_files")

    request.addfinalizer(fin)

    return gb
Ejemplo n.º 12
0
    def test_same_notebooks_with_submissions(self, db):
        """Is it ok to run nbgrader assign with the same notebooks and existing submissions?"""
        gb = Gradebook(db)
        assignment = gb.add_assignment("ps1")

        self._copy_file("files/test.ipynb", "source/ps1/test.ipynb")
        run_command(["nbgrader", "assign", "ps1", "--db", db])

        gb.db.refresh(assignment)
        assert len(assignment.notebooks) == 1
        notebook = assignment.notebooks[0]

        gb.add_student("hacker123")
        submission = gb.add_submission("ps1", "hacker123")
        submission_notebook = submission.notebooks[0]

        run_command(["nbgrader", "assign", "ps1", "--db", db, "--force"])

        gb.db.refresh(assignment)
        assert len(assignment.notebooks) == 1
        gb.db.refresh(notebook)
        gb.db.refresh(submission)
        gb.db.refresh(submission_notebook)
Ejemplo n.º 13
0
    def test_same_notebooks_with_submissions(self, db):
        """Is it ok to run nbgrader assign with the same notebooks and existing submissions?"""
        gb = Gradebook(db)
        assignment = gb.add_assignment("ps1")

        self._copy_file("files/test.ipynb", "source/ps1/test.ipynb")
        run_command('nbgrader assign ps1 --db="{}"'.format(db))

        gb.db.refresh(assignment)
        assert len(assignment.notebooks) == 1
        notebook = assignment.notebooks[0]

        gb.add_student("hacker123")
        submission = gb.add_submission("ps1", "hacker123")
        submission_notebook = submission.notebooks[0]

        run_command('nbgrader assign ps1 --db="{}" --force'.format(db))

        gb.db.refresh(assignment)
        assert len(assignment.notebooks) == 1
        gb.db.refresh(notebook)
        gb.db.refresh(submission)
        gb.db.refresh(submission_notebook)
Ejemplo n.º 14
0
 def _setup_db(self):
     dbpath = self._init_db()
     gb = Gradebook(dbpath)
     gb.add_assignment("ps1")
     gb.add_student("foo")
     return dbpath
Ejemplo n.º 15
0
def gradebook(db):
    gb = Gradebook(db)
    gb.add_assignment("ps0")
    gb.add_student("bar")
    return gb
Ejemplo n.º 16
0
class TestSaveAutoGrades(TestBase):

    def setup(self):
        super(TestSaveAutoGrades, self).setup()
        db_url = self._init_db()
        self.gb = Gradebook(db_url)
        self.gb.add_assignment("ps0")
        self.gb.add_student("bar")

        self.preprocessor1 = SaveCells()
        self.preprocessor2 = SaveAutoGrades()
        self.resources = {
            "nbgrader": {
                "db_url": db_url,
                "assignment": "ps0",
                "notebook": "test",
                "student": "bar"
            }
        }

    def test_grade_correct_code(self):
        """Is a passing code cell correctly graded?"""
        cell = self._create_grade_cell("hello", "code", "foo", 1)
        nb = new_notebook()
        nb.cells.append(cell)
        self.preprocessor1.preprocess(nb, self.resources)
        self.gb.add_submission("ps0", "bar")
        self.preprocessor2.preprocess(nb, self.resources)

        grade_cell = self.gb.find_grade("foo", "test", "ps0", "bar")
        assert_equal(grade_cell.score, 1)
        assert_equal(grade_cell.max_score, 1)
        assert_equal(grade_cell.auto_score, 1)
        assert_equal(grade_cell.manual_score, None)
        assert not grade_cell.needs_manual_grade

    def test_grade_incorrect_code(self):
        """Is a failing code cell correctly graded?"""
        cell = self._create_grade_cell("hello", "code", "foo", 1)
        cell.outputs = [new_output('error', ename="NotImplementedError", evalue="", traceback=["error"])]
        nb = new_notebook()
        nb.cells.append(cell)
        self.preprocessor1.preprocess(nb, self.resources)
        self.gb.add_submission("ps0", "bar")
        self.preprocessor2.preprocess(nb, self.resources)

        grade_cell = self.gb.find_grade("foo", "test", "ps0", "bar")
        assert_equal(grade_cell.score, 0)
        assert_equal(grade_cell.max_score, 1)
        assert_equal(grade_cell.auto_score, 0)
        assert_equal(grade_cell.manual_score, None)
        assert not grade_cell.needs_manual_grade

    def test_grade_unchanged_markdown(self):
        """Is an unchanged markdown cell correctly graded?"""
        cell = self._create_grade_and_solution_cell("hello", "markdown", "foo", 1)
        nb = new_notebook()
        nb.cells.append(cell)
        self.preprocessor1.preprocess(nb, self.resources)
        self.gb.add_submission("ps0", "bar")
        self.preprocessor2.preprocess(nb, self.resources)

        grade_cell = self.gb.find_grade("foo", "test", "ps0", "bar")
        assert_equal(grade_cell.score, 0)
        assert_equal(grade_cell.max_score, 1)
        assert_equal(grade_cell.auto_score, 0)
        assert_equal(grade_cell.manual_score, None)
        assert not grade_cell.needs_manual_grade

    def test_grade_changed_markdown(self):
        """Is a changed markdown cell correctly graded?"""
        cell = self._create_grade_and_solution_cell("hello", "markdown", "foo", 1)
        nb = new_notebook()
        nb.cells.append(cell)
        self.preprocessor1.preprocess(nb, self.resources)
        self.gb.add_submission("ps0", "bar")
        cell.source = "hello!"
        self.preprocessor2.preprocess(nb, self.resources)

        grade_cell = self.gb.find_grade("foo", "test", "ps0", "bar")
        assert_equal(grade_cell.score, 0)
        assert_equal(grade_cell.max_score, 1)
        assert_equal(grade_cell.auto_score, None)
        assert_equal(grade_cell.manual_score, None)
        assert grade_cell.needs_manual_grade

    def test_comment_unchanged_code(self):
        """Is an unchanged code cell given the correct comment?"""
        cell = self._create_solution_cell("hello", "code")
        nb = new_notebook()
        nb.cells.append(cell)
        self.preprocessor1.preprocess(nb, self.resources)
        self.gb.add_submission("ps0", "bar")
        self.preprocessor2.preprocess(nb, self.resources)

        comment = self.gb.find_comment(0, "test", "ps0", "bar")
        assert_equal(comment.comment, "No response.")

    def test_comment_changed_code(self):
        """Is a changed code cell given the correct comment?"""
        cell = self._create_solution_cell("hello", "code")
        nb = new_notebook()
        nb.cells.append(cell)
        self.preprocessor1.preprocess(nb, self.resources)
        self.gb.add_submission("ps0", "bar")
        cell.source = "hello!"
        self.preprocessor2.preprocess(nb, self.resources)

        comment = self.gb.find_comment(0, "test", "ps0", "bar")
        assert_equal(comment.comment, None)

    def test_comment_unchanged_markdown(self):
        """Is an unchanged markdown cell given the correct comment?"""
        cell = self._create_grade_and_solution_cell("hello", "markdown", "foo", 1)
        nb = new_notebook()
        nb.cells.append(cell)
        self.preprocessor1.preprocess(nb, self.resources)
        self.gb.add_submission("ps0", "bar")
        self.preprocessor2.preprocess(nb, self.resources)

        comment = self.gb.find_comment(0, "test", "ps0", "bar")
        assert_equal(comment.comment, "No response.")

    def test_comment_changed_markdown(self):
        """Is a changed markdown cell given the correct comment?"""
        cell = self._create_grade_and_solution_cell("hello", "markdown", "foo", 1)
        nb = new_notebook()
        nb.cells.append(cell)
        self.preprocessor1.preprocess(nb, self.resources)
        self.gb.add_submission("ps0", "bar")
        cell.source = "hello!"
        self.preprocessor2.preprocess(nb, self.resources)

        comment = self.gb.find_comment(0, "test", "ps0", "bar")
        assert_equal(comment.comment, None)
Ejemplo n.º 17
0
def gradebook(db):
    gb = Gradebook(db)
    gb.add_assignment("ps1", duedate="2015-02-02 14:58:23.948203 PST")
    gb.add_student("foo")
    gb.add_student("bar")
    return db
Ejemplo n.º 18
0
def gradebook(db):
    gb = Gradebook(db)
    gb.add_assignment("ps1", duedate="2015-02-02 14:58:23.948203 PST")
    gb.add_student("foo")
    gb.add_student("bar")
    return db
Ejemplo n.º 19
0
# Create the database.
from nbgrader.api import Gradebook
gb = Gradebook('sqlite:///gradebook.db')

# Load the student data from disk.
import csv
dbReader = None
try:
    with open(studentDB) as dbFile:
        dbReader = csv.DictReader(dbFile)
        
        # Populate the database.
        for entry in dbReader:
            gb.add_student(entry['Net ID'],
                           first_name=entry['First Name'],
                           last_name=entry['Last Name'],
                           email='*****@*****.**'%entry['Net ID'])
except IOError as exc:
    print exc
    print 'Unable to access database at %s.'%dbFile

# Add some test students as well.
gb.add_student('stormhold',
               first_name='King',
               last_name='Stormhold',
               email='*****@*****.**'%'davis68')
gb.add_student('tristan',
               first_name='Tristan',
               last_name='of Wall',
               email='*****@*****.**'%'davis68')
gb.add_student('yvaine',
Ejemplo n.º 20
0
def gradebook(db):
    gb = Gradebook(db)
    gb.add_assignment("ps0")
    gb.add_student("bar")
    return gb
Ejemplo n.º 21
0
    def init_assignment(self, assignment_id, student_id):
        super(AutogradeApp, self).init_assignment(assignment_id, student_id)

        # try to get the student from the database, and throw an error if it
        # doesn't exist
        gb = Gradebook(self.db_url)
        try:
            gb.find_student(student_id)
        except MissingEntry:
            if self.create_student:
                self.log.warning("Creating student with ID '%s'", student_id)
                gb.add_student(student_id)
            else:
                self.fail("No student with ID '%s' exists in the database",
                          student_id)

        # try to read in a timestamp from file
        src_path = self._format_source(assignment_id, student_id)
        timestamp = self._get_existing_timestamp(src_path)
        if timestamp:
            submission = gb.update_or_create_submission(assignment_id,
                                                        student_id,
                                                        timestamp=timestamp)
            self.log.info("%s submitted at %s", submission, timestamp)

            # if the submission is late, print out how many seconds late it is
            if timestamp and submission.total_seconds_late > 0:
                self.log.warning("%s is %s seconds late", submission,
                                 submission.total_seconds_late)

        else:
            submission = gb.update_or_create_submission(
                assignment_id, student_id)

        # copy files over from the source directory
        self.log.info(
            "Overwriting files with master versions from the source directory")
        dest_path = self._format_dest(assignment_id, student_id)
        source_path = self.directory_structure.format(
            nbgrader_step=self.source_directory,
            student_id='.',
            assignment_id=assignment_id)
        source_files = utils.find_all_files(source_path,
                                            self.ignore + ["*.ipynb"])

        # copy them to the build directory
        for filename in source_files:
            dest = os.path.join(dest_path,
                                os.path.relpath(filename, source_path))
            ensure_dir_exists(os.path.dirname(dest))
            if not os.path.normpath(dest) == os.path.normpath(filename):
                self.log.info("Linking %s -> %s", filename, dest)
                link_or_copy(filename, dest)

        # ignore notebooks that aren't in the database
        notebooks = []
        for notebook in self.notebooks:
            notebook_id = os.path.splitext(os.path.basename(notebook))[0]
            try:
                gb.find_notebook(notebook_id, assignment_id)
            except MissingEntry:
                self.log.warning("Skipping unknown notebook: %s", notebook)
                continue
            else:
                notebooks.append(notebook)
        self.notebooks = notebooks