diff --git a/lib/questionlib.php b/lib/questionlib.php index 9b47a4b3929..8371f3bc3e3 100644 --- a/lib/questionlib.php +++ b/lib/questionlib.php @@ -210,56 +210,16 @@ function question_context_has_any_questions($context) { /** * Returns list of 'allowed' grades for grade selection * formatted suitably for dropdown box function + * + * @deprecated since 2.1. Use {@link question_bank::fraction_options()} or + * {@link question_bank::fraction_options_full()} instead. + * * @return object ->gradeoptionsfull full array ->gradeoptions +ve only */ function get_grade_options() { - // define basic array of grades. This list comprises all fractions of the form: - // a. p/q for q <= 6, 0 <= p <= q - // b. p/10 for 0 <= p <= 10 - // c. 1/q for 1 <= q <= 10 - // d. 1/20 - $grades = array( - 1.0000000, - 0.9000000, - 0.8333333, - 0.8000000, - 0.7500000, - 0.7000000, - 0.6666667, - 0.6000000, - 0.5000000, - 0.4000000, - 0.3333333, - 0.3000000, - 0.2500000, - 0.2000000, - 0.1666667, - 0.1428571, - 0.1250000, - 0.1111111, - 0.1000000, - 0.0500000, - 0.0000000); - - // iterate through grades generating full range of options - $gradeoptionsfull = array(); - $gradeoptions = array(); - foreach ($grades as $grade) { - $percentage = 100 * $grade; - $gradeoptions["$grade"] = $percentage . '%'; - $gradeoptionsfull["$grade"] = $percentage . '%'; - $gradeoptionsfull['' . (-$grade)] = (-$percentage) . '%'; - } - $gradeoptionsfull['0'] = $gradeoptions['0'] = get_string('none'); - - // sort lists - arsort($gradeoptions, SORT_NUMERIC); - arsort($gradeoptionsfull, SORT_NUMERIC); - - // construct return object $grades = new stdClass(); - $grades->gradeoptions = $gradeoptions; - $grades->gradeoptionsfull = $gradeoptionsfull; + $grades->gradeoptions = question_bank::fraction_options(); + $grades->gradeoptionsfull = question_bank::fraction_options_full(); return $grades; } diff --git a/question/engine/bank.php b/question/engine/bank.php index eb2a51230b5..dd25b246b70 100644 --- a/question/engine/bank.php +++ b/question/engine/bank.php @@ -56,6 +56,17 @@ abstract class question_bank { private static $questionconfig = null; + /** + * @var array string => string The standard set of grade options (fractions) + * to use when editing questions, in the range 0 to 1 inclusive. Array keys + * are string becuase: a) we want grades to exactly 7 d.p., and b. you can't + * have float array keys in PHP. + * Initialised by {@link ensure_grade_options_initialised()}. + */ + private static $fractionoptions = null; + /** @var array string => string The full standard set of (fractions) -1 to 1 inclusive. */ + private static $fractionoptionsfull = null; + /** * @param string $qtypename a question type name, e.g. 'multichoice'. * @return bool whether that question type is installed in this Moodle. @@ -309,6 +320,81 @@ abstract class question_bank { } self::$testdata[$question->id] = $question; } + + protected function ensure_fraction_options_initialised() { + if (!is_null(self::$fractionoptions)) { + return; + } + + // define basic array of grades. This list comprises all fractions of the form: + // a. p/q for q <= 6, 0 <= p <= q + // b. p/10 for 0 <= p <= 10 + // c. 1/q for 1 <= q <= 10 + // d. 1/20 + $rawfractions = array( + 0.9000000, + 0.8333333, + 0.8000000, + 0.7500000, + 0.7000000, + 0.6666667, + 0.6000000, + 0.5000000, + 0.4000000, + 0.3333333, + 0.3000000, + 0.2500000, + 0.2000000, + 0.1666667, + 0.1428571, + 0.1250000, + 0.1111111, + 0.1000000, + 0.0500000, + ); + + // Put the None option at the top. + self::$fractionoptions = array( + '0.0' => get_string('none'), + '1.0' => '100%', + ); + self::$fractionoptionsfull = array( + '0.0' => get_string('none'), + '1.0' => '100%', + ); + + // The the positive grades in descending order. + foreach ($rawfractions as $fraction) { + $percentage = (100 * $fraction) . '%'; + self::$fractionoptions["$fraction"] = $percentage; + self::$fractionoptionsfull["$fraction"] = $percentage; + } + + // The the negative grades in descending order. + foreach (array_reverse($rawfractions) as $fraction) { + self::$fractionoptionsfull['' . (-$fraction)] = (-100 * $fraction) . '%'; + } + + self::$fractionoptionsfull['-1.0'] = '-100%'; + } + + /** + * @return array string => string The standard set of grade options (fractions) + * to use when editing questions, in the range 0 to 1 inclusive. Array keys + * are string becuase: a) we want grades to exactly 7 d.p., and b. you can't + * have float array keys in PHP. + * Initialised by {@link ensure_grade_options_initialised()}. + */ + public static function fraction_options() { + self::ensure_fraction_options_initialised(); + return self::$fractionoptions; + } + + /** @return array string => string The full standard set of (fractions) -1 to 1 inclusive. */ + public static function fraction_options_full() { + self::ensure_fraction_options_initialised(); + return self::$fractionoptionsfull; + } } diff --git a/question/engine/simpletest/testquestionbank.php b/question/engine/simpletest/testquestionbank.php index 4610f90d93c..697a7a69381 100644 --- a/question/engine/simpletest/testquestionbank.php +++ b/question/engine/simpletest/testquestionbank.php @@ -58,4 +58,34 @@ class question_bank_test extends UnitTestCase { 'frog' => 'toad', )); } -} \ No newline at end of file + + public function test_fraction_options() { + $fractions = question_bank::fraction_options(); + $this->assertIdentical(get_string('none'), reset($fractions)); + $this->assertIdentical('0.0', key($fractions)); + $this->assertIdentical('5%', end($fractions)); + $this->assertIdentical('0.05', key($fractions)); + array_shift($fractions); + array_pop($fractions); + array_pop($fractions); + $this->assertIdentical('100%', reset($fractions)); + $this->assertIdentical('1.0', key($fractions)); + $this->assertIdentical('11.11111%', end($fractions)); + $this->assertIdentical('0.1111111', key($fractions)); + } + + public function test_fraction_options_full() { + $fractions = question_bank::fraction_options_full(); + $this->assertIdentical(get_string('none'), reset($fractions)); + $this->assertIdentical('0.0', key($fractions)); + $this->assertIdentical('-100%', end($fractions)); + $this->assertIdentical('-1.0', key($fractions)); + array_shift($fractions); + array_pop($fractions); + array_pop($fractions); + $this->assertIdentical('100%', reset($fractions)); + $this->assertIdentical('1.0', key($fractions)); + $this->assertIdentical('-83.33333%', end($fractions)); + $this->assertIdentical('-0.8333333', key($fractions)); + } +}