def test_compute_checksum_cell_type(): # does the cell type make a difference? cell1 = create_grade_cell("hello", "code", "foo", 1) cell2 = create_grade_cell("hello", "markdown", "foo", 1) assert utils.compute_checksum(cell1) != utils.compute_checksum(cell2) cell1 = create_solution_cell("hello", "code", "foo") cell2 = create_solution_cell("hello", "markdown", "foo") assert utils.compute_checksum(cell1) != utils.compute_checksum(cell2)
def test_compute_checksum_identical(self): # is the same for two identical cells? cell1 = self._create_grade_cell("hello", "code", "foo", 1) cell2 = self._create_grade_cell("hello", "code", "foo", 1) assert_equal(utils.compute_checksum(cell1), utils.compute_checksum(cell2)) cell1 = self._create_solution_cell("hello", "code") cell2 = self._create_solution_cell("hello", "code") assert_equal(utils.compute_checksum(cell1), utils.compute_checksum(cell2))
def test_compute_checksum_identical(): # is the same for two identical cells? cell1 = create_grade_cell("hello", "code", "foo", 1) cell2 = create_grade_cell("hello", "code", "foo", 1) assert utils.compute_checksum(cell1) == utils.compute_checksum(cell2) cell1 = create_solution_cell("hello", "code", "foo") cell2 = create_solution_cell("hello", "code", "foo") assert utils.compute_checksum(cell1) == utils.compute_checksum(cell2)
def test_compute_checksum_cell_type(self): # does the cell type make a difference? cell1 = self._create_grade_cell("hello", "code", "foo", 1) cell2 = self._create_grade_cell("hello", "markdown", "foo", 1) assert_not_equal(utils.compute_checksum(cell1), utils.compute_checksum(cell2)) cell1 = self._create_solution_cell("hello", "code") cell2 = self._create_solution_cell("hello", "markdown") assert_not_equal(utils.compute_checksum(cell1), utils.compute_checksum(cell2))
def test_checksum_locked_cell_type(self, preprocessor): """Test that the checksum is computed for locked cells""" cell1 = create_locked_cell("", "code", "foo") cell1 = preprocessor.preprocess_cell(cell1, {}, 0)[0] cell2 = create_locked_cell("", "markdown", "foo") cell2 = preprocessor.preprocess_cell(cell2, {}, 0)[0] assert cell1.metadata.nbgrader["checksum"] == compute_checksum(cell1) assert cell2.metadata.nbgrader["checksum"] == compute_checksum(cell2) assert cell1.metadata.nbgrader["checksum"] != cell2.metadata.nbgrader["checksum"]
def test_checksum_grade_id(self, preprocessor): """Test that the checksum is computed for grade cells with different ids""" cell1 = create_grade_cell("", "code", "foo", 1) cell1 = preprocessor.preprocess_cell(cell1, {}, 0)[0] cell2 = create_grade_cell("", "code", "bar", 1) cell2 = preprocessor.preprocess_cell(cell2, {}, 0)[0] assert cell1.metadata.nbgrader["checksum"] == compute_checksum(cell1) assert cell2.metadata.nbgrader["checksum"] == compute_checksum(cell2) assert cell1.metadata.nbgrader["checksum"] != cell2.metadata.nbgrader["checksum"]
def test_checksum_solution_source(self): """Test that the checksum is computed for solution cells with different sources""" cell1 = self._create_solution_cell("a", "code") cell1 = self.preprocessor.preprocess_cell(cell1, {}, 0)[0] cell2 = self._create_solution_cell("b", "code") cell2 = self.preprocessor.preprocess_cell(cell2, {}, 0)[0] assert_equal(cell1.metadata.nbgrader["checksum"], compute_checksum(cell1)) assert_equal(cell2.metadata.nbgrader["checksum"], compute_checksum(cell2)) assert_not_equal(cell1.metadata.nbgrader["checksum"], cell2.metadata.nbgrader["checksum"])
def test_checksum_grade_id(self): """Test that the checksum is computed for grade cells with different ids""" cell1 = self._create_grade_cell("", "code", "foo", 1) cell1 = self.preprocessor.preprocess_cell(cell1, {}, 0)[0] cell2 = self._create_grade_cell("", "code", "bar", 1) cell2 = self.preprocessor.preprocess_cell(cell2, {}, 0)[0] assert_equal(cell1.metadata.nbgrader["checksum"], compute_checksum(cell1)) assert_equal(cell2.metadata.nbgrader["checksum"], compute_checksum(cell2)) assert_not_equal(cell1.metadata.nbgrader["checksum"], cell2.metadata.nbgrader["checksum"])
def test_checksum_solution_source(self, preprocessor): """Test that the checksum is computed for solution cells with different sources""" cell1 = create_solution_cell("a", "code") cell1 = preprocessor.preprocess_cell(cell1, {}, 0)[0] cell2 = create_solution_cell("b", "code") cell2 = preprocessor.preprocess_cell(cell2, {}, 0)[0] assert cell1.metadata.nbgrader["checksum"] == compute_checksum(cell1) assert cell2.metadata.nbgrader["checksum"] == compute_checksum(cell2) assert cell1.metadata.nbgrader["checksum"] != cell2.metadata.nbgrader["checksum"]
def test_compute_checksum_grade_id(): # does the grade id make a difference (only for grade cells)? cell1 = create_grade_cell("hello", "code", "foo", 1) cell2 = create_grade_cell("hello", "code", "bar", 1) assert utils.compute_checksum(cell1) != utils.compute_checksum(cell2) cell1 = create_grade_cell("hello", "code", "foo", 1) cell2 = create_grade_cell("hello", "code", "bar", 1) cell1.metadata.nbgrader["grade"] = False cell2.metadata.nbgrader["grade"] = False assert utils.compute_checksum(cell1) != utils.compute_checksum(cell2)
def test_compute_checksum_points(): # does the number of points make a difference (only for grade cells)? cell1 = create_grade_cell("hello", "code", "foo", 2) cell2 = create_grade_cell("hello", "code", "foo", 1) assert utils.compute_checksum(cell1) != utils.compute_checksum(cell2) cell1 = create_grade_cell("hello", "code", "foo", 2) cell2 = create_grade_cell("hello", "code", "foo", 1) cell1.metadata.nbgrader["grade"] = False cell2.metadata.nbgrader["grade"] = False assert utils.compute_checksum(cell1) == utils.compute_checksum(cell2)
def test_checksum_grade_and_solution(self): """Test that a checksum is created for grade cells that are also solution cells""" cell1 = self._create_grade_cell("", "markdown", "foo", 1) cell1 = self.preprocessor.preprocess_cell(cell1, {}, 0)[0] cell2 = self._create_grade_cell("", "markdown", "foo", 1) cell2.metadata.nbgrader["solution"] = True cell2 = self.preprocessor.preprocess_cell(cell2, {}, 0)[0] assert_equal(cell1.metadata.nbgrader["checksum"], compute_checksum(cell1)) assert_equal(cell2.metadata.nbgrader["checksum"], compute_checksum(cell2)) assert_not_equal(cell1.metadata.nbgrader["checksum"], cell2.metadata.nbgrader["checksum"])
def test_checksum_grade_source(self, preprocessor): """Test that the checksum is computed for grade cells with different sources""" cell1 = create_grade_cell("a", "code", "foo", 1) cell1 = preprocessor.preprocess_cell(cell1, {}, 0)[0] cell2 = create_grade_cell("b", "code", "foo", 1) cell2 = preprocessor.preprocess_cell(cell2, {}, 0)[0] assert cell1.metadata.nbgrader["checksum"] == compute_checksum(cell1) assert cell2.metadata.nbgrader["checksum"] == compute_checksum(cell2) assert cell1.metadata.nbgrader["checksum"] != cell2.metadata.nbgrader[ "checksum"]
def test_compute_checksum_grade_id(self): # does the grade id make a difference (only for grade cells)? cell1 = self._create_grade_cell("hello", "code", "foo", 1) cell2 = self._create_grade_cell("hello", "code", "bar", 1) assert_not_equal(utils.compute_checksum(cell1), utils.compute_checksum(cell2)) cell1 = self._create_grade_cell("hello", "code", "foo", 1) cell2 = self._create_grade_cell("hello", "code", "bar", 1) cell1.metadata.nbgrader["grade"] = False cell2.metadata.nbgrader["grade"] = False assert_equal(utils.compute_checksum(cell1), utils.compute_checksum(cell2))
def test_checksum_grade_and_solution(self, preprocessor): """Test that a checksum is created for grade cells that are also solution cells""" cell1 = create_grade_cell("", "markdown", "foo", 1) cell1 = preprocessor.preprocess_cell(cell1, {}, 0)[0] cell2 = create_grade_cell("", "markdown", "foo", 1) cell2.metadata.nbgrader["solution"] = True cell2 = preprocessor.preprocess_cell(cell2, {}, 0)[0] assert cell1.metadata.nbgrader["checksum"] == compute_checksum(cell1) assert cell2.metadata.nbgrader["checksum"] == compute_checksum(cell2) assert cell1.metadata.nbgrader["checksum"] != cell2.metadata.nbgrader["checksum"]
def test_checksum_locked_cell_type(self, preprocessor): """Test that the checksum is computed for locked cells""" cell1 = create_locked_cell("", "code", "foo") cell1 = preprocessor.preprocess_cell(cell1, {}, 0)[0] cell2 = create_locked_cell("", "markdown", "foo") cell2 = preprocessor.preprocess_cell(cell2, {}, 0)[0] assert cell1.metadata.nbgrader["checksum"] == compute_checksum(cell1) assert cell2.metadata.nbgrader["checksum"] == compute_checksum(cell2) assert cell1.metadata.nbgrader["checksum"] != cell2.metadata.nbgrader[ "checksum"]
def test_checksum_grade_and_solution(self, preprocessor): """Test that a checksum is created for grade cells that are also solution cells""" cell1 = create_grade_cell("", "markdown", "foo", 1) cell1 = preprocessor.preprocess_cell(cell1, {}, 0)[0] cell2 = create_grade_cell("", "markdown", "foo", 1) cell2.metadata.nbgrader["solution"] = True cell2 = preprocessor.preprocess_cell(cell2, {}, 0)[0] assert cell1.metadata.nbgrader["checksum"] == compute_checksum(cell1) assert cell2.metadata.nbgrader["checksum"] == compute_checksum(cell2) assert cell1.metadata.nbgrader["checksum"] != cell2.metadata.nbgrader[ "checksum"]
def preprocess_cell(self, cell, resources, cell_index): grade_id = cell.metadata.get('nbgrader', {}).get('grade_id', None) if grade_id is None: return cell, resources try: source_cell = self.gradebook.find_source_cell( grade_id, self.notebook_id, self.assignment_id) except MissingEntry: self.log.warning("Cell '{}' does not exist in the database".format(grade_id)) del cell.metadata.nbgrader['grade_id'] return cell, resources # check that the cell type hasn't changed if cell.cell_type != source_cell.cell_type: self.report_change(grade_id, "cell_type", source_cell.cell_type, cell.cell_type) self.update_cell_type(cell, source_cell.cell_type) # check that the locked status hasn't changed if utils.is_locked(cell) != source_cell.locked: self.report_change(grade_id, "locked", source_cell.locked, utils.is_locked(cell)) cell.metadata.nbgrader["locked"] = source_cell.locked # if it's a grade cell, check that the max score hasn't changed if utils.is_grade(cell): grade_cell = self.gradebook.find_grade_cell( grade_id, self.notebook_id, self.assignment_id) old_points = float(grade_cell.max_score) new_points = float(cell.metadata.nbgrader["points"]) if old_points != new_points: self.report_change(grade_id, "points", old_points, new_points) cell.metadata.nbgrader["points"] = old_points # always update the checksum, just in case cell.metadata.nbgrader["checksum"] = source_cell.checksum # if it's locked, check that the checksum hasn't changed if source_cell.locked: old_checksum = source_cell.checksum new_checksum = utils.compute_checksum(cell) if old_checksum != new_checksum: self.report_change(grade_id, "checksum", old_checksum, new_checksum) cell.source = source_cell.source # double check the the checksum is correct now if utils.compute_checksum(cell) != source_cell.checksum: raise RuntimeError("Inconsistent checksums for cell {}".format(source_cell.name)) return cell, resources
def test_overwrite_locked_checksum(self, preprocessors, resources): """Is the checksum overwritten for locked cells?""" cell = create_locked_cell("hello", "code", "foo") cell.metadata.nbgrader['checksum'] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) nb, resources = preprocessors[0].preprocess(nb, resources) cell.metadata.nbgrader["checksum"] = "1234" nb, resources = preprocessors[1].preprocess(nb, resources) assert cell.metadata.nbgrader["checksum"] == compute_checksum(cell)
def test_overwrite_locked_checksum(self, preprocessors, resources): """Is the checksum overwritten for locked cells?""" cell = create_locked_cell("hello", "code", "foo") cell.metadata.nbgrader["checksum"] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) nb, resources = preprocessors[0].preprocess(nb, resources) cell.metadata.nbgrader["checksum"] = "1234" nb, resources = preprocessors[1].preprocess(nb, resources) assert cell.metadata.nbgrader["checksum"] == compute_checksum(cell)
def preprocess_cell(self, cell, resources, cell_index): grade_id = cell.metadata.get('nbgrader', {}).get('grade_id', None) if grade_id is None: return cell, resources source_cell = self.gradebook.find_source_cell(grade_id, self.notebook_id, self.assignment_id) # check that the cell type hasn't changed if cell.cell_type != source_cell.cell_type: self.report_change(grade_id, "cell_type", source_cell.cell_type, cell.cell_type) self.update_cell_type(cell, source_cell.cell_type) # check that the locked status hasn't changed if utils.is_locked(cell) != source_cell.locked: self.report_change(grade_id, "locked", source_cell.locked, utils.is_locked(cell)) cell.metadata.nbgrader["locked"] = source_cell.locked # if it's a grade cell, check that the max score hasn't changed if utils.is_grade(cell): grade_cell = self.gradebook.find_grade_cell( grade_id, self.notebook_id, self.assignment_id) old_points = float(grade_cell.max_score) new_points = float(cell.metadata.nbgrader["points"]) if old_points != new_points: self.report_change(grade_id, "points", old_points, new_points) cell.metadata.nbgrader["points"] = old_points # always update the checksum, just in case cell.metadata.nbgrader["checksum"] = source_cell.checksum # if it's locked, check that the checksum hasn't changed if source_cell.locked: old_checksum = source_cell.checksum new_checksum = utils.compute_checksum(cell) if old_checksum != new_checksum: self.report_change(grade_id, "checksum", old_checksum, new_checksum) cell.source = source_cell.source # double check the the checksum is correct now if utils.compute_checksum(cell) != source_cell.checksum: raise RuntimeError( "Inconsistent checksums for cell {}".format( source_cell.name)) return cell, resources
def preprocess_cell(self, cell, resources, cell_index): if utils.is_grade(cell): try: grade_cell = self.gradebook.find_grade_cell( grade_id=cell.metadata.nbgrader.grade_id, notebook_id=self.notebook_id, assignment=self.assignment) except: return cell, resources cell.metadata.nbgrader['points'] = grade_cell.max_score # we only want the source and checksum for non-solution cells if not utils.is_solution(cell) and grade_cell.source: old_checksum = grade_cell.checksum new_checksum = utils.compute_checksum(cell) if old_checksum != new_checksum: self.log.warning("Checksum for grade cell %s has changed!", grade_cell.grade_id) cell.source = grade_cell.source cell.metadata.nbgrader['checksum'] = grade_cell.checksum self.log.debug("Overwrote grade cell %s", grade_cell.grade_id) return cell, resources
def preprocess_cell(self, cell, resources, cell_index): if not utils.is_grade(cell): return cell, resources # if we're ignoring checksums, then remove the checksum from the # cell metadata if self.ignore_checksums and 'checksum' in cell.metadata.nbgrader: del cell.metadata.nbgrader['checksum'] # verify checksums of cells if not utils.is_solution(cell) and 'checksum' in cell.metadata.nbgrader: old_checksum = cell.metadata.nbgrader['checksum'] new_checksum = utils.compute_checksum(cell) if old_checksum != new_checksum: resources['nbgrader']['checksum_mismatch'].append(cell_index) # if it's a grade cell, the add a grade score, max_score = utils.determine_grade(cell) # it's a markdown cell, so we can't do anything if score is None: pass elif score < max_score: resources['nbgrader']['failed_cells'].append(cell_index) else: resources['nbgrader']['passed_cells'].append(cell_index) return cell, resources
def preprocess_cell(self, cell, resources, cell_index): if not (utils.is_grade(cell) or utils.is_locked(cell)): return cell, resources # if we're ignoring checksums, then remove the checksum from the # cell metadata if self.ignore_checksums and 'checksum' in cell.metadata.nbgrader: del cell.metadata.nbgrader['checksum'] # verify checksums of cells if utils.is_locked(cell) and 'checksum' in cell.metadata.nbgrader: old_checksum = cell.metadata.nbgrader['checksum'] new_checksum = utils.compute_checksum(cell) if old_checksum != new_checksum: resources['nbgrader']['checksum_mismatch'].append(cell_index) # if it's a grade cell, the check the grade if utils.is_grade(cell): score, max_score = utils.determine_grade(cell) # it's a markdown cell, so we can't do anything if score is None: pass elif score < max_score: resources['nbgrader']['failed_cells'].append(cell_index) else: resources['nbgrader']['passed_cells'].append(cell_index) return cell, resources
def test_determine_grade_markdown_grade_and_solution(): cell = create_grade_and_solution_cell('test', "markdown", "foo", 10) cell.metadata.nbgrader['checksum'] = utils.compute_checksum(cell) assert utils.determine_grade(cell) == (0, 10) cell = create_grade_and_solution_cell('test', "markdown", "foo", 10) cell.source = 'test!' assert utils.determine_grade(cell) == (None, 10)
def test_determine_grade_code_grade_and_solution(): cell = create_grade_and_solution_cell('test', "code", "foo", 10) cell.metadata.nbgrader['checksum'] = utils.compute_checksum(cell) cell.outputs = [] assert utils.determine_grade(cell) == (0, 10) cell.outputs = [new_output('error', ename="NotImplementedError", evalue="", traceback=["error"])] cell.source = 'test!' assert utils.determine_grade(cell) == (None, 10)
def calculate_checksum(nb): m = hashlib.sha256() for cell in nb.cells: if utils.is_grade(cell): grade_id = cell.metadata.nbgrader['grade_id'] checksum = utils.compute_checksum(cell) m.update(grade_id.encode('utf-8')) m.update(checksum.encode('utf-8')) return m.hexdigest()
def preprocess_cell(self, cell, resources, cell_index): if utils.is_grade(cell): grade_cell = self.gradebook.find_grade_cell( cell.metadata.nbgrader["grade_id"], self.notebook_id, self.assignment_id) cell.metadata.nbgrader['points'] = grade_cell.max_score # we only want the source and checksum for non-solution cells if not utils.is_solution(cell): old_checksum = grade_cell.checksum new_checksum = utils.compute_checksum(cell) if old_checksum != new_checksum: self.log.warning("Checksum for grade cell %s has changed!", grade_cell.name) cell.source = grade_cell.source cell.metadata.nbgrader['checksum'] = grade_cell.checksum self.update_cell_type(cell, grade_cell.cell_type) self.log.debug("Overwrote grade cell %s", grade_cell.name) if utils.is_solution(cell): solution_cell = self.gradebook.find_solution_cell( self.comment_index, self.notebook_id, self.assignment_id) old_checksum = solution_cell.checksum new_checksum = utils.compute_checksum(cell) if cell.cell_type != solution_cell.cell_type: self.log.warning("Cell type for solution cell %s has changed!", solution_cell.name) cell.metadata.nbgrader['checksum'] = solution_cell.checksum self.update_cell_type(cell, solution_cell.cell_type) self.log.debug("Overwrote solution cell #%s", self.comment_index) self.comment_index += 1 return cell, resources
def test_overwrite_grade_checksum(self): """Is the checksum overwritten for grade cells?""" cell = self._create_grade_cell("hello", "code", "foo", 1) nb = new_notebook() nb.cells.append(cell) nb, resources = self.preprocessor1.preprocess(nb, self.resources) cell.metadata.nbgrader["checksum"] = "1234" nb, resources = self.preprocessor2.preprocess(nb, self.resources) assert_equal(cell.metadata.nbgrader["checksum"], compute_checksum(cell))
def preprocess_cell(self, cell, resources, cell_index): # compute checksums of grade cell and solution cells if utils.is_grade(cell) or utils.is_solution(cell) or utils.is_locked( cell): checksum = utils.compute_checksum(cell) cell.metadata.nbgrader['checksum'] = checksum if utils.is_grade(cell) or utils.is_solution(cell): self.log.debug("Checksum for '%s' is %s", cell.metadata.nbgrader['grade_id'], checksum) return cell, resources
def test_dont_overwrite_solution_source(self, preprocessors, resources): """Is the source not overwritten for solution cells?""" cell = create_solution_cell("hello", "code", "foo") cell.metadata.nbgrader["checksum"] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) nb, resources = preprocessors[0].preprocess(nb, resources) cell.source = "hello!" nb, resources = preprocessors[1].preprocess(nb, resources) assert cell.source == "hello!"
def test_overwrite_locked_source_markdown(self, preprocessors, resources): """Is the source overwritten for locked markdown cells?""" cell = create_locked_cell("hello", "markdown", "foo") cell.metadata.nbgrader["checksum"] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) nb, resources = preprocessors[0].preprocess(nb, resources) cell.source = "hello!" nb, resources = preprocessors[1].preprocess(nb, resources) assert cell.source == "hello"
def test_overwrite_grade_cell_type(self, preprocessors, resources): """Is the cell type overwritten for grade cells?""" cell = create_grade_cell("hello", "code", "foo", 1) cell.metadata.nbgrader["checksum"] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) nb, resources = preprocessors[0].preprocess(nb, resources) cell.cell_type = "markdown" nb, resources = preprocessors[1].preprocess(nb, resources) assert cell.cell_type == "code"
def test_overwrite_locked_source_markdown(self, preprocessors, resources): """Is the source overwritten for locked markdown cells?""" cell = create_locked_cell("hello", "markdown", "foo") cell.metadata.nbgrader['checksum'] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) nb, resources = preprocessors[0].preprocess(nb, resources) cell.source = "hello!" nb, resources = preprocessors[1].preprocess(nb, resources) assert cell.source == "hello"
def test_overwrite_grade_source(self, preprocessors, resources): """Is the source overwritten for grade cells?""" cell = create_grade_cell("hello", "code", "foo", 1) cell.metadata.nbgrader['checksum'] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) nb, resources = preprocessors[0].preprocess(nb, resources) cell.source = "hello!" nb, resources = preprocessors[1].preprocess(nb, resources) assert cell.source == "hello"
def test_overwrite_points(self, preprocessors, resources): """Are points overwritten for grade cells?""" cell = create_grade_cell("hello", "code", "foo", 1) cell.metadata.nbgrader["checksum"] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) nb, resources = preprocessors[0].preprocess(nb, resources) cell.metadata.nbgrader["points"] = 2 nb, resources = preprocessors[1].preprocess(nb, resources) assert cell.metadata.nbgrader["points"] == 1
def test_comment_unchanged_markdown(self, preprocessors, gradebook, resources): """Is an unchanged markdown cell given the correct comment?""" cell = create_grade_and_solution_cell("hello", "markdown", "foo", 1) cell.metadata.nbgrader['checksum'] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) preprocessors[0].preprocess(nb, resources) gradebook.add_submission("ps0", "bar") preprocessors[1].preprocess(nb, resources) comment = gradebook.find_comment("foo", "test", "ps0", "bar") assert comment.auto_comment == "No response."
def test_save_unchanged_code(self, preprocessors, gradebook, resources): """Is an unchanged code cell given the correct comment?""" cell = create_solution_cell("hello", "code", "foo") cell.metadata.nbgrader['checksum'] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) preprocessors[0].preprocess(nb, resources) gradebook.add_submission("ps0", "bar") preprocessors[1].preprocess(nb, resources) preprocessors[2].preprocess(nb, resources) assert cell.metadata.nbgrader['comment'] == "No response."
def test_overwrite_solution_cell_type(self, preprocessors, resources): """Is the cell type overwritten for solution cells?""" cell = create_solution_cell("hello", "code", "foo") cell.metadata.nbgrader['checksum'] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) nb, resources = preprocessors[0].preprocess(nb, resources) cell.cell_type = "markdown" nb, resources = preprocessors[1].preprocess(nb, resources) assert cell.cell_type == "code"
def _create_solution_cell(source, cell_type): if cell_type == "markdown": cell = new_markdown_cell(source=source) elif cell_type == "code": cell = new_code_cell(source=source) else: raise ValueError("invalid cell type: {}".format(cell_type)) cell.metadata.nbgrader = {} cell.metadata.nbgrader["solution"] = True cell.metadata.nbgrader["checksum"] = compute_checksum(cell) return cell
def preprocess_cell(self, cell, resources, cell_index): # compute checksums of grade cell and solution cells if utils.is_grade(cell) or utils.is_solution(cell) or utils.is_locked(cell): checksum = utils.compute_checksum(cell) cell.metadata.nbgrader['checksum'] = checksum if utils.is_grade(cell) or utils.is_solution(cell): self.log.debug( "Checksum for '%s' is %s", cell.metadata.nbgrader['grade_id'], checksum) return cell, resources
def _add_comment(self, cell, resources): comment = self.gradebook.find_comment( cell.metadata['nbgrader']['grade_id'], self.notebook_id, self.assignment_id, self.student_id) if cell.metadata.nbgrader.get("checksum", None) == utils.compute_checksum(cell): comment.auto_comment = "No response." else: comment.auto_comment = None self.gradebook.db.commit() self.log.debug(comment)
def test_comment_changed_code(self, preprocessors, gradebook, resources): """Is a changed code cell given the correct comment?""" cell = create_solution_cell("hello", "code", "foo") cell.metadata.nbgrader['checksum'] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) preprocessors[0].preprocess(nb, resources) gradebook.add_submission("ps0", "bar") cell.source = "hello!" preprocessors[1].preprocess(nb, resources) comment = gradebook.find_comment("foo", "test", "ps0", "bar") assert comment.auto_comment is None
def test_save_correct_code(self, preprocessors, gradebook, resources): """Is a passing code cell correctly graded?""" cell = create_grade_cell("hello", "code", "foo", 1) cell.metadata.nbgrader['checksum'] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) preprocessors[0].preprocess(nb, resources) gradebook.add_submission("ps0", "bar") preprocessors[1].preprocess(nb, resources) preprocessors[2].preprocess(nb, resources) assert cell.metadata.nbgrader['score'] == 1 assert cell.metadata.nbgrader['points'] == 1 assert 'comment' not in cell.metadata.nbgrader
def test_save_locked_markdown_cell(self, preprocessor, resources): cell = create_locked_cell("hello", "markdown", "foo") cell.metadata.nbgrader['checksum'] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) nb, resources = preprocessor.preprocess(nb, resources) gb = preprocessor.gradebook source_cell = gb.find_source_cell("foo", "test", "ps0") assert source_cell.source == "hello" assert source_cell.checksum == cell.metadata.nbgrader["checksum"] assert source_cell.cell_type == "markdown" assert source_cell.locked
def test_save_unchanged_markdown(self, preprocessors, gradebook, resources): """Is an unchanged markdown cell correctly graded?""" cell = create_grade_and_solution_cell("hello", "markdown", "foo", 1) cell.metadata.nbgrader['checksum'] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) preprocessors[0].preprocess(nb, resources) gradebook.add_submission("ps0", "bar") preprocessors[1].preprocess(nb, resources) preprocessors[2].preprocess(nb, resources) assert cell.metadata.nbgrader['score'] == 0 assert cell.metadata.nbgrader['points'] == 1 assert cell.metadata.nbgrader['comment'] == "No response."
def test_save_incorrect_code(self, preprocessors, gradebook, resources): """Is a failing code cell correctly graded?""" cell = create_grade_cell("hello", "code", "foo", 1) cell.metadata.nbgrader['checksum'] = compute_checksum(cell) cell.outputs = [new_output('error', ename="NotImplementedError", evalue="", traceback=["error"])] nb = new_notebook() nb.cells.append(cell) preprocessors[0].preprocess(nb, resources) gradebook.add_submission("ps0", "bar") preprocessors[1].preprocess(nb, resources) preprocessors[2].preprocess(nb, resources) assert cell.metadata.nbgrader['score'] == 0 assert cell.metadata.nbgrader['points'] == 1 assert 'comment' not in cell.metadata.nbgrader
def test_grade_correct_code(self, preprocessors, gradebook, resources): """Is a passing code cell correctly graded?""" cell = create_grade_cell("hello", "code", "foo", 1) cell.metadata.nbgrader['checksum'] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) preprocessors[0].preprocess(nb, resources) gradebook.add_submission("ps0", "bar") preprocessors[1].preprocess(nb, resources) grade_cell = gradebook.find_grade("foo", "test", "ps0", "bar") assert grade_cell.score == 1 assert grade_cell.max_score == 1 assert grade_cell.auto_score == 1 assert grade_cell.manual_score == None assert not grade_cell.needs_manual_grade
def test_grade_changed_markdown(self, preprocessors, gradebook, resources): """Is a changed markdown cell correctly graded?""" cell = create_grade_and_solution_cell("hello", "markdown", "foo", 1) cell.metadata.nbgrader['checksum'] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) preprocessors[0].preprocess(nb, resources) gradebook.add_submission("ps0", "bar") cell.source = "hello!" preprocessors[1].preprocess(nb, resources) grade_cell = gradebook.find_grade("foo", "test", "ps0", "bar") assert grade_cell.score == 0 assert grade_cell.max_score == 1 assert grade_cell.auto_score == None assert grade_cell.manual_score == None assert grade_cell.needs_manual_grade
def test_save_code_grade_cell(self, preprocessor, resources): cell = create_grade_cell("hello", "code", "foo", 1) cell.metadata.nbgrader['checksum'] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) nb, resources = preprocessor.preprocess(nb, resources) gb = preprocessor.gradebook grade_cell = gb.find_grade_cell("foo", "test", "ps0") assert grade_cell.max_score == 1 assert grade_cell.cell_type == "code" source_cell = gb.find_source_cell("foo", "test", "ps0") assert source_cell.source == "hello" assert source_cell.checksum == cell.metadata.nbgrader["checksum"] assert source_cell.cell_type == "code" assert source_cell.locked
def test_grade_existing_auto_comment(self, preprocessors, gradebook, resources): """Is a failing code cell correctly graded?""" cell = create_grade_and_solution_cell("hello", "markdown", "foo", 1) cell.metadata.nbgrader['checksum'] = compute_checksum(cell) nb = new_notebook() nb.cells.append(cell) preprocessors[0].preprocess(nb, resources) gradebook.add_submission("ps0", "bar") preprocessors[1].preprocess(nb, resources) comment = gradebook.find_comment("foo", "test", "ps0", "bar") assert comment.auto_comment == "No response." nb.cells[-1].source = 'goodbye' preprocessors[1].preprocess(nb, resources) gradebook.db.refresh(comment) assert comment.auto_comment is None