MDL-20636 Finish implementing answer processing.

This commit is contained in:
Tim Hunt 2011-03-30 14:30:14 +01:00
parent b3c9da2f0a
commit d7d8cee279
4 changed files with 101 additions and 17 deletions

View File

@ -99,7 +99,7 @@ class qtype_numerical_question extends question_graded_automatically {
return array();
}
return array('answer' => $answer->answer);
return array('answer' => $this->ap->add_unit($answer->answer));
}
/**
@ -128,6 +128,19 @@ class qtype_numerical_question extends question_graded_automatically {
return null;
}
protected function apply_unit_penalty($fraction, $unit) {
if (!empty($unit)) {
return $fraction;
}
if ($this->unitgradingtype == qtype_numerical::UNITGRADEDOUTOFMARK) {
$fraction -= $this->unitpenalty * $fraction;
} else if ($this->unitgradingtype == qtype_numerical::UNITGRADEDOUTOFMAX) {
$fraction -= $this->unitpenalty;
}
return max($fraction, 0);
}
public function grade_response(array $response) {
list($value, $unit) = $this->ap->apply_units($response['answer']);
$answer = $this->get_matching_answer($value);
@ -135,16 +148,7 @@ class qtype_numerical_question extends question_graded_automatically {
return array(0, question_state::$gradedwrong);
}
$fraction = $answer->fraction;
if (empty($unit)) {
if ($this->unitgradingtype == qtype_numerical::UNITGRADEDOUTOFMARK) {
$fraction -= $this->unitpenalty * $fraction;
} else if ($this->unitgradingtype == qtype_numerical::UNITGRADEDOUTOFMAX) {
$fraction -= $this->unitpenalty;
}
$fraction = max($fraction, 0);
}
$fraction = $this->apply_unit_penalty($answer->fraction, $unit);
return array($fraction, question_state::graded_state_for_fraction($fraction));
}
@ -158,8 +162,9 @@ class qtype_numerical_question extends question_graded_automatically {
if (!$ans) {
return array($this->id => question_classified_response::no_response());
}
return array($this->id => new question_classified_response(
$ans->id, $response['answer'], $ans->fraction));
return array($this->id => new question_classified_response($ans->id,
$response['answer'],
$this->apply_unit_penalty($ans->fraction, $unit)));
}
}

View File

@ -1203,7 +1203,12 @@ class qtype_numerical_answer_processor {
* @param string $answer a response.
* @param string $unit a unit.
*/
public function add_unit($answer, $unit) {
public function add_unit($answer, $unit = null) {
if (is_null($unit)) {
reset($this->units);
$unit = key($this->units);
}
if (!$unit) {
return $answer;
}

View File

@ -120,5 +120,6 @@ class qtype_numerical_answer_processor_test extends UnitTestCase {
$this->assertEqual(array('100', '$'), $ap->apply_units('$100.'));
$this->assertEqual(array('100.00', '$'), $ap->apply_units('$100.00'));
$this->assertEqual(array('100', ''), $ap->apply_units('100'));
$this->assertEqual(array('100', ''), $ap->apply_units('frog 100'));
}
}

View File

@ -131,6 +131,20 @@ class qtype_numerical_question_test extends UnitTestCase {
$question->get_correct_response());
}
public function test_get_correct_response_units() {
$question = test_question_maker::make_question('numerical', 'unit');
$this->assertEqual(array('answer' => '1.25 m'),
$question->get_correct_response());
}
public function test_get_correct_response_currency() {
$question = test_question_maker::make_question('numerical', 'currency');
$this->assertEqual(array('answer' => '$ 1332'),
$question->get_correct_response());
}
public function test_get_question_summary() {
$num = test_question_maker::make_question('numerical');
$qsummary = $num->get_question_summary();
@ -139,8 +153,22 @@ class qtype_numerical_question_test extends UnitTestCase {
public function test_summarise_response() {
$num = test_question_maker::make_question('numerical');
$summary = $num->summarise_response(array('answer' => '3.1'));
$this->assertEqual('3.1', $summary);
$this->assertEqual('3.1', $num->summarise_response(array('answer' => '3.1')));
}
public function test_summarise_response_unit() {
$num = test_question_maker::make_question('numerical', 'unit');
$this->assertEqual('3.1', $num->summarise_response(array('answer' => '3.1')));
$this->assertEqual('3.1m', $num->summarise_response(array('answer' => '3.1m')));
$this->assertEqual('3.1 cm', $num->summarise_response(array('answer' => '3.1 cm')));
}
public function test_summarise_response_currency() {
$num = test_question_maker::make_question('numerical', 'currency');
$this->assertEqual('100', $num->summarise_response(array('answer' => '100')));
$this->assertEqual('$100', $num->summarise_response(array('answer' => '$100')));
$this->assertEqual('$ 100', $num->summarise_response(array('answer' => '$ 100')));
$this->assertEqual('100 frogs', $num->summarise_response(array('answer' => '100 frogs')));
}
public function test_classify_response() {
@ -160,4 +188,49 @@ class qtype_numerical_question_test extends UnitTestCase {
question_classified_response::no_response()),
$num->classify_response(array('answer' => '')));
}
}
public function test_classify_response_unit() {
$num = test_question_maker::make_question('numerical', 'unit');
$num->start_attempt(new question_attempt_step());
$this->assertEqual(array(
new question_classified_response(13, '1.25', 0.5)),
$num->classify_response(array('answer' => '1.25')));
$this->assertEqual(array(
new question_classified_response(13, '1.25 m', 1.0)),
$num->classify_response(array('answer' => '1.25 m')));
$this->assertEqual(array(
new question_classified_response(13, '125cm', 1.0)),
$num->classify_response(array('answer' => '125cm')));
$this->assertEqual(array(
new question_classified_response(14, '123 cm', 0.5)),
$num->classify_response(array('answer' => '123 cm')));
$this->assertEqual(array(
new question_classified_response(14, '1.27m', 0.5)),
$num->classify_response(array('answer' => '1.27m')));
$this->assertEqual(array(
new question_classified_response(13, '1.25 frogs', 0.5)),
$num->classify_response(array('answer' => '1.25 frogs')));
$this->assertEqual(array(
new question_classified_response(17, '3 frogs', 0)),
$num->classify_response(array('answer' => '3 frogs')));
$this->assertEqual(array(
new question_classified_response(17, '3.0 m', 0)),
$num->classify_response(array('answer' => '3.0 m')));
$this->assertEqual(array(
question_classified_response::no_response()),
$num->classify_response(array('answer' => '')));
}
public function test_classify_response_currency() {
$num = test_question_maker::make_question('numerical', 'currency');
$num->start_attempt(new question_attempt_step());
$this->assertEqual(array(
new question_classified_response(14, '$100', 0)),
$num->classify_response(array('answer' => '$100')));
$this->assertEqual(array(
new question_classified_response(13, '1,332', 0.8)),
$num->classify_response(array('answer' => '1,332')));
}
}