Skip to content
code.py 41.7 KiB
Newer Older
        of the question), in :ref:`markup`.
    """

    def __init__(self, vctx, location, page_desc):
        super(PythonCodeQuestionWithHumanTextFeedback, self).__init__(
                vctx, location, page_desc)

Dong Zhuang's avatar
Dong Zhuang committed
        if vctx is not None:
            if (hasattr(self.page_desc, "human_feedback_value")
                and
                    hasattr(self.page_desc, "human_feedback_percentage")):
                raise ValidationError(
                    string_concat(
                        "%(location)s: ",
                        _("'human_feedback_value' and "
                          "'human_feedback_percentage' are not "
                          "allowed to coexist"))
                    % {'location': location}
                )
            if not (hasattr(self.page_desc, "human_feedback_value")
                    or hasattr(self.page_desc, "human_feedback_percentage")):
                raise ValidationError(
                    string_concat(
                        "%(location)s: ",
                        _("expecting either 'human_feedback_value' "
                          "or 'human_feedback_percentage', found neither."))
                    % {'location': location}
                )
            if hasattr(self.page_desc, "human_feedback_value"):
                vctx.add_warning(
                    location,
                    _("Used deprecated 'human_feedback_value' attribute--"
                      "use 'human_feedback_percentage' instead."))
                if self.page_desc.value == 0:
                    raise ValidationError("".join([
                        "%s: ",
                        _("'human_feedback_value' attribute is not allowed "
                          "if value of question is 0, use "
                          "'human_feedback_percentage' instead")])
                        % location)
                if self.page_desc.human_feedback_value > self.page_desc.value:
                    raise ValidationError("".join([
                        "%s: ",
                        _("human_feedback_value greater than overall "
                            "value of question")])
                        % location)
            if hasattr(self.page_desc, "human_feedback_percentage"):
                if not (
                        0 <= self.page_desc.human_feedback_percentage <= 100):
                    raise ValidationError("".join([
                        "%s: ",
                        _("the value of human_feedback_percentage "
                          "must be between 0 and 100")])
                        % location)

        if hasattr(self.page_desc, "human_feedback_value"):
            self.human_feedback_percentage = \
                self.page_desc.human_feedback_value * 100 / self.page_desc.value
        else:
            self.human_feedback_percentage = self.page_desc.human_feedback_percentage

    def required_attrs(self):
        return super(
                PythonCodeQuestionWithHumanTextFeedback, self).required_attrs() + (
                        # value is otherwise optional, but we require it here
                        ("value", (int, float)),
Dong Zhuang's avatar
Dong Zhuang committed
                        )

    def allowed_attrs(self):
        return super(
                PythonCodeQuestionWithHumanTextFeedback, self).allowed_attrs() + (
                        ("human_feedback_value", (int, float)),
Dong Zhuang's avatar
Dong Zhuang committed
                        ("human_feedback_percentage", (int, float)),
    def human_feedback_point_value(self, page_context, page_data):
Dong Zhuang's avatar
Dong Zhuang committed
        return self.page_desc.value * self.human_feedback_percentage / 100
    def grade(self, page_context, page_data, answer_data, grade_data):
        if answer_data is None:
            return AnswerFeedback(correctness=0,
ifaint's avatar
ifaint committed
                    feedback=_("No answer provided."))

        if grade_data is not None and not grade_data["released"]:
            grade_data = None

        code_feedback = PythonCodeQuestion.grade(self, page_context,
                page_data, answer_data, grade_data)

Dong Zhuang's avatar
Dong Zhuang committed
        human_points = self.human_feedback_point_value(page_context, page_data)
        code_points = self.page_desc.value - human_points

        correctness = None
        percentage = None
        if (code_feedback is not None
                and code_feedback.correctness is not None
                and grade_data is not None
                and grade_data["grade_percent"] is not None):
Dong Zhuang's avatar
Dong Zhuang committed
            code_feedback_percentage = 100 - self.human_feedback_percentage
            percentage = (
                    code_feedback.correctness * code_feedback_percentage

                    + grade_data["grade_percent"] / 100
Dong Zhuang's avatar
Dong Zhuang committed
                    * self.human_feedback_percentage
                    )
            correctness = percentage / 100
        elif (self.human_feedback_percentage == 100
                and grade_data is not None
                and grade_data["grade_percent"] is not None):
            correctness = grade_data["grade_percent"] / 100
            percentage = correctness * 100
        elif (self.human_feedback_percentage == 0
                and code_feedback.correctness is not None):
            correctness = code_feedback.correctness
            percentage = correctness * 100

        human_feedback_text = None

        human_feedback_points = None
        if grade_data is not None:
            if grade_data["feedback_text"] is not None:
                human_feedback_text = markup_to_html(
                        page_context, grade_data["feedback_text"])

Dong Zhuang's avatar
Dong Zhuang committed
            human_graded_percentage = grade_data["grade_percent"]
            if human_graded_percentage is not None:
                human_feedback_points = (human_graded_percentage/100.
                        * human_points)

        code_feedback_points = None
        if (code_feedback is not None
                and code_feedback.correctness is not None):
            code_feedback_points = code_feedback.correctness*code_points

        from django.template.loader import render_to_string
        feedback = render_to_string(
                "course/feedback-code-with-human.html",
                {
                    "percentage": percentage,
                    "code_feedback": code_feedback,
                    "code_feedback_points": code_feedback_points,
                    "code_points": code_points,
                    "human_feedback_text": human_feedback_text,
                    "human_feedback_points": human_feedback_points,
                    "human_points": human_points,
                    })

        return AnswerFeedback(
                correctness=correctness,
                feedback=feedback,
                bulk_feedback=code_feedback.bulk_feedback)