Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Question Engine 2:Numerical formats: Difference between revisions

From MoodleDocs
No edit summary
Line 10: Line 10:
Please put your comments on the forum.
Please put your comments on the forum.
http://moodle.org/mod/forum/discuss.php?d=174387
http://moodle.org/mod/forum/discuss.php?d=174387
See also http://tracker.moodle.org/browse/MDL-27363





Revision as of 11:49, 5 May 2011

The Question Engine 2 structure allows implementation of new features for numerical question types ( numerical and calculated).

This page describes a possible implementation and its rationale.

The text should be readed as a personal summary of the work in progress and not as a textbook on computer language and real numbers representation.

It is related to an initial quiz forum discussion http://moodle.org/mod/forum/discuss.php?d=172211#p755927

Please put your comments on the forum. http://moodle.org/mod/forum/discuss.php?d=174387

See also http://tracker.moodle.org/browse/MDL-27363


Numbers as written by human and readed by computer language

The main feature of numerical question type is to ask the student to give a numerical answer i.e. a number. Most often this means a numerical value that is not an integer ( dates are a current example of integer value response) but a real number which value is expressed most often as a decimal number i.e 1.234 .

Computer languages ( i.e PHP used in Moodle) store real numbers in a different way than human do (decimal part and exponent similar to 1.234 E00) and humans do not expressed real nmumbers in an universal format.

The separator between the unit and the decimal fraction is often either a . or a ,  
1.234   1,234

Furthermore to help reading large numbers, most language add another separator for thousands often space or , if it is not used already as unit separator.

123 456.78     123,456.78   123 456,78 

PHP as a computer language use space to separate the language components so cannot use space as a thousand separator.

, is also used to separate variables so PHP use a simpler syntax 123456.78.

As this is stored in the computer as 2 parts (number and exponent).

1.2345678+E05 will be a structure that is well recognized by a computer language as PHP.

Setting the answer when creating the question

In Moodle 1,9 and 2,0 in the edit_numerical_form.php, the number enter by the teacher (although student could be allowed to create question, I will use teacher for text clarity) must be conform to the PHP syntax (no thousand separator or space and . as decimal separator. E syntax is allowed.

                if (!(is_numeric($trimmedanswer) || $trimmedanswer == '*')) {
                   $errors['answer[' . $key . ']'] =
                           get_string('answermustbenumberorstar', 'qtype_numerical');
               }

So the teacher must know the PHP specific number syntax.

In the numerical/questiontype.php function save_question_options($question) there is an additional verification mostly for numerical questions imported through various formats or inside a Cloze numerical multianswer question.

            
               $answer->answer = $this->apply_unit($answerdata, $units);
               if ($answer->answer === false) {
                   $result->notice = get_string('invalidnumericanswer', 'quiz');
               }
   

the Moodle 2,0 apply_unit

   
   /**
    * 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.
       $rawresponse = trim($rawresponse) ;
       $search  = array(' ', ',');
       // test if a . is present or there are multiple , (i.e. 2,456,789 ) so that we don't need spaces and ,
       if ( strpos($rawresponse,'.' ) !== false || substr_count($rawresponse,',') > 1 ) {
           $replace = array(, );
       }else { // remove spaces and normalise , to a . .
           $replace = array(, '.');
       }
       $rawresponse = str_replace($search, $replace, $rawresponse);


       // Apply any unit that is present.
       if (ereg('^([+-]?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([eE][-+]?[0-9]+)?)([^0-9].*)?$',
               $rawresponse, $responseparts)) {

echo"

responseparts

";print_r($responseparts) ;echo"

";

           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;
   }

The 2,0 apply_unit allows more number formats than the test in the editing form.

  • regular numbers 13500.67 : 13 500.67 : 13500,67: 13 500,67
  • if you use , as thousand separator *always* put the decimal . as in 13,500.67 : 13,500.
  • for exponent form, say 1.350067 * 104, use 1.350067 E4 : 1.350067 E04 ';

The 1,9 apply_unit is more restrictive as it does not support , as decimal separator.

More formats were allowed in 2,0 as the main objective in a numerical question is the numerical value. More about this further in the page (todo)

Retrieving the numerical value from the student response

As the function apply_unit() is also used to analyze the student response the number formats allowed are the same as the formats allowed for NON edit_numerical_form.php numerical i.e. import or Cloze.

However to help students know what are the number formats allowed an help icon aside the number text input element is shown on Moodle 2,0 numerical questions created either by edit_numerical_form.php or import but not for Cloze.

Numerical question grading

There are 3 elements that can be graded in a numerical question

  1. the numeric value
  2. the unit used in relation to the numeric value
  3. the number format used to express the value

1 and 2 are addressed in Moodle 2,0 for questions created from edit_numerical_form.php.

3 can give a 0 grade if the student does not use one of the number formats allowed but there is no specific grading designed as the unit penalty since Moodle 2,0.

Designing a number format penalty

We have already 2 ways to grade the student response available in the edit_numerical_form.php. i.e.

  • the answer-tolerance combination
  • the detailed unit grading

We need flexibility to take in account that number format can vary even at a same location i.e. in Canada there are two locales as there are two official languages (french and english).

Teacher sometimes ask for specific number formats as fraction that cannot be allowed simultanuously to other grading.

The most universal solution is to associate a grade to a specific answer numerical format as the tolerance is used.

For example in calculated the tolerance can be set as relative or absolute.

So my proposal is to add the number format as a new answer parameter.

To an official locales list of available formats we could add

  • specific Moodle formats as the one used for 1,9 2,0 ,
  • a fraction format,
  • time format,
  • degree, minute, second
  • etc.

Feasability of adding number format as an additional numerical answer table

The answer field being set as TEXT can easily store a numerical value in any format that can be validated easily in edit_numerical_form.php and the


   /**
    * Get an answer that contains the feedback and fraction that should be
    * awarded for this resonse.
    * @param number $value the numerical value of a response.
    * @return question_answer the matching answer.
    */
   public function get_matching_answer($value) {
       foreach ($this->answers as $aid => $answer) {
           if ($answer->within_tolerance($value)) {
               $answer->id = $aid;
               return $answer;
           }
       }
       return null;
   }

modified accordingly.

If the 2,1 new engine initial code uses an equivalent to the Moodle 2,0 apply_unit() function, this improvement could wait after 2,1 release.

The actual code does not detect number format

The historical objective in the apply_unit() was to convert various number formats so that they comply to the PHP norm for a number.

The most current thousand separators( i.e space and ,) are filtered out.

In 2,0 the , as unit separator is replaced by .

In all cases PHP numerical format is valid i.e. 123456.78 or 1.2345678e5

A clever student will never use thousand separators and will learn once for all if he can use , or . as unit separator.

Shortanswer is a better way to test for number formats...

Implementing a number format analysis

to do ...


Pierre Pichet 22:13, 2 May 2011 (WST)