mirror of
https://github.com/moodle/moodle.git
synced 2025-01-17 21:49:15 +01:00
MDL-79875 qtype_ordering: Template to output grade detail
Part of: MDL-79863 Creates an exporter class and a template to output the grade detail to a given question attempt.
This commit is contained in:
parent
31fc5161c9
commit
de5fc46b41
@ -0,0 +1,108 @@
|
||||
<?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 qtype_ordering_question;
|
||||
|
||||
/**
|
||||
* Renderable class for the displaying the grade detail of the response.
|
||||
*
|
||||
* @package qtype_ordering
|
||||
* @copyright 2023 Ilya Tregubov <ilya.a.tregubov@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class specific_grade_detail_feedback extends renderable_base {
|
||||
|
||||
/**
|
||||
* Export the data for the mustache template.
|
||||
*
|
||||
* @param \renderer_base $output renderer to be used to render the action bar elements.
|
||||
* @return array
|
||||
*/
|
||||
public function export_for_template(\renderer_base $output): array {
|
||||
|
||||
$data = [];
|
||||
$question = $this->qa->get_question();
|
||||
|
||||
// Decide if we should show grade explanation for "partial" or "wrong" states.
|
||||
// This should detect "^graded(partial|wrong)$" and possibly others.
|
||||
$showpartialwrong = false;
|
||||
if ($step = $this->qa->get_last_step()) {
|
||||
$showpartialwrong = preg_match('/(partial|wrong)$/', $step->get_state());
|
||||
}
|
||||
$data['showpartialwrong'] = $showpartialwrong;
|
||||
if (!$showpartialwrong) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$plugin = 'qtype_ordering';
|
||||
|
||||
// Show grading details if they are required.
|
||||
if ($question->options->showgrading) {
|
||||
// Fetch grading type.
|
||||
$gradingtype = $question->options->gradingtype;
|
||||
$gradingtype = qtype_ordering_question::get_grading_types($gradingtype);
|
||||
|
||||
// Format grading type, e.g. Grading type: Relative to next item, excluding last item.
|
||||
if ($gradingtype) {
|
||||
$data['gradingtype'] = get_string('gradingtype', $plugin) . ': ' . $gradingtype;
|
||||
}
|
||||
|
||||
// Fetch grade details and score details.
|
||||
if ($currentresponse = $question->currentresponse) {
|
||||
|
||||
$totalscore = 0;
|
||||
$totalmaxscore = 0;
|
||||
|
||||
$data['orderinglayoutclass'] = $question->get_ordering_layoutclass();
|
||||
|
||||
// Format scoredetails, e.g. 1 /2 = 50%, for each item.
|
||||
foreach ($currentresponse as $position => $answerid) {
|
||||
if (array_key_exists($answerid, $question->answers)) {
|
||||
$score = $question->get_ordering_item_score($question, $position, $answerid);
|
||||
[$score, $maxscore, $fraction, $percent, $class] = $score;
|
||||
if (!isset($maxscore)) {
|
||||
$score = get_string('noscore', $plugin);
|
||||
} else {
|
||||
$totalscore += $score;
|
||||
$totalmaxscore += $maxscore;
|
||||
}
|
||||
$data['scoredetails'][] = [
|
||||
'score' => $score,
|
||||
'maxscore' => $maxscore,
|
||||
'percent' => $percent,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if ($totalmaxscore == 0) {
|
||||
unset($data['scoredetails']); // All or nothing.
|
||||
} else {
|
||||
// Format gradedetails, e.g. 4/6 = 67%.
|
||||
if ($totalscore == 0) {
|
||||
$data['gradedetails'] = 0;
|
||||
} else {
|
||||
$data['gradedetails'] = round(100 * $totalscore / $totalmaxscore, 0);
|
||||
}
|
||||
$data['totalscore'] = $totalscore;
|
||||
$data['totalmaxscore'] = $totalmaxscore;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
@ -93,6 +93,9 @@ class qtype_ordering_question extends question_graded_automatically {
|
||||
/** @var array contatining current order of answerids */
|
||||
public $currentresponse;
|
||||
|
||||
/** @var array of scored for every item */
|
||||
protected $itemscores = [];
|
||||
|
||||
/**
|
||||
* Start a new attempt at this question, storing any information that will
|
||||
* be needed later in the step.
|
||||
@ -856,7 +859,8 @@ class qtype_ordering_question extends question_graded_automatically {
|
||||
list($correctresponse, $currentresponse) = $this->get_response_depend_on_grading_type($gradingtype);
|
||||
|
||||
foreach ($this->currentresponse as $position => $answerid) {
|
||||
$fraction = $this->get_fraction_of_item($position, $answerid, $correctresponse, $currentresponse);
|
||||
[$fraction, $score, $maxscore] =
|
||||
$this->get_fraction_maxscore_score_of_item($position, $answerid, $correctresponse, $currentresponse);
|
||||
if (is_null($fraction)) {
|
||||
continue;
|
||||
}
|
||||
@ -880,14 +884,14 @@ class qtype_ordering_question extends question_graded_automatically {
|
||||
* @param int $answerid The answerid of the current response.
|
||||
* @param array $correctresponse The correct response list base on grading type.
|
||||
* @param array $currentresponse The current response list base on grading type.
|
||||
* @return float|null Float if the grade, base on the fraction scale and null if the item is not in the correct response.
|
||||
* @return array.
|
||||
*/
|
||||
protected function get_fraction_of_item(
|
||||
protected function get_fraction_maxscore_score_of_item(
|
||||
int $position,
|
||||
int $answerid,
|
||||
array $correctresponse,
|
||||
array $currentresponse
|
||||
): float|null {
|
||||
): array {
|
||||
$gradingtype = $this->options->gradingtype;
|
||||
|
||||
$score = 0;
|
||||
@ -952,7 +956,7 @@ class qtype_ordering_question extends question_graded_automatically {
|
||||
}
|
||||
$fraction = $maxscore ? $score / $maxscore : $maxscore;
|
||||
|
||||
return $fraction;
|
||||
return [$fraction, $score, $maxscore];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1005,4 +1009,49 @@ class qtype_ordering_question extends question_graded_automatically {
|
||||
|
||||
return [$correctresponse, $currentresponse];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns score for one item depending on correctness and question settings.
|
||||
*
|
||||
* @param question_definition $question question definition object
|
||||
* @param int $position The position of the current response.
|
||||
* @param int $answerid The answerid of the current response.
|
||||
* @return array (score, maxscore, fraction, percent, class)
|
||||
*/
|
||||
public function get_ordering_item_score(question_definition $question, int $position, int $answerid): array {
|
||||
|
||||
if (!isset($this->itemscores[$position])) {
|
||||
|
||||
[$correctresponse, $currentresponse] = $this->get_response_depend_on_grading_type($question->options->gradingtype);
|
||||
|
||||
$percent = 0; // 100 * $fraction.
|
||||
[$fraction, $score, $maxscore] =
|
||||
$this->get_fraction_maxscore_score_of_item($position, $answerid, $correctresponse, $currentresponse);
|
||||
|
||||
if ($maxscore === null) {
|
||||
// An unscored item is either an illegal item
|
||||
// or last item of RELATIVE_NEXT_EXCLUDE_LAST
|
||||
// or an item in an incorrect ALL_OR_NOTHING
|
||||
// or an item from an unrecognized grading type.
|
||||
$class = 'unscored';
|
||||
} else {
|
||||
if ($maxscore > 0) {
|
||||
$percent = round(100 * $fraction, 0);
|
||||
}
|
||||
$class = match (true) {
|
||||
$fraction > 0.999999 => 'correct',
|
||||
$fraction < 0.000001 => 'incorrect',
|
||||
$fraction >= 0.66 => 'partial66',
|
||||
$fraction >= 0.33 => 'partial33',
|
||||
default => 'partial00',
|
||||
};
|
||||
}
|
||||
|
||||
$score = [$score, $maxscore, $fraction, $percent, $class];
|
||||
$this->itemscores[$position] = $score;
|
||||
}
|
||||
|
||||
return $this->itemscores[$position];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -138,6 +138,7 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
|
||||
switch ($options->correctness) {
|
||||
case question_display_options::VISIBLE:
|
||||
$score = $this->get_ordering_item_score($question, $position, $answerid);
|
||||
// To do: we need image calculation in MDL-79873.
|
||||
list($score, $maxscore, $fraction, $percent, $class, $img) = $score;
|
||||
$class = trim("$sortableitem $class");
|
||||
break;
|
||||
@ -154,6 +155,7 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
|
||||
|
||||
if (isset($options->highlightresponse) && $options->highlightresponse) {
|
||||
$score = $this->get_ordering_item_score($question, $position, $answerid);
|
||||
// To do: we need image calculation here in MDL-79873.
|
||||
list($score, $maxscore, $fraction, $percent, $class, $img) = $score;
|
||||
$class = trim("$sortableitem $class");
|
||||
}
|
||||
@ -246,86 +248,9 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
|
||||
* @return string Output grade detail of the response.
|
||||
*/
|
||||
public function specific_grade_detail_feedback(question_attempt $qa): string {
|
||||
$gradingtype = '';
|
||||
$gradedetails = '';
|
||||
$scoredetails = '';
|
||||
|
||||
// Decide if we should show grade explanation for "partial" or "wrong" states.
|
||||
// This should detect "^graded(partial|wrong)$" and possibly others.
|
||||
if ($step = $qa->get_last_step()) {
|
||||
$show = preg_match('/(partial|wrong)$/', $step->get_state());
|
||||
} else {
|
||||
$show = false;
|
||||
}
|
||||
|
||||
// If required, add explanation of grade calculation.
|
||||
if ($show) {
|
||||
|
||||
$plugin = 'qtype_ordering';
|
||||
$question = $qa->get_question();
|
||||
|
||||
// Show grading details if they are required.
|
||||
if ($question->options->showgrading) {
|
||||
|
||||
// Fetch grading type.
|
||||
$gradingtype = $question->options->gradingtype;
|
||||
$gradingtype = qtype_ordering_question::get_grading_types($gradingtype);
|
||||
|
||||
// Format grading type, e.g. Grading type: Relative to next item, excluding last item.
|
||||
if ($gradingtype) {
|
||||
$gradingtype = get_string('gradingtype', $plugin).': '.$gradingtype;
|
||||
$gradingtype = html_writer::tag('p', $gradingtype, array('class' => 'gradingtype'));
|
||||
}
|
||||
|
||||
// Fetch grade details and score details.
|
||||
if ($currentresponse = $question->currentresponse) {
|
||||
|
||||
$totalscore = 0;
|
||||
$totalmaxscore = 0;
|
||||
|
||||
$sortableitem = $question->get_ordering_layoutclass();
|
||||
$params = array('class' => $sortableitem);
|
||||
|
||||
$scoredetails .= html_writer::tag('p', get_string('scoredetails', $plugin));
|
||||
$scoredetails .= html_writer::start_tag('ol', array('class' => 'scoredetails'));
|
||||
|
||||
// Format scoredetails, e.g. 1 /2 = 50%, for each item.
|
||||
foreach ($currentresponse as $position => $answerid) {
|
||||
if (array_key_exists($answerid, $question->answers)) {
|
||||
$answer = $question->answers[$answerid];
|
||||
$score = $this->get_ordering_item_score($question, $position, $answerid);
|
||||
list($score, $maxscore, $fraction, $percent, $class, $img) = $score;
|
||||
if ($maxscore === null) {
|
||||
$score = get_string('noscore', $plugin);
|
||||
} else {
|
||||
$totalscore += $score;
|
||||
$totalmaxscore += $maxscore;
|
||||
$score = "$score / $maxscore = $percent%";
|
||||
}
|
||||
$scoredetails .= html_writer::tag('li', $score, $params);
|
||||
}
|
||||
}
|
||||
|
||||
$scoredetails .= html_writer::end_tag('ol');
|
||||
|
||||
if ($totalmaxscore == 0) {
|
||||
$scoredetails = ''; // ALL_OR_NOTHING.
|
||||
} else {
|
||||
// Format gradedetails, e.g. 4 /6 = 67%.
|
||||
if ($totalscore == 0) {
|
||||
$gradedetails = 0;
|
||||
} else {
|
||||
$gradedetails = round(100 * $totalscore / $totalmaxscore, 0);
|
||||
}
|
||||
$gradedetails = "$totalscore / $totalmaxscore = $gradedetails%";
|
||||
$gradedetails = get_string('gradedetails', $plugin).': '.$gradedetails;
|
||||
$gradedetails = html_writer::tag('p', $gradedetails, array('class' => 'gradedetails'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $gradingtype.$gradedetails.$scoredetails;
|
||||
$specificgradedetailfeedback = new \qtype_ordering\output\specific_grade_detail_feedback($qa);
|
||||
return $this->output->render_from_template('qtype_ordering/specific_grade_detail_feedback',
|
||||
$specificgradedetailfeedback->export_for_template($this->output));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -358,6 +283,7 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
|
||||
|
||||
/**
|
||||
* Fills $this->correctinfo and $this->currentinfo depending on question options.
|
||||
* TO DO: REMOVE ME in MDL-79873
|
||||
*
|
||||
* @param object $question
|
||||
*/
|
||||
@ -407,6 +333,8 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
|
||||
/**
|
||||
* Returns score for one item depending on correctness and question settings.
|
||||
*
|
||||
* TO DO: REMOVE ME in MDL-79873
|
||||
*
|
||||
* @param object $question
|
||||
* @param int $position
|
||||
* @param int $answerid
|
||||
@ -539,6 +467,7 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
|
||||
|
||||
/**
|
||||
* Return true if answer is 100% correct.
|
||||
* TO DO: REMOVE ME in MDL-79873
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
@ -0,0 +1,70 @@
|
||||
{{!
|
||||
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/specific_grade_detail_feedback
|
||||
|
||||
Renders the grade detail of the response.
|
||||
|
||||
Context variables required for this template:
|
||||
* showpartialwrong - Whether to show grade details.
|
||||
* gradingtype - Grading type.
|
||||
* gradedetails - Total score (percent).
|
||||
* orderinglayoutclass - The ordering layout CSS class.
|
||||
* scoredetails - An array containing the score details.
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"showpartialwrong": true,
|
||||
"gradingtype": "Grading type: Absolute position",
|
||||
"gradedetails": "93",
|
||||
"orderinglayoutclass": "vertical",
|
||||
"scoredetails": [
|
||||
{
|
||||
"score": "1",
|
||||
"maxscore": "1",
|
||||
"percent": "100"
|
||||
},
|
||||
{
|
||||
"score": "0",
|
||||
"maxscore": "1",
|
||||
"percent": "0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
|
||||
{{#showpartialwrong}}
|
||||
{{#gradingtype}}
|
||||
<p class="gradingtype">
|
||||
{{gradingtype}}
|
||||
</p>
|
||||
{{/gradingtype}}
|
||||
{{#gradedetails}}
|
||||
<p class="gradedetails">
|
||||
{{#str}} gradedetails, qtype_ordering {{/str}}:
|
||||
{{totalscore}} / {{totalmaxscore}} = {{gradedetails}}%
|
||||
</p>
|
||||
{{/gradedetails}}
|
||||
{{#str}} scoredetails, qtype_ordering {{/str}}
|
||||
<ol class="scoredetails">
|
||||
{{#scoredetails}}
|
||||
<li class="{{orderinglayoutclass}}">
|
||||
{{score}} / {{maxscore}} = {{percent}}%
|
||||
</li>
|
||||
{{/scoredetails}}
|
||||
</ol>
|
||||
{{/showpartialwrong}}
|
@ -0,0 +1,160 @@
|
||||
<?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 <ilya.a.tregubov@gmail.com.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @covers \qtype_ordering\output\specific_grade_detail_feedback
|
||||
*/
|
||||
class specific_grade_detail_feedback_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 string $layouttype The type of the layout.
|
||||
* @param array $expected The expected exported data.
|
||||
* @return void
|
||||
* @covers ::export_for_template
|
||||
*/
|
||||
public function test_export_for_template(array $answeritems, int $gradingtype, string $layouttype, array $expected): void {
|
||||
global $PAGE;
|
||||
|
||||
$question = test_question_maker::make_question('ordering');
|
||||
$question->options->layouttype = $layouttype === 'horizontal' ? qtype_ordering_question::LAYOUT_HORIZONTAL :
|
||||
qtype_ordering_question::LAYOUT_VERTICAL;
|
||||
$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));
|
||||
$values = array_values($answeritems);
|
||||
|
||||
$step->set_qt_var('_currentresponse', $keys);
|
||||
|
||||
list($fraction, $state) = $question->grade_response(qtype_ordering_test_helper::get_response($question, $values));
|
||||
$qa->get_last_step()->set_state($state);
|
||||
|
||||
$renderer = $PAGE->get_renderer('core');
|
||||
$specificgradedetailfeedback = new specific_grade_detail_feedback($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 [
|
||||
'Do not show partial or wrong' => [
|
||||
[13 => 'Modular', 14 => 'Object', 15 => 'Oriented', 16 => 'Dynamic', 17 => 'Learning', 18 => 'Environment'],
|
||||
qtype_ordering_question::GRADING_RELATIVE_NEXT_EXCLUDE_LAST,
|
||||
'horizontal',
|
||||
[
|
||||
'showpartialwrong' => false,
|
||||
],
|
||||
],
|
||||
'Partially correct question attempt (horizontal layout). Relative to ALL the previous and next items' => [
|
||||
[13 => 'Modular', 14 => 'Object', 15 => 'Oriented', 17 => 'Learning', 16 => 'Dynamic', 18 => 'Environment'],
|
||||
qtype_ordering_question::GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT,
|
||||
'horizontal',
|
||||
[
|
||||
'showpartialwrong' => 1,
|
||||
'gradingtype' => 'Grading type: Relative to ALL the previous and next items',
|
||||
'orderinglayoutclass' => 'horizontal',
|
||||
'gradedetails' => 93.0,
|
||||
'totalscore' => 28,
|
||||
'totalmaxscore' => 30,
|
||||
'scoredetails' => [
|
||||
['score' => 5, 'maxscore' => 5, 'percent' => 100],
|
||||
['score' => 5, 'maxscore' => 5, 'percent' => 100],
|
||||
['score' => 5, 'maxscore' => 5, 'percent' => 100],
|
||||
['score' => 4, 'maxscore' => 5, 'percent' => 80],
|
||||
['score' => 4, 'maxscore' => 5, 'percent' => 80],
|
||||
['score' => 5, 'maxscore' => 5, 'percent' => 100],
|
||||
],
|
||||
],
|
||||
],
|
||||
'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_RELATIVE_ALL_PREVIOUS_AND_NEXT,
|
||||
'horizontal',
|
||||
[
|
||||
'showpartialwrong' => 1,
|
||||
'gradingtype' => 'Grading type: Relative to ALL the previous and next items',
|
||||
'orderinglayoutclass' => 'horizontal',
|
||||
'gradedetails' => 67.0,
|
||||
'totalscore' => 20,
|
||||
'totalmaxscore' => 30,
|
||||
'scoredetails' => [
|
||||
['score' => 4, 'maxscore' => 5, 'percent' => 80],
|
||||
['score' => 3, 'maxscore' => 5, 'percent' => 60],
|
||||
['score' => 3, 'maxscore' => 5, 'percent' => 60],
|
||||
['score' => 4, 'maxscore' => 5, 'percent' => 80],
|
||||
['score' => 4, 'maxscore' => 5, 'percent' => 80],
|
||||
['score' => 2, 'maxscore' => 5, 'percent' => 40],
|
||||
],
|
||||
],
|
||||
],
|
||||
'Incorrect question attempt (vertical layout). Grading type: Relative to the next item (excluding last)' => [
|
||||
[14 => 'Object', 16 => 'Dynamic', 13 => 'Modular', 17 => 'Learning', 18 => 'Environment', 15 => 'Oriented'],
|
||||
qtype_ordering_question::GRADING_RELATIVE_NEXT_EXCLUDE_LAST,
|
||||
'vertical',
|
||||
[
|
||||
'showpartialwrong' => 1,
|
||||
'gradingtype' => 'Grading type: Relative to the next item (excluding last)',
|
||||
'orderinglayoutclass' => 'vertical',
|
||||
'gradedetails' => 20.0,
|
||||
'totalscore' => 1,
|
||||
'totalmaxscore' => 5,
|
||||
'scoredetails' => [
|
||||
['score' => 0, 'maxscore' => 1, 'percent' => 0.0],
|
||||
['score' => 0, 'maxscore' => 1, 'percent' => 0.0],
|
||||
['score' => 0, 'maxscore' => 1, 'percent' => 0.0],
|
||||
['score' => 1, 'maxscore' => 1, 'percent' => 100.0],
|
||||
['score' => 'No score', 'maxscore' => null, 'percent' => 0],
|
||||
['score' => 0, 'maxscore' => 1, 'percent' => 0.0],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user