Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
 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)
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
    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
Ejemplo n.º 11
0
    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
Ejemplo n.º 12
0
    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
Ejemplo n.º 13
0
    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
Ejemplo n.º 14
0
 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
Ejemplo n.º 15
0
    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
Ejemplo n.º 16
0
    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
Ejemplo n.º 17
0
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
Ejemplo n.º 18
0
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()
Ejemplo n.º 19
0
 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
Ejemplo n.º 20
0
    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
Ejemplo n.º 21
0
    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
Ejemplo n.º 22
0
    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
Ejemplo n.º 23
0
    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
Ejemplo n.º 24
0
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
Ejemplo n.º 25
0
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
Ejemplo n.º 26
0
    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
Ejemplo n.º 27
0
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
Ejemplo n.º 28
0
    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
Ejemplo n.º 29
0
    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
Ejemplo n.º 30
0
def is_description(cell):
    return is_nbgrader_cell(cell) and not is_grade(cell) and is_locked(cell)
Ejemplo n.º 31
0
def get_points(cell):
    if is_grade(cell):
        return cell.metadata.nbgrader.points
    return 0