MDL-79863 qtype_ordering: qtype_ordering add new option to SHOW/HIDE score calculations when a student reviews a response to an Ordering qusetion

This commit is contained in:
Gordon Bateson 2016-08-16 19:54:58 +09:00 committed by Mathew May
parent cacd38f1e0
commit 533221a68e
8 changed files with 134 additions and 70 deletions

View File

@ -8,8 +8,9 @@
<FIELD NAME="layouttype" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="questionid" NEXT="selecttype"/>
<FIELD NAME="selecttype" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="layouttype" NEXT="selectcount"/>
<FIELD NAME="selectcount" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="selecttype" NEXT="gradingtype"/>
<FIELD NAME="gradingtype" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="selectcount" NEXT="correctfeedback"/>
<FIELD NAME="correctfeedback" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" PREVIOUS="gradingtype" NEXT="correctfeedbackformat"/>
<FIELD NAME="gradingtype" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="selectcount" NEXT="showgrading"/>
<FIELD NAME="showgrading" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="gradingtype" NEXT="correctfeedback"/>
<FIELD NAME="correctfeedback" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" PREVIOUS="showgrading" NEXT="correctfeedbackformat"/>
<FIELD NAME="correctfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="correctfeedback" NEXT="incorrectfeedback"/>
<FIELD NAME="incorrectfeedback" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" PREVIOUS="correctfeedbackformat" NEXT="incorrectfeedbackformat"/>
<FIELD NAME="incorrectfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="incorrectfeedback" NEXT="partiallycorrectfeedback"/>

View File

@ -219,6 +219,17 @@ function xmldb_qtype_ordering_upgrade($oldversion) {
}
}
$newversion = 2016081655;
if ($oldversion < $newversion) {
$table = new xmldb_table('qtype_ordering_options');
$field = new xmldb_field('showgrading', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, 1, 'gradingtype');
if ($dbman->field_exists($table, $field)) {
$dbman->change_field_type($table, $field);
} else {
$dbman->add_field($table, $field);
}
upgrade_plugin_savepoint(true, $newversion, 'qtype', 'ordering');
}
return true;
}

View File

