📄 questiontype.php
字号:
fwrite ($bf,full_tag("ANSWER",$level+1,false,$calculated->answer)); fwrite ($bf,full_tag("TOLERANCE",$level+1,false,$calculated->tolerance)); fwrite ($bf,full_tag("TOLERANCETYPE",$level+1,false,$calculated->tolerancetype)); fwrite ($bf,full_tag("CORRECTANSWERLENGTH",$level+1,false,$calculated->correctanswerlength)); fwrite ($bf,full_tag("CORRECTANSWERFORMAT",$level+1,false,$calculated->correctanswerformat)); //Now backup numerical_units $status = question_backup_numerical_units($bf,$preferences,$question,7); //Now backup required dataset definitions and items... $status = question_backup_datasets($bf,$preferences,$question,7); //End calculated data $status = $status &&fwrite ($bf,end_tag("CALCULATED",$level,true)); } //Now print question_answers $status = question_backup_answers($bf,$preferences,$question); } return $status; }/// RESTORE FUNCTIONS ///////////////// /* * Restores the data in the question * * This is used in question/restorelib.php */ function restore($old_question_id,$new_question_id,$info,$restore) { $status = true; //Get the calculated-s array $calculateds = $info['#']['CALCULATED']; //Iterate over calculateds for($i = 0; $i < sizeof($calculateds); $i++) { $cal_info = $calculateds[$i]; //traverse_xmlize($cal_info); //Debug //print_object ($GLOBALS['traverse_array']); //Debug //$GLOBALS['traverse_array']=""; //Debug //Now, build the question_calculated record structure $calculated->question = $new_question_id; $calculated->answer = backup_todb($cal_info['#']['ANSWER']['0']['#']); $calculated->tolerance = backup_todb($cal_info['#']['TOLERANCE']['0']['#']); $calculated->tolerancetype = backup_todb($cal_info['#']['TOLERANCETYPE']['0']['#']); $calculated->correctanswerlength = backup_todb($cal_info['#']['CORRECTANSWERLENGTH']['0']['#']); $calculated->correctanswerformat = backup_todb($cal_info['#']['CORRECTANSWERFORMAT']['0']['#']); ////We have to recode the answer field $answer = backup_getid($restore->backup_unique_code,"question_answers",$calculated->answer); if ($answer) { $calculated->answer = $answer->new_id; } //The structure is equal to the db, so insert the question_calculated $newid = insert_record ("question_calculated",$calculated); //Do some output if (($i+1) % 50 == 0) { if (!defined('RESTORE_SILENTLY')) { echo "."; if (($i+1) % 1000 == 0) { echo "<br />"; } } backup_flush(300); } //Now restore numerical_units $status = question_restore_numerical_units ($old_question_id,$new_question_id,$cal_info,$restore); //Now restore dataset_definitions if ($status && $newid) { $status = question_restore_dataset_definitions ($old_question_id,$new_question_id,$cal_info,$restore); } if (!$newid) { $status = false; } } 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->qtype ='calculated'; $question->qtype ='calculated'; $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->nextpageparam["forceregeneration"]= 1; $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->number = array(1 => 5.4 , 2 => 4.9); $dataset_form->itemid = array(1 => '' , 2 => ''); $dataset_form->calcdistribution = array(1 => 'uniform', 2 => 'uniform'); $dataset_form->definition = array(1 => "1-0-a", 2 => "1-0-b"); $dataset_form->nextpageparam = array('forceregeneration' => false); $dataset_form->addbutton = 1; $dataset_form->selectadd = 1; $dataset_form->courseid = $courseid; $dataset_form->cmid = 0; $dataset_form->id = $new_question->id; $this->save_dataset_items($new_question, $dataset_form); return $new_question; }}//// END OF CLASS ////////////////////////////////////////////////////////////////////////////////// INITIATION - Without this line the question type is not in use... /////////////////////////////////////////////////////////////////////////////question_register_questiontype(new question_calculated_qtype());function qtype_calculated_calculate_answer($formula, $individualdata, $tolerance, $tolerancetype, $answerlength, $answerformat='1', $unit='') {/// The return value has these properties:/// ->answer the correct answer/// ->min the lower bound for an acceptable response/// ->max the upper bound for an accetpable response /// Exchange formula variables with the correct values... global $QTYPES; $answer = $QTYPES['calculated']->substitute_variables($formula, $individualdata); if ('1' == $answerformat) { /* Answer is to have $answerlength decimals */ /*** Adjust to the correct number of decimals ***/ if (stripos($answer,'e')>0 ){ $answerlengthadd = strlen($answer)-stripos($answer,'e'); }else { $answerlengthadd = 0 ; } $calculated->answer = round(floatval($answer), $answerlength+$answerlengthadd); 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) { $answer = -$answer; $sign = '-'; } else { $sign = ''; } // Determine the format 0.[1-9][0-9]* for the answer... $p10 = 0; while ($answer < 1) { --$p10; $answer *= 10; } while ($answer >= 1) { ++$p10; $answer /= 10; } // ... and have the answer rounded of to the correct length $answer = round($answer, $answerlength); // Have the answer written on a suitable format, // Either scientific or plain numeric if (-2 > $p10 || 4 < $p10) { // Use scientific format: $eX = 'e'.--$p10; $answer *= 10; if (1 == $answerlength) { $calculated->answer = $sign.$answer.$eX.$unit; } else { // Attach additional zeros at the end of $answer, $answer .= (1==strlen($answer) ? '.' : '') . '00000000000000000000000000000000000000000x'; $calculated->answer = $sign .substr($answer, 0, $answerlength +1).$eX.$unit; } } else { // Stick to plain numeric format $answer *= "1e$p10"; if (0.1 <= $answer / "1e$answerlength") { $calculated->answer = $sign.$answer.$unit; } else { // Could be an idea to add some zeros here $answer .= (ereg('^[0-9]*$', $answer) ? '.' : '') . '00000000000000000000000000000000000000000x'; $oklen = $answerlength + ($p10 < 1 ? 2-$p10 : 1); $calculated->answer = $sign.substr($answer, 0, $oklen).$unit; } } } else { $calculated->answer = 0.0; } /// Return the result return $calculated;}function qtype_calculated_find_formula_errors($formula) {/// Validates the formula submitted from the question edit page./// Returns false if everything is alright./// Otherwise it constructs an error message // Strip away dataset names while (ereg('\\{[[:alpha:]][^>} <{"\']*\\}', $formula, $regs)) { $formula = str_replace($regs[0], '1', $formula); } // Strip away empty space and lowercase it $formula = strtolower(str_replace(' ', '', $formula)); $safeoperatorchar = '-+/*%>:^~<?=&|!'; /* */ $operatorornumber = "[$safeoperatorchar.0-9eE]"; while (ereg("(^|[$safeoperatorchar,(])([a-z0-9_]*)\\(($operatorornumber+(,$operatorornumber+((,$operatorornumber+)+)?)?)?\\)", $formula, $regs)) { switch ($regs[2]) { // Simple parenthesis case '': if ($regs[4] || strlen($regs[3])==0) { return get_string('illegalformulasyntax', 'quiz', $regs[0]); } break; // Zero argument functions case 'pi': if ($regs[3]) { return get_string('functiontakesnoargs', 'quiz', $regs[2]); } break; // Single argument functions (the most common case) case 'abs': case 'acos': case 'acosh': case 'asin': case 'asinh': case 'atan': case 'atanh': case 'bindec': case 'ceil': case 'cos': case 'cosh': case 'decbin': case 'decoct': case 'deg2rad': case 'exp': case 'expm1': case 'floor': case 'is_finite': case 'is_infinite': case 'is_nan': case 'log10': case 'log1p': case 'octdec': case 'rad2deg': case 'sin': case 'sinh': case 'sqrt': case 'tan': case 'tanh': if ($regs[4] || empty($regs[3])) { return get_string('functiontakesonearg','quiz',$regs[2]); } break; // Functions that take one or two arguments case 'log': case 'round': if ($regs[5] || empty($regs[3])) { return get_string('functiontakesoneortwoargs','quiz',$regs[2]); } break; // Functions that must have two arguments case 'atan2': case 'fmod': case 'pow': if ($regs[5] || empty($regs[4])) { return get_string('functiontakestwoargs', 'quiz', $regs[2]); } break; // Functions that take two or more arguments case 'min': case 'max': if (empty($regs[4])) { return get_string('functiontakesatleasttwo','quiz',$regs[2]); } break; default: return get_string('unsupportedformulafunction','quiz',$regs[2]); } // Exchange the function call with '1' and then chack for // another function call... if ($regs[1]) { // The function call is proceeded by an operator $formula = str_replace($regs[0], $regs[1] . '1', $formula); } else { // The function call starts the formula $formula = ereg_replace("^$regs[2]\\([^)]*\\)", '1', $formula); } } if (ereg("[^$safeoperatorchar.0-9eE]+", $formula, $regs)) { return get_string('illegalformulasyntax', 'quiz', $regs[0]); } else { // Formula just might be valid return false; }}function dump($obj) { echo "<pre>\n"; var_dump($obj); echo "</pre><br />\n";}?>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -