Beispiel #1
0
    def update(self, subsection, only_if_higher=None):
        """
        Updates the SubsectionGrade object for the student and subsection.
        """
        # Save ourselves the extra queries if the course does not persist
        # subsection grades.
        self._log_event(log.warning, u"update, subsection: {}".format(subsection.location), subsection)

        calculated_grade = SubsectionGrade(subsection).init_from_structure(
            self.student, self.course_structure, self._submissions_scores, self._csm_scores,
        )

        if PersistentGradesEnabledFlag.feature_enabled(self.course.id):
            if only_if_higher:
                try:
                    grade_model = PersistentSubsectionGrade.read_grade(self.student.id, subsection.location)
                except PersistentSubsectionGrade.DoesNotExist:
                    pass
                else:
                    orig_subsection_grade = SubsectionGrade(subsection).init_from_model(
                        self.student, grade_model, self.course_structure, self._submissions_scores, self._csm_scores,
                    )
                    if not is_score_higher_or_equal(
                            orig_subsection_grade.graded_total.earned,
                            orig_subsection_grade.graded_total.possible,
                            calculated_grade.graded_total.earned,
                            calculated_grade.graded_total.possible,
                    ):
                        return orig_subsection_grade

            grade_model = calculated_grade.update_or_create_model(self.student)
            self._update_saved_subsection_grade(subsection.location, grade_model)

        return calculated_grade
Beispiel #2
0
    def update(self, subsection, only_if_higher=None, score_deleted=False, force_update_subsections=False, persist_grade=True):
        """
        Updates the SubsectionGrade object for the student and subsection.
        """
        self._log_event(log.debug, u"update, subsection: {}".format(subsection.location), subsection)

        calculated_grade = CreateSubsectionGrade(
            subsection, self.course_data.structure, self._submissions_scores, self._csm_scores,
        )

        if persist_grade and should_persist_grades(self.course_data.course_key):
            if only_if_higher:
                try:
                    grade_model = PersistentSubsectionGrade.read_grade(self.student.id, subsection.location)
                except PersistentSubsectionGrade.DoesNotExist:
                    pass
                else:
                    orig_subsection_grade = ReadSubsectionGrade(subsection, grade_model, self)
                    if not is_score_higher_or_equal(
                        orig_subsection_grade.graded_total.earned,
                        orig_subsection_grade.graded_total.possible,
                        calculated_grade.graded_total.earned,
                        calculated_grade.graded_total.possible,
                        treat_undefined_as_zero=True,
                    ):
                        return orig_subsection_grade

            grade_model = calculated_grade.update_or_create_model(
                self.student,
                score_deleted,
                force_update_subsections
            )
            self._update_saved_subsection_grade(subsection.location, grade_model)

        return calculated_grade
    def update(self, subsection, only_if_higher=None, score_deleted=False):
        """
        Updates the SubsectionGrade object for the student and subsection.
        """
        self._log_event(log.debug, u"update, subsection: {}".format(subsection.location), subsection)

        calculated_grade = CreateSubsectionGrade(
            subsection, self.course_data.structure, self._submissions_scores, self._csm_scores,
        )

        if should_persist_grades(self.course_data.course_key):
            if only_if_higher:
                try:
                    grade_model = PersistentSubsectionGrade.read_grade(self.student.id, subsection.location)
                except PersistentSubsectionGrade.DoesNotExist:
                    pass
                else:
                    orig_subsection_grade = ReadSubsectionGrade(subsection, grade_model, self)
                    if not is_score_higher_or_equal(
                            orig_subsection_grade.graded_total.earned,
                            orig_subsection_grade.graded_total.possible,
                            calculated_grade.graded_total.earned,
                            calculated_grade.graded_total.possible,
                    ):
                        return orig_subsection_grade

            grade_model = calculated_grade.update_or_create_model(self.student, score_deleted)
            self._update_saved_subsection_grade(subsection.location, grade_model)

        return calculated_grade
Beispiel #4
0
def score_published_handler(sender, block, user, raw_earned, raw_possible,
                            only_if_higher, **kwargs):  # pylint: disable=unused-argument
    """
    Handles whenever a block's score is published.
    Returns whether the score was actually updated.
    """
    update_score = True
    if only_if_higher:
        previous_score = get_score(user.id, block.location)

        if previous_score is not None:
            prev_raw_earned, prev_raw_possible = (previous_score.grade,
                                                  previous_score.max_grade)

            if not is_score_higher_or_equal(prev_raw_earned, prev_raw_possible,
                                            raw_earned, raw_possible):
                update_score = False
                log.warning(
                    u"Grades: Rescore is not higher than previous: "
                    u"user: {}, block: {}, previous: {}/{}, new: {}/{} ".
                    format(
                        user,
                        block.location,
                        prev_raw_earned,
                        prev_raw_possible,
                        raw_earned,
                        raw_possible,
                    ))

    if update_score:
        # Set the problem score in CSM.
        score_modified_time = set_score(user.id, block.location, raw_earned,
                                        raw_possible)

        # Set the problem score on the xblock.
        if isinstance(block, ScorableXBlockMixin):
            block.set_score(
                Score(raw_earned=raw_earned, raw_possible=raw_possible))

        # Fire a signal (consumed by enqueue_subsection_update, below)
        PROBLEM_RAW_SCORE_CHANGED.send(
            sender=None,
            raw_earned=raw_earned,
            raw_possible=raw_possible,
            weight=getattr(block, 'weight', None),
            user_id=user.id,
            course_id=unicode(block.location.course_key),
            usage_id=unicode(block.location),
            only_if_higher=only_if_higher,
            modified=score_modified_time,
            score_db_table=ScoreDatabaseTableEnum.courseware_student_module,
            score_deleted=kwargs.get('score_deleted', False),
        )
    return update_score
Beispiel #5
0
    def update(self, subsection, only_if_higher=None, score_deleted=False, force_update_subsections=False, persist_grade=True):  # lint-amnesty, pylint: disable=line-too-long
        """
        Updates the SubsectionGrade object for the student and subsection.
        """
        self._log_event(log.debug,
                        u"update, subsection: {}".format(subsection.location),
                        subsection)

        calculated_grade = CreateSubsectionGrade(
            subsection,
            self.course_data.structure,
            self._submissions_scores,
            self._csm_scores,
        )

        if persist_grade and should_persist_grades(
                self.course_data.course_key):
            if only_if_higher:
                try:
                    grade_model = PersistentSubsectionGrade.read_grade(
                        self.student.id, subsection.location)
                except PersistentSubsectionGrade.DoesNotExist:
                    pass
                else:
                    orig_subsection_grade = ReadSubsectionGrade(
                        subsection, grade_model, self)
                    if not is_score_higher_or_equal(
                            orig_subsection_grade.graded_total.earned,
                            orig_subsection_grade.graded_total.possible,
                            calculated_grade.graded_total.earned,
                            calculated_grade.graded_total.possible,
                            treat_undefined_as_zero=True,
                    ):
                        return orig_subsection_grade

            grade_model = calculated_grade.update_or_create_model(
                self.student, score_deleted, force_update_subsections)
            self._update_saved_subsection_grade(subsection.location,
                                                grade_model)

            if settings.FEATURES.get(
                    'ENABLE_COURSE_ASSESSMENT_GRADE_CHANGE_SIGNAL'):
                COURSE_ASSESSMENT_GRADE_CHANGED.send(
                    sender=self,
                    course_id=self.course_data.course_key,
                    user=self.student,
                    subsection_id=calculated_grade.location,
                    subsection_grade=calculated_grade.graded_total.earned)

        return calculated_grade
    def update(self, subsection, only_if_higher=None, score_deleted=False):
        """
        Updates the SubsectionGrade object for the student and subsection.
        """
        # Save ourselves the extra queries if the course does not persist
        # subsection grades.
        self._log_event(log.warning,
                        u"update, subsection: {}".format(subsection.location),
                        subsection)

        calculated_grade = SubsectionGrade(subsection).init_from_structure(
            self.student,
            self.course_data.structure,
            self._submissions_scores,
            self._csm_scores,
        )

        if should_persist_grades(self.course_data.course_key):
            if only_if_higher:
                try:
                    grade_model = PersistentSubsectionGrade.read_grade(
                        self.student.id, subsection.location)
                except PersistentSubsectionGrade.DoesNotExist:
                    pass
                else:
                    orig_subsection_grade = SubsectionGrade(
                        subsection).init_from_model(
                            self.student,
                            grade_model,
                            self.course_data.structure,
                            self._submissions_scores,
                            self._csm_scores,
                        )
                    if not is_score_higher_or_equal(
                            orig_subsection_grade.graded_total.earned,
                            orig_subsection_grade.graded_total.possible,
                            calculated_grade.graded_total.earned,
                            calculated_grade.graded_total.possible,
                    ):
                        return orig_subsection_grade

            grade_model = calculated_grade.update_or_create_model(
                self.student, score_deleted)
            self._update_saved_subsection_grade(subsection.location,
                                                grade_model)

        return calculated_grade
Beispiel #7
0
def score_published_handler(sender, block, user, raw_earned, raw_possible, only_if_higher, **kwargs):  # pylint: disable=unused-argument
    """
    Handles whenever a block's score is published.
    Returns whether the score was actually updated.
    """
    update_score = True
    if only_if_higher:
        previous_score = get_score(user.id, block.location)

        if previous_score is not None:
            prev_raw_earned, prev_raw_possible = (previous_score.grade, previous_score.max_grade)

            if not is_score_higher_or_equal(prev_raw_earned, prev_raw_possible, raw_earned, raw_possible):
                update_score = False
                log.warning(
                    u"Grades: Rescore is not higher than previous: "
                    u"user: {}, block: {}, previous: {}/{}, new: {}/{} ".format(
                        user, block.location, prev_raw_earned, prev_raw_possible, raw_earned, raw_possible,
                    )
                )

    if update_score:
        # Set the problem score in CSM.
        score_modified_time = set_score(user.id, block.location, raw_earned, raw_possible)

        # Set the problem score on the xblock.
        if isinstance(block, ScorableXBlockMixin):
            block.set_score(Score(raw_earned=raw_earned, raw_possible=raw_possible))

        # Fire a signal (consumed by enqueue_subsection_update, below)
        PROBLEM_RAW_SCORE_CHANGED.send(
            sender=None,
            raw_earned=raw_earned,
            raw_possible=raw_possible,
            weight=getattr(block, 'weight', None),
            user_id=user.id,
            course_id=six.text_type(block.location.course_key),
            usage_id=six.text_type(block.location),
            only_if_higher=only_if_higher,
            modified=score_modified_time,
            score_db_table=ScoreDatabaseTableEnum.courseware_student_module,
            score_deleted=kwargs.get('score_deleted', False),
            grader_response=kwargs.get('grader_response', False)
        )
    return update_score