Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-16427

Calculated and numerical questions : always marked as correct if the right answer is 0

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 1.9
    • Fix Version/s: None
    • Component/s: Questions
    • Labels:
      None
    • Affected Branches:
      MOODLE_19_STABLE

      Description

      When the right answer for a calculated or numerical question is 0, even if the student's answer is incorrect, the question is marked as correct.

      I think this issue is related with this one : http://tracker.moodle.org/browse/MDL-7496

      In Moodle 1.6.3, it was working fine.

        Gliffy Diagrams

          Activity

          Hide
          ppichet Pierre Pichet added a comment -

          You pinpoint a real(although rare) problem and related to the common way of calculted questions and numerical to calculate the relative tolerance when the answer is 0.
          I put it on the top of my todo list and it should be solved soon.

          Show
          ppichet Pierre Pichet added a comment - You pinpoint a real(although rare) problem and related to the common way of calculted questions and numerical to calculate the relative tolerance when the answer is 0. I put it on the top of my todo list and it should be solved soon.
          Hide
          ppichet Pierre Pichet added a comment -

          It is a REAL bug related to difference between == and === .

          The use of * was allowed to indicate that any response is valid.
          So when the valid answer is * there is no test of the response.
          in numerical/questiontype.php
          function test_response(&$question, &$state, $answer) {
          // Deal with the match anything answer.
          if ($answer->answer == '*')

          { return true; }

          $response = $this->apply_unit($state->responses[''], $question->options->units);

          if ($response === false) { return false; // The student did not type a number. }

          // The student did type a number, so check it with tolerances.
          $this->get_tolerance_interval($answer);
          return ($answer->min <= $response && $response <= $answer->max);
          }
          However if $answer->answer = 0 the test
          if ($answer->answer == '*') { return true; }

          is ALWAYS true so its return without further testing.
          Changing this to identity testing i.e.
          if ($answer->answer === '*')

          { return true; }

          solve the problem

          The same function is used in calculated question.
          So I will do the necessary changes and some testing and CVS soon to all versions that applied this '*' convention
          to numerical, shortanswer and calculated questions.

          Unless Tim want to control this.

          Show
          ppichet Pierre Pichet added a comment - It is a REAL bug related to difference between == and === . The use of * was allowed to indicate that any response is valid. So when the valid answer is * there is no test of the response. in numerical/questiontype.php function test_response(&$question, &$state, $answer) { // Deal with the match anything answer. if ($answer->answer == '*') { return true; } $response = $this->apply_unit($state->responses [''] , $question->options->units); if ($response === false) { return false; // The student did not type a number. } // The student did type a number, so check it with tolerances. $this->get_tolerance_interval($answer); return ($answer->min <= $response && $response <= $answer->max); } However if $answer->answer = 0 the test if ($answer->answer == '*') { return true; } is ALWAYS true so its return without further testing. Changing this to identity testing i.e. if ($answer->answer === '*') { return true; } solve the problem The same function is used in calculated question. So I will do the necessary changes and some testing and CVS soon to all versions that applied this '*' convention to numerical, shortanswer and calculated questions. Unless Tim want to control this.
          Hide
          timhunt Tim Hunt added a comment -

          I hate PHP! how can 0 == '*' be true? (Well, actually, I do know the answer to that question.)

          Looks like you have worked it out correctly. Please go ahead and test and commit the fix. Thanks Pierre.

          Show
          timhunt Tim Hunt added a comment - I hate PHP! how can 0 == '*' be true? (Well, actually, I do know the answer to that question.) Looks like you have worked it out correctly. Please go ahead and test and commit the fix. Thanks Pierre.
          Hide
          ppichet Pierre Pichet added a comment -

          The problem is more complex.
          On closer look it is
          However if $answer->answer = '' the test
          if ($answer->answer == '*')

          { return true; }


          so not 0 == '' but '' == ''. is always true
          However if the answer = 0 in calculated questiontype
          function substitute_variables($str, $dataset) {
          $formula = parent::substitute_variables($str, $dataset);
          echo "<p> formula in $formula </p>";
          if ($error = qtype_calculated_find_formula_errors($formula))

          { return $error; }

          echo "<p> formula out $formula </p>";
          /// Calculate the correct answer
          if (empty($formula))

          { $str = ''; }

          else if ($formula === '*')

          { $str = '*'; }

          else

          { eval('$str = '.$formula.';'); }

          echo "<p> str $str </p>";
          return $str;
          }
          give the following result
          formula in 0

          formula out 0

          str

          formula in 0+0

          formula out 0+0

          str 0
          i.e.
          eval('$str = '.0.';');
          return str =''
          quite surprising...

          So the problem is more specific to calculated and I will look further if I can implement the '*' convention as for bother questiontypes.

          Show
          ppichet Pierre Pichet added a comment - The problem is more complex. On closer look it is However if $answer->answer = '' the test if ($answer->answer == '*') { return true; } so not 0 == ' ' but '' == ' '. is always true However if the answer = 0 in calculated questiontype function substitute_variables($str, $dataset) { $formula = parent::substitute_variables($str, $dataset); echo "<p> formula in $formula </p>"; if ($error = qtype_calculated_find_formula_errors($formula)) { return $error; } echo "<p> formula out $formula </p>"; /// Calculate the correct answer if (empty($formula)) { $str = ''; } else if ($formula === '*') { $str = '*'; } else { eval('$str = '.$formula.';'); } echo "<p> str $str </p>"; return $str; } give the following result formula in 0 formula out 0 str formula in 0+0 formula out 0+0 str 0 i.e. eval('$str = '.0.';'); return str ='' quite surprising... So the problem is more specific to calculated and I will look further if I can implement the '*' convention as for bother questiontypes.
          Hide
          dakota.duff@greenbush Dakota Duff added a comment -

          This can be solved by using (zero) instead of 0, so it seems to me the easiest fix would something like this before the rest of the script runs:
          if ($answer == 0) $answer = (zero);

          Show
          dakota.duff@greenbush Dakota Duff added a comment - This can be solved by using (zero) instead of 0, so it seems to me the easiest fix would something like this before the rest of the script runs: if ($answer == 0) $answer = (zero);
          Hide
          ppichet Pierre Pichet added a comment -

          Thanks for your remarks.
          However I solve this and add '*' i.e (any response) already in numerical and short answer to calculated question.down to 1.8.
          I don't close the bug now because I want to document this and the active issue is a reminder to do the docs...
          Most people prefer to solve bugs than to document them.

          Show
          ppichet Pierre Pichet added a comment - Thanks for your remarks. However I solve this and add '*' i.e (any response) already in numerical and short answer to calculated question.down to 1.8. I don't close the bug now because I want to document this and the active issue is a reminder to do the docs... Most people prefer to solve bugs than to document them.
          Hide
          ppichet Pierre Pichet added a comment -

          I just realize that the CVS to add '*' i.e (any response) already in numerical and short answer to calculated question. to 1.9 and 1.8. are not done.
          Will do them in the weekend

          Show
          ppichet Pierre Pichet added a comment - I just realize that the CVS to add '*' i.e (any response) already in numerical and short answer to calculated question. to 1.9 and 1.8. are not done. Will do them in the weekend
          Hide
          ppichet Pierre Pichet added a comment -

          CVS down to 1.8
          This is not a problem in 1.7

          Show
          ppichet Pierre Pichet added a comment - CVS down to 1.8 This is not a problem in 1.7

            People

            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: