From: pichetp Date: Wed, 25 Apr 2007 08:15:50 +0000 (+0000) Subject: MDL-9496 Adding multianswer to calculated and MDL-9657 cleaning abstractype code. X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=a6d46515f1862ead7e25c26f29702f5e225a4a86;p=moodle.git MDL-9496 Adding multianswer to calculated and MDL-9657 cleaning abstractype code. --- diff --git a/question/type/calculated/edit_calculated_form.php b/question/type/calculated/edit_calculated_form.php index a38f13b27e..c8821cdff2 100644 --- a/question/type/calculated/edit_calculated_form.php +++ b/question/type/calculated/edit_calculated_form.php @@ -27,9 +27,16 @@ class question_edit_calculated_form extends question_edit_form { function definition_inner(&$mform) { global $QTYPES; $this->qtypeobj =& $QTYPES[$this->qtype()]; + $label = get_string("sharedwildcards", "qtype_datasetdependent"); + $mform->addElement('hidden', 'initialcategory', 1); + $html2 = $this->qtypeobj->print_dataset_definitions_category($this->question); + $mform->insertElementBefore($mform->createElement('static','listcategory',$label,$html2),'name'); + $addfieldsname='updatecategory'; + $addstring=get_string("updatecategory", "qtype_calculated"); + $mform->registerNoSubmitButton($addfieldsname); + + $mform->insertElementBefore( $mform->createElement('submit', $addfieldsname, $addstring),'listcategory'); -//------------------------------------------------------------------------------------------ -/* //not working now datasetdependent code cannot handle multiple answer formulas and not needed ?? $repeated = array(); $repeated[] =& $mform->createElement('header', 'answerhdr', get_string('answerhdr', 'qtype_calculated', '{no}')); @@ -61,50 +68,9 @@ class question_edit_calculated_form extends question_edit_form { $count = 0; } $repeatsatstart = $count + 1; - $this->repeat_elements($repeated, $repeatsatstart, $repeatedoptions, 'noanswers', 'addanswers', 1, get_string('addmoreanswerblanks', 'qtype_calculated'));*/ -//------------------------------------------------------------------------------------------ - $label = get_string("sharedwildcards", "qtype_datasetdependent"); - $mform->addElement('hidden', 'initialcategory', 1); - $html2 = $this->qtypeobj->print_dataset_definitions_category($this->question); - $mform->insertElementBefore($mform->createElement('static','listcategory',$label,$html2),'name'); - $addfieldsname='updatecategory'; - $addstring=get_string("updatecategory", "qtype_calculated"); - $mform->registerNoSubmitButton($addfieldsname); - - $mform->insertElementBefore( $mform->createElement('submit', $addfieldsname, $addstring),'listcategory'); - - $mform->addElement('header', 'answerhdr', get_string('answerhdr', 'qtype_calculated')); - - $mform->addElement('text', 'answers[0]', get_string('correctanswerformula', 'quiz')); - $mform->setType('answers[0]', PARAM_NOTAGS); - -/* $creategrades = get_grade_options(); - $gradeoptions = $creategrades->gradeoptions; - $mform->addElement('select', 'fraction[0]', get_string('grade'), $gradeoptions); - $mform->setDefault('fraction[0]', 0);*/ - $mform->addElement('hidden', 'fraction[0]', 1); - // $mform->setConstants(array('fraction[0]'=>PARAM_INT)); - - $tolgrp = array(); - $tolgrp[] =& $mform->createElement('text', 'tolerance[0]', get_string('tolerance', 'qtype_calculated')); - $mform->setType('tolerance[0]', PARAM_NUMBER); - $mform->setDefault('tolerance[0]', 0.01); - $tolgrp[] =& $mform->createElement('select', 'tolerancetype[0]', get_string('tolerancetype', 'quiz'), $this->qtypeobj->tolerance_types()); - $mform->addGroup($tolgrp, 'tolgrp', get_string('tolerance', 'qtype_calculated'), null, false); + $this->repeat_elements($repeated, $repeatsatstart, $repeatedoptions, 'noanswers', 'addanswers', 1, get_string('addmoreanswerblanks', 'qtype_calculated')); - $anslengrp = array(); - $anslengrp[] =& $mform->createElement('select', 'correctanswerlength[0]', get_string('correctanswershows', 'qtype_calculated'), range(0, 9)); - $mform->setDefault('correctanswerlength[0]', 2); - - $answerlengthformats = array('1' => get_string('decimalformat', 'quiz'), '2' => get_string('significantfiguresformat', 'quiz')); - $anslengrp[] =& $mform->createElement('select', 'correctanswerformat[0]', get_string('correctanswershowsformat', 'qtype_calculated'), $answerlengthformats); - $mform->addGroup($anslengrp, 'anslengrp', get_string('correctanswershows', 'qtype_calculated'), null, false); - - $mform->addElement('htmleditor', 'feedback[0]', get_string('feedback', 'quiz')); - $mform->setType('feedback', PARAM_RAW); - -//------------------------------------------------------------------------------------------ - $repeated = array(); + $repeated = array(); $repeated[] =& $mform->createElement('header', 'unithdr', get_string('unithdr', 'qtype_numerical', '{no}')); $repeated[] =& $mform->createElement('text', 'unit', get_string('unit', 'quiz')); @@ -150,7 +116,7 @@ class question_edit_calculated_form extends question_edit_form { } $units = array_values($question->options->units); // make sure the default unit is at index 0 - usort($units, create_function('$a, $b', // make sure the default unit is at index 0 + usort($units, create_function('$a, $b', 'if (1.0 === (float)$a->multiplier) { return -1; } else '. 'if (1.0 === (float)$b->multiplier) { return 1; } else { return 0; }')); if (count($units)) { @@ -194,22 +160,21 @@ class question_edit_calculated_form extends question_edit_form { $errors = array(); $answers = $data['answers']; $answercount = 0; - //check grades - /*$totalfraction = 0; - $maxfraction = -1; */ + $maxgrade = false; $possibledatasets = $this->qtypeobj->find_dataset_names($data['questiontext']); $mandatorydatasets = array(); foreach ($answers as $key => $answer){ - $mandatorydatasets += $this->qtypeobj->find_dataset_names($data['questiontext']); + $mandatorydatasets += $this->qtypeobj->find_dataset_names($answer); } - if (count($possibledatasets) == 0 && count($mandatorydatasets )==0){ - $errors['questiontext']=get_string('atleastonewildcard', 'qtype_datasetdependent'); + if ( count($mandatorydatasets )==0){ + // $errors['questiontext']=get_string('atleastonewildcard', 'qtype_datasetdependent'); foreach ($answers as $key => $answer){ $errors['answers['.$key.']'] = get_string('atleastonewildcard', 'qtype_datasetdependent'); } } foreach ($answers as $key => $answer){ //check no of choices + // the * for everykind of answer not actually implemented $trimmedanswer = trim($answer); if (($trimmedanswer!='')||$answercount==0){ $eqerror = qtype_calculated_find_formula_errors($trimmedanswer); @@ -225,6 +190,9 @@ class question_edit_calculated_form extends question_edit_form { if (!is_numeric($data['tolerance'][$key])){ $errors['tolerance['.$key.']'] = get_string('mustbenumeric', 'qtype_calculated'); } + if ($data['fraction'][$key] == 1) { + $maxgrade = true; + } $answercount++; } @@ -276,6 +244,9 @@ class question_edit_calculated_form extends question_edit_form { if ($answercount==0){ $errors['answers[0]'] = get_string('atleastoneanswer', 'qtype_calculated'); } + if ($maxgrade == false) { + $errors['fraction[0]'] = get_string('fractionsnomax', 'question'); + } return $errors; } diff --git a/question/type/calculated/questiontype.php b/question/type/calculated/questiontype.php index 11c4a31dd3..607e02d78c 100644 --- a/question/type/calculated/questiontype.php +++ b/question/type/calculated/questiontype.php @@ -19,35 +19,49 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype function get_question_options(&$question) { // First get the datasets and default options - if(false === parent::get_question_options($question)) { + global $CFG; + if (!$question->options->answers = get_records_sql( + "SELECT a.*, c.tolerance, c.tolerancetype, c.correctanswerlength, c.correctanswerformat " . + "FROM {$CFG->prefix}question_answers a, " . + " {$CFG->prefix}question_calculated c " . + "WHERE a.question = $question->id " . + "AND a.id = c.answer ". + "ORDER BY a.id ASC")) { + notify('Error: Missing question answer!'); return false; } - if (!$options = get_record('question_calculated', 'question', $question->id)) { +/* + if(false === parent::get_question_options($question)) { + return false; + } + + if (!$options = get_records('question_calculated', 'question', $question->id)) { notify("No options were found for calculated question #{$question->id}! Proceeding with defaults."); - $options = new stdClass; + // $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 // the values in $question->options instead. - foreach ($question->options->answers as $key => $answer) { + foreach ($question->options->answers as $key => $answer) { $answer = &$question->options->answers[$key]; // for PHP 4.x - $answer->calcid = $options->id; + $answer->calcid = $options->id; $answer->tolerance = $options->tolerance; $answer->tolerancetype = $options->tolerancetype; $answer->correctanswerlength = $options->correctanswerlength; $answer->correctanswerformat = $options->correctanswerformat; - } + }*/ $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); } @@ -106,88 +120,93 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype //$options = $question->subtypeoptions; // Get old answers: global $CFG; - if (!$oldanswers = get_records_sql( - "SELECT a.*, c.tolerance, c.tolerancetype, - c.correctanswerlength, c.id AS calcid - FROM {$CFG->prefix}question_answers a, - {$CFG->prefix}question_calculated c - WHERE c.question = $question->id AND a.id = c.answer - ORDER BY a.id ASC")) { + + // Get old versions of the objects + if (!$oldanswers = get_records('question_answers', 'question', $question->id, 'id ASC')) { $oldanswers = array(); } - // Update with new answers - $answerrec->question = $calcrec->question = $question->id; - $n = count($question->answers); - for ($i = 0; $i < $n; $i++) { - $answerrec->answer = $question->answers[$i]; - $answerrec->fraction = isset($question->fraction[$i]) - ? $question->fraction[$i] : 1.0; - $answerrec->feedback = isset($question->feedback[$i]) - ? $question->feedback[$i] : ''; - $calcrec->tolerance = isset($question->tolerance[$i]) - ? $question->tolerance[$i] - : $question->tolerance[0]; - $calcrec->tolerancetype = isset($question->tolerancetype[$i]) - ? $question->tolerancetype[$i] - : $question->tolerancetype[0]; - $calcrec->correctanswerlength = isset($question->correctanswerlength[$i]) - ? $question->correctanswerlength[$i] - : $question->correctanswerlength[0]; - $calcrec->correctanswerformat = isset($question->correctanswerformat[$i]) - ? $question->correctanswerformat[$i] - : $question->correctanswerformat[0]; - if ($oldanswer = array_shift($oldanswers)) { - // Reuse old records: - $calcrec->answer = $answerrec->id = $oldanswer->id; - $calcrec->id = $oldanswer->calcid; - if (!update_record('question_answers', $answerrec)) { - error("Unable to update answer for calculated question #{$question->id}!"); - } else { - // notify("Answer updated successfully for calculated question $question->name"); - } - if (!update_record('question_calculated', $calcrec)) { - error("Unable to update options for calculated question #{$question->id}!"); - } else { - // notify("Options updated successfully for calculated question $question->name"); + if (!$oldoptions = get_records('question_calculated', 'question', $question->id, 'answer ASC')) { + $oldoptions = array(); + } + // Save the units. + // Save units + $virtualqtype = $this->get_virtual_qtype(); + $result = $virtualqtype->save_numerical_units($question); + if (isset($result->error)) { + return $result; + } else { + $units = &$result->units; + } + // Insert all the new answers + foreach ($question->answers as $key => $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)) { + $result->error = "Could not update question answer! (id=$answer->id)"; + return $result; + } + } else { // This is a completely new answer + if (! $answer->id = insert_record("question_answers", $answer)) { + $result->error = "Could not insert question answer!"; + return $result; + } } - } else { - unset($answerrec->id); - unset($calcrec->id); - if (!($calcrec->answer = insert_record('question_answers', - $answerrec))) { - error("Unable to insert answer for calculated question $question->id"); - } else { - // notify("Answer inserted successfully for calculated question $question->id"); + + // Set up the options object + if (!$options = array_shift($oldoptions)) { + $options = new stdClass; } - if (!insert_record('question_calculated', $calcrec)) { - error("Unable to insert options calculared question $question->id"); - } else { - // notify("Options inserted successfully for calculated question $question->id"); + $options->question = $question->id; + $options->answer = $answer->id; + $options->tolerance = trim($question->tolerance[$key]); + $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)) { + $result->error = "Could not update question calculated options! (id=$options->id)"; + return $result; + } + } else { // new options + if (! insert_record('question_calculated', $options)) { + $result->error = "Could not insert question calculated options!"; + return $result; + } } } } - - // Delete excessive records: - foreach ($oldanswers as $oldanswer) { - if (!delete_records('question_answers', 'id', $oldanswer->id)) { - error("Unable to delete old answers for calculated question $question->id"); - } else { - // notify("Old answers deleted successfully for calculated question $question->id"); + // delete old answer records + if (!empty($oldanswers)) { + foreach($oldanswers as $oa) { + delete_records('question_answers', 'id', $oa->id); } - if (!delete_records('question_calculated', 'id', $oldanswer->calcid)) { - error("Unable to delete old options for calculated question $question->id"); - } else { - // notify("Old options deleted successfully for calculated question $question->id"); + } + + // delete old answer records + if (!empty($oldoptions)) { + foreach($oldoptions as $oo) { + delete_records('question_calculated', 'id', $oo->id); } } - // Save units - $virtualqtype = $this->get_virtual_qtype(); - $virtualqtype->save_numerical_units($question); + if( isset($question->import_process)&&$question->import_process){ $this->import_datasets($question); } + // Report any problems. + if (!empty($result->notice)) { + return $result; + } return true; } @@ -258,7 +277,8 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype $question->options->answers = array(); foreach ($form->answers as $key => $answer) { $a->answer = trim($form->answer[$key]); - $a->tolerance = $form->tolerance[$key]; + $a->fraction = $form->fraction[$key];//new + $a->tolerance = $form->tolerance[$key]; $a->tolerancetype = $form->tolerancetype[$key]; $a->correctanswerlength = $form->correctanswerlength[$key]; $a->correctanswerformat = $form->correctanswerformat[$key]; @@ -339,39 +359,52 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype $unit = $virtualqtype->get_default_numerical_unit($question); // We modify the question to look like a numerical question - $numericalquestion = clone($question); - $numericalquestion->options = clone($question->options); + $numericalquestion = fullclone($question); + /* $numericalquestion->options = clone($question->options); foreach ($question->options->answers as $key => $answer) { $numericalquestion->options->answers[$key] = clone($answer); - } + }*/ foreach ($numericalquestion->options->answers as $key => $answer) { - $answer = &$numericalquestion->options->answers[$key]; // for PHP 4.x + // $answer = &$numericalquestion->options->answers[$key]; // for PHP 4.x + $answer = fullclone($numericalquestion->options->answers[$key]); $correctanswer = qtype_calculated_calculate_answer( $answer->answer, $state->options->dataset, $answer->tolerance, $answer->tolerancetype, $answer->correctanswerlength, $answer->correctanswerformat, $unit->unit); - $answer->answer = $correctanswer->answer; + $numericalquestion->options->answers[$key]->answer = $correctanswer->answer; } $numericalquestion->questiontext = parent::substitute_variables( $numericalquestion->questiontext, $state->options->dataset); $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 but not actually.. + echo "calculated question type question grade_reponse
";print_r($question);
 
         // We modify the question to look like a numerical question
-        $numericalquestion = clone($question);
+        $numericalquestion = fullclone($question);
+    /*      echo "calculated1question type question grade_reponse 
";print_r($numericalquestion);
         $numericalquestion->options = clone($question->options);
+          echo "calculated2 question type question grade_reponse 
";print_r($numericalquestion);
         foreach ($question->options->answers as $key => $answer) {
             $numericalquestion->options->answers[$key] = clone($answer);
         }
-        foreach ($numericalquestion->options->answers as $key => $answer) {
-            $answer = &$numericalquestion->options->answers[$key]; // for PHP 4.x
-            $answer->answer = $this->substitute_variables($answer->answer,
+        */
+           echo "calculated3question type question grade_reponse 
";print_r($numericalquestion);
+       foreach ($numericalquestion->options->answers as $key => $answer) {
+            $answer = $numericalquestion->options->answers[$key]->answer; // for PHP 4.x
+           echo "calculated3aquestion type question grade_reponse answer $key
";print_r($answer);
+           echo "calculated3aquestion type question grade_reponse numerical
";print_r($numericalquestion);
+          $numericalquestion->options->answers[$key]->answer = $this->substitute_variables($answer,
              $state->options->dataset);
-        }
-        return parent::grade_responses($numericalquestion, $state, $cmoptions);
+            echo "calculated3aquestion type question grade_reponse answer after
";print_r($answer);
+           echo "calculated3aquestion type question grade_reponse numerical after
";print_r($numericalquestion);
+       }
+          echo "calculated4question type question grade_reponse 
";print_r($numericalquestion);
+         $virtualqtype = $this->get_virtual_qtype();
+        return $virtualqtype->grade_responses($numericalquestion, $state, $cmoptions) ;
+      
+      //  return parent::grade_responses($numericalquestion, $state, $cmoptions);
     }
 
     function response_summary($question, $state, $length=80) {
@@ -393,7 +426,12 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype
             $answer->answer = $this->substitute_variables($answer->answer,
              $state->options->dataset);
         }
-        return parent::check_response($numericalquestion, $state);
+                                   echo "calculated numrericalquestion check_reponse 
";print_r($numericalquestion);
+                                   echo "calculated numrericalquestion 
";print_r($state);
+        $virtualqtype = $this->get_virtual_qtype();
+        return $virtualqtype->check_response($numericalquestion, $state) ;
+
+   //     return parent::check_response($numericalquestion, $state);
     }
 
     // ULPGC ecastro
@@ -415,7 +453,7 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype
              $state->options->dataset);
             // apply_unit
         }
-        $numericalquestion->questiontext = parent::substitute_variables(
+        $numericalquestion->questiontext = $this->substitute_variables(
                                   $numericalquestion->questiontext, $state->options->dataset);
         $responses = $virtualqtype->get_all_responses($numericalquestion, $state);
         $response = reset($responses->responses);