]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-9506 Implemented rescaling and grade adjustment formulas in grade_item::adjust_gr...
authornicolasconnault <nicolasconnault>
Tue, 1 May 2007 03:18:55 +0000 (03:18 +0000)
committernicolasconnault <nicolasconnault>
Tue, 1 May 2007 03:18:55 +0000 (03:18 +0000)
lib/grade/grade_item.php
lib/simpletest/testgradelib.php

index 4fbc9cc94d9df5f272d0393b191b147aa4135854..c19670322cc4c2242d5b78ef6f4d6e79548b1490 100644 (file)
@@ -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;
index 73d8401fc7a338b933650f81e489bf1a5f5cbd87..56a0d331fc6c434cc8ef3cb73528162cfca284ef 100644 (file)
@@ -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