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

          Attachments

            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: