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) # 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) else: resources['nbgrader']['passed_cells'].append(cell) 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 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_grade(self): cell = self._create_code_cell() assert not utils.is_grade(cell) cell.metadata['nbgrader'] = {} assert not utils.is_grade(cell) cell.metadata['nbgrader']['grade'] = False assert not utils.is_grade(cell) cell.metadata['nbgrader']['grade'] = True assert utils.is_grade(cell)
def test_is_grade(self): cell = self._create_code_cell() assert not utils.is_grade(cell) cell.metadata['nbgrader'] = {} assert not utils.is_grade(cell) cell.metadata['nbgrader']['grade'] = False assert not utils.is_grade(cell) cell.metadata['nbgrader']['grade'] = True assert utils.is_grade(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 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(self, nb, resources, retries=None): autograde_cells = [] self.log.info("Notebook cells: {}".format(len(nb.cells))) for cell in nb.cells: if is_grade(cell) or is_solution(cell): autograde_cells.append(cell) self.log.info("Notebook autograde cells: {}".format(len(autograde_cells))) old_cells = copy.deepcopy(nb.cells) nb.cells = autograde_cells kernel_name = nb.metadata.get('kernelspec', {}).get('name', 'python') if self.extra_arguments == [] and kernel_name == "python": self.extra_arguments = ["--HistoryManager.hist_file=:memory:"] if retries is None: retries = self.execute_retries try: output = super(Execute, self).preprocess(nb, resources) except RuntimeError: if retries == 0: raise UnresponsiveKernelError() else: self.log.warning("Failed to execute notebook, trying again...") return self.preprocess(nb, resources, retries=retries - 1) nb.cells = old_cells return output
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 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 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 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 grade(nb): total_score = 0 max_total_score = 0 for cell in nb.cells: if utils.is_grade(cell): score, max_score = utils.determine_grade(cell) total_score += score max_total_score += max_score return total_score, max_total_score
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 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 elif self.lock_readonly_cells and utils.is_locked(cell): cell.metadata['deletable'] = False 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): 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 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 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 get_task_info(nb): subtasks = [] subtask = [] for idx, cell in enumerate(nb.cells): subtask.append(idx) if is_grade(cell): subtasks.append(subtask) subtask = [] task = dict() if (len(subtasks) > 0 and len(subtasks[0]) > 0 and is_description(nb.cells[subtasks[0][0]])): task["header"] = subtasks[0].pop(0) task["subtasks"] = subtasks if len(subtask) > 0: task["other"] = subtask return task
def add_question_to_task(coursedir, path, question_type, grade_id=None, points=0): presetmodel = PresetModel(coursedir) nb = nbformat.read(path, as_version=nbformat.NO_CONVERT) cells = presetmodel.get_question_preset(question_type) if grade_id is not None: for cell in cells: cell.metadata.nbgrader.grade_id = cell.metadata.nbgrader.grade_id.replace( "task", grade_id) if is_grade(cell): cell.metadata.nbgrader.points = points nb.cells.extend(cells) nbformat.write(nb, path) return path
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 determine_grade( cell: NotebookNode, log: Logger = None ) -> Tuple[Optional[float], float]: if not nbutils.is_grade(cell): raise ValueError("cell is not a grade cell") if not (is_multiplechoice(cell) or is_singlechoice(cell)): return nbutils.determine_grade(cell, log) max_points = float(cell.metadata["nbgrader"]["points"]) if is_singlechoice(cell): # Get the choices of the student student_choices = get_choices(cell) # Get the instructor choices instructor_choices = get_instructor_choices(cell) if ( (len(student_choices) > 0) and (len(instructor_choices) > 0) and (student_choices[0] == instructor_choices[0]) ): return max_points, max_points else: return 0, max_points elif is_multiplechoice(cell): # Get the choices of the student student_choices = get_choices(cell) # Get the weights of the answer instructor_choices = get_instructor_choices(cell) option_points = max_points / get_num_of_choices(cell) points = 0 for i in range(get_num_of_choices(cell)): if ((i in student_choices) and (i in instructor_choices)) or ( (i not in student_choices) and (i not in instructor_choices) ): points += option_points else: points -= option_points return max(0, points), max_points
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): if not utils.is_grade(cell): return cell, resources # verify checksums of cells if '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 is_description(cell): return is_nbgrader_cell(cell) and not is_grade(cell) and is_locked(cell)
def get_points(cell): if is_grade(cell): return cell.metadata.nbgrader.points return 0