Details

    • Type: Sub-task Sub-task
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 1.6
    • Fix Version/s: 1.6.7, 1.7.5, 1.8.5, 1.9.1, 2.0
    • Component/s: Quiz
    • Labels:
      None
    • Affected Branches:
      MOODLE_16_STABLE
    • Fixed Branches:
      MOODLE_16_STABLE, MOODLE_17_STABLE, MOODLE_18_STABLE, MOODLE_19_STABLE, MOODLE_20_STABLE
    • Rank:
      37111

      Description

      The function generate_dataset_item() does not generate correclty the dataset_item() in the loguniform option as it use the decimal paramter as a numbre of significant figure. So is decimal is set to 0 the result is 0...
      A bug unnoticed since the CREATION of this question type.
      This is why I set to 1.6. but could be 1.5.
      As it was unnoticed I will not merge to 1.5.

        Activity

        Hide
        Pierre Pichet added a comment - - edited

        The generate_dataset_item() use the same code that the answer i.e. qtype_calculated_calculate_answer()
        function generate_dataset_item($options) {
        if (!ereg('^(uniform|loguniform)[^:])[^:])[0-9]*)$',
        $options, $regs))

        { // Unknown options... return false; }
        if ($regs[1] == 'uniform') { $nbr = $regs[2] + ($regs[3]-$regs[2])*mt_rand()/mt_getrandmax(); return sprintf("%.".$regs[4]."f",$nbr); } else if ($regs[1] == 'loguniform') {
        $log0 = log(abs($regs[2])); // It would have worked the other way to
        $nbr = exp($log0 + (log(abs($regs[3])) - $log0)*mt_rand()/mt_getrandmax());

        // Reformat according to the precision $regs[4]:

        // Determine the format 0.[1-9][0-9]* for the nbr...
        $p10 = 0;
        while ($nbr < 1) { --$p10; $nbr *= 10; }
        while ($nbr >= 1) { ++$p10; $nbr /= 10; }
        // ... and have the nbr rounded off to the correct length
        // $nbr = round($nbr, $regs[4]);
        $nbr = sprintf("%.".$regs[4]."f",$nbr);
        // Have the nbr written on a suitable format,
        // Either scientific or plain numeric
        if (-2 > $p10 || 4 < $p10) {
        // Use scientific format:
        $eX = 'e'.--$p10;
        $nbr *= 10;
        if (1 == $regs[4]) { $nbr = $nbr.$eX; } else { // Attach additional zeros at the end of $nbr, $nbr .= (1==strlen($nbr) ? '.' : '') . '00000000000000000000000000000000000000000x'; $nbr = substr($nbr, 0, $regs[4] +1).$eX; }
        } else {
        // Stick to plain numeric format
        $nbr *= "1e$p10";
        if (0.1 <= $nbr / "1e$regs[4]") { $nbr = $nbr; } else { // Could be an idea to add some zeros here $nbr .= (ereg('^[0-9]*$', $nbr) ? '.' : '') . '00000000000000000000000000000000000000000x'; $oklen = $regs[4] + ($p10 < 1 ? 2-$p10 : 1); $nbr = substr($nbr, 0, $oklen); }
        }

        // The larger of the values decide the sign in case the
        // have equal different signs (which they really must not have)
        if ($regs[2] + $regs[3] > 0) { return $nbr; } else { return -$nbr; }

        } else { error("The distribution $regs[1] caused problems"); }
        return '';
        }
        which will be shortened to
        function generate_dataset_item($options) {
        if (!ereg('^(uniform|loguniform)[^:])[^:])[0-9]*)$',
        $options, $regs)) { // Unknown options... return false; }

        if ($regs[1] == 'uniform')

        { $nbr = $regs[2] + ($regs[3]-$regs[2])*mt_rand()/mt_getrandmax(); return sprintf("%.".$regs[4]."f",$nbr); }

        else if ($regs[1] == 'loguniform')

        { $log0 = log(abs($regs[2])); // It would have worked the other way to $nbr = exp($log0 + (log(abs($regs[3])) - $log0)*mt_rand()/mt_getrandmax()); return sprintf("%.".$regs[4]."f",$nbr); }

        else

        { error("The distribution $regs[1] caused problems"); }

        return '';
        }

        Show
        Pierre Pichet added a comment - - edited The generate_dataset_item() use the same code that the answer i.e. qtype_calculated_calculate_answer() function generate_dataset_item($options) { if (!ereg('^(uniform|loguniform) [^:] ) [^:] ) [0-9] *)$', $options, $regs)) { // Unknown options... return false; } if ($regs [1] == 'uniform') { $nbr = $regs[2] + ($regs[3]-$regs[2])*mt_rand()/mt_getrandmax(); return sprintf("%.".$regs[4]."f",$nbr); } else if ($regs [1] == 'loguniform') { $log0 = log(abs($regs [2] )); // It would have worked the other way to $nbr = exp($log0 + (log(abs($regs [3] )) - $log0)*mt_rand()/mt_getrandmax()); // Reformat according to the precision $regs [4] : // Determine the format 0. [1-9] [0-9] * for the nbr... $p10 = 0; while ($nbr < 1) { --$p10; $nbr *= 10; } while ($nbr >= 1) { ++$p10; $nbr /= 10; } // ... and have the nbr rounded off to the correct length // $nbr = round($nbr, $regs [4] ); $nbr = sprintf("%.".$regs [4] ."f",$nbr); // Have the nbr written on a suitable format, // Either scientific or plain numeric if (-2 > $p10 || 4 < $p10) { // Use scientific format: $eX = 'e'.--$p10; $nbr *= 10; if (1 == $regs [4] ) { $nbr = $nbr.$eX; } else { // Attach additional zeros at the end of $nbr, $nbr .= (1==strlen($nbr) ? '.' : '') . '00000000000000000000000000000000000000000x'; $nbr = substr($nbr, 0, $regs[4] +1).$eX; } } else { // Stick to plain numeric format $nbr *= "1e$p10"; if (0.1 <= $nbr / "1e$regs [4] ") { $nbr = $nbr; } else { // Could be an idea to add some zeros here $nbr .= (ereg('^[0-9]*$', $nbr) ? '.' : '') . '00000000000000000000000000000000000000000x'; $oklen = $regs[4] + ($p10 < 1 ? 2-$p10 : 1); $nbr = substr($nbr, 0, $oklen); } } // The larger of the values decide the sign in case the // have equal different signs (which they really must not have) if ($regs [2] + $regs [3] > 0) { return $nbr; } else { return -$nbr; } } else { error("The distribution $regs[1] caused problems"); } return ''; } which will be shortened to function generate_dataset_item($options) { if (!ereg('^(uniform|loguniform) [^:] ) [^:] ) [0-9] *)$', $options, $regs)) { // Unknown options... return false; } if ($regs [1] == 'uniform') { $nbr = $regs[2] + ($regs[3]-$regs[2])*mt_rand()/mt_getrandmax(); return sprintf("%.".$regs[4]."f",$nbr); } else if ($regs [1] == 'loguniform') { $log0 = log(abs($regs[2])); // It would have worked the other way to $nbr = exp($log0 + (log(abs($regs[3])) - $log0)*mt_rand()/mt_getrandmax()); return sprintf("%.".$regs[4]."f",$nbr); } else { error("The distribution $regs[1] caused problems"); } return ''; }
        Hide
        Pierre Pichet added a comment -

        Merged down to 1.6 STABLE

        Show
        Pierre Pichet added a comment - Merged down to 1.6 STABLE

          People

          • Assignee:
            Pierre Pichet
            Reporter:
            Pierre Pichet
            Participants:
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: