Merge branch 'MDL-33105' of https://github.com/ppichet/moodle
authorDan Poltawski <dan@moodle.com>
Tue, 29 Jan 2013 08:31:50 +0000 (16:31 +0800)
committerDan Poltawski <dan@moodle.com>
Tue, 29 Jan 2013 08:31:50 +0000 (16:31 +0800)
question/type/numerical/question.php
question/type/numerical/questiontype.php
question/type/numerical/tests/answerprocessor_test.php

index 0e48155..2e39db1 100644 (file)
@@ -106,10 +106,6 @@ class qtype_numerical_question extends question_graded_automatically {
             return false;
         }
 
-        if ($this->ap->contains_thousands_seaparator($response['answer'])) {
-            return false;
-        }
-
         return true;
     }
 
@@ -131,11 +127,6 @@ class qtype_numerical_question extends question_graded_automatically {
             return get_string('unitnotselected', 'qtype_numerical');
         }
 
-        if ($this->ap->contains_thousands_seaparator($response['answer'])) {
-            return get_string('pleaseenteranswerwithoutthousandssep', 'qtype_numerical',
-                    $this->ap->get_separator());
-        }
-
         return '';
     }
 
@@ -287,7 +278,7 @@ class qtype_numerical_question extends question_graded_automatically {
             list($value, $unit, $multiplier) = $this->ap->apply_units(
                     $currentanswer, $selectedunit);
             $answer = $this->get_matching_answer($value, $multiplier);
-            $answerid = reset($args); // itemid is answer id.
+            $answerid = reset($args); // Itemid is answer id.
             return $options->feedback && $answer && $answerid == $answer->id;
 
         } else if ($component == 'question' && $filearea == 'hint') {
index c02e91f..ba0d64d 100644 (file)
@@ -75,8 +75,8 @@ class qtype_numerical extends question_type {
                 array('questionid' => $question->id), 'id ASC');
 
         $this->get_numerical_units($question);
-        // get_numerical_options() need to know if there are units
-        // to set correctly default values
+        // Function get_numerical_options() need to know if there are units
+        // to set correctly default values.
         $this->get_numerical_options($question);
 
         // If units are defined we strip off the default unit from the answer, if
@@ -153,7 +153,7 @@ class qtype_numerical extends question_type {
         global $DB;
         $context = $question->context;
 
-        // Get old versions of the objects
+        // Get old versions of the objects.
         $oldanswers = $DB->get_records('question_answers',
                 array('question' => $question->id), 'id ASC');
         $oldoptions = $DB->get_records('question_numerical',
@@ -167,7 +167,7 @@ class qtype_numerical extends question_type {
             $units = $result->units;
         }
 
-        // Insert all the new answers
+        // Insert all the new answers.
         foreach ($question->answer as $key => $answerdata) {
             // Check for, and ingore, completely blank answer from the form.
             if (trim($answerdata) == '' && $question->fraction[$key] == 0 &&
@@ -200,7 +200,7 @@ class qtype_numerical extends question_type {
             $answer->feedbackformat = $question->feedback[$key]['format'];
             $DB->update_record('question_answers', $answer);
 
-            // Set up the options object
+            // Set up the options object.
             if (!$options = array_shift($oldoptions)) {
                 $options = new stdClass();
             }
@@ -323,7 +323,7 @@ class qtype_numerical extends question_type {
         $units = array();
         $unitalreadyinsert = array();
         foreach ($question->multiplier as $i => $multiplier) {
-            // Discard any unit which doesn't specify the unit or the multiplier
+            // Discard any unit which doesn't specify the unit or the multiplier.
             if (!empty($question->multiplier[$i]) && !empty($question->unit[$i]) &&
                     !array_key_exists($question->unit[$i], $unitalreadyinsert)) {
                 $unitalreadyinsert[$question->unit[$i]] = 1;
@@ -632,17 +632,35 @@ class qtype_numerical_answer_processor {
         // Strip spaces (which may be thousands separators) and change other forms
         // of writing e to e.
         $response = str_replace(' ', '', $response);
+        // Strip thousand separators like half space.
+        if (!in_array($this->thousandssep, array(',', '.', ' '))) {
+            if (strpos($value, $this->thousandssep) !== false) {
+                $response = str_replace($this->thousandssep, '', $response);
+            }
+        }
         $response = preg_replace('~(?:e|E|(?:x|\*|×)10(?:\^|\*\*))([+-]?\d+)~', 'e$1', $response);
-
-        // If a . is present or there are multiple , (i.e. 2,456,789 ) assume ,
-        // is a thouseands separator, and strip it, else assume it is a decimal
-        // separator, and change it to ..
-        if (strpos($response, '.') !== false || substr_count($response, ',') > 1) {
-            $response = str_replace(',', '', $response);
-        } else {
-            $response = str_replace(',', '.', $response);
+        // Dot . is mostly a decimal separator there a few exceptions where it is a thousand separator
+        // If a . is present or there are multiple , (i.e. 2,456,789 ) assume,
+        // is a thousands separator and strip it or else assume it is a decimal
+        // separator and change it to .
+        // if only one and it is , then change to .
+        if (substr_count($response, ',')+ substr_count($response, '.') == 1 ) {
+            if (strpos($response, ',') !== false) {
+                $response = str_replace(',', '.', $response);
+            }
+        } else if (substr_count($response, ',') == 1 && substr_count($response, '.') == 1) {
+            if (strpos($response, '.') > strpos($response, ',')) { // Then , is thousand.
+                $response = str_replace(',', '', $response);
+            } else {
+                $response = str_replace('.', '', $response);
+                $response = str_replace(',', '.', $response);
+            }
+        } else if (substr_count($response, ',') > 1) {
+              $response = str_replace(',', '', $response);
+        } else if (substr_count($response, '.') > 1) {
+              $response = str_replace('.', '', $response);
+              $response = str_replace(',', '.', $response);
         }
-
         $regex = '[+-]?(?:\d+(?:\\.\d*)?|\\.\d+)(?:e[-+]?\d+)?';
         if ($this->unitsbefore) {
             $regex = "/$regex$/";
@@ -655,7 +673,7 @@ class qtype_numerical_answer_processor {
 
         $numberstring = $matches[0];
         if ($this->unitsbefore) {
-            // substr returns false when it means '', so cast back to string.
+            // Function substr returns false when it means '', so cast back to string.
             $unit = (string) substr($response, 0, -strlen($numberstring));
         } else {
             $unit = (string) substr($response, strlen($numberstring));
@@ -671,7 +689,7 @@ class qtype_numerical_answer_processor {
             $multiplier = null;
         }
 
-        return array($numberstring + 0, $unit, $multiplier); // + 0 to convert to number.
+        return array($numberstring + 0, $unit, $multiplier); // Add + 0 to convert to number.
     }
 
     /**
index f27bb2f..7a81f66 100644 (file)
@@ -131,9 +131,28 @@ class qtype_numerical_answer_processor_test extends advanced_testcase {
         $ap = new qtype_numerical_answer_processor(array(), false, ',', ' ');
 
         $this->assertEquals(array(-1000, '', null), $ap->apply_units('-1 000'));
+        $this->assertEquals(array(-1000000, '', null), $ap->apply_units('-1 000 000'));
+        $this->assertEquals(array(-1000000, '', null), $ap->apply_units('-1.000.000'));
+        $this->assertEquals(array(-1000000, '', null), $ap->apply_units('-1,000,000'));
+        $this->assertEquals(array(-1000.1, '', null), $ap->apply_units('-1000,1'));
+        $this->assertEquals(array(-1000.1, '', null), $ap->apply_units('-1.000,1'));
+        $this->assertEquals(array(-1000.1, '', null), $ap->apply_units('-1,000.1'));
         $this->assertEquals(array(3.14159, '', null), $ap->apply_units('3,14159'));
     }
 
+    public function test_deutsch_style() {
+        $ap = new qtype_numerical_answer_processor(array(), false, ',', '.');
+
+        $this->assertEquals(array(-1000, '', null), $ap->apply_units('-1 000'));
+        $this->assertEquals(array(-1000000, '', null), $ap->apply_units('-1 000 000'));
+        $this->assertEquals(array(-1000000, '', null), $ap->apply_units('-1.000.000'));
+        $this->assertEquals(array(-1000000, '', null), $ap->apply_units('-1.000.000,'));
+        $this->assertEquals(array(-1000.1, '', null), $ap->apply_units('-1000,1'));
+        $this->assertEquals(array(-1000.1, '', null), $ap->apply_units('-1.000,1'));
+        $this->assertEquals(array(-1000.1, '', null), $ap->apply_units('-1,000.1'));
+        $this->assertEquals(array(3.14159, '', null), $ap->apply_units('3.14159'));
+        $this->assertEquals(array(3.14159, '', null), $ap->apply_units('3,14159'));
+    }
     public function test_percent() {
         $ap = new qtype_numerical_answer_processor(array('%' => 100), false, '.', ',');