From 01533e9ccebbbbd7262f2c16479f785967945c45 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Fri, 1 Jul 2011 09:14:56 +0100 Subject: [PATCH] MDL-28138 fix calculated-specific format float function Sadly this has to be done in question.php and in two places in the ugprade code :-(. --- question/type/calculated/db/upgradelib.php | 17 ++++++++++--- question/type/calculated/question.php | 9 ++++--- .../simpletest/testvariablesubstituter.php | 24 +++++++++++++++++++ .../type/calculatedmulti/db/upgradelib.php | 17 ++++++++++--- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/question/type/calculated/db/upgradelib.php b/question/type/calculated/db/upgradelib.php index c3db14ca4c3..d4c841808c3 100644 --- a/question/type/calculated/db/upgradelib.php +++ b/question/type/calculated/db/upgradelib.php @@ -203,18 +203,29 @@ class qtype_calculated_qe2_attempt_updater extends question_qtype_attempt_update } /** + * This function should be identical to + * {@link qtype_calculated_variable_substituter::format_float()}. Except that + * we do not try to do locale-aware replacement of the decimal point. + * + * Having to copy it here is a pain, but it is the standard rule about not + * using library code (which may change in future) in upgrade code, which + * exists at a point in time. + * * Display a float properly formatted with a certain number of decimal places. - * @param $x + * @param number $x the number to format + * @param int $length restrict to this many decimal places or significant + * figures. If null, the number is not rounded. + * @param int format 1 => decimalformat, 2 => significantfigures. + * @return string formtted number. */ public function format_float($x, $length = null, $format = null) { if (!is_null($length) && !is_null($format)) { if ($format == 1) { // Decimal places. $x = sprintf('%.' . $length . 'F', $x); - } else if ($format == 1) { + } else if ($format == 2) { // Significant figures. $x = sprintf('%.' . $length . 'g', $x); - $x = str_replace(',', '.', $x); } } return $x; diff --git a/question/type/calculated/question.php b/question/type/calculated/question.php index b89b9c8a6f3..bb59e1ec9cf 100644 --- a/question/type/calculated/question.php +++ b/question/type/calculated/question.php @@ -307,17 +307,20 @@ class qtype_calculated_variable_substituter { /** * Display a float properly formatted with a certain number of decimal places. - * @param $x + * @param number $x the number to format + * @param int $length restrict to this many decimal places or significant + * figures. If null, the number is not rounded. + * @param int format 1 => decimalformat, 2 => significantfigures. + * @return string formtted number. */ public function format_float($x, $length = null, $format = null) { if (!is_null($length) && !is_null($format)) { if ($format == 1) { // Decimal places. $x = sprintf('%.' . $length . 'F', $x); - } else if ($format == 1) { + } else if ($format == 2) { // Significant figures. $x = sprintf('%.' . $length . 'g', $x); - $x = str_replace(',', '.', $x); } } return str_replace('.', $this->decimalpoint, $x); diff --git a/question/type/calculated/simpletest/testvariablesubstituter.php b/question/type/calculated/simpletest/testvariablesubstituter.php index 63e1be10a57..9c1005e651c 100644 --- a/question/type/calculated/simpletest/testvariablesubstituter.php +++ b/question/type/calculated/simpletest/testvariablesubstituter.php @@ -90,4 +90,28 @@ class qtype_calculated_variable_substituter_test extends UnitTestCase { $this->assertEqual('phi (1,61803399) + pi (3,14159265) = 4,75962664', $vs->replace_expressions_in_text('phi ({phi}) + pi ({pi}) = {={phi} + {pi}}')); } + + public function test_format_float_dot() { + $vs = new qtype_calculated_variable_substituter(array('a' => -1, 'b' => 2), '.'); + $this->assertIdentical('0.12345', $vs->format_float(0.12345)); + + $this->assertIdentical('0', $vs->format_float(0.12345, 0, 1)); + $this->assertIdentical('0.12', $vs->format_float(0.12345, 2, 1)); + $this->assertIdentical('0.1235', $vs->format_float(0.12345, 4, 1)); + + $this->assertIdentical('0.12', $vs->format_float(0.12345, 2, 2)); + $this->assertIdentical('0.0012', $vs->format_float(0.0012345, 4, 1)); + } + + public function test_format_float_comma() { + $vs = new qtype_calculated_variable_substituter(array('a' => -1, 'b' => 2), ','); + $this->assertIdentical('0,12345', $vs->format_float(0.12345)); + + $this->assertIdentical('0', $vs->format_float(0.12345, 0, 1)); + $this->assertIdentical('0,12', $vs->format_float(0.12345, 2, 1)); + $this->assertIdentical('0,1235', $vs->format_float(0.12345, 4, 1)); + + $this->assertIdentical('0,12', $vs->format_float(0.12345, 2, 2)); + $this->assertIdentical('0,0012', $vs->format_float(0.0012345, 4, 1)); + } } diff --git a/question/type/calculatedmulti/db/upgradelib.php b/question/type/calculatedmulti/db/upgradelib.php index 8dd51ba55b6..d2b131c0240 100644 --- a/question/type/calculatedmulti/db/upgradelib.php +++ b/question/type/calculatedmulti/db/upgradelib.php @@ -227,18 +227,29 @@ class qtype_calculatedmulti_qe2_attempt_updater extends question_qtype_attempt_u } /** + * This function should be identical to + * {@link qtype_calculated_variable_substituter::format_float()}. Except that + * we do not try to do locale-aware replacement of the decimal point. + * + * Having to copy it here is a pain, but it is the standard rule about not + * using library code (which may change in future) in upgrade code, which + * exists at a point in time. + * * Display a float properly formatted with a certain number of decimal places. - * @param $x + * @param number $x the number to format + * @param int $length restrict to this many decimal places or significant + * figures. If null, the number is not rounded. + * @param int format 1 => decimalformat, 2 => significantfigures. + * @return string formtted number. */ public function format_float($x, $length = null, $format = null) { if (!is_null($length) && !is_null($format)) { if ($format == 1) { // Decimal places. $x = sprintf('%.' . $length . 'F', $x); - } else if ($format == 1) { + } else if ($format == 2) { // Significant figures. $x = sprintf('%.' . $length . 'g', $x); - $x = str_replace(',', '.', $x); } } return $x;