From d8676dc32ef57fe8ba6a5c39f358d9afe2b813da Mon Sep 17 00:00:00 2001 From: nicolasconnault Date: Tue, 1 May 2007 03:18:55 +0000 Subject: [PATCH] MDL-9506 Implemented rescaling and grade adjustment formulas in grade_item::adjust_grade(). Also wrote unit tests. --- lib/grade/grade_item.php | 23 +++++++++-------- lib/simpletest/testgradelib.php | 45 +++++++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/lib/grade/grade_item.php b/lib/grade/grade_item.php index 4fbc9cc94d..c19670322c 100644 --- a/lib/grade/grade_item.php +++ b/lib/grade/grade_item.php @@ -383,11 +383,14 @@ class grade_item extends grade_object { $count = 0; $grade_final_array = array(); + $grade_raw_array = array(); if (!empty($userid)) { $grade_final_array[$userid] = $this->grade_grades_final[$userid]; + $grade_raw_array[$userid] = $this->grade_grades_raw[$userid]; } else { $grade_final_array = $this->grade_grades_final; + $grade_raw_array = $this->grade_grades_raw; } foreach ($grade_raw_array as $userid => $raw) { @@ -401,6 +404,7 @@ class grade_item extends grade_object { $final = $this->grade_grades_final[$userid]; $final->gradevalue = $this->adjust_grade($raw, $newgradevalue); + if ($final->update($newgradevalue)) { $count++; } else { @@ -441,18 +445,17 @@ class grade_item extends grade_object { } else { // Something's wrong, the raw grade has no value!? } - - $raw_diff = $grade_raw->grademax - $grade_raw->grademin; - $item_diff = $this->grademax - $this->grademin; - $min_diff = $grade_raw->grademin - $this->grademin; - $diff_factor = max($raw_diff, $item_diff) / min($raw_diff, $item_diff); + // Adjust both scales to 0-? and store offsets + $raw_offset = -(0 - $grade_raw->grademin); + $item_offset = -(0 - $this->grademin); + $raw_adjusted_max = $grade_raw->grademax - $raw_offset; + $item_adjusted_max = $this->grademax - $item_offset; - if ($raw_diff > $item_diff) { - $gradevalue = $gradevalue / $diff_factor; - } else { - $gradevalue = $gradevalue * $diff_factor; - } + // Compute factor from adjusted scales + $factor = ($item_adjusted_max) / ($raw_adjusted_max); + $gradevalue = ($gradevalue - $raw_offset) * $factor; + $gradevalue += $item_offset; // Apply factors $gradevalue *= $this->multfactor; diff --git a/lib/simpletest/testgradelib.php b/lib/simpletest/testgradelib.php index 73d8401fc7..56a0d331fc 100644 --- a/lib/simpletest/testgradelib.php +++ b/lib/simpletest/testgradelib.php @@ -588,7 +588,6 @@ class gradelib_test extends UnitTestCase { $timestamp = mktime(); $grade_item->set_timecreated(); - $this->assertEqual($timestamp, $grade_item->timecreated); $this->assertEqual($grade_item->timecreated, get_field('grade_items', 'timecreated', 'id', $grade_item->id)); } @@ -696,7 +695,7 @@ class gradelib_test extends UnitTestCase { } /** - * Test update of all final grades + * Test update of all final grades, then only 1 grade (give a $userid) */ function test_grade_item_update_final_grades() { $grade_item = new grade_item($this->grade_items[0]); @@ -735,25 +734,61 @@ class gradelib_test extends UnitTestCase { $grade_item = new grade_item($this->grade_items[0]); $this->assertTrue(method_exists($grade_item, 'adjust_grade')); $grade_raw = new stdClass(); + $grade_raw->gradevalue = 40; $grade_raw->grademax = 100; $grade_raw->grademin = 0; + $grade_item->multfactor = 1; $grade_item->plusfactor = 0; $grade_item->grademax = 50; $grade_item->grademin = 0; + + $original_grade_raw = clone($grade_raw); + $original_grade_item = clone($grade_item); $this->assertEqual(20, $grade_item->adjust_grade($grade_raw)); - + + // Try a larger maximum grade $grade_item->grademax = 150; $grade_item->grademin = 0; $this->assertEqual(60, $grade_item->adjust_grade($grade_raw)); - $grade_item->grademax = 150; + // Try larger minimum grade $grade_item->grademin = 50; - $this->assertEqual(40, $grade_item->adjust_grade($grade_raw)); + $this->assertEqual(90, $grade_item->adjust_grade($grade_raw)); + + // Rescaling from a small scale (0-50) to a larger scale (0-100) + $grade_raw->grademax = 50; + $grade_raw->grademin = 0; + $grade_item->grademax = 100; + $grade_item->grademin = 0; + + $this->assertEqual(80, $grade_item->adjust_grade($grade_raw)); + + // Rescaling from a small scale (0-50) to a larger scale with offset (40-100) + $grade_item->grademax = 100; + $grade_item->grademin = 40; + + $this->assertEqual(88, $grade_item->adjust_grade($grade_raw)); + + // Try multfactor and plusfactor + $grade_raw = clone($original_grade_raw); + $grade_item = clone($original_grade_item); + $grade_item->multfactor = 1.23; + $grade_item->plusfactor = 3; + + $this->assertEqual(27.6, $grade_item->adjust_grade($grade_raw)); + + // Try multfactor below 0 and a negative plusfactor + $grade_raw = clone($original_grade_raw); + $grade_item = clone($original_grade_item); + $grade_item->multfactor = 0.23; + $grade_item->plusfactor = -3; + + $this->assertEqual(round(1.6), round($grade_item->adjust_grade($grade_raw))); } // GRADE_CATEGORY OBJECT -- 2.39.5