Skip to content

Commit

Permalink
Changing correctanswers to store column numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
AnupamaSarjoshi authored and mkassaei committed Oct 24, 2023
1 parent 5945e6a commit 4de5986
Show file tree
Hide file tree
Showing 13 changed files with 86 additions and 121 deletions.
19 changes: 1 addition & 18 deletions backup/moodle2/restore_qtype_oumatrix_plugin.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,24 +74,7 @@ public function process_qtype_oumatrix_column(array $data): void {
* @param array $data
*/
public function process_qtype_oumatrix_row(array $data): void {
$data = (object)$data;

// Detect if the question is created or mapped.
$questioncreated = $this->get_mappingid('question_created',
$this->get_old_parentid('question'));

// If the question has been created by restore, we need to update the correctanswers to store new column id's.
if ($questioncreated) {
// Adjust correct answers.
$decodedanswers = json_decode($data->correctanswers, true);
foreach ($decodedanswers as $columnid => $value) {
$newcolumnid = $this->get_mappingid('qtype_oumatrix_columns', $columnid);
$decodedanswers[$newcolumnid] = $value;
unset($decodedanswers[$columnid]);
}
$data->correctanswers = json_encode($decodedanswers);
}
self::process_qtype_oumatrix_data_with_table_name((array)$data, 'qtype_oumatrix_rows');
self::process_qtype_oumatrix_data_with_table_name($data, 'qtype_oumatrix_rows');
}

/**
Expand Down
14 changes: 0 additions & 14 deletions classes/column.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,4 @@ public function __construct(int $questionid, int $number, string $name, int $id
$this->name = $name;
$this->id = $id;
}

/**
* Returns the array of columns by id's.
*
* @param array $columns
* @return array
*/
public static function get_column_ids(array $columns): array {
$columnids = [];
foreach ($columns as $column) {
$columnids[$column->id] = $column;
}
return $columnids;
}
}
2 changes: 1 addition & 1 deletion db/install.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<FIELD NAME="questionid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="number" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="numbered sequentially 1, 2, 3 in a given question"/>
<FIELD NAME="name" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" COMMENT="The text presenting the question in a row."/>
<FIELD NAME="correctanswers" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" COMMENT="A json-encoded list of correct answers for a given row."/>
<FIELD NAME="correctanswers" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" COMMENT="A list of correct answers(column numbers) for a given row."/>
<FIELD NAME="feedback" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for the row."/>
<FIELD NAME="feedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false"/>
</FIELDS>
Expand Down
2 changes: 0 additions & 2 deletions db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@

defined('MOODLE_INTERNAL') || die();

require_once(__DIR__.'/upgradelib.php');

/**
* Execute qtype_oumatrix upgrade from the given old version.
*
Expand Down
6 changes: 3 additions & 3 deletions edit_oumatrix_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -258,15 +258,15 @@ private function data_preprocessing_rows($question) {
$question->rowname = [];
foreach ($question->rows as $index => $row) {
$question->rowname[$row->number - 1] = $row->name;
$decodedanswers = json_decode($row->correctanswers, true);
$answerslist = explode(',', $row->correctanswers);
foreach ($question->columns as $key => $column) {
if (array_key_exists($column->id, $decodedanswers)) {
if (in_array($column->number, $answerslist)) {
$columnvalue = 'a' . ($column->number);
if ($question->options->inputtype == 'single') {
$question->rowanswers[$row->number - 1] = $columnvalue;
} else {
$rowanswerslabel = "rowanswers" . $columnvalue;
$question->{$rowanswerslabel}[$row->number - 1] = $decodedanswers[$column->id];
$question->{$rowanswerslabel}[$row->number - 1] = '1';
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion lang/en/qtype_oumatrix.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,4 @@
$string['yougot1right'] = 'You have correctly selected one option.';
$string['yougotnright'] = 'You have correctly selected {$a->num} options';
$string['yougot1rightsubquestion'] = 'You have correctly answered one sub-question.';
$string['yougotnrightsubquestion'] = 'You have correctly answered {$a->num} sub-question.';
$string['yougotnrightsubquestion'] = 'You have correctly answered {$a->num} sub-questions.';
18 changes: 7 additions & 11 deletions question.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,11 @@ protected function field(int $rowkey): string {

public function get_correct_response(): ?array {
$response = [];
$columnids = column::get_column_ids($this->columns);
foreach ($this->roworder as $key => $rownumber) {
$row = $this->rows[$rownumber];
foreach ($row->correctanswers as $colkey => $answer) {
foreach ($row->correctanswers as $colnum => $answer) {
// Get the corresponding column number associated with the column key.
$response[$this->field($key)] = $columnids[$colkey]->number;
$response[$this->field($key)] = $colnum;
}
}
return $response;
Expand Down Expand Up @@ -255,12 +254,10 @@ public function grade_response(array $response): array {

public function get_num_parts_right(array $response): array {
$numright = 0;
$columnids = column::get_column_ids($this->columns);
foreach ($this->roworder as $key => $rownumber) {
$row = $this->rows[$rownumber];
$column = $columnids[array_key_first($row->correctanswers)];
if (array_key_exists($this->field($key), $response) &&
$response[$this->field($key)] == $column->number) {
array_key_exists($response[$this->field($key)], $row->correctanswers)) {
$numright++;
}
}
Expand Down Expand Up @@ -324,12 +321,11 @@ public function is_same_response(array $prevresponse, array $newresponse): bool

public function get_correct_response(): ?array {
$response = [];
$columnids = column::get_column_ids($this->columns);
foreach ($this->roworder as $key => $rownumber) {
$row = $this->rows[$rownumber];
foreach ($row->correctanswers as $colkey => $answer) {
foreach ($row->correctanswers as $colnum => $answer) {
// Get the corresponding column number associated with the column key.
$response[$this->field($key, $columnids[$colkey]->number)] = $answer;
$response[$this->field($key, $colnum)] = $answer;
}
}
return $response;
Expand Down Expand Up @@ -401,7 +397,7 @@ public function get_num_grade_allornone(array $response): array {
foreach ($this->columns as $column) {
$reponsekey = $this->field($rowkey, $column->number);
if (array_key_exists($reponsekey, $response)) {
if (array_key_exists($column->id, $row->correctanswers)) {
if (array_key_exists($column->number, $row->correctanswers)) {
// Add to the count of correct responses.
$rowrightresponse++;
} else {
Expand Down Expand Up @@ -435,7 +431,7 @@ public function get_num_parts_grade_partial(array $response): array {
if ($row->correctanswers != '' ) {
foreach ($this->columns as $column) {
$reponsekey = $this->field($rowkey, $column->number);
if (array_key_exists($reponsekey, $response) && array_key_exists($column->id, $row->correctanswers)) {
if (array_key_exists($reponsekey, $response) && array_key_exists($column->number, $row->correctanswers)) {
$rightresponse++;
}
}
Expand Down
47 changes: 25 additions & 22 deletions questiontype.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public function save_columns(stdClass $question): array {
$column->number = $columnnumber;
$column->name = $question->columnname[$i];
$column->id = $DB->insert_record('qtype_oumatrix_columns', $column);
$columnslist[] = $column;
$columnslist[$column->number] = $column;
$columnnumber++;
}
return $columnslist;
Expand Down Expand Up @@ -141,17 +141,18 @@ public function save_rows(stdClass $question, array $columnslist) {
// Prepare correct answers.
for ($c = 0; $c < count($columnslist); $c++) {
if ($question->inputtype == 'single') {
$columnindex = preg_replace("/[^0-9]/", "", $question->rowanswers[$i]);
$answerslist[$columnslist[$columnindex - 1]->id] = "1";
$columnnumber = preg_replace("/[^0-9]/", "", $question->rowanswers[$i]);
$answerslist[] = $columnnumber;
break;
} else {
$rowanswerslabel = "rowanswers" . 'a' . ($c + 1);
if (!isset($question->$rowanswerslabel) || !array_key_exists($i, $question->$rowanswerslabel)) {
continue;
}
$answerslist[$columnslist[$c]->id] = $question->{$rowanswerslabel}[$i];
$answerslist[] = $c + 1;
}
}
$questionrow->correctanswers = json_encode($answerslist);
$questionrow->correctanswers = implode(',',$answerslist);
$questionrow->feedback = $question->feedback[$i]['text'];
$questionrow->feedbackformat = FORMAT_HTML;
$questionrow->id = $DB->insert_record('qtype_oumatrix_rows', $questionrow);
Expand Down Expand Up @@ -219,12 +220,12 @@ protected function initialise_question_rows(question_definition $question, stdCl
$newrow = $this->make_row($row);
$correctanswers = [];
foreach ($questiondata->columns as $column) {
if (array_key_exists($column->id, $newrow->correctanswers)) {
if (in_array($column->number, $newrow->correctanswers)) {
if ($questiondata->options->inputtype == 'single') {
$anslabel = 'a' . $column->number;
$correctanswers[$column->id] = $anslabel;
$correctanswers[$column->number] = $anslabel;
} else {
$correctanswers[$column->id] = $newrow->correctanswers[$column->id];
$correctanswers[$column->number] = '1';
}
}
}
Expand All @@ -241,7 +242,11 @@ protected function initialise_question_rows(question_definition $question, stdCl
*/
public function make_row(stdClass $rowdata): row {
return new row($rowdata->id, $rowdata->questionid, $rowdata->number, $rowdata->name,
json_decode($rowdata->correctanswers, true), $rowdata->feedback, $rowdata->feedbackformat);
explode(',', $rowdata->correctanswers), $rowdata->feedback, $rowdata->feedbackformat);
}

