MDL-79877 qtype_ordering: Template to output correct parts
Part of: MDL-79863 Creates an exporter class and a template to output the correct part to a given question attempt.
This commit is contained in:
committed by
Mathew May
parent
36822f0c0a
commit
d00061da26
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace qtype_ordering\output;
|
||||
|
||||
/**
|
||||
* Renderable class for the statement of how many sub-parts of the question the student got correct|partial|incorrect.
|
||||
*
|
||||
* @package qtype_ordering
|
||||
* @copyright 2023 Ilya Tregubov <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class num_parts_correct extends renderable_base {
|
||||
|
||||
/**
|
||||
* Export the data for the mustache template.
|
||||
*
|
||||
* @param \renderer_base $output The output renderer.
|
||||
* @return array
|
||||
*/
|
||||
public function export_for_template(\renderer_base $output): array {
|
||||
|
||||
list($numright, $numpartial, $numincorrect) = $this->qa->get_question()->get_num_parts_right(
|
||||
$this->qa->get_last_qt_data());
|
||||
|
||||
return [
|
||||
'numcorrect' => $numright,
|
||||
'numpartial' => $numpartial,
|
||||
'numincorrect' => $numincorrect,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -71,9 +71,6 @@ $string['gradingtype_help'] = 'Choose the type of grading calculation.
|
||||
$string['highlightresponse'] = 'Highlight response as correct or incorrect';
|
||||
$string['horizontal'] = 'Horizontal';
|
||||
|
||||
$string['itemplural'] = 'items';
|
||||
$string['itemsingular'] = 'item';
|
||||
|
||||
$string['layouttype_help'] = 'Choose whether to display the items vertically or horizontally.';
|
||||
$string['layouttype'] = 'Layout of items';
|
||||
$string['longestcontiguoussubset'] = 'Longest contiguous subset';
|
||||
@@ -123,6 +120,6 @@ $string['showgrading'] = 'Grading details';
|
||||
$string['showgrading_help'] = 'Choose whether to show or hide details of the score calculation when a student reviews a response to this Ordering question.';
|
||||
|
||||
$string['vertical'] = 'Vertical';
|
||||
$string['yougotnright'] = 'You have {$a->numright} {$a->numrightplural} correct.';
|
||||
$string['yougotnpartial'] = 'You have {$a->numpartial} {$a->numpartialplural} partially correct.';
|
||||
$string['yougotnincorrect'] = 'You have {$a->numincorrect} {$a->numincorrectplural} incorrect.';
|
||||
$string['correctitemsnumber'] = 'Correct items: {$a}';
|
||||
$string['partialitemsnumber'] = 'Partially correct items: {$a}';
|
||||
$string['incorrectitemsnumber'] = 'Incorrect items: {$a}';
|
||||
|
||||
@@ -480,34 +480,15 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gereate a brief statement of how many sub-parts of this question the
|
||||
* Generate a brief statement of how many sub-parts of this question the
|
||||
* student got correct|partial|incorrect.
|
||||
*
|
||||
* @param question_attempt $qa The question attempt to display.
|
||||
* @return string HTML fragment.
|
||||
*/
|
||||
protected function num_parts_correct(question_attempt $qa) {
|
||||
$a = new stdClass();
|
||||
$output = '';
|
||||
|
||||
list($a->numright, $a->numpartial, $a->numincorrect) = $qa->get_question()->get_num_parts_right(
|
||||
$qa->get_last_qt_data());
|
||||
|
||||
if ($a->numright) {
|
||||
$a->numrightplural = get_string($a->numright > 1 ? 'itemplural' : 'itemsingular', 'qtype_ordering');
|
||||
$output .= html_writer::nonempty_tag('div', get_string('yougotnright', 'qtype_ordering', $a));
|
||||
}
|
||||
|
||||
if ($a->numpartial) {
|
||||
$a->numpartialplural = get_string($a->numpartial > 1 ? 'itemplural' : 'itemsingular', 'qtype_ordering');
|
||||
$output .= html_writer::nonempty_tag('div', get_string('yougotnpartial', 'qtype_ordering', $a));
|
||||
}
|
||||
|
||||
if ($a->numincorrect) {
|
||||
$a->numincorrectplural = get_string($a->numincorrect > 1 ? 'itemplural' : 'itemsingular', 'qtype_ordering');
|
||||
$output .= html_writer::nonempty_tag('div', get_string('yougotnincorrect', 'qtype_ordering', $a));
|
||||
}
|
||||
|
||||
return $output;
|
||||
$numpartscorrect = new \qtype_ordering\output\num_parts_correct($qa);
|
||||
return $this->output->render_from_template('qtype_ordering/num_parts_correct',
|
||||
$numpartscorrect->export_for_template($this->output));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
{{!
|
||||
This file is part of Moodle - http://moodle.org/
|
||||
|
||||
Moodle is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Moodle is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@template qtype_ordering/num_parts_correct
|
||||
|
||||
Renders a statement of how many sub-parts of the question the student got correct|partial|incorrect.
|
||||
|
||||
Context variables required for this template:
|
||||
* numcorrect - The number of correct answers.
|
||||
* numpartial - The number of partially correct answers.
|
||||
* numincorrect - The number of incorrect answers.
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"numcorrect": 1,
|
||||
"numpartial": 3,
|
||||
"numincorrect": 0
|
||||
}
|
||||
}}
|
||||
|
||||
{{#numcorrect}}
|
||||
<div>
|
||||
{{#str}} correctitemsnumber, qtype_ordering, {{numcorrect}} {{/str}}
|
||||
</div>
|
||||
{{/numcorrect}}
|
||||
{{#numpartial}}
|
||||
<div>
|
||||
{{#str}} partialitemsnumber, qtype_ordering, {{numpartial}} {{/str}}
|
||||
</div>
|
||||
{{/numpartial}}
|
||||
{{#numincorrect}}
|
||||
<div>
|
||||
{{#str}} incorrectitemsnumber, qtype_ordering, {{numincorrect}} {{/str}}
|
||||
</div>
|
||||
{{/numincorrect}}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace qtype_ordering\output;
|
||||
|
||||
use advanced_testcase;
|
||||
use test_question_maker;
|
||||
use qtype_ordering_question;
|
||||
use qtype_ordering_test_helper;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
|
||||
|
||||
/**
|
||||
* A test class used to test specific_grade_detail_feedback.
|
||||
*
|
||||
* @package qtype_ordering
|
||||
* @copyright 2023 Ilya Tregubov <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @covers \qtype_ordering\output\specific_grade_detail_feedback
|
||||
*/
|
||||
class num_parts_correct_test extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test the exported data for the template that renders the specific grade detail feedback test to a given question attempt.
|
||||
*
|
||||
* @dataProvider export_for_template_provider
|
||||
* @param array $answeritems The array of ordered answers.
|
||||
* @param int $gradingtype Grading type.
|
||||
* @param array $expected The expected exported data.
|
||||
* @return void
|
||||
* @covers ::export_for_template
|
||||
*/
|
||||
public function test_export_for_template(array $answeritems, int $gradingtype, array $expected): void {
|
||||
global $PAGE;
|
||||
|
||||
$question = test_question_maker::make_question('ordering');
|
||||
$qa = new \testable_question_attempt($question, 0);
|
||||
$step = new \question_attempt_step();
|
||||
$qa->add_step($step);
|
||||
$question->start_attempt($step, 1);
|
||||
$question->options->gradingtype = $gradingtype;
|
||||
|
||||
$keys = implode(',', array_keys($answeritems));
|
||||
$step->set_qt_var('_currentresponse', $keys);
|
||||
|
||||
$renderer = $PAGE->get_renderer('core');
|
||||
$specificgradedetailfeedback = new num_parts_correct($qa);
|
||||
$actual = $specificgradedetailfeedback->export_for_template($renderer);
|
||||
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for the test_export_for_template test.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function export_for_template_provider(): array {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/question/type/ordering/question.php');
|
||||
|
||||
return [
|
||||
'Partially correct question attempt. Absolute position' => [
|
||||
[13 => 'Modular', 14 => 'Object', 15 => 'Oriented', 17 => 'Learning', 16 => 'Dynamic', 18 => 'Environment'],
|
||||
qtype_ordering_question::GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT,
|
||||
[
|
||||
'numcorrect' => 4,
|
||||
'numpartial' => 2,
|
||||
'numincorrect' => 0,
|
||||
],
|
||||
],
|
||||
'Incorrect question attempt (horizontal layout). Relative to ALL the previous and next items' => [
|
||||
[14 => 'Object', 16 => 'Dynamic', 13 => 'Modular', 17 => 'Learning', 18 => 'Environment', 15 => 'Oriented'],
|
||||
qtype_ordering_question::GRADING_ABSOLUTE_POSITION,
|
||||
[
|
||||
'numcorrect' => 0,
|
||||
'numpartial' => 0,
|
||||
'numincorrect' => 6,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -140,10 +140,13 @@ class walkthrough_test extends \qbehaviour_walkthrough_test_base {
|
||||
$this->get_does_not_contain_submit_button_expectation(),
|
||||
$this->get_contains_try_again_button_expectation(true),
|
||||
$this->get_does_not_contain_correctness_expectation(),
|
||||
$this->get_contains_num_parts_correct_ordering(0, 5, 1),
|
||||
$this->get_contains_hint_expectation('This is the first hint')
|
||||
);
|
||||
|
||||
$this->check_output_does_not_contain(get_string('correctitemsnumber', 'qtype_ordering', 0));
|
||||
$this->check_output_contains(get_string('partialitemsnumber', 'qtype_ordering', 5));
|
||||
$this->check_output_contains(get_string('incorrectitemsnumber', 'qtype_ordering', 1));
|
||||
|
||||
// Do try again.
|
||||
$this->process_submission(['-tryagain' => 1]);
|
||||
|
||||
@@ -181,43 +184,4 @@ class walkthrough_test extends \qbehaviour_walkthrough_test_base {
|
||||
$this->check_current_state(question_state::$gradedright);
|
||||
$this->check_current_mark(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return question pattern expectation.
|
||||
*
|
||||
* @param int $numright The number of item correct.
|
||||
* @param int $numpartial The number of partial correct item.
|
||||
* @param int $numincorrect The number of incorrect item.
|
||||
* @return question_pattern_expectation
|
||||
*/
|
||||
protected function get_contains_num_parts_correct_ordering(
|
||||
int $numright,
|
||||
int $numpartial,
|
||||
int $numincorrect
|
||||
): question_pattern_expectation {
|
||||
$a = new stdClass();
|
||||
$a->numright = $numright;
|
||||
$a->numpartial = $numpartial;
|
||||
$a->numincorrect = $numincorrect;
|
||||
|
||||
$output = '';
|
||||
if ($a->numright) {
|
||||
$a->numrightplural = get_string($a->numright > 1 ? 'itemplural' : 'itemsingular', 'qtype_ordering');
|
||||
$output .= '<div>' . get_string('yougotnright', 'qtype_ordering', $a) . '</div>';
|
||||
}
|
||||
|
||||
if ($a->numpartial) {
|
||||
$a->numpartialplural = get_string($a->numpartial > 1 ? 'itemplural' : 'itemsingular', 'qtype_ordering');
|
||||
$output .= '<div>' . get_string('yougotnpartial', 'qtype_ordering', $a) . '</div>';
|
||||
}
|
||||
|
||||
if ($a->numincorrect) {
|
||||
$a->numincorrectplural = get_string($a->numincorrect > 1 ? 'itemplural' : 'itemsingular', 'qtype_ordering');
|
||||
$output .= '<div>' . get_string('yougotnincorrect', 'qtype_ordering', $a) . '</div>';
|
||||
}
|
||||
|
||||
$pattern = '/<div class="numpartscorrect">' . preg_quote($output, '/');
|
||||
|
||||
return new question_pattern_expectation($pattern . '/');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user