@ -107,6 +107,15 @@ class qtype_ordering_edit_form extends question_edit_form {
$mform->addHelpButton($name, $name, $plugin);
$mform->setDefault($name, $this->get_default_value($name, qtype_ordering_question::GRADING_ABSOLUTE_POSITION));
// Field for showgrading.
$name = 'showgrading';
$label = get_string($name, $plugin);
$options = array(0 => get_string('hide'),
1 => get_string('show'));
$mform->addElement('select', $name, $label, $options);
$mform->addHelpButton($name, $name, $plugin);
$mform->setDefault($name, $this->get_default_value($name, 1));
$elements = array();
$options = array();
@ -319,8 +328,9 @@ class qtype_ordering_edit_form extends question_edit_form {
$names = array(
'layouttype' => qtype_ordering_question::LAYOUT_VERTICAL,
'selecttype' => qtype_ordering_question::SELECT_ALL,
'selectcount' => 0, // 0 means all.
'gradingtype' => qtype_ordering_question::GRADING_ABSOLUTE_POSITION
'selectcount' => 0, // 0 means ALL.
'gradingtype' => qtype_ordering_question::GRADING_ABSOLUTE_POSITION,
'showgrading' => 1 // 1 means SHOW.
);
foreach ($names as $name => $default) {
if (isset($question->options->$name)) {
@ -363,7 +373,7 @@ class qtype_ordering_edit_form extends question_edit_form {
// If adding a new ordering question, update defaults.
if (empty($errors) && empty($data['id'])) {
$fields = array('layouttype', 'selecttype', 'selectcount', 'gradingtype');
$fields = array('layouttype', 'selecttype', 'selectcount', 'gradingtype', 'showgrading');
foreach ($fields as $field) {
if (array_key_exists($field, $data)) {
$this->set_default_value($field, $data[$field]);

View File

@ -89,4 +89,6 @@ $string['selectcount'] = 'Size of subset';
$string['selectrandom'] = 'Select a random subset of items';
$string['selecttype_help'] = 'Choose whether to display all the items or a subset of the items.';
$string['selecttype'] = 'Item selection type';
$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['showgrading'] = 'Grading details';
$string['vertical'] = 'Vertical';

View File

@ -451,6 +451,7 @@ class qtype_ordering_question extends question_graded_automatically {
'selecttype' => self::SELECT_ALL,
'selectcount' => 0,
'gradingtype' => self::GRADING_ABSOLUTE_POSITION,
'showgradingdetails' => 1,
'correctfeedback' => '',
'correctfeedbackformat' => FORMAT_MOODLE,
'incorrectfeedback' => '',

View File

@ -216,7 +216,8 @@ class qtype_ordering extends question_type {
'layouttype' => $question->layouttype,
'selecttype' => $question->selecttype,
'selectcount' => $question->selectcount,
'gradingtype' => $question->gradingtype
'gradingtype' => $question->gradingtype,
'showgrading' => $question->showgrading
);
$options = $this->save_combined_feedback_helper($options, $question, $context, true);
$this->save_hints($question, false);
@ -379,14 +380,16 @@ class qtype_ordering extends question_type {
'RELATIVE|REL'.
'LONGEST_ORDERED_SUBSET|'.
'LONGEST_CONTIGUOUS_SUBSET)?';
$showgrading = '(?:SHOW|TRUE|YES|1|HIDE|FALSE|NO|0)?';
$search = '/^(' . $questionname . ')\s*\{>\s*(' . $selectcount . ')\s*(' . $selecttype . ')\s*' .
'(' . $layouttype . ')\s*(' . $gradingtype . ')\s*(.*?)\s*\}\s*$/s';
'(' . $layouttype . ')\s*(' . $gradingtype . ')\s*(' . $showgrading . ')\s*(.*?)\s*\}\s*$/s';
// Item $1 the question name.
// Item $2 the number of items to be shown.
// Item $3 the extraction/grading type.
// Item $3 the extraction/grading type.
// Item $4 the layout type.
// Item $5 the grading type.
// Item $6 the lines of items to be ordered.
// Item $5 the grading type.
// Item $6 show the grading details (SHOW/HIDE).
// Item $7 the lines of items to be ordered.
if (empty($extra) || ! preg_match($search, $lines, $matches)) {
return false; // Format not recognized.
}
@ -396,7 +399,8 @@ class qtype_ordering extends question_type {
$selecttype = trim($matches[3]);
$layouttype = trim($matches[4]);
$gradingtype = trim($matches[5]);
$lines = explode(PHP_EOL, $matches[6]);
$showgrading = trim($matches[6]);
$lines = explode(PHP_EOL, $matches[7]);
unset($matches);
$question->qtype = 'ordering';
@ -411,7 +415,7 @@ class qtype_ordering extends question_type {
} else {
$selectcount = min(6, count($lines));
}
$this->set_layout_select_count_grading($question, $layouttype, $selecttype, $selectcount, $gradingtype);
$this->set_layout_select_count_grading($question, $layouttype, $selecttype, $selectcount, $gradingtype, $showgrading);
// Remove blank items.
$lines = array_map('trim', $lines);
@ -456,8 +460,8 @@ class qtype_ordering extends question_type {
}
/**
* Given question object, returns array with array layouttype, selecttype, selectcount, gradingtype, where
* layouttype, selecttype, gradingtype are string representation.
* Given question object, returns array with array layouttype, selecttype, selectcount, gradingtype, showgrading
* where layouttype, selecttype, gradingtype and showgrading are string representations.
*
* @param object $question
* @return array(layouttype, selecttype, selectcount, gradingtype)
@ -518,10 +522,21 @@ class qtype_ordering extends question_type {
$grading = ''; // Shouldn't happen !!
}
switch ($question->options->showgrading) {
case 0:
$show = 'HIDE';
break;
case 1:
$show = 'SHOW';
break;
default:
$show = ''; // Shouldn't happen !!
}
// Note: this used to be (selectcount + 2).
$count = $question->options->selectcount;
return array($layout, $select, $count, $grading);
return array($layout, $select, $count, $grading, $show);
}
/**
@ -536,11 +551,12 @@ class qtype_ordering extends question_type {
global $CFG;
require_once($CFG->dirroot.'/question/type/ordering/question.php');
list($layouttype, $selecttype, $selectcount, $gradingtype) = $this->extract_layout_select_count_grading($question);
list($layouttype, $selecttype, $selectcount, $gradingtype, $showgrading) = $this->extract_layout_select_count_grading($question);
$output = $question->questiontext.'{>'.$selectcount.' '.
$selecttype.' '.
$layouttype.' '.
$gradingtype."\n";
$gradingtype.' '.
$showgrading."\n";
foreach ($question->options->answers as $answer) {
$output .= $answer->answer."\n";
}
@ -560,13 +576,14 @@ class qtype_ordering extends question_type {
global $CFG;
require_once($CFG->dirroot.'/question/type/ordering/question.php');
list($layouttype, $selecttype, $selectcount, $gradingtype) = $this->extract_layout_select_count_grading($question);
list($layouttype, $selecttype, $selectcount, $gradingtype, $showgrading) = $this->extract_layout_select_count_grading($question);
$output = '';
$output .= " <layouttype>$layouttype</layouttype>\n";
$output .= " <selecttype>$selecttype</selecttype>\n";
$output .= " <selectcount>$selectcount</selectcount>\n";
$output .= " <gradingtype>$gradingtype</gradingtype>\n";
$output .= " <showgrading>$showgrading</showgrading>\n";
$output .= $format->write_combined_feedback($question->options, $question->id, $question->contextid);
foreach ($question->options->answers as $answer) {
@ -626,7 +643,8 @@ class qtype_ordering extends question_type {
$selecttype = $format->getpath($data, array('#', $selecttype, 0, '#'), 'RANDOM');
$selectcount = $format->getpath($data, array('#', $selectcount, 0, '#'), 6);
$gradingtype = $format->getpath($data, array('#', 'gradingtype', 0, '#'), 'RELATIVE');
$this->set_layout_select_count_grading($newquestion, $layouttype, $selecttype, $selectcount, $gradingtype);
$showgrading = $format->getpath($data, array('#', 'showgrading', 0, '#'), '1');
$this->set_layout_select_count_grading($newquestion, $layouttype, $selecttype, $selectcount, $gradingtype, $showgrading);
$newquestion->answer = array();
$newquestion->answerformat = array();
@ -679,21 +697,23 @@ class qtype_ordering extends question_type {
}
/**
* Set layouttype, selecttype, selectcount, gradingtype based on their textual representation
* Set layouttype, selecttype, selectcount, gradingtype, showgrading based on their textual representation
*
* @param object $question (passed by reference)
* @param string $layout the layout type
* @param string $select the select type
* @param string $count the number of items to display
* @param string $grading the grading type
* @param string $show the grading details or not
*/
public function set_layout_select_count_grading(&$question, $layout, $select, $count, $grading) {
public function set_layout_select_count_grading(&$question, $layout, $select, $count, $grading, $show) {
// Set default values.
$layouttype = qtype_ordering_question::LAYOUT_VERTICAL;
$selecttype = qtype_ordering_question::SELECT_RANDOM;
$selectcount = 3;
$gradingtype = qtype_ordering_question::GRADING_RELATIVE_NEXT_EXCLUDE_LAST;
$showgrading = 1;
switch (strtoupper($layout)) {
@ -766,9 +786,24 @@ class qtype_ordering extends question_type {
break;
}
// Set "showgrading" from $show.
switch (strtoupper($show)) {
case 'SHOW':
case 'TRUE':
case 'YES':
$showgrading = 1;
break;
case 'HIDE':
case 'FALSE':
case 'NO':
$showgrading = 0;
break;
}
$question->layouttype = $layouttype;
$question->selecttype = $selecttype;
$question->selectcount = $selectcount;
$question->gradingtype = $gradingtype;
$question->showgrading = $showgrading;
}
}

View File

@ -198,59 +198,63 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
$plugin = 'qtype_ordering';
$question = $qa->get_question();
// Fetch grading type.
$gradingtype = $question->options->gradingtype;
$gradingtype = qtype_ordering_question::get_grading_types($gradingtype);
// show grading details if they are required
if ($question->options->showgrading) {
// 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 grading type.
$gradingtype = $question->options->gradingtype;
$gradingtype = qtype_ordering_question::get_grading_types($gradingtype);
// Fetch grade details and score details.
if ($currentresponse = $question->currentresponse) {
$totalscore = 0;
$totalmaxscore = 0;
$layoutclass = $question->get_ordering_layoutclass();
$params = array('class' => $layoutclass);
$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);
}
// 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'));
}
$scoredetails .= html_writer::end_tag('ol');
// Fetch grade details and score details.
if ($currentresponse = $question->currentresponse) {
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);
$totalscore = 0;
$totalmaxscore = 0;
$layoutclass = $question->get_ordering_layoutclass();
$params = array('class' => $layoutclass);
$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'));
}
$gradedetails = "$totalscore / $totalmaxscore = $gradedetails%";
$gradedetails = get_string('gradedetails', $plugin).': '.$gradedetails;
$gradedetails = html_writer::tag('p', $gradedetails, array('class' => 'gradedetails'));
}
}
}

View File

@ -29,5 +29,5 @@ $plugin->cron = 0;
$plugin->component = 'qtype_ordering';
$plugin->maturity = MATURITY_STABLE;
$plugin->requires = 2011070100; // Moodle 2.1.
$plugin->version = 2016051154;
$plugin->release = '2016-05-11 (54)';
$plugin->version = 2016081655;
$plugin->release = '2016-08-16 (55)';