MDL-28138 fix calculated-specific format float function
authorTim Hunt <T.J.Hunt@open.ac.uk>
Fri, 1 Jul 2011 08:14:56 +0000 (09:14 +0100)
committerTim Hunt <T.J.Hunt@open.ac.uk>
Fri, 1 Jul 2011 08:14:56 +0000 (09:14 +0100)
Sadly this has to be done in question.php and in two places in the ugprade code :-(.

question/type/calculated/db/upgradelib.php
question/type/calculated/question.php
question/type/calculated/simpletest/testvariablesubstituter.php
question/type/calculatedmulti/db/upgradelib.php

index c3db14c..d4c8418 100644 (file)
@@ -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;
index b89b9c8..bb59e1e 100644 (file)
@@ -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);
index 63e1be1..9c1005e 100644 (file)
@@ -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));
+    }
 }
index 8dd51ba..d2b131c 100644 (file)
@@ -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;