Skip to content

Commit

Permalink
Matrix: Reimplement get_possible_responses() for stats #746912
Browse files Browse the repository at this point in the history
  • Loading branch information
mkassaei committed Feb 23, 2024
1 parent 64dd6f7 commit ab1631e
Show file tree
Hide file tree
Showing 7 changed files with 484 additions and 76 deletions.
2 changes: 1 addition & 1 deletion classes/privacy/provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class provider implements
* @param collection $collection The initialised collection to add items to.
* @return collection A listing of user data stored through this system.
*/
public static function get_metadata(collection $collection) : collection {
public static function get_metadata(collection $collection): collection {
$collection->add_user_preference('qtype_oumatrix_defaultmark', 'privacy:preference:defaultmark');
$collection->add_user_preference('qtype_oumatrix_penalty', 'privacy:preference:penalty');
$collection->add_user_preference('qtype_oumatrix_inputtype', 'privacy:preference:inputtype');
Expand Down
87 changes: 87 additions & 0 deletions question.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public function apply_attempt_state(question_attempt_step $step) {

/**
* Returns the roworder of the question being displayed.
*
* @param question_attempt $qa
* @return array|null
*/
Expand Down Expand Up @@ -269,6 +270,50 @@ public function is_complete_response(array $response): bool {
return true;
}

public function classify_response(array $response): array {
$selectedchoices = [];
foreach ($this->rows as $rownumber => $row) {
$fieldname = $this->field($rownumber - 1);
if (array_key_exists($fieldname, $response) && $response[$fieldname]) {
foreach ($this->columns as $colnumber => $col) {
if ($response[$fieldname] === $colnumber &&
in_array($response[$fieldname], array_keys($row->correctanswers))) {
$fraction = 1;
} else {
$fraction = 0;
}
$selectedchoices[$rownumber][$colnumber] =
new question_classified_response ($colnumber, $row->name . ': ' . $col->name, $fraction);
}
} else {
$selectedchoices[$rownumber] = question_classified_response::no_response();
}
}
return $selectedchoices;
}

public function prepare_simulated_post_data($simulatedresponse): array {
$postdata = [];
$subquestions = array_keys($simulatedresponse);
$answers = array_values($simulatedresponse);

foreach ($this->roworder as $key => $rowid) {
$row = $this->rows[$rowid];
if ($row->name !== $subquestions[$key]) {
continue;
}
if ($key === ($row->number - 1) && $row->name === $subquestions[$key]) {
foreach ($this->columns as $colid => $column) {
if ($column->name !== $answers[$key]) {
continue;
}
$postdata[$this->field($key)] = $column->number;
}
}
}
return $postdata;
}

public function grade_response(array $response): array {
// Retrieve the number of right responses and the total number of responses.
[$numrightparts, $total] = $this->get_num_parts_right($response);
Expand Down Expand Up @@ -388,6 +433,48 @@ public function is_complete_response(array $response): bool {
return true;
}

public function classify_response(array $response) {
$selectedchoices = [];
foreach ($this->rows as $rownumber => $row) {
foreach ($this->columns as $colnumber => $col) {
$fieldname = $this->field($rownumber - 1, $colnumber);
if (array_key_exists($fieldname, $response) && $response[$fieldname] &&
in_array($colnumber, array_keys($row->correctanswers))) {
$fraction = 1 / count($row->correctanswers);
} else {
$fraction = 0;
}
$selectedchoices[$rownumber][$colnumber] =
new question_classified_response ($colnumber, $row->name . ': ' . $col->name, $fraction);
}
}
return $selectedchoices;
}

public function prepare_simulated_post_data($simulatedresponse): array {
$postdata = [];
$subquestions = array_keys($simulatedresponse);
$answers = array_values($simulatedresponse);
foreach ($this->roworder as $key => $rowid) {
$row = $this->rows[$rowid];
$rowanswers = $answers[$key];
if ($key === ($row->number - 1) && $row->name === $subquestions[$key]) {
foreach ($this->columns as $colid => $column) {
// Set the field to '0' initially.
$postdata[$this->field($key, $column->number)] = '0';
foreach ($rowanswers as $colnumber => $colname) {
if ($row->name === $subquestions[$key] &&
$column->number === $colnumber && $column->name === $colname) {
// Set the field to '1' if it has been ticked..
$postdata[$this->field($key, $column->number)] = '1';
}
}
}
}
}
return $postdata;
}

public function grade_response(array $response): array {
// Retrieve the number of right responses and the total number of responses.
if ($this->grademethod == 'allnone') {
Expand Down
34 changes: 13 additions & 21 deletions questiontype.php
Original file line number Diff line number Diff line change
Expand Up @@ -316,30 +316,22 @@ public function get_num_correct_choices(stdClass $questiondata): int {
}

public function get_possible_responses($questiondata) {
if ($questiondata->options->single) {
$responses = [];

// TODO: Sort out this funtion to work with rows and columns, etc.
foreach ($questiondata->options->answers as $aid => $answer) {
$responses[$aid] = new question_possible_response(
question_utils::to_plain_text($answer->answer, $answer->answerformat),
$answer->fraction);
$q = $this->make_question($questiondata);
$subqs = [];
$responses = [];
foreach ($q->rows as $rownumber => $row) {
foreach ($q->columns as $colnumber => $col) {
if (in_array($colnumber, array_keys($row->correctanswers))) {
$fraction = 1;
} else {
$fraction = 0;
}
$responses[$colnumber] = new question_possible_response($row->name . ': ' . $col->name, $fraction);
}

$responses[null] = question_possible_response::no_response();
return [$questiondata->id => $responses];
} else {
$parts = [];

foreach ($questiondata->options->answers as $aid => $answer) {
$parts[$aid] = [
$aid => new question_possible_response(question_utils::to_plain_text(
$answer->answer, $answer->answerformat), $answer->fraction),
];
}

return $parts;
$subqs[$rownumber] = $responses;
}
return $subqs;
}

public function import_from_xml($data, $question, qformat_xml $format, $extra = null) {
Expand Down
90 changes: 36 additions & 54 deletions tests/helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,54 +72,46 @@ public function get_oumatrix_question_data_animals_single(): stdClass {
$qdata->options->shownumcorrect = 1;

$qdata->columns = [
11 => (object) [
'id' => 11,
1 => (object) [
'number' => 1,
'name' => 'Insects',
],
12 => (object) [
'id' => 12,
2 => (object) [
'number' => 2,
'name' => 'Fish',
],
13 => (object) [
'id' => 13,
3 => (object) [
'number' => 3,
'name' => 'Birds',
],
14 => (object) [
'id' => 13,
4 => (object) [
'number' => 4,
'name' => 'Mammals',
],
];
$qdata->rows = [
11 => (object) [
'id' => 11,
1 => (object) [
'number' => 1,
'name' => 'Bee',
'correctanswers' => ['1' => 'a1'],
'feedback' => 'Flies and Bees are insects.',
'feedbackformat' => FORMAT_HTML,
],
12 => (object) [
'id' => 12,
2 => (object) [
'number' => 2,
'name' => 'Salmon',
'correctanswers' => ['2' => 'a2'],
'feedback' => 'Cod, Salmon and Trout are fish.',
'feedbackformat' => FORMAT_HTML,
],
13 => (object) [
'id' => 13,
3 => (object) [
'number' => 3,
'name' => 'Seagull',
'correctanswers' => ['3' => 'a3'],
'feedback' => 'Gulls and Owls are birds.',
'feedbackformat' => FORMAT_HTML,
],
14 => (object) [
'id' => 14,
4 => (object) [
'number' => 4,
'name' => 'Dog',
'correctanswers' => ['4' => 'a4'],
Expand Down Expand Up @@ -266,61 +258,51 @@ public function get_oumatrix_question_data_food_multiple(): stdClass {
$qdata->options->shownumcorrect = 1;

$qdata->columns = [
21 => (object) [
'id' => 21,
1 => (object) [
'number' => 1,
'name' => 'Chicken breast',
],
22 => (object) [
'id' => 22,
2 => (object) [
'number' => 2,
'name' => 'Carrot',
],
23 => (object) [
'id' => 23,
3 => (object) [
'number' => 3,
'name' => 'Salmon fillet',
],
24 => (object) [
'id' => 24,
4 => (object) [
'number' => 4,
'name' => 'Asparagus',
],
25 => (object) [
'id' => 25,
5 => (object) [
'number' => 5,
'name' => 'Olive oil',
],
26 => (object) [
'id' => 26,
6 => (object) [
'number' => 6,
'name' => 'Steak',
],
27 => (object) [
'id' => 27,
7 => (object) [
'number' => 7,
'name' => 'Potato',
],
];
$qdata->rows = [
21 => (object) [
'id' => 21,
1 => (object) [
'number' => 1,
'name' => 'Proteins',
'correctanswers' => [1, 3, 6],
'feedback' => 'Chicken, fish and red meat containing proteins.',
'feedbackformat' => FORMAT_HTML,
],
22 => (object) [
'id' => 22,
2 => (object) [
'number' => 2,
'name' => 'Vegetables',
'correctanswers' => [2, 4, 7],
'feedback' => 'Carrot, Asparagus, Potato are vegetables.',
'feedbackformat' => FORMAT_HTML,
],
23 => (object) [
'id' => 23,
3 => (object) [
'number' => 3,
'name' => 'Fats',
'correctanswers' => [5],
Expand Down Expand Up @@ -481,20 +463,20 @@ public function make_oumatrix_question_animals_single(): qtype_oumatrix_single {
$question->shownumcorrect = 1;

$question->columns = [
11 => new column($question->id, 1, 'Insects', 11),
12 => new column($question->id, 2, 'Fish', 12),
13 => new column($question->id, 3, 'Birds', 13),
14 => new column($question->id, 4, 'Mammals', 14),
1 => new column($question->id, 1, 'Insects'),
2 => new column($question->id, 2, 'Fish'),
3 => new column($question->id, 3, 'Birds'),
4 => new column($question->id, 4, 'Mammals'),
];

$question->rows = [
11 => new row(11, $question->id, 1, 'Bee', [1 => '1'],
1 => new row(1, $question->id, 1, 'Bee', [1 => '1'],
'Flies and Bees are insects.', FORMAT_HTML),
12 => new row(12, $question->id, 2, 'Salmon', [2 => '1'],
2 => new row(2, $question->id, 2, 'Salmon', [2 => '1'],
'Cod, Salmon and Trout are fish.', FORMAT_HTML),
13 => new row(13, $question->id, 3, 'Seagull', [3 => '1'],
3 => new row(3, $question->id, 3, 'Seagull', [3 => '1'],
'Gulls and Owls are birds.', FORMAT_HTML),
14 => new row(14, $question->id, 4, 'Dog', [4 => '1'],
4 => new row(4, $question->id, 4, 'Dog', [4 => '1'],
'Cows, Dogs and Horses are mammals.', FORMAT_HTML),
];

Expand Down Expand Up @@ -538,21 +520,21 @@ public function make_oumatrix_question_food_multiple(): qtype_oumatrix_multiple
$question->shownumcorrect = 1;

$question->columns = [
21 => new column($question->id, 1, 'Chicken breast', 21),
22 => new column($question->id, 2, 'Carrot', 22),
23 => new column($question->id, 3, 'Salmon fillet', 23),
24 => new column($question->id, 4, 'Asparagus', 24),
25 => new column($question->id, 5, 'Olive oil', 25),
26 => new column($question->id, 6, 'Steak', 26),
27 => new column($question->id, 7, 'Potato', 27),
1 => new column($question->id, 1, 'Chicken breast'),
2 => new column($question->id, 2, 'Carrot'),
3 => new column($question->id, 3, 'Salmon fillet'),
4 => new column($question->id, 4, 'Asparagus'),
5 => new column($question->id, 5, 'Olive oil'),
6 => new column($question->id, 6, 'Steak'),
7 => new column($question->id, 7, 'Potato'),
];

$question->rows = [
21 => new row(21, $question->id, 1, 'Proteins', [1 => '1', 3 => '1', 6 => '1'],
1 => new row(21, $question->id, 1, 'Proteins', [1 => '1', 3 => '1', 6 => '1'],
'Chicken, fish and red meat containing proteins.', FORMAT_HTML),
22 => new row(22, $question->id, 2, 'Vegetables', [2 => '1', 4 => '1', 7 => '1'],
2 => new row(22, $question->id, 2, 'Vegetables', [2 => '1', 4 => '1', 7 => '1'],
'Carrot, Asparagus, Potato are vegetables.', FORMAT_HTML),
23 => new row(23, $question->id, 3, 'Fats', [5 => '1'],
3 => new row(23, $question->id, 3, 'Fats', [5 => '1'],
'Olive oil contains fat.', FORMAT_HTML),
];

Expand Down
Loading

0 comments on commit ab1631e

Please sign in to comment.