protected function make_hint($hint) {
return question_hint_with_parts::load_from_record($hint);
}

public function delete_question($questionid, $contextid) {
Expand Down Expand Up @@ -283,8 +288,7 @@ public function get_total_number_of_choices(object $questiondata):? int {
public function get_num_correct_choices($questiondata) {
$numright = 0;
foreach ($questiondata->rows as $row) {
$rowanwers = json_decode($row->correctanswers, true);
$numright += count($rowanwers);
$numright += count((array)$row->correctanswers);
}
return $numright;
}
Expand Down Expand Up @@ -362,7 +366,7 @@ public function import_columns(qformat_xml $format, stdClass $question, array $c
static $indexno = 0;
$question->columns[$indexno]['name'] =
$format->import_text($format->getpath($column, ['#', 'text'], ''));
$question->columns[$indexno]['id'] = $format->getpath($column, ['@', 'key'], $indexno);
$question->columns[$indexno]['number'] = $format->getpath($column, ['@', 'number'], $indexno);

$question->columnname[$indexno] =
$format->import_text($format->getpath($column, ['#', 'text'], ''));
Expand All @@ -373,23 +377,22 @@ public function import_columns(qformat_xml $format, stdClass $question, array $c
public function import_rows(qformat_xml $format, stdClass $question, array $rows) {
foreach ($rows as $row) {
static $indexno = 0;
$question->rows[$indexno]['id'] = $format->getpath($row, ['@', 'key'], $indexno);
$question->rows[$indexno]['number'] = $format->getpath($row, ['@', 'number'], $indexno);
$question->rows[$indexno]['name'] =
$format->import_text($format->getpath($row, ['#', 'name', 0, '#', 'text'], ''));

$correctanswer = $format->getpath($row, ['#', 'correctanswers', 0, '#', 'text', 0, '#'], '');
$decodedanswers = json_decode($correctanswer, true);
foreach ($question->columns as $colindex => $col) {
if (array_key_exists($col['id'], $decodedanswers)) {
$answerslist = explode(',', $correctanswer);
foreach ($question->columns as $col) {
if (in_array($col['number'], $answerslist)) {
// Import correct answers for single choice.
if ($question->inputtype == 'single') {
// Assigning $colindex + 1 as answers are stored as 1,2 and so on.
$question->rowanswers[$indexno] = ($colindex + 1);
$question->rowanswers[$indexno] = $col['number'];
break;
} else {
// Import correct answers for multiple choice.
$rowanswerslabel = "rowanswers" . 'a' . ($colindex + 1);
if (array_key_exists($col['id'], $decodedanswers)) {
$rowanswerslabel = "rowanswers" . 'a' . $col['number'];
if (in_array($col['number'], $answerslist)) {
$question->{$rowanswerslabel}[$indexno] = "1";
}
}
Expand All @@ -416,7 +419,7 @@ public function export_to_xml($question, qformat_xml $format, $extra = null) {
$output .= " <columns>\n";
ksort($question->columns);
foreach ($question->columns as $columnkey => $column) {
$output .= " <column key=\"{$columnkey}\">\n";
$output .= " <column number=\"{$column->number}\">\n";
$output .= $format->writetext($column->name, 4);
$output .= " </column>\n";
}
Expand All @@ -428,7 +431,7 @@ public function export_to_xml($question, qformat_xml $format, $extra = null) {
ksort($question->rows);
$indent = 5;
foreach ($question->rows as $rowkey => $row) {
$output .= " <row key=\"{$rowkey}\">\n";
$output .= " <row number=\"{$row->number}\">\n";
$output .= " <name>\n";
$output .= $format->writetext($row->name, $indent);
$output .= " </name>\n";
Expand Down
12 changes: 5 additions & 7 deletions renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ abstract protected function get_input_id(question_attempt $qa, $value, $columnnu
protected function is_right(question_definition $question, $rowkey, $columnkey) {
$row = $question->rows[$rowkey];
foreach ($question->columns as $column) {
if ($column->number == $columnkey && array_key_exists($column->id, $row->correctanswers)) {
if ($column->number == $columnkey && array_key_exists($column->number, $row->correctanswers)) {
return 1;
}
}
Expand Down Expand Up @@ -242,9 +242,8 @@ protected function get_input_id(question_attempt $qa, $value, $columnnumber) {
public function correct_response(question_attempt $qa) {
$question = $qa->get_question();
$right = [];
$columnids = column::get_column_ids($question->columns);
foreach ($question->rows as $row) {
$right[] = $row->name . '' . $columnids[array_key_first($row->correctanswers)]->name;
$right[] = $row->name . '' . $question->columns[array_key_first($row->correctanswers)]->name;
}
return $this->correct_choices($right);
}
Expand Down Expand Up @@ -276,14 +275,13 @@ protected function get_input_id(question_attempt $qa, $value, $columnnumber) {

public function correct_response(question_attempt $qa) {
$question = $qa->get_question();
$columnids = column::get_column_ids($question->columns);
foreach ($question->rows as $row) {
// Get the correct row.
$rowanswer = $row->name . '';
$answers = [];
if ($row->correctanswers != '') {
foreach ($row->correctanswers as $columnkey => $notused) {
$answers[] = $columnids[$columnkey]->name;
foreach ($row->correctanswers as $columnnumber => $notused) {
$answers[] = $question->columns[$columnnumber]->name;
}
$rowanswer .= implode(', ', $answers);
$rightanswers[] = $rowanswer;
Expand All @@ -300,7 +298,7 @@ protected function num_parts_correct(question_attempt $qa): string {

$a = new stdClass();
if ($qa->get_question()->grademethod == 'allnone') {
list($a->num, $a->outof) = $qa->get_question()->get_num_parts_right($qa->get_last_qt_data());
list($a->num, $a->outof) = $qa->get_question()->get_num_grade_allornone($qa->get_last_qt_data());
if (is_null($a->outof)) {
return '';
}
Expand Down
2 changes: 1 addition & 1 deletion tests/behat/export.feature
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Feature: Test exporting Numerical questions
When I am on the "Course 1" "core_question > course question export" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
Then following "click here" should download between "5500" and "5800" bytes
Then following "click here" should download between "5300" and "5600" bytes
# If the download step is the last in the scenario then we can sometimes run
# into the situation where the download page causes a http redirect but behat
# has already conducted its reset (generating an error). By putting a logout
Expand Down
Loading

0 comments on commit 4de5986

Please sign in to comment.