Newer
Older
"correct answer"))
% location)
def required_attrs(self):
return super(TextQuestion, self).required_attrs() + (
("answers", list),
)
def allowed_attrs(self):
return super(TextQuestion, self).allowed_attrs() + (
("answer_explanation", "markup"),
)
def get_validators(self):
return self.matchers
def grade(self, page_context, page_data, answer_data, grade_data):
if answer_data is None:
return AnswerFeedback(correctness=0,
feedback=gettext("No answer provided."))
answer = answer_data["answer"]
# Must start with 'None' to allow matcher to set feedback for zero
# correctness.
afb = None
Andreas Klöckner
committed
for matcher in self.matchers:
try:
matcher.validate(answer)
except forms.ValidationError:
continue
Andreas Klöckner
committed
matcher_afb = matcher.grade(answer)
if matcher_afb.correctness is not None:
if afb is None:
afb = matcher_afb
elif matcher_afb.correctness > afb.correctness:
afb = matcher_afb
if afb is None:
afb = AnswerFeedback(0)
Andreas Klöckner
committed
return afb
def correct_answer(self, page_context, page_data, answer_data, grade_data):
# FIXME: Could use 'best' match to answer
for matcher in self.matchers: # pragma: no branch
unspec_correct_answer_text = matcher.correct_answer_text()
if unspec_correct_answer_text is not None:
break
assert unspec_correct_answer_text
result = CORRECT_ANSWER_PATTERN % unspec_correct_answer_text
if hasattr(self.page_desc, "answer_explanation"):
result += markup_to_html(page_context, self.page_desc.answer_explanation)
return result
Andreas Klöckner
committed
def _is_case_sensitive(self):
return any(matcher._is_case_sensitive for matcher in self.matchers)
# }}}
# {{{ human-graded text question
class HumanGradedTextQuestion(TextQuestionBase, PageBaseWithValue,
PageBaseWithHumanTextFeedback, PageBaseWithCorrectAnswer):
"""
A page asking for a textual answer
.. attribute:: id
|id-page-attr|
.. attribute:: type
``HumanGradedTextQuestion``
.. attribute:: is_optional_page
|is-optional-page-attr|
.. attribute:: access_rules
|access-rules-page-attr|
.. attribute:: title
|title-page-attr|
.. attribute:: value
|value-page-attr|
.. attribute:: prompt
The page's prompt, written in :ref:`markup`.
.. attribute:: widget
.. attribute:: initial_text
Text with which to prepopulate the input widget.
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
.. attribute:: validators
Optional.
TODO
.. attribute:: correct_answer
Optional.
Content that is revealed when answers are visible
(see :ref:`flow-permissions`). Written in :ref:`markup`.
.. attribute:: rubric
Required.
The grading guideline for this question, in :ref:`markup`.
"""
def __init__(self, vctx, location, page_desc):
super(HumanGradedTextQuestion, self).__init__(vctx, location, page_desc)
self.validators = [
parse_validator(
vctx,
"%s, validator %d" % (location, i+1),
for i, answer in enumerate(
getattr(page_desc, "validators", []))]
def allowed_attrs(self):
return super(HumanGradedTextQuestion, self).allowed_attrs() + (
("validators", list),
)
def human_feedback_point_value(self, page_context, page_data):
return self.max_points(page_data)
def get_validators(self):
return self.validators