Permalink
Browse files

MDL-31680 Correcting the format of calculated types correct response

  • Loading branch information...
1 parent b6f8a93 commit 9ddb8a56a366ce438a9afcbe505323e6225fbd9a @ppichet ppichet committed Jun 6, 2013
@@ -139,7 +139,7 @@ protected function definition() {
$name = get_string('wildcard', 'qtype_calculated', $datasetdef->name);
}
$mform->addElement('text', "number[$j]", $name);
- $mform->setType("number[$j]", PARAM_FLOAT);
+ $mform->setType("number[$j]", PARAM_RAW); // This parameter will be validated in validation().
$this->qtypeobj->custom_generator_tools_part($mform, $idx, $j);
$idx++;
$mform->addElement('hidden', "definition[$j]");
@@ -161,11 +161,10 @@ protected function definition() {
$answers = fullclone($this->question->options->answers);
$key1 =1;
foreach ($answers as $key => $answer) {
- if ('' === $answer->answer) {
- // Do nothing.
- } else if ('*' === $answer->answer) {
+ $ans = shorten_text($answer->answer, 17, true);
+ if ($ans === '*') {
$mform->addElement('static',
- 'answercomment[' . ($this->noofitems+$key1) . ']', $answer->answer);
+ 'answercomment[' . ($this->noofitems+$key1) . ']', $ans);
$mform->addElement('hidden', 'tolerance['.$key.']', '');
$mform->setType('tolerance['.$key.']', PARAM_RAW);
$mform->setAdvanced('tolerance['.$key.']', true);
@@ -178,9 +177,9 @@ protected function definition() {
$mform->addElement('hidden', 'correctanswerformat['.$key.']', '');
$mform->setType('correctanswerformat['.$key.']', PARAM_RAW);
$mform->setAdvanced('correctanswerformat['.$key.']', true);
- } else {
+ } else if ( $ans !== '' ) {
$mform->addElement('static', 'answercomment[' . ($this->noofitems+$key1) . ']',
- $answer->answer);
+ $ans);
$mform->addElement('text', 'tolerance['.$key.']',
get_string('tolerance', 'qtype_calculated'));
$mform->setType('tolerance['.$key.']', PARAM_RAW);
@@ -290,7 +289,7 @@ protected function definition() {
} else {
$mform->addElement('hidden', "number[$j]" , '');
}
- $mform->setType("number[$j]", PARAM_FLOAT);
+ $mform->setType("number[$j]", PARAM_RAW); // This parameter will be validated in validation().
$mform->addElement('hidden', "itemid[$j]");
$mform->setType("itemid[$j]", PARAM_INT);
@@ -312,11 +311,11 @@ protected function definition() {
'Formulas {=..} in question text');
foreach ($textequations as $key => $equation) {
if ($formulaerrors = qtype_calculated_find_formula_errors($equation)) {
- $str=$formulaerrors;
+ $str = $formulaerrors;
} else {
eval('$str = '.$equation.';');
}
-
+ $equation = shorten_text($equation, 17, true);
$mform->addElement('static', "textequation", "{=$equation}", "=".$str);
}
}
@@ -485,19 +484,18 @@ public function validation($data, $files) {
$numbers = $data['number'];
foreach ($numbers as $key => $number) {
if (! is_numeric($number)) {
- if (stristr($number, ', ')) {
- $errors['number['.$key.']'] = get_string(
- 'The , cannot be used, use . as in 0.013 or 1.3e-2', 'qtype_calculated');
+ if (stristr($number, ',')) {
+ $errors['number['.$key.']'] = get_string('nocommaallowed', 'qtype_calculated');
} else {
- $errors['number['.$key.']'] = get_string(
- 'This is not a valid number', 'qtype_calculated');
+ $errors['number['.$key.']'] = get_string('notvalidnumber', 'qtype_calculated');
}
} else if (stristr($number, 'x')) {
- $errors['number['.$key.']'] = get_string(
- 'Hexadecimal format (i.e. 0X12d) is not allowed', 'qtype_calculated');
+ $a = new stdClass();
+ $a->name = '';
+ $a->value = $number;
+ $errors['number['.$key.']'] = get_string('hexanotallowed', 'qtype_calculated', $a);
} else if (is_nan($number)) {
- $errors['number['.$key.']'] = get_string(
- 'is a NAN number', 'qtype_calculated');
+ $errors['number['.$key.']'] = get_string('notvalidnumber', 'qtype_calculated');
}
}
return $errors;
@@ -86,6 +86,25 @@ public function get_variants_selection_seed() {
return parent::get_variants_selection_seed();
}
}
+
+ public function get_correct_response() {
+ $answer = $this->get_correct_answer();
+ if (!$answer) {
+ return array();
+ }
+
+ $response = array('answer' => $this->vs->format_float($answer->answer,
+ $answer->correctanswerlength, $answer->correctanswerformat));
+
+ if ($this->has_separate_unit_field()) {
+ $response['unit'] = $this->ap->get_default_unit();
+ } else if ($this->unitdisplay == qtype_numerical::UNITINPUT) {
+ $response['answer'] = $this->ap->add_unit($response['answer']);
+ }
+
+ return $response;
+ }
+
}
@@ -318,9 +337,67 @@ public function format_float($x, $length = null, $format = null) {
if ($format == '1' ) { // Answer is to have $length decimals.
// Decimal places.
$x = sprintf('%.' . $length . 'F', $x);
- } else if ($format == 2) {
- // Significant figures.
- $x = sprintf('%.' . $length . 'g', $x);
+
+ } else if ($x) { // Significant figures does only apply if the result is non-zero.
+ $answer = $x;
+ // 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, $length);
+
+ // If we rounded up to 1.0, place the answer back into 0.[1-9][0-9]* format.
+ if ($answer >= 1) {
+ ++$p10;
+ $answer /= 10;
+ }
+
+ // Have the answer written on a suitable format.
+ // Either scientific or plain numeric.
+ if (-2 > $p10 || 4 < $p10) {
+ // Use scientific format.
+ $exponent = 'e'.--$p10;
+ $answer *= 10;
+ if (1 == $length) {
+ $x = $sign.$answer.$exponent;
+ } else {
+ // Attach additional zeros at the end of $answer.
+ $answer .= (1 == strlen($answer) ? '.' : '')
+ . '00000000000000000000000000000000000000000x';
+ $x = $sign
+ .substr($answer, 0, $length +1).$exponent;
+ }
+ } else {
+ // Stick to plain numeric format.
+ $answer *= "1e$p10";
+ if (0.1 <= $answer / "1e$length") {
+ $x = $sign.$answer;
+ } else {
+ // Could be an idea to add some zeros here.
+ $answer .= (preg_match('~^[0-9]*$~', $answer) ? '.' : '')
+ . '00000000000000000000000000000000000000000x';
+ $oklen = $length + ($p10 < 1 ? 2-$p10 : 1);
+ $x = $sign.substr($answer, 0, $oklen);
+ }
+ }
+
+ } else {
+ $x = 0.0;
}
}
return str_replace('.', $this->decimalpoint, $x);
@@ -1032,11 +1032,8 @@ public function comment_header($question) {
$answers = $question->options->answers;
foreach ($answers as $key => $answer) {
- if (is_string($answer)) {
- $strheader .= $delimiter.$answer;
- } else {
- $strheader .= $delimiter.$answer->answer;
- }
+ $ans = shorten_text($answer->answer, 17, true);
+ $strheader .= $delimiter.$ans;
$delimiter = '<br/><br/><br/>';
}
return $strheader;
@@ -1083,10 +1080,11 @@ public function comment_on_datasetitems($qtypeobj, $questionid, $questiontext,
$comment->stranswers[$key] = $formula . ' = ' .
get_string('anyvalue', 'qtype_calculated') . '<br/><br/><br/>';
} else {
+ $formula = shorten_text($formula, 57, true);
$comment->stranswers[$key] = $formula . ' = ' . $formattedanswer->answer . '<br/>';
$correcttrue = new stdClass();
$correcttrue->correct = $formattedanswer->answer;
- $correcttrue->true = $answer->answer;
+ $correcttrue->true = '';
if ($formattedanswer->answer < $answer->min ||
$formattedanswer->answer > $answer->max) {
$comment->outsidelimit = true;
@@ -1106,57 +1104,6 @@ public function comment_on_datasetitems($qtypeobj, $questionid, $questiontext,
}
return fullclone($comment);
}
- public function multichoice_comment_on_datasetitems($questionid, $questiontext,
- $answers, $data, $number) {
- global $DB;
- $comment = new stdClass();
- $comment->stranswers = array();
- $comment->outsidelimit = false;
- $comment->answers = array();
- // Find a default unit.
- if (!empty($questionid) && $unit = $DB->get_record('question_numerical_units',
- array('question' => $questionid, 'multiplier' => 1.0))) {
- $unit = $unit->unit;
- } else {
- $unit = '';
- }
-
- $answers = fullclone($answers);
- $errors = '';
- $delimiter = ': ';
- foreach ($answers as $key => $answer) {
- $answer->answer = $this->substitute_variables($answer->answer, $data);
- // Evaluate the equations i.e {=5+4).
- $qtext = '';
- $qtextremaining = $answer->answer;
- while (preg_match('~\{=([^[:space:]}]*)}~', $qtextremaining, $regs1)) {
- $qtextsplits = explode($regs1[0], $qtextremaining, 2);
- $qtext = $qtext.$qtextsplits[0];
- $qtextremaining = $qtextsplits[1];
- if (empty($regs1[1])) {
- $str = '';
- } else {
- if ($formulaerrors = qtype_calculated_find_formula_errors($regs1[1])) {
- $str = $formulaerrors;
- } else {
- eval('$str = '.$regs1[1].';');
-
- $texteval= qtype_calculated_calculate_answer(
- $str, $data, $answer->tolerance,
- $answer->tolerancetype, $answer->correctanswerlength,
- $answer->correctanswerformat, '');
- $str = $texteval->answer;
-
- }
- }
- $qtext = $qtext.$str;
- }
- $answer->answer = $qtext.$qtextremaining;
- $comment->stranswers[$key]= $answer->answer;
-
- }
- return fullclone($comment);
- }
public function tolerance_types() {
return array(
@@ -1878,32 +1825,9 @@ function qtype_calculated_calculate_answer($formula, $individualdata,
$calculated->answer = NAN;
return $calculated;
}
- 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 (preg_match('~^(.*\\.)(.*)$~', $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;
- }
+ if ('1' == $answerformat) { // Answer is to have $answerlength decimals.
+ // Decimal places.
+ $calculated->answer = sprintf('%.' . $answerlength . 'F', $answer);
} else if ($answer) { // Significant figures does only apply if the result is non-zero.
@@ -1941,31 +1865,34 @@ function qtype_calculated_calculate_answer($formula, $individualdata,
$exponent = 'e'.--$p10;
$answer *= 10;
if (1 == $answerlength) {
- $calculated->answer = $sign.$answer.$exponent.$unit;
+ $calculated->answer = $sign.$answer.$exponent;
} else {
// Attach additional zeros at the end of $answer.
$answer .= (1 == strlen($answer) ? '.' : '')
. '00000000000000000000000000000000000000000x';
$calculated->answer = $sign
- .substr($answer, 0, $answerlength +1).$exponent.$unit;
+ .substr($answer, 0, $answerlength +1).$exponent;
}
} else {
// Stick to plain numeric format.
$answer *= "1e$p10";
if (0.1 <= $answer / "1e$answerlength") {
- $calculated->answer = $sign.$answer.$unit;
+ $calculated->answer = $sign.$answer;
} else {
// Could be an idea to add some zeros here.
$answer .= (preg_match('~^[0-9]*$~', $answer) ? '.' : '')
. '00000000000000000000000000000000000000000x';
$oklen = $answerlength + ($p10 < 1 ? 2-$p10 : 1);
- $calculated->answer = $sign.substr($answer, 0, $oklen).$unit;
+ $calculated->answer = $sign.substr($answer, 0, $oklen);
}
}
} else {
$calculated->answer = 0.0;
}
+ if ($unit != '') {
+ $calculated->answer = $calculated->answer . ' ' . $unit;
+ }
// Return the result.
return $calculated;
@@ -36,4 +36,19 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class qtype_calculated_renderer extends qtype_numerical_renderer {
+ public function correct_response(question_attempt $qa) {
+ $question = $qa->get_question();
+ $answer = $question->get_correct_response();
+ if (!$answer) {
+ return '';
+ }
+
+ $response = $answer['answer'];
+ if ($question->unitdisplay != qtype_numerical::UNITNONE && $question->unitdisplay != qtype_numerical::UNITINPUT) {
+ $response = $question->ap->add_unit($response);
+ }
+
+ return get_string('correctansweris', 'qtype_shortanswer', $response);
+ }
+
}
@@ -28,6 +28,8 @@
global $CFG;
require_once($CFG->dirroot . '/question/type/calculated/question.php');
+require_once($CFG->dirroot . '/question/type/numerical/question.php');
+require_once($CFG->dirroot . '/question/type/numerical/questiontype.php');
require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
@@ -75,6 +77,8 @@ public function make_calculated_question_sum() {
$q->datasetloader = new qtype_calculated_test_dataset_loader(0, array(
array('a' => 1, 'b' => 5),
array('a' => 3, 'b' => 4),
+ array('a' => 3, 'b' => 0.01416),
+ array('a' => 31, 'b' => 0.01416),
));
return $q;
Oops, something went wrong.

0 comments on commit 9ddb8a5

Please sign in to comment.