Moodle
  1. Moodle
  2. MDL-16427

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

    Details

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

      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.

        Activity

        Hide
        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
        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
        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
        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
        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
        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
        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
        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 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 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
        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
        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
        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
        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
        Pierre Pichet added a comment -

        CVS down to 1.8
        This is not a problem in 1.7

        Show
        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: