📄 questiontype.php
字号:
// The student did type a number, so check it with tolerances. $this->get_tolerance_interval($answer); return ($answer->min <= $response && $response <= $answer->max); } function get_correct_responses(&$question, &$state) { $correct = parent::get_correct_responses($question, $state); $unit = $this->get_default_numerical_unit($question); if (isset($correct['']) && $correct[''] != '*' && $unit) { $correct[''] .= ' '.$unit->unit; } return $correct; } // ULPGC ecastro function get_all_responses(&$question, &$state) { $result = new stdClass; $answers = array(); $unit = $this->get_default_numerical_unit($question); if (is_array($question->options->answers)) { foreach ($question->options->answers as $aid=>$answer) { $r = new stdClass; $r->answer = $answer->answer; $r->credit = $answer->fraction; $this->get_tolerance_interval($answer); if ($r->answer != '*' && $unit) { $r->answer .= ' ' . $unit->unit; } if ($answer->max != $answer->min) { $max = "$answer->max"; //format_float($answer->max, 2); $min = "$answer->min"; //format_float($answer->max, 2); $r->answer .= ' ('.$min.'..'.$max.')'; } $answers[$aid] = $r; } } $result->id = $question->id; $result->responses = $answers; return $result; } function get_tolerance_interval(&$answer) { // No tolerance if (empty($answer->tolerance)) { $answer->tolerance = 0; } // Calculate the interval of correct responses (min/max) if (!isset($answer->tolerancetype)) { $answer->tolerancetype = 2; // nominal } // We need to add a tiny fraction depending on the set precision to make the // comparison work correctly. Otherwise seemingly equal values can yield // false. (fixes bug #3225) $tolerance = (float)$answer->tolerance + ("1.0e-".ini_get('precision')); switch ($answer->tolerancetype) { case '1': case 'relative': /// Recalculate the tolerance and fall through /// to the nominal case: $tolerance = $answer->answer * $tolerance; // Do not fall through to the nominal case because the tiny fraction is a factor of the answer $tolerance = abs($tolerance); // important - otherwise min and max are swapped $max = $answer->answer + $tolerance; $min = $answer->answer - $tolerance; break; case '2': case 'nominal': $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 } 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 } $max = $answer->answer + $tolerance; $min = $answer->answer - $tolerance; break; case '3': case 'geometric': $quotient = 1 + abs($tolerance); $max = $answer->answer * $quotient; $min = $answer->answer / $quotient; break; default: error("Unknown tolerance type $answer->tolerancetype"); } $answer->min = $min; $answer->max = $max; return true; } /** * Checks if the $rawresponse has a unit and applys it if appropriate. * * @param string $rawresponse The response string to be converted to a float. * @param array $units An array with the defined units, where the * unit is the key and the multiplier the value. * @return float The rawresponse with the unit taken into * account as a float. */ function apply_unit($rawresponse, $units) { // Make units more useful $tmpunits = array(); foreach ($units as $unit) { $tmpunits[$unit->unit] = $unit->multiplier; } // remove spaces and normalise decimal places. $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]]; } else { // Valid number with invalid unit. Must be wrong. return false; } } else { // Valid number without unit. return (float)$responseparts[1]; } } // Invalid number. Must be wrong. return false; } /// BACKUP FUNCTIONS //////////////////////////// /** * Backup the data in the question * * This is used in question/backuplib.php */ function backup($bf,$preferences,$question,$level=6) { $status = true; $numericals = get_records('question_numerical', 'question', $question, 'id ASC'); //If there are numericals if ($numericals) { //Iterate over each numerical foreach ($numericals as $numerical) { $status = fwrite ($bf,start_tag("NUMERICAL",$level,true)); //Print numerical contents fwrite ($bf,full_tag("ANSWER",$level+1,false,$numerical->answer)); fwrite ($bf,full_tag("TOLERANCE",$level+1,false,$numerical->tolerance)); //Now backup numerical_units $status = question_backup_numerical_units($bf,$preferences,$question,7); $status = fwrite ($bf,end_tag("NUMERICAL",$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 numerical array if (isset($info['#']['NUMERICAL'])) { $numericals = $info['#']['NUMERICAL']; } else { $numericals = array(); } //Iterate over numericals for($i = 0; $i < sizeof($numericals); $i++) { $num_info = $numericals[$i]; //Now, build the question_numerical record structure $numerical = new stdClass; $numerical->question = $new_question_id; $numerical->answer = backup_todb($num_info['#']['ANSWER']['0']['#']); $numerical->tolerance = backup_todb($num_info['#']['TOLERANCE']['0']['#']); //We have to recode the answer field $answer = backup_getid($restore->backup_unique_code,"question_answers",$numerical->answer); if ($answer) { $numerical->answer = $answer->new_id; } //The structure is equal to the db, so insert the question_numerical $newid = insert_record ("question_numerical", $numerical); //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,$num_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) = 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.question_register_questiontype(new question_numerical_qtype());?>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -