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"]
Andreas Klöckner
committed
afb = AnswerFeedback(0)
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
and matcher_afb.correctness > afb.correctness):
afb = matcher_afb
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.
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
.. 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