From 180bcb27405d684e33cfa0425c6e0362fdb0524f Mon Sep 17 00:00:00 2001 From: kaipe Date: Sun, 5 Dec 2004 13:02:49 +0000 Subject: [PATCH] New feature that makes it possible to specify the number of decimals for the correct answer in calculated questions as well as some minor refactoring and debugging. --- lang/en/quiz.php | 4 + .../questiontypes/calculated/calculated.html | 20 +++-- .../questiontypes/calculated/editquestion.php | 86 ++++++++++++++----- .../questiontypes/calculated/questiontype.php | 40 +++++++-- .../datasetdependent/questiondatasets.html | 14 +-- 5 files changed, 118 insertions(+), 46 deletions(-) diff --git a/lang/en/quiz.php b/lang/en/quiz.php index 6e09043f40..f793774606 100644 --- a/lang/en/quiz.php +++ b/lang/en/quiz.php @@ -52,6 +52,7 @@ $string['correctanswer'] = 'Correct answer'; $string['correctanswerformula'] = 'Correct Answer Formula'; $string['correctanswerlength'] = 'Significant Figures'; $string['correctanswers'] = 'Correct answers'; +$string['correctanswershows'] = 'Correct answer shows'; $string['corrresp'] = 'Correct Response'; $string['countdown'] = 'Countdown'; $string['countdownfinished'] = 'The quiz is closing, you should submit your answers now.'; @@ -63,6 +64,7 @@ $string['custom'] = 'Custom format'; $string['datasetdefinitions'] = 'Reusable dataset definitions for category $a'; $string['datasetnumber'] = 'Number'; $string['daysavailable'] = 'Days available'; +$string['decimalformat'] = 'decimals'; $string['decimals'] = ' with $a '; $string['default'] = 'Default'; $string['defaultgrade'] = 'Default question grade'; @@ -238,6 +240,7 @@ $string['showcorrectanswer'] = 'In feedback, show correct answers?'; $string['showfeedback'] = 'After answering, show feedback?'; $string['shuffleanswers'] = 'Shuffle answers'; $string['shufflequestions'] = 'Shuffle questions'; +$string['significantfiguresformat'] = 'significant figures'; $string['significantfigures'] = ' with $a '; $string['subneterror'] = 'Sorry, this quiz has been locked so that it is only accessible from certain locations. Currently your computer is not one of those allowed to use this quiz.'; $string['substitutedby'] = 'will be substituted by'; @@ -267,5 +270,6 @@ $string['withsummary'] = 'with Summary Statistics'; $string['wronggrade'] = 'Wrong grade (after line $a) : '; $string['xml'] = 'Moodle XML format'; $string['yourfinalgradeis'] = 'Your final grade for this quiz is $a'; +$string['zerosignificantfiguresnotallowed'] = 'The correct answer cannot have zero significant figures!'; ?> diff --git a/mod/quiz/questiontypes/calculated/calculated.html b/mod/quiz/questiontypes/calculated/calculated.html index 4a2a264fb2..397b690e56 100644 --- a/mod/quiz/questiontypes/calculated/calculated.html +++ b/mod/quiz/questiontypes/calculated/calculated.html @@ -88,14 +88,18 @@ -: +: - '1', '2' => '2', '3' => '3', - '4' => '4', '5' => '5', '6' => '6', - '7' => '7', '8' => '8', '9' => '9', - '10' => '10'), + ' 0 ', + '1' => ' 1 ', '2' => ' 2 ', '3' => ' 3 ', + '4' => ' 4 ', '5' => ' 5 ', '6' => ' 6 ', + '7' => ' 7 ', '8' => ' 8 ', '9' => ' 9 '), 'correctanswerlength[]', $answers[0]->correctanswerlength, false); ?> + get_string('decimalformat', 'quiz'), + '2' => get_string('significantfiguresformat', 'quiz')), + 'correctanswerformat[]', + $answers[0]->correctanswerformat, false); ?> @@ -158,7 +162,7 @@ function determineMinAndMax() { return false; /* It could perhaps be an idea to parse the formula here * but as it is necessary at the server anyway, we can - * leave like this for the moment. */ + * it leave like this for the moment. */ } else if (''!=defaultunit.value && !isNaN(defaultunit.value)) { alert(''); @@ -166,6 +170,10 @@ function determineMinAndMax() { } else if (isNaN(tolerance0.value)) { alert(''); return false; + } else if ('2' == document.theform['correctanswerformat[]'].value + && '0' == document.theform['correctanswerlength[]'].value) { + alert(''); + return false; } else { return true; } diff --git a/mod/quiz/questiontypes/calculated/editquestion.php b/mod/quiz/questiontypes/calculated/editquestion.php index f8da530516..4a5ffdbaa6 100644 --- a/mod/quiz/questiontypes/calculated/editquestion.php +++ b/mod/quiz/questiontypes/calculated/editquestion.php @@ -36,9 +36,15 @@ if ($form) { // Let's trust the drop down menus. $answers[0]->tolerancetype = array_shift($form->tolerancetype); - $answers[0]->correctanswerlength = array_shift($form->correctanswerlength); $answers[0]->fraction = array_shift($form->fraction); + $answers[0]->correctanswerlength = array_shift($form->correctanswerlength); + $answers[0]->correctanswerformat = array_shift($form->correctanswerformat); + + 2 == $answers[0]->correctanswerformat + and 0 == $answers[0]->correctanswerlength + and $calculatedmessages[]=get_string('zerosignificantfiguresnotallowed','quiz'); + // Fill with remaining answers, in case calculated.html // supports multiple formulas. $i = 1; @@ -50,6 +56,8 @@ if ($form) { $answers[$i]->tolerancetype = $form->tolerancetype[$key]; $answers[$i]->correctanswerlength = $form->correctanswerlength[$key]; + $answers[$i]->correctanswerformat = + $form->correctanswerformat[$key]; $answers[$i]->fraction = $form->fraction[$key]; $answers[$i]->feedback = $form->feedback[$key]; @@ -85,65 +93,99 @@ if ($form) { if (empty($calculatedmessages)) { - // First page calculated.html passed all right! + /*First page in the question wizard (calculated.html) passed all right!*/ if (!empty($form->dataset)) { - // Dataset definitions have been set - // Save question! + /* Second page in the question wizard has also passed all right */ + + /***** Save question! ... ****/ $subtypeoptions->answers = $answers; $subtypeoptions->units = $units; $question = $qtypeobj->save_question ($question, $form, $course, $subtypeoptions); + + /***** ... and continue to the dataset item editing: *****/ require("$CFG->dirroot/mod/quiz/questiontypes/datasetdependent/datasetitems.php"); exit(); - } else { - $datasetmessage = ''; } - // Now continue by preparing for the second page questiondatasets.html + /***** Now continue by preparing for the second page ****** + ***** in the question wizard: "questiondatasets.html" ******/ + $datasetmessage = ''; + + /*** Answer information is not to be shown ***/ + $hiddeninputnames= array(); + $hiddeninputvalues= array(); + foreach ($answers as $answer) { + $hiddeninputnames[] = 'answer[]'; + $hiddeninputvalues[] = $answer->answer; + $hiddeninputnames[] = 'fraction[]'; + $hiddeninputvalues[] = $answer->fraction; + $hiddeninputnames[] = 'feedback[]'; + $hiddeninputvalues[] = $answer->feedback; + $hiddeninputnames[] = 'tolerance[]'; + $hiddeninputvalues[] = $answer->tolerance; + $hiddeninputnames[] = 'tolerancetype[]'; + $hiddeninputvalues[] = $answer->tolerancetype; + $hiddeninputnames[] = 'correctanswerlength[]'; + $hiddeninputvalues[] = $answer->correctanswerlength; + $hiddeninputnames[] = 'correctanswerformat[]'; + $hiddeninputvalues[] = $answer->correctanswerformat; + } + foreach ($units as $unit) { + $hiddeninputnames[] = 'unit[]'; + $hiddeninputvalues[] = $unit->unit; + $hiddeninputnames[] = 'multiplier[]'; + $hiddeninputvalues[] = $unit->multiplier; + } - $possibledatasets = $qtypeobj->find_dataset_names( - $question->questiontext); - + /*** Determine possible and mandatory datasets... ***/ + $possibledatasets = $qtypeobj->find_dataset_names($question->questiontext); $mandatorydatasets = array(); foreach ($answers as $answer) { $mandatorydatasets += $qtypeobj ->find_dataset_names($answer->answer); } - $datasets = $qtypeobj->construct_dataset_menus( $question, $mandatorydatasets, $possibledatasets); + + /*** Print the page ***/ print_heading_with_help(get_string("choosedatasetproperties", "quiz"), "questiondatasets", "quiz"); require("$CFG->dirroot/mod/quiz/questiontypes/datasetdependent/questiondatasets.html"); exit(); } } else { -// First page in question wizard - calculated.html! +/*********************************************************/ +/***** First page in question wizard - calculated.html! **/ +/*********************************************************/ // The layout of the editing page will only support // one formula alternative for calculated questions. // However, the code behind supports up to six formulas // and the database store and attempt/review framework // does not have any limit. - if (!empty($question->id)) { - $answersraw= $qtypeobj->get_answers($question); - } $answers= array(); for ($i=0; $i<6; $i++) { - // Make answer slots with default values + /*** Make answer slots with default values ***/ $answers[$i]->answer = ""; $answers[$i]->feedback = ""; $answers[$i]->fraction = "1.0"; $answers[$i]->tolerance = "0.01"; $answers[$i]->tolerancetype = "1"; - $answers[$i]->correctanswerlength = "2"; + $answers[$i]->correctanswerlength = "2"; // Defaults to two ... + $answers[$i]->correctanswerformat = "1"; // ... decimals } - if (!empty($answersraw)) { - $i=0; - foreach ($answersraw as $answer) { - $answers[$i] = $answer; - $i++; + if (!empty($question->id)) { + $answersraw = $qtypeobj->get_answers($question); + if (!empty($answersraw)) { + /*** Overwrite the default valued answer slots *** + *** with correct values from database ***/ + $i=0; + foreach ($answersraw as $answer) { + $answers[$i] = $answer; + $i++; + } } } diff --git a/mod/quiz/questiontypes/calculated/questiontype.php b/mod/quiz/questiontypes/calculated/questiontype.php index 00ae524ac0..6cf80ded26 100644 --- a/mod/quiz/questiontypes/calculated/questiontype.php +++ b/mod/quiz/questiontypes/calculated/questiontype.php @@ -15,7 +15,7 @@ class quiz_calculated_qtype extends quiz_dataset_dependent_questiontype { function get_answers($question) { global $CFG; return get_records_sql( - "SELECT a.*, c.tolerance, c.tolerancetype, c.correctanswerlength, c.id calcid + "SELECT a.*, c.tolerance, c.tolerancetype, c.correctanswerlength, c.correctanswerformat, c.id calcid FROM {$CFG->prefix}quiz_answers a, {$CFG->prefix}quiz_calculated c WHERE c.question = $question->id AND a.id = c.answer"); @@ -126,7 +126,7 @@ class quiz_calculated_qtype extends quiz_dataset_dependent_questiontype { ++$p10; $nbr /= 10; } - // ... and have the nbr rounded of to the correct length + // ... and have the nbr rounded off to the correct length $nbr = round($nbr, $regs[4]); // Have the nbr written on a suitable format, @@ -202,7 +202,8 @@ class quiz_calculated_qtype extends quiz_dataset_dependent_questiontype { foreach ($answers as $answer) { $calculated = quiz_qtype_calculated_calculate_answer( $answer->answer, $data, $answer->tolerance, - $answer->tolerancetype, $answer->correctanswerlength, $unit); + $answer->tolerancetype, $answer->correctanswerlength, + $answer->correctanswerformat, $unit); if ($calculated->min === '') { // This should mean that something is wrong $errors .= " -$calculated->answer"; @@ -237,6 +238,7 @@ class quiz_calculated_qtype extends quiz_dataset_dependent_questiontype { $calcrec->tolerance = $newanswer->tolerance; $calcrec->tolerancetype = $newanswer->tolerancetype; $calcrec->correctanswerlength = $newanswer->correctanswerlength; + $calcrec->correctanswerformat = $newanswer->correctanswerformat; if ($oldanswer = array_shift($oldanswers)) { // Reuse old record: $calcrec->answer = $answerrec->id = $oldanswer->id; @@ -386,7 +388,8 @@ class quiz_calculated_qtype extends quiz_dataset_dependent_questiontype { $answernumerical = quiz_qtype_calculated_calculate_answer( $answer->answer, $individualdata, $answer->tolerance, $answer->tolerancetype, - $answer->correctanswerlength, $unit); + $answer->correctanswerlength, + $answer->correctanswerformat, $unit); $answers[$aid]->answer = $answernumerical->answer; $answers[$aid]->min = $answernumerical->min; $answers[$aid]->max = $answernumerical->max; @@ -410,7 +413,7 @@ class quiz_calculated_qtype extends quiz_dataset_dependent_questiontype { $QUIZ_QTYPES[CALCULATED]= new quiz_calculated_qtype(); function quiz_qtype_calculated_calculate_answer($formula, $individualdata, - $tolerance, $tolerancetype, $answerlength, $unit='') { + $tolerance, $tolerancetype, $answerlength, $answerformat='1', $unit='') { /// The return value has these properties: /// ->answer the correct answer /// ->min the lower bound for an acceptable response @@ -466,8 +469,30 @@ function quiz_qtype_calculated_calculate_answer($formula, $individualdata, $calculated->min = $min; $calculated->max = $max; - /// Adjust the number of significant digits for the correct answer - if ($answer) { // Applies only if the result is non-zero + if ('1' == $answerformat) { /* Answer is to have $answerlength decimals */ + /*** Adjust to the correct number of decimals ***/ + + $calculated->answer = round($answer, $answerlength); + + if ($answerlength) { + /* Try to include missing zeros at the end */ + + if (ereg('^(.*\\.)(.*)$', $calculated->answer, $regs)) { + $calculated->answer = $regs[1] . substr( + $regs[2] . '00000000000000000000000000000000000000000x', + 0, $answerlength) + . $unit; + } else { + $calculated->answer .= + substr('.00000000000000000000000000000000000000000x', + 0, $answerlength + 1) . $unit; + } + } else { + /* Attach unit */ + $calculated->answer .= $unit; + } + + } else if ($answer) { // Significant figures does only apply if the result is non-zero // Convert to positive answer... if ($answer < 0) { @@ -518,6 +543,7 @@ function quiz_qtype_calculated_calculate_answer($formula, $individualdata, $calculated->answer = $sign.substr($answer, 0, $oklen).$unit; } } + } else { $calculated->answer = 0.0; } diff --git a/mod/quiz/questiontypes/datasetdependent/questiondatasets.html b/mod/quiz/questiontypes/datasetdependent/questiondatasets.html index cfc6af5761..f9a19d1075 100644 --- a/mod/quiz/questiontypes/datasetdependent/questiondatasets.html +++ b/mod/quiz/questiontypes/datasetdependent/questiondatasets.html @@ -33,17 +33,9 @@ - - - - - - - - - - - + $hiddeninputname) { ?> + -- 2.39.5