mirror of
https://github.com/moodle/moodle.git
synced 2025-08-04 00:16:46 +02:00
MDL-20636 Finish implementing answer processing.
This commit is contained in:
parent
b3c9da2f0a
commit
d7d8cee279
4 changed files with 101 additions and 17 deletions
|
@ -99,7 +99,7 @@ class qtype_numerical_question extends question_graded_automatically {
|
||||||
return array();
|
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;
|
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) {
|
public function grade_response(array $response) {
|
||||||
list($value, $unit) = $this->ap->apply_units($response['answer']);
|
list($value, $unit) = $this->ap->apply_units($response['answer']);
|
||||||
$answer = $this->get_matching_answer($value);
|
$answer = $this->get_matching_answer($value);
|
||||||
|
@ -135,16 +148,7 @@ class qtype_numerical_question extends question_graded_automatically {
|
||||||
return array(0, question_state::$gradedwrong);
|
return array(0, question_state::$gradedwrong);
|
||||||
}
|
}
|
||||||
|
|
||||||
$fraction = $answer->fraction;
|
$fraction = $this->apply_unit_penalty($answer->fraction, $unit);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return array($fraction, question_state::graded_state_for_fraction($fraction));
|
return array($fraction, question_state::graded_state_for_fraction($fraction));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,8 +162,9 @@ class qtype_numerical_question extends question_graded_automatically {
|
||||||
if (!$ans) {
|
if (!$ans) {
|
||||||
return array($this->id => question_classified_response::no_response());
|
return array($this->id => question_classified_response::no_response());
|
||||||
}
|
}
|
||||||
return array($this->id => new question_classified_response(
|
return array($this->id => new question_classified_response($ans->id,
|
||||||
$ans->id, $response['answer'], $ans->fraction));
|
$response['answer'],
|
||||||
|
$this->apply_unit_penalty($ans->fraction, $unit)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1203,7 +1203,12 @@ class qtype_numerical_answer_processor {
|
||||||
* @param string $answer a response.
|
* @param string $answer a response.
|
||||||
* @param string $unit a unit.
|
* @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) {
|
if (!$unit) {
|
||||||
return $answer;
|
return $answer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,5 +120,6 @@ class qtype_numerical_answer_processor_test extends UnitTestCase {
|
||||||
$this->assertEqual(array('100', '$'), $ap->apply_units('$100.'));
|
$this->assertEqual(array('100', '$'), $ap->apply_units('$100.'));
|
||||||
$this->assertEqual(array('100.00', '$'), $ap->apply_units('$100.00'));
|
$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('100'));
|
||||||
|
$this->assertEqual(array('100', ''), $ap->apply_units('frog 100'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,20 @@ class qtype_numerical_question_test extends UnitTestCase {
|
||||||
$question->get_correct_response());
|
$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() {
|
public function test_get_question_summary() {
|
||||||
$num = test_question_maker::make_question('numerical');
|
$num = test_question_maker::make_question('numerical');
|
||||||
$qsummary = $num->get_question_summary();
|
$qsummary = $num->get_question_summary();
|
||||||
|
@ -139,8 +153,22 @@ class qtype_numerical_question_test extends UnitTestCase {
|
||||||
|
|
||||||
public function test_summarise_response() {
|
public function test_summarise_response() {
|
||||||
$num = test_question_maker::make_question('numerical');
|
$num = test_question_maker::make_question('numerical');
|
||||||
$summary = $num->summarise_response(array('answer' => '3.1'));
|
$this->assertEqual('3.1', $num->summarise_response(array('answer' => '3.1')));
|
||||||
$this->assertEqual('3.1', $summary);
|
}
|
||||||
|
|
||||||
|
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() {
|
public function test_classify_response() {
|
||||||
|
@ -160,4 +188,49 @@ class qtype_numerical_question_test extends UnitTestCase {
|
||||||
question_classified_response::no_response()),
|
question_classified_response::no_response()),
|
||||||
$num->classify_response(array('answer' => '')));
|
$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')));
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue