def preprocess_cell(self, cell, resources, cell_index): if utils.is_grade(cell): # check for blank grade ids grade_id = cell.metadata.nbgrader.get("grade_id", "") if grade_id == "": raise RuntimeError("Blank grade id!") resources['grade_ids'].append(grade_id) # check for valid points points = cell.metadata.nbgrader.get("points", "") try: points = float(points) except ValueError: raise RuntimeError( "Point value for grade cell {} is invalid: {}".format( grade_id, points)) # check that code cells are grade OR solution (not both) if cell.cell_type == "code" and utils.is_grade(cell) and utils.is_solution(cell): raise RuntimeError( "Code grade cell '{}' is also marked as a solution cell".format( grade_id)) # check that markdown cells are grade AND solution (not either/or) if cell.cell_type == "markdown" and utils.is_grade(cell) and not utils.is_solution(cell): raise RuntimeError( "Markdown grade cell '{}' is not marked as a solution cell".format( grade_id)) if cell.cell_type == "markdown" and not utils.is_grade(cell) and utils.is_solution(cell): raise RuntimeError( "Markdown solution cell (index {}) is not marked as a grade cell".format( cell_index)) return cell, resources
def preprocess_cell(self, cell, resources, cell_index): if utils.is_grade(cell) or utils.is_solution(cell): # check for invalid grade ids grade_id = cell.metadata.nbgrader.get("grade_id", "") if not re.match(r"^[a-zA-Z0-9_\-]+$", grade_id): raise RuntimeError("Invalid grade id: {}".format(grade_id)) resources['grade_ids'].append(grade_id) if utils.is_grade(cell): # check for valid points points = cell.metadata.nbgrader.get("points", "") try: points = float(points) except ValueError: raise RuntimeError( "Point value for grade cell {} is invalid: {}".format( grade_id, points)) # check that markdown cells are grade AND solution (not either/or) if cell.cell_type == "markdown" and utils.is_grade(cell) and not utils.is_solution(cell): raise RuntimeError( "Markdown grade cell '{}' is not marked as a solution cell".format( grade_id)) if cell.cell_type == "markdown" and not utils.is_grade(cell) and utils.is_solution(cell): raise RuntimeError( "Markdown solution cell (index {}) is not marked as a grade cell".format( cell_index)) return cell, resources
def test_is_solution(self): cell = self._create_code_cell() assert not utils.is_solution(cell) cell.metadata['nbgrader'] = {} assert not utils.is_solution(cell) cell.metadata['nbgrader']['solution'] = False assert not utils.is_solution(cell) cell.metadata['nbgrader']['solution'] = True assert utils.is_solution(cell)
def preprocess_cell(self, cell, resources, cell_index): if utils.is_grade(cell): self._create_grade_cell(cell) if utils.is_solution(cell): self._create_solution_cell(cell) if utils.is_grade(cell) or utils.is_solution(cell) or utils.is_locked(cell): self._create_source_cell(cell) return cell, resources
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 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 utils.is_grade(cell): max_score = float(cell.metadata.nbgrader['points']) cell_type = cell.cell_type source = cell.source checksum = cell.metadata.nbgrader.get('checksum', None) grade_cell = self.gradebook.update_or_create_grade_cell( cell.metadata.nbgrader['grade_id'], self.notebook_id, self.assignment_id, max_score=max_score, source=source, checksum=checksum, cell_type=cell_type) self.log.debug("Recorded grade cell %s into database", grade_cell) if utils.is_solution(cell): cell_type = cell.cell_type source = cell.source checksum = cell.metadata.nbgrader.get('checksum', None) solution_cell = self.gradebook.update_or_create_solution_cell( self.comment_index, self.notebook_id, self.assignment_id, cell_type=cell_type, source=source, checksum=checksum) self.comment_index += 1 self.log.debug("Recorded solution cell %s into database", solution_cell) return cell, resources
def preprocess_cell(self, cell, resources, cell_index): if is_solution(cell): if cell.cell_type == 'code': cell.input = '#' + self.solution_stub else: cell.input = self.solution_stub return cell, resources
def preprocess_cell(self, cell, resources, cell_index): is_hidden = utils.is_hidden(cell) if is_hidden: replaced_solution = self._replace_hidden_cell(cell) else: # replace solution regions with the relevant stubs replaced_solution = self._replace_solution_region(cell) # determine whether the cell is a solution/grade cell is_solution = utils.is_solution(cell) # check that it is marked as a solution cell if we replaced a solution # region -- if it's not, then this is a problem, because the cell needs # to be given an id if not (is_solution or is_hidden) and replaced_solution: raise RuntimeError( "Solution region detected in a non-solution cell; " "please make sure all solution regions are within " "solution cells") # replace solution cells with the code/text stub -- but not if # we already replaced a solution region, because that means # there are parts of the cells that should be preserved if is_solution and not replaced_solution: if cell.cell_type == 'code': cell.source = self.code_stub else: cell.source = self.text_stub return cell, resources
def preprocess_cell(self, cell, resources, cell_index): if self.lock_all_cells: cell.metadata['deletable'] = False elif self.lock_grade_cells and utils.is_grade(cell): cell.metadata['deletable'] = False elif self.lock_solution_cells and utils.is_solution(cell): cell.metadata['deletable'] = False return cell, resources
def preprocess_cell(self, cell, resources, cell_index): # if it's a grade cell, the add a grade if utils.is_grade(cell): self._add_score(cell, resources) if utils.is_solution(cell): self._add_comment(cell, resources) return cell, resources
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 preprocess_cell(self, cell, resources, cell_index): if not (utils.is_grade(cell) or utils.is_solution(cell) or utils.is_locked(cell)): return cell, resources grade_id = cell.metadata.nbgrader['grade_id'] if grade_id in self.grade_ids: self.log.warning("Cell with id '%s' exists multiple times!", grade_id) cell.metadata.nbgrader = {} else: self.grade_ids.add(grade_id) return cell, resources
def preprocess_cell(self, cell, resources, cell_index): # replace solution regions with the relevant stubs replaced_solution = self._replace_solution_region(cell) # determine whether the cell is a solution cell is_solution = utils.is_solution(cell) # replace solution cells with the code/text stub -- but not if # we already replaced a solution region, because that means # there are parts of the cells that should be preserved if is_solution and not replaced_solution: if cell.cell_type == 'code': cell.input = self.code_stub else: cell.source = self.text_stub return cell, resources
def preprocess_cell(self, cell, resources, cell_index): # replace solution regions with the relevant stubs replaced_solution = self._replace_solution_region(cell) # determine whether the cell is a solution cell is_solution = utils.is_solution(cell) # replace solution cells with the code/text stub -- but not if # we already replaced a solution region, because that means # there are parts of the cells that should be preserved if is_solution and not replaced_solution: if cell.cell_type == 'code': cell.source = self.code_stub else: cell.source = self.text_stub return cell, resources
def preprocess_cell(self, cell, resources, cell_index): if utils.is_grade(cell): grade_cell = self.gradebook.find_or_create_grade_cell( grade_id=cell.metadata.nbgrader.grade_id, notebook_id=self.notebook_id, assignment=self.assignment) grade_cell.max_score = float(cell.metadata.nbgrader['points']) # we only want the source and checksum for non-solution cells if utils.is_solution(cell): grade_cell.source = None grade_cell.checksum = None else: grade_cell.source = cell.source grade_cell.checksum = cell.metadata.nbgrader['checksum'] self.gradebook.update_grade_cell(grade_cell) self.log.debug("Recorded grade cell %s into database", grade_cell.grade_id) return cell, resources
def preprocess_cell(self, cell, resources, cell_index): # replace solution regions with the relevant stubs replaced_solution = self._replace_solution_region(cell) # determine whether the cell is a solution cell is_solution = utils.is_solution(cell) # replace solution cells with the code/text stub -- but not if # we already replaced a solution region, because that means # there are parts of the cells that should be preserved if is_solution and not replaced_solution: if cell.cell_type == 'code': cell.source = self.code_stub else: cell.source = self.text_stub # if we replaced a solution region, then make sure the cell is marked # as a solution cell if replaced_solution: if 'nbgrader' not in cell.metadata: cell.metadata.nbgrader = {} cell.metadata.nbgrader['solution'] = True return cell, resources
def cell_changed(self, cell: NotebookNode): return not (is_solution(cell) and "checksum" in cell.metadata.nbgrader and cell.metadata.nbgrader["checksum"] == compute_checksum(cell))
def is_solution_cell(cell): return is_nbgrader_cell(cell) and is_solution(cell)