Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

CONTRIB-490 Added support for scripted generation of questions. Calcu…

…lated type not yet supported (datasets too complicated ;)
  • Loading branch information...
commit 933f6db4b9fc32d7f5081a63adf7dfa4383632bc 1 parent 2bf5901
nicolasconnault authored
View
184 question/type/calculated/questiontype.php
@@ -40,13 +40,13 @@ function get_question_options(&$question) {
if (!$options = get_records('question_calculated', 'question', $question->id)) {
notify("No options were found for calculated question
#{$question->id}! Proceeding with defaults.");
- // $options = new Array();
+ // $options = new Array();
$options= new stdClass;
$options->tolerance = 0.01;
$options->tolerancetype = 1; // relative
$options->correctanswerlength = 2;
$options->correctanswerformat = 1; // decimals
- }
+ }
// For historic reasons we also need these fields in the answer objects.
// This should eventually be removed and related code changed to use
@@ -62,13 +62,13 @@ function get_question_options(&$question) {
$virtualqtype = $this->get_virtual_qtype();
$virtualqtype->get_numerical_units($question);
-
+
if( isset($question->export_process)&&$question->export_process){
$question->options->datasets = $this->get_datasets_for_export($question);
- }
+ }
return true;
}
-
+
function get_datasets_for_export(&$question){
$datasetdefs = array();
if (!empty($question->id)) {
@@ -79,25 +79,25 @@ function get_datasets_for_export(&$question){
WHERE d.question = '$question->id'
AND d.datasetdefinition = i.id
";
- if ($records = get_records_sql($sql)) {
+ if ($records = get_records_sql($sql)) {
foreach ($records as $r) {
$def = $r ;
if ($def->category=='0'){
$def->status='private';
- } else {
+ } else {
$def->status='shared';
- }
+ }
$def->type ='calculated' ;
list($distribution, $min, $max,$dec) = explode(':', $def->options, 4);
$def->distribution=$distribution;
$def->minimum=$min;
$def->maximum=$max;
- $def->decimals=$dec ;
+ $def->decimals=$dec ;
if ($def->itemcount > 0 ) {
// get the datasetitems
$def->items = array();
$sql1= (" SELECT itemnumber, definition, id, value
- FROM {$CFG->prefix}question_dataset_items
+ FROM {$CFG->prefix}question_dataset_items
WHERE definition = '$def->id' order by itemnumber ASC ");
if ($items = get_records_sql($sql1)){
$n = 0;
@@ -110,18 +110,18 @@ function get_datasets_for_export(&$question){
$def->number_of_items=$n ;
}
}
- $datasetdefs["1-$r->category-$r->name"] = $def;
+ $datasetdefs["1-$r->category-$r->name"] = $def;
}
}
}
return $datasetdefs ;
- }
-
+ }
+
function save_question_options($question) {
//$options = $question->subtypeoptions;
// Get old answers:
global $CFG;
-
+
// Get old versions of the objects
if (!$oldanswers = get_records('question_answers', 'question', $question->id, 'id ASC')) {
$oldanswers = array();
@@ -141,13 +141,13 @@ function save_question_options($question) {
}
// Insert all the new answers
foreach ($question->answers as $key => $dataanswer) {
- if ( trim($dataanswer) != '' ) {
+ if ( trim($dataanswer) != '' ) {
$answer = new stdClass;
$answer->question = $question->id;
$answer->answer = trim($dataanswer);
$answer->fraction = $question->fraction[$key];
$answer->feedback = trim($question->feedback[$key]);
-
+
if ($oldanswer = array_shift($oldanswers)) { // Existing answer, so reuse it
$answer->id = $oldanswer->id;
if (! update_record("question_answers", $answer)) {
@@ -171,7 +171,7 @@ function save_question_options($question) {
$options->tolerancetype = trim($question->tolerancetype[$key]);
$options->correctanswerlength = trim($question->correctanswerlength[$key]);
$options->correctanswerformat = trim($question->correctanswerformat[$key]);
-
+
// Save options
if (isset($options->id)) { // reusing existing record
if (! update_record('question_calculated', $options)) {
@@ -203,7 +203,7 @@ function save_question_options($question) {
if( isset($question->import_process)&&$question->import_process){
$this->import_datasets($question);
- }
+ }
// Report any problems.
if (!empty($result->notice)) {
return $result;
@@ -214,12 +214,12 @@ function save_question_options($question) {
function import_datasets($question){
$n = count($question->dataset);
foreach ($question->dataset as $dataset) {
- // name, type, option,
+ // name, type, option,
$datasetdef = new stdClass();
$datasetdef->name = $dataset->name;
$datasetdef->type = 1 ;
$datasetdef->options = $dataset->distribution.':'.$dataset->min.':'.$dataset->max.':'.$dataset->length;
- $datasetdef->itemcount=$dataset->itemcount;
+ $datasetdef->itemcount=$dataset->itemcount;
if ( $dataset->status =='private'){
$datasetdef->category = 0;
$todo='create' ;
@@ -238,18 +238,18 @@ function import_datasets($question){
} else { // different so create a private one
$datasetdef->category = 0;
$todo='create' ;
- }
+ }
}else { // no so create one
$datasetdef->category =$question->category ;
$todo='create' ;
- }
- }
+ }
+ }
if ( $todo=='create'){
if (!$datasetdef->id = insert_record(
'question_dataset_definitions', $datasetdef)) {
error("Unable to create dataset $defid");
- }
- }
+ }
+ }
// Create relation to the dataset:
$questiondataset = new stdClass;
$questiondataset->question = $question->id;
@@ -267,11 +267,11 @@ function import_datasets($question){
if (!insert_record('question_dataset_items', $datasetitem)) {
error("Unable to insert dataset item $item->itemnumber with $item->value for $datasetdef->name");
}
- }
- }
+ }
+ }
}
}
-
+
function create_runtime_question($question, $form) {
$question = parent::create_runtime_question($question, $form);
$question->options->answers = array();
@@ -360,7 +360,7 @@ function print_question_formulation_and_controls(&$question, &$state, $cmoptions
$unit = $unit->unit;
} else {
$unit = '';
- }
+ }
// We modify the question to look like a numerical question
$numericalquestion = fullclone($question);
foreach ($numericalquestion->options->answers as $key => $answer) {
@@ -373,7 +373,7 @@ function print_question_formulation_and_controls(&$question, &$state, $cmoptions
}
$numericalquestion->questiontext = parent::substitute_variables(
$numericalquestion->questiontext, $state->options->dataset);
- //evaluate the equations i.e {=5+4)
+ //evaluate the equations i.e {=5+4)
$qtext = "";
$qtextremaining = $numericalquestion->questiontext ;
while (ereg('\{=([^[:space:]}]*)}', $qtextremaining, $regs1)) {
@@ -385,17 +385,17 @@ function print_question_formulation_and_controls(&$question, &$state, $cmoptions
} else {
if( $formulaerrors = qtype_calculated_find_formula_errors($regs1[1])){
$str=$formulaerrors ;
- }else {
- eval('$str = '.$regs1[1].';');
+ }else {
+ eval('$str = '.$regs1[1].';');
}
}
- $qtext = $qtext.$str ;
- }
+ $qtext = $qtext.$str ;
+ }
$numericalquestion->questiontext = $qtext.$qtextremaining ; // end replace equations
$virtualqtype->print_question_formulation_and_controls($numericalquestion, $state, $cmoptions, $options);
}
function grade_responses(&$question, &$state, $cmoptions) {
- // Forward the grading to the virtual qtype
+ // Forward the grading to the virtual qtype
// We modify the question to look like a numerical question
$numericalquestion = fullclone($question);
foreach ($numericalquestion->options->answers as $key => $answer) {
@@ -579,7 +579,7 @@ function save_dataset_items($question, $fromform){
global $CFG ;
// max datasets = 100 items
$max100 = 100 ;
- if(isset($fromform->nextpageparam["forceregeneration"])) {
+ if(isset($fromform->nextpageparam["forceregeneration"])) {
$regenerate = $fromform->nextpageparam["forceregeneration"];
}else{
$regenerate = 0 ;
@@ -589,6 +589,7 @@ function save_dataset_items($question, $fromform){
}
//get the old datasets for this question
$datasetdefs = $this->get_dataset_definitions($question->id, array());
+
// Handle generator options...
$olddatasetdefs = fullclone($datasetdefs);
$datasetdefs = $this->update_dataset_options($datasetdefs, $fromform);
@@ -675,7 +676,7 @@ function save_dataset_items($question, $fromform){
//pp echo "<pre>"; print_r( $datasetitem );
if (!insert_record('question_dataset_items', $datasetitem)) {
error("Error: Unable to insert new dataset item");
- }
+ }
}
}//for number added
}// datasetsdefs end
@@ -687,7 +688,7 @@ function save_dataset_items($question, $fromform){
update_record('question_dataset_definitions', $newdef);
}
}
- }
+ }
if (isset($fromform->deletebutton)) {
if(isset($fromform->selectdelete)) $newmaxnumber = $maxnumber-$fromform->selectdelete ;
@@ -695,7 +696,7 @@ function save_dataset_items($question, $fromform){
if ($newmaxnumber < 0 ) $newmaxnumber = 0 ;
foreach ($datasetdefs as $datasetdef) {
if ($datasetdef->itemcount == $maxnumber) {
- $datasetdef->itemcount= $newmaxnumber ;
+ $datasetdef->itemcount= $newmaxnumber ;
if (!update_record('question_dataset_definitions',
$datasetdef)) {
error("Error: Unable to update itemcount");
@@ -705,6 +706,7 @@ function save_dataset_items($question, $fromform){
}
}
function generate_dataset_item($options) {
+
if (!ereg('^(uniform|loguniform):([^:]*):([^:]*):([0-9]*)$',
$options, $regs)) {
// Unknown options...
@@ -775,7 +777,7 @@ function comment_on_datasetitems($question, $data, $number) {
$virtualqtype->get_tolerance_interval($calculated);
if ($calculated->min === '') {
// This should mean that something is wrong
- $stranswers .= " -$calculated->answer".'<br/><br/>';
+ $stranswers .= " -$calculated->answer".'<br/><br/>';
} else {
$stranswers .= $formula.' = '.$calculated->answer.'<br/>' ;
$stranswers .= $strmin. $delimiter.$calculated->min.'---';
@@ -796,7 +798,7 @@ function dataset_options($form, $name, $mandatory=true,$renameabledatasets=false
// Takes datasets from the parent implementation but
// filters options that are currently not accepted by calculated
// It also determines a default selection...
- //$renameabledatasets not implemented anmywhere
+ //$renameabledatasets not implemented anmywhere
list($options, $selected) = parent::dataset_options($form, $name,'','qtype_calculated');
// list($options, $selected) = $this->dataset_optionsa($form, $name);
@@ -806,11 +808,11 @@ function dataset_options($form, $name, $mandatory=true,$renameabledatasets=false
}
}
if (!$selected) {
- if ($mandatory){
+ if ($mandatory){
$selected = LITERAL . "-0-$name"; // Default
}else {
$selected = "0"; // Default
- }
+ }
}
return array($options, $selected);
}
@@ -849,7 +851,7 @@ function get_correct_responses(&$question, &$state) {
$unit = $unit->unit;
} else {
$unit = '';
- }
+ }
foreach ($question->options->answers as $answer) {
if (((int) $answer->fraction) === 1) {
$answernumerical = qtype_calculated_calculate_answer(
@@ -871,24 +873,24 @@ function substitute_variables($str, $dataset) {
if (empty($formula)) {
$str = '';
} else {
- eval('$str = '.$formula.';');
+ eval('$str = '.$formula.';');
}
return $str;
}
-
+
/**
* This function retrieve the item count of the available category shareable
- * wild cards that is added as a comment displayed when a wild card with
+ * wild cards that is added as a comment displayed when a wild card with
* the same name is displayed in datasetdefinitions_form.php
- */
+ */
function get_dataset_definitions_category($form) {
global $CFG;
$datasetdefs = array();
$lnamemax = 30;
- if (!empty($form->category)) {
+ if (!empty($form->category)) {
$sql = "SELECT i.*,d.*
FROM {$CFG->prefix}question_datasets d,
- {$CFG->prefix}question_dataset_definitions i
+ {$CFG->prefix}question_dataset_definitions i
WHERE i.id = d.datasetdefinition
AND i.category = '$form->category'
;
@@ -898,18 +900,18 @@ function get_dataset_definitions_category($form) {
if ( !isset ($datasetdefs["$r->name"])) $datasetdefs["$r->name"] = $r->itemcount;
}
}
- }
+ }
return $datasetdefs ;
- }
+ }
/**
* This function build a table showing the available category shareable
* wild cards, their name, their definition (Min, Max, Decimal) , the item count
* and the name of the question where they are used.
- * This table is intended to be add before the question text to help the user use
+ * This table is intended to be add before the question text to help the user use
* these wild cards
- */
-
+ */
+
function print_dataset_definitions_category($form) {
global $CFG;
$datasetdefs = array();
@@ -921,20 +923,20 @@ function print_dataset_definitions_category($form) {
$questionusingstr = get_string('usedinquestion','qtype_calculated');
$itemscountstr = get_string('itemscount','qtype_datasetdependent');
$text ='';
- if (!empty($form->category)) {
+ if (!empty($form->category)) {
list($category) = explode(',', $form->category);
$sql = "SELECT i.*,d.*
FROM {$CFG->prefix}question_datasets d,
- {$CFG->prefix}question_dataset_definitions i
+ {$CFG->prefix}question_dataset_definitions i
WHERE i.id = d.datasetdefinition
- AND i.category = $category;
+ AND i.category = $category;
" ;
if ($records = get_records_sql($sql)) {
foreach ($records as $r) {
$sql1 = "SELECT q.*
- FROM {$CFG->prefix}question q
- WHERE q.id = $r->question
- ";
+ FROM {$CFG->prefix}question q
+ WHERE q.id = $r->question
+ ";
if ( !isset ($datasetdefs["$r->type-$r->category-$r->name"])){
$datasetdefs["$r->type-$r->category-$r->name"]= $r;
}
@@ -945,8 +947,8 @@ function print_dataset_definitions_category($form) {
}
}
if (!empty ($datasetdefs)){
-
- $text ="<table width=\"100%\" border=\"1\"><tr><th style=\"white-space:nowrap;\" class=\"header\" scope=\"col\" >$namestr</th><th style=\"white-space:nowrap;\" class=\"header\" scope=\"col\">$rangeofvaluestr</th><th style=\"white-space:nowrap;\" class=\"header\" scope=\"col\">$itemscountstr</th><th style=\"white-space:nowrap;\" class=\"header\" scope=\"col\">$questionusingstr</th></tr>";
+
+ $text ="<table width=\"100%\" border=\"1\"><tr><th style=\"white-space:nowrap;\" class=\"header\" scope=\"col\" >$namestr</th><th style=\"white-space:nowrap;\" class=\"header\" scope=\"col\">$rangeofvaluestr</th><th style=\"white-space:nowrap;\" class=\"header\" scope=\"col\">$itemscountstr</th><th style=\"white-space:nowrap;\" class=\"header\" scope=\"col\">$questionusingstr</th></tr>";
foreach ($datasetdefs as $datasetdef){
list($distribution, $min, $max,$dec) = explode(':', $datasetdef->options, 4);
$text .="<tr><td valign=\"top\" align=\"center\"> $datasetdef->name </td><td align=\"center\" valign=\"top\"> $min <strong>-</strong> $max </td><td align=\"right\" valign=\"top\">$datasetdef->itemcount&nbsp;&nbsp;</td><td align=\"left\">";
@@ -958,16 +960,16 @@ function print_dataset_definitions_category($form) {
} else {
$qu->name = '';
}
- $text .=" &nbsp;&nbsp; $qu->name <br/>";
- }
+ $text .=" &nbsp;&nbsp; $qu->name <br/>";
+ }
$text .="</td></tr>";
}
$text .="</table>";
}else{
- $text .=get_string('nosharedwildcard', 'qtype_calculated');
+ $text .=get_string('nosharedwildcard', 'qtype_calculated');
}
return $text ;
- }
+ }
/// BACKUP FUNCTIONS ////////////////////////////
@@ -1070,6 +1072,54 @@ function restore($old_question_id,$new_question_id,$info,$restore) {
return $status;
}
+
+ /**
+ * Runs all the code required to set up and save an essay question for testing purposes.
+ * Alternate DB table prefix may be used to facilitate data deletion.
+ */
+ function generate_test($name, $courseid = null) {
+ list($form, $question) = parent::generate_test($name, $courseid);
+ $form->feedback = 1;
+ $form->multiplier = array(1, 1);
+ $form->shuffleanswers = 1;
+ $form->noanswers = 1;
+
+ $form->answers = array('{a} + {b}');
+ $form->fraction = array(1);
+ $form->tolerance = array(0.01);
+ $form->tolerancetype = array(1);
+ $form->correctanswerlength = array(2);
+ $form->correctanswerformat = array(1);
+ $form->questiontext = "What is {a} + {b}?";
+
+ if ($courseid) {
+ $course = get_record('course', 'id', $courseid);
+ }
+
+ $new_question = $this->save_question($question, $form, $course);
+
+ $dataset_form = new stdClass();
+ $dataset_form->number = array(1 => 2.4, 2 => 7.2, 3 => 6.7, 4 => 6.3);
+ $dataset_form->calcmin = array(1 => 1.0, 2 => 1.0);
+ $dataset_form->calcmax = array(1 => 10.0, 2 => 10.0);
+ $dataset_form->calclength = array(1 => 1, 2 => 1);
+ $dataset_form->calcdistribution = array(1 => 'uniform', 2 => 'uniform');
+ $dataset_form->definition = array(1 => "1-$new_question->category-b",
+ 2 => "1-$new_question->category-a",
+ 3 => "1-$new_question->category-b",
+ 4 => "1-$new_question->category-a");
+ $dataset_form->itemid = array(1 => 2, 2 => 1, 3 => 0, 4 => 0);
+ $dataset_form->nextpageparam = array('forceregeneration' => false);
+ $dataset_form->addbutton = 1;
+ $dataset_form->selectadd = 1;
+ $dataset_form->selectdelete = 1;
+ $dataset_form->courseid = $courseid;
+ $dataset_form->cmid = 0;
+
+ $this->save_dataset_items($new_question, $dataset_form);
+
+ return $new_question;
+ }
}
//// END OF CLASS ////
View
19 question/type/essay/questiontype.php
@@ -133,6 +133,25 @@ function backup($bf, $preferences, $questionid, $level = 6) {
return question_backup_answers($bf, $preferences, $questionid, $level);
}
+ /**
+ * Runs all the code required to set up and save an essay question for testing purposes.
+ * Alternate DB table prefix may be used to facilitate data deletion.
+ */
+ function generate_test($name, $courseid = null) {
+ list($form, $question) = parent::generate_test($name, $courseid);
+ $form->questiontext = "What is the purpose of life?";
+ $form->feedback = "feedback";
+ $form->generalfeedback = "General feedback";
+ $form->fraction = 0;
+ $form->penalty = 0;
+
+ if ($courseid) {
+ $course = get_record('course', 'id', $courseid);
+ }
+
+ return $this->save_question($question, $form, $course);
+ }
+
// Restore method not needed.
}
//// END OF CLASS ////
View
57 question/type/multianswer/questiontype.php
@@ -37,7 +37,7 @@ function get_question_options(&$question) {
// We want an array with question ids as index and the positions as values
$sequence = array_flip(explode(',', $sequence));
array_walk($sequence, create_function('&$val', '$val++;'));
- //si une question est manquante l,indice est nul
+ //si une question est manquante l,indice est nul
foreach($sequence as $seq){
$question->options->questions[$seq]= '';
}
@@ -79,7 +79,7 @@ function save_question_options($question) {
if ($wrapped != ''){
// if we still have some old wrapped question ids, reuse the next of them
if (is_array($oldwrappedids) && $oldwrappedid = array_shift($oldwrappedids)) {
-
+
if( $oldqtype = get_field('question', 'qtype', 'id',$oldwrappedid->id)){
$wrapped->id = $oldwrappedid->id;
if($oldqtype != $wrapped->qtype ) {
@@ -115,7 +115,7 @@ function save_question_options($question) {
}
// Delete redundant wrapped questions
- if(is_array($oldwrappedids) && count($oldwrappedids)){
+ if(is_array($oldwrappedids) && count($oldwrappedids)){
foreach ($oldwrappedids as $id) {
delete_question($id) ;
}
@@ -282,9 +282,9 @@ function print_question_formulation_and_controls(&$question, &$state, $cmoptions
$feedbackimg = '';
$feedback = '' ;
$correctanswer = '';
- $strfeedbackwrapped = $strfeedback;
+ $strfeedbackwrapped = $strfeedback;
// if($wrapped->qtype == 'numerical' ||$wrapped->qtype == 'shortanswer'){
- $testedstate = clone($state);
+ $testedstate = clone($state);
if ($correctanswers = $QTYPES[$wrapped->qtype]->get_correct_responses($wrapped, $testedstate)) {
if ($options->readonly && $options->correct_responses) {
$delimiter = '';
@@ -292,7 +292,7 @@ function print_question_formulation_and_controls(&$question, &$state, $cmoptions
foreach ($correctanswers as $ca) {
switch($wrapped->qtype){
case 'numerical':
- case 'shortanswer':
+ case 'shortanswer':
$correctanswer .= $delimiter.$ca;
break ;
case 'multichoice':
@@ -300,7 +300,7 @@ function print_question_formulation_and_controls(&$question, &$state, $cmoptions
$correctanswer .= $delimiter.$answers[$ca]->answer;
}
break ;
- }
+ }
$delimiter = ', ';
}
}
@@ -364,7 +364,7 @@ function print_question_formulation_and_controls(&$question, &$state, $cmoptions
}
}
if ($feedback !='' && $popup == ''){
- $strfeedbackwrapped = get_string('correctanswer', 'qtype_multianswer');
+ $strfeedbackwrapped = get_string('correctanswer', 'qtype_multianswer');
$feedback = s(str_replace(array("\\", "'"), array("\\\\", "\\'"), $feedback));
$popup = " onmouseover=\"return overlib('$feedback', STICKY, MOUSEOFF, CAPTION, '$strfeedbackwrapped', FGCOLOR, '#FFFFFF');\" ".
" onmouseout=\"return nd();\" ";
@@ -379,18 +379,18 @@ function print_question_formulation_and_controls(&$question, &$state, $cmoptions
if (strlen(trim($answer->answer)) > $size ){
$size = strlen(trim($answer->answer));
}
- }
+ }
if (strlen(trim($response))> $size ){
$size = strlen(trim($response))+1;
}
$size = $size + rand(0,$size*0.15);
- $size > 60 ? $size = 60 : $size = $size;
+ $size > 60 ? $size = 60 : $size = $size;
$styleinfo = "size=\"$size\"";
/**
* Uncomment the following lines if you want to limit for small sizes.
- * Results may vary with browsers see MDL-3274
+ * Results may vary with browsers see MDL-3274
*/
- /*
+ /*
if ($size < 2) {
$styleinfo = 'style="width: 1.1em;"';
}
@@ -404,7 +404,7 @@ function print_question_formulation_and_controls(&$question, &$state, $cmoptions
$styleinfo = 'style="width: 2.8em;"';
}
*/
-
+
echo "<input $style $readonly $popup name=\"$inputname\"";
echo " type=\"text\" value=\"".s($response, true)."\" ".$styleinfo." /> ";
if (!empty($feedback) && !empty($USER->screenreader)) {
@@ -448,7 +448,7 @@ function print_question_formulation_and_controls(&$question, &$state, $cmoptions
if(! isset($question->options->questions[$positionkey])){
echo $regs[0];
}else {
- echo '<div class="error" >'.get_string('questionnotfound','qtype_multianswer',$positionkey).'</div>';
+ echo '<div class="error" >'.get_string('questionnotfound','qtype_multianswer',$positionkey).'</div>';
}
}
}
@@ -456,7 +456,7 @@ function print_question_formulation_and_controls(&$question, &$state, $cmoptions
// Print the final piece of question text:
echo $qtextremaining;
$this->print_question_submit_buttons($question, $state, $cmoptions, $options);
- echo '</div>';
+ echo '</div>';
}
function grade_responses(&$question, &$state, $cmoptions) {
@@ -702,6 +702,33 @@ function restore_recode_answer($state, $restore) {
return $answer_field;
}
+ /**
+ * Runs all the code required to set up and save an essay question for testing purposes.
+ * Alternate DB table prefix may be used to facilitate data deletion.
+ */
+ function generate_test($name, $courseid = null) {
+ list($form, $question) = parent::generate_test($name, $courseid);
+ $question->category = $form->category;
+ $form->questiontext = "This question consists of some text with an answer embedded right here {1:MULTICHOICE:Wrong answer#Feedback for this wrong answer~Another wrong answer#Feedback for the other wrong answer~=Correct answer#Feedback for correct answer~%50%Answer that gives half the credit#Feedback for half credit answer} and right after that you will have to deal with this short answer {1:SHORTANSWER:Wrong answer#Feedback for this wrong answer~=Correct answer#Feedback for correct answer~%50%Answer that gives half the credit#Feedback for half credit answer} and finally we have a floating point number {2:NUMERICAL:=23.8:0.1#Feedback for correct answer 23.8~%50%23.8:2#Feedback for half credit answer in the nearby region of the correct answer}.
+
+Note that addresses like www.moodle.org and smileys :-) all work as normal:
+ a) How good is this? {:MULTICHOICE:=Yes#Correct~No#We have a different opinion}
+ b) What grade would you give it? {3:NUMERICAL:=3:2}
+
+Good luck!
+";
+ $form->feedback = "feedback";
+ $form->generalfeedback = "General feedback";
+ $form->fraction = 0;
+ $form->penalty = 0.1;
+ $form->versioning = 0;
+
+ if ($courseid) {
+ $course = get_record('course', 'id', $courseid);
+ }
+
+ return $this->save_question($question, $form, $course);
+ }
}
//// END OF CLASS ////
View
28 question/type/multichoice/questiontype.php
@@ -669,6 +669,34 @@ function replace_file_links($question, $fromcourseid, $tocourseid, $url, $destin
}
}
}
+
+ /**
+ * Runs all the code required to set up and save an essay question for testing purposes.
+ * Alternate DB table prefix may be used to facilitate data deletion.
+ */
+ function generate_test($name, $courseid = null) {
+ list($form, $question) = parent::generate_test($name, $courseid);
+ $question->category = $form->category;
+ $form->questiontext = "How old is the sun?";
+ $form->generalfeedback = "General feedback";
+ $form->penalty = 0.1;
+ $form->single = 1;
+ $form->shuffleanswers = 1;
+ $form->answernumbering = 'abc';
+ $form->noanswers = 3;
+ $form->answer = array('Ancient', '5 billion years old', '4.5 billion years old');
+ $form->fraction = array(0.3, 0.9, 1);
+ $form->feedback = array('True, but lacking in accuracy', 'Close, but no cigar!', 'Yep, that is it!');
+ $form->correctfeedback = 'Excellent!';
+ $form->incorrectfeedback = 'Nope!';
+ $form->partiallycorrectfeedback = 'Not bad';
+
+ if ($courseid) {
+ $course = get_record('course', 'id', $courseid);
+ }
+
+ return $this->save_question($question, $form, $course);
+ }
}
// Register this question type with the question bank.
View
50 question/type/numerical/questiontype.php
@@ -107,7 +107,7 @@ function save_question_options($question) {
// Insert all the new answers
foreach ($question->answer as $key => $dataanswer) {
- if (!isset( $question->deleteanswer[$key] ) && !( trim($dataanswer) == 0 && $question->fraction[$key]== 0 &&trim($question->feedback[$key])=='')) {
+ if (!isset( $question->deleteanswer[$key] ) && !( trim($dataanswer) == 0 && $question->fraction[$key]== 0 &&trim($question->feedback[$key])=='')) {
$answer = new stdClass;
$answer->question = $question->id;
if (trim($dataanswer) == '*') {
@@ -148,7 +148,7 @@ function save_question_options($question) {
$result->notice = get_string('invalidnumerictolerance', 'quiz');
}
}
-
+
// Save options
if (isset($options->id)) { // reusing existing record
if (! update_record('question_numerical', $options)) {
@@ -181,7 +181,7 @@ function save_question_options($question) {
if (!empty($result->notice)) {
return $result;
}
-
+
return true;
}
@@ -329,11 +329,11 @@ function get_tolerance_interval(&$answer) {
$tolerance = abs($tolerance); // important - otherwise min and max are swapped
// $answer->tolerance 0 or something else
if ((float)$answer->tolerance == 0.0 && abs((float)$answer->answer) <= $tolerance ){
- $tolerance = (float) ("1.0e-".ini_get('precision')) * abs((float)$answer->answer) ; //tiny fraction
+ $tolerance = (float) ("1.0e-".ini_get('precision')) * abs((float)$answer->answer) ; //tiny fraction
} else if ((float)$answer->tolerance != 0.0 && abs((float)$answer->tolerance) < abs((float)$answer->answer) && abs((float)$answer->answer) <= $tolerance){
- $tolerance = (1+("1.0e-".ini_get('precision')) )* abs((float) $answer->tolerance) ;//tiny fraction
- }
-
+ $tolerance = (1+("1.0e-".ini_get('precision')) )* abs((float) $answer->tolerance) ;//tiny fraction
+ }
+
$max = $answer->answer + $tolerance;
$min = $answer->answer - $tolerance;
break;
@@ -370,13 +370,13 @@ function apply_unit($rawresponse, $units) {
$search = array(' ', ',');
$replace = array('', '.');
$rawresponse = str_replace($search, $replace, trim($rawresponse));
-
+
// Apply any unit that is present.
if (ereg('^([+-]?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([eE][-+]?[0-9]+)?)([^0-9].*)?$',
$rawresponse, $responseparts)) {
-
+
if (!empty($responseparts[5])) {
-
+
if (isset($tmpunits[$responseparts[5]])) {
// Valid number with unit.
return (float)$responseparts[1] / $tmpunits[$responseparts[5]];
@@ -393,7 +393,7 @@ function apply_unit($rawresponse, $units) {
// Invalid number. Must be wrong.
return false;
}
-
+
/// BACKUP FUNCTIONS ////////////////////////////
/**
@@ -483,6 +483,34 @@ function restore($old_question_id,$new_question_id,$info,$restore) {
return $status;
}
+ /**
+ * Runs all the code required to set up and save an essay question for testing purposes.
+ * Alternate DB table prefix may be used to facilitate data deletion.
+ */
+ function generate_test($name, $courseid = null) {
+ list($form, $question) = default_questiontype::generate_test($name, $courseid);
+ $question->category = $form->category;
+
+ $form->questiontext = "What is 674 * 36?";
+ $form->generalfeedback = "Thank you";
+ $form->penalty = 0.1;
+ $form->defaultgrade = 1;
+ $form->noanswers = 3;
+ $form->answer = array('24264', '24264', '1');
+ $form->tolerance = array(10, 100, 0);
+ $form->fraction = array(1, 0.5, 0);
+ $form->nounits = 2;
+ $form->unit = array(0 => null, 1 => null);
+ $form->multiplier = array(1, 0);
+ $form->feedback = array('Very good', 'Close, but not quite there', 'Well at least you tried....');
+
+ if ($courseid) {
+ $course = get_record('course', 'id', $courseid);
+ }
+
+ return $this->save_question($question, $form, $course);
+ }
+
}
// INITIATION - Without this line the question type is not in use.
View
28 question/type/shortanswer/questiontype.php
@@ -440,6 +440,34 @@ function print_question_grading_details(&$question, &$state, $cmoptions, $option
}
}
}
+
+ /**
+ * Runs all the code required to set up and save an essay question for testing purposes.
+ * Alternate DB table prefix may be used to facilitate data deletion.
+ */
+ function generate_test($name, $courseid = null) {
+ list($form, $question) = parent::generate_test($name, $courseid);
+ $question->category = $form->category;
+
+ $form->questiontext = "What is the purpose of life, the universe, and everything";
+ $form->generalfeedback = "Congratulations, you may have solved my biggest problem!";
+ $form->penalty = 0.1;
+ $form->usecase = false;
+ $form->defaultgrade = 1;
+ $form->noanswers = 3;
+ $form->answer = array('42', 'who cares?', 'Be happy');
+ $form->fraction = array(1, 0.6, 0.8);
+ $form->feedback = array('True, but what does that mean?', 'Well you do, dont you?', 'Yes, but thats not funny...');
+ $form->correctfeedback = 'Excellent!';
+ $form->incorrectfeedback = 'Nope!';
+ $form->partiallycorrectfeedback = 'Not bad';
+
+ if ($courseid) {
+ $course = get_record('course', 'id', $courseid);
+ }
+
+ return $this->save_question($question, $form, $course);
+ }
}
//// END OF CLASS ////
View
21 question/type/truefalse/questiontype.php
@@ -345,6 +345,27 @@ function restore_recode_answer($state, $restore) {
}
}
+ /**
+ * Runs all the code required to set up and save an essay question for testing purposes.
+ * Alternate DB table prefix may be used to facilitate data deletion.
+ */
+ function generate_test($name, $courseid = null) {
+ list($form, $question) = parent::generate_test($name, $courseid);
+ $question->category = $form->category;
+
+ $form->questiontext = "This question is really stupid";
+ $form->penalty = 1;
+ $form->defaultgrade = 1;
+ $form->correctanswer = 0;
+ $form->feedbacktrue = array('Can you justify such a hasty judgment?');
+ $form->feedbackfalse = array('Wisdom has spoken!');
+
+ if ($courseid) {
+ $course = get_record('course', 'id', $courseid);
+ }
+
+ return $this->save_question($question, $form, $course);
+ }
}
//// END OF CLASS ////
Please sign in to comment.
Something went wrong with that request. Please try again.