MDL-79863 qtype_ordering: Implement response analysis for the quiz Statistics report

This commit is contained in:
Tim Hunt 2018-11-23 15:00:36 +00:00 committed by Mathew May
parent c231dab5cf
commit 9f6e662d30
5 changed files with 130 additions and 11 deletions

View File

@ -80,6 +80,7 @@ $string['longestorderedsubset'] = 'Longest ordered subset';
$string['noresponsedetails'] = 'Sorry, no details of the response to this question are available.';
$string['noscore'] = 'No score';
$string['notenoughanswers'] = 'Ordering questions must have more than {$a} answers.';
$string['positionx'] = 'Position {$a}';
$string['relativeallpreviousandnext'] = 'Relative to ALL the previous and next items';
$string['relativenextexcludelast'] = 'Relative to the next item (excluding last)';
$string['relativenextincludelast'] = 'Relative to the next item (including last)';

View File

@ -18,6 +18,7 @@
* Ordering question definition classes.
*
* @package qtype_ordering
*
* @copyright 2013 Gordon Bateson (gordon.bateson@gmail.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -251,7 +252,22 @@ class qtype_ordering_question extends question_graded_automatically {
* returns an empty array if no analysis is possible.
*/
public function classify_response(array $response) {
return array();
$this->update_current_response($response);
$fraction = 1 / count($this->correctresponse);
$classifiedresponse = array();
foreach ($this->correctresponse as $position => $answerid) {
if (in_array($answerid, $this->currentresponse)) {
$currentposition = array_search($answerid, $this->currentresponse);
}
$answer = $this->answers[$answerid];
$classifiedresponse[question_utils::to_plain_text($answer->answer, $answer->answerformat)] =
new question_classified_response($currentposition + 1,
get_string('positionx', 'qtype_ordering', $currentposition + 1),
($position == $currentposition) * $fraction);
}
return $classifiedresponse;
}
/**

View File

@ -296,17 +296,23 @@ class qtype_ordering extends question_type {
* responses to that subquestion.
*/
public function get_possible_responses($questiondata) {
$responses = array();
$question = $this->make_question($questiondata);
if ($question->correctresponse) {
foreach ($question->correctresponse as $position => $answerid) {
$responses[] = $position.': '.$question->answers[$answerid]->answer;
}
$responseclasses = array();
$itemcount = count($questiondata->options->answers);
$position = 0;
foreach ($questiondata->options->answers as $answerid => $answer) {
$position += 1;
$classes = array();
for ($i = 1; $i <= $itemcount; $i++) {
$classes[$i] = new question_possible_response(
get_string('positionx', 'qtype_ordering', $i),
($i === $position) / $itemcount);
}
$responseclasses[question_utils::to_plain_text(
$answer->answer, $answer->answerformat)] = $classes;
}
return array(
0 => question_possible_response::no_response(),
1 => implode(', ', $responses)
);
return $responseclasses;
}
/**

View File

@ -24,6 +24,8 @@
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
@ -378,4 +380,42 @@ class qtype_ordering_question_test extends advanced_testcase {
$numberofids--;
}
}
public function test_classify_response_correct() {
$question = test_question_maker::make_question('ordering');
$question->start_attempt(new question_attempt_step(), 1);
$response = $this->get_response($question, ['Modular', 'Object', 'Oriented', 'Dynamic', 'Learning', 'Environment']);
$classifiedresponse = $question->classify_response($response);
$expected = [
'Modular' => new question_classified_response(1, 'Position 1', 0.1666667),
'Object' => new question_classified_response(2, 'Position 2', 0.1666667),
'Oriented' => new question_classified_response(3, 'Position 3', 0.1666667),
'Dynamic' => new question_classified_response(4, 'Position 4', 0.1666667),
'Learning' => new question_classified_response(5, 'Position 5', 0.1666667),
'Environment' => new question_classified_response(6, 'Position 6', 0.1666667),
];
$this->assertEquals($expected, $classifiedresponse, '', 0.0000005);
}
public function test_classify_response_partially_correct() {
$question = test_question_maker::make_question('ordering');
$question->start_attempt(new question_attempt_step(), 1);
$response = $this->get_response($question, ['Dynamic', 'Modular', 'Object', 'Oriented', 'Learning', 'Environment']);
$classifiedresponse = $question->classify_response($response);
$expected = [
'Modular' => new question_classified_response(2, 'Position 2', 0),
'Object' => new question_classified_response(3, 'Position 3', 0),
'Oriented' => new question_classified_response(4, 'Position 4', 0),
'Dynamic' => new question_classified_response(1, 'Position 1', 0),
'Learning' => new question_classified_response(5, 'Position 5', 0.1666667),
'Environment' => new question_classified_response(6, 'Position 6', 0.1666667),
];
$this->assertEquals($expected, $classifiedresponse, '', 0.0000005);
}
}

View File

@ -104,4 +104,60 @@ class qtype_ordering_test extends advanced_testcase {
}
}
}
public function test_get_possible_responses() {
$questiondata = test_question_maker::get_question_data('ordering');
$possibleresponses = $this->qtype->get_possible_responses($questiondata);
$expectedresponseclasses = array(
'Modular' => array(
1 => new question_possible_response('Position 1', 0.1666667),
2 => new question_possible_response('Position 2', 0),
3 => new question_possible_response('Position 3', 0),
4 => new question_possible_response('Position 4', 0),
5 => new question_possible_response('Position 5', 0),
6 => new question_possible_response('Position 6', 0),
),
'Object' => array(
1 => new question_possible_response('Position 1', 0),
2 => new question_possible_response('Position 2', 0.1666667),
3 => new question_possible_response('Position 3', 0),
4 => new question_possible_response('Position 4', 0),
5 => new question_possible_response('Position 5', 0),
6 => new question_possible_response('Position 6', 0),
),
'Oriented' => array(
1 => new question_possible_response('Position 1', 0),
2 => new question_possible_response('Position 2', 0),
3 => new question_possible_response('Position 3', 0.1666667),
4 => new question_possible_response('Position 4', 0),
5 => new question_possible_response('Position 5', 0),
6 => new question_possible_response('Position 6', 0),
),
'Dynamic' => array(
1 => new question_possible_response('Position 1', 0),
2 => new question_possible_response('Position 2', 0),
3 => new question_possible_response('Position 3', 0),
4 => new question_possible_response('Position 4', 0.1666667),
5 => new question_possible_response('Position 5', 0),
6 => new question_possible_response('Position 6', 0),
),
'Learning' => array(
1 => new question_possible_response('Position 1', 0),
2 => new question_possible_response('Position 2', 0),
3 => new question_possible_response('Position 3', 0),
4 => new question_possible_response('Position 4', 0),
5 => new question_possible_response('Position 5', 0.1666667),
6 => new question_possible_response('Position 6', 0),
),
'Environment' => array(
1 => new question_possible_response('Position 1', 0),
2 => new question_possible_response('Position 2', 0),
3 => new question_possible_response('Position 3', 0),
4 => new question_possible_response('Position 4', 0),
5 => new question_possible_response('Position 5', 0),
6 => new question_possible_response('Position 6', 0.1666667),
),
);
$this->assertEquals($expectedresponseclasses, $possibleresponses, '', 0.0000005);
}
}