]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-9137 calculated grades should work now, some other minor cleanup
authorskodak <skodak>
Mon, 18 Jun 2007 22:52:55 +0000 (22:52 +0000)
committerskodak <skodak>
Mon, 18 Jun 2007 22:52:55 +0000 (22:52 +0000)
lib/grade/grade_calculation.php
lib/grade/grade_item.php
lib/simpletest/fixtures/gradetest.php
lib/simpletest/grade/simpletest/testgradecalculation.php

index b9a6b17e949fed4f3b47bcb19753f7def2dde64e..ac2b342797f86c2160ca2334a388fbb9530c79a1 100644 (file)
@@ -75,6 +75,14 @@ class grade_calculation extends grade_object {
      */
     var $grade_item;
 
+    /**
+     * Get associated grade_item object
+     * @return object
+     */
+    function get_grade_item() {
+        return grade_item::fetch('id', $this->itemid);
+    }
+
     /**
      * Applies the formula represented by this object. The parameteres are taken from final
      * grades of grade items in current course only.
@@ -90,7 +98,7 @@ class grade_calculation extends grade_object {
         }
 
         // init grade_item
-        $this->grade_item = grade_item::fetch('id', $this->itemid);
+        $this->grade_item = $this->get_grade_item();
 
         //init used items
         $this->useditems = $this->dependson();
@@ -149,7 +157,7 @@ class grade_calculation extends grade_object {
             if (!array_key_exists('gi'.$gi, $params)) {
                 $params['gi'.$gi] = 0;
             } else {
-                $params['gi'.$gi] = (float)$params[$gi];
+                $params['gi'.$gi] = (float)$params['gi'.$gi];
             }
         }
 
@@ -160,21 +168,28 @@ class grade_calculation extends grade_object {
         $this->formula->set_params($params);
         $result = $this->formula->evaluate();
 
+
         // insert final grade if needed
         if (empty($final)) {
-            $this->grade_item->grade_grades_final[$userid] = new grade_grades_final(array('itemid'=>$this->grade_item->id, 'userid'=>$userid));
-            $this->grade_item->grade_grades_final[$userid]->insert();
+            $final = new grade_grades_final(array('itemid'=>$this->grade_item->id, 'userid'=>$userid), false);
+            $final->insert();
         }
 
         // store the result
         if ($result === false) {
-            $final->grade_value = null;
+            $final->gradevalue = null;
             $final->update();
             return false;
 
         } else {
-            $final = $result;
-            $this->grade_item->grade_grades_final[$userid]->update();
+            // normalize
+            $result = bounded_number($this->grade_item->grademin, $result, $this->grade_item->grademax);
+            if ($this->grade_item->gradetype == GRADE_TYPE_SCALE) {
+                $result = round($result+0.00001); // round upwards
+            }
+
+            $final->gradevalue = $result;
+            $final->update();
             return true;
         }
     }
index 73b0011dcc2d1844ad74872ce7629b66f882c166..46c74194c15b4b5b4ec6ba1cded495898316da45 100644 (file)
@@ -535,10 +535,8 @@ class grade_item extends grade_object {
 
         $errors = array();
 
-        if ($this->get_calculation()) {
-            // this is calculated grade
-            $this->upgrade_calculation_to_object();
-            if ($this->calculation->compute()) {
+        if ($calculation = $this->get_calculation()) {
+            if ($calculation->compute()) {
                 $this->needsupdate = false;
                 $this->update();
                 return true;
@@ -601,16 +599,6 @@ class grade_item extends grade_object {
         }
     }
 
-    /**
-     * Use this when the calculation object is a stdClass (rare) and you need it to have full
-     * object status (with methods and all).
-     */
-    function upgrade_calculation_to_object() {
-        if (!is_a($this->calculation, 'grade_calculation')) {
-            $this->calculation = new grade_calculation($this->calculation, false);
-        }
-    }
-
     /**
      * Given a float grade value or integer grade scale, applies a number of adjustment based on
      * grade_item variables and returns the result.
@@ -661,7 +649,7 @@ class grade_item extends grade_object {
                 $gradevalue = standardise_score($gradevalue, $rawgrade->grademin, $rawgrade->grademax, $this->grademin, $this->grademax);
             }
 
-            return (int)bounded_number(0, round($gradevalue), $this->grademax);
+            return (int)bounded_number(0, round($gradevalue+0.00001), $this->grademax);
 
 
         } else if ($this->gradetype == GRADE_TYPE_TEXT or $this->gradetype == GRADE_TYPE_NONE) { // no value
@@ -812,12 +800,12 @@ class grade_item extends grade_object {
      * @param boolean $fetch Whether to fetch the value from the DB or not (false == just use the object's value)
      * @return mixed $calculation Object if found, false otherwise.
      */
-    function get_calculation($fetch = false) {
+    function get_calculation($nocache = false) {
         if (is_null($this->calculation)) {
-            $fetch = true;
+            $nocache = true;
         }
 
-        if ($fetch) {
+        if ($nocache) {
             $this->calculation = grade_calculation::fetch('itemid', $this->id);
         }
 
@@ -833,42 +821,42 @@ class grade_item extends grade_object {
      */
     function set_calculation($formula) {
         // remove cached calculation object
-        $this->calculation = null;
-
         if (empty($formula)) { // We are removing this calculation
             if (!empty($this->id)) {
-                if ($grade_calculation = $this->get_calculation()) {
+                if ($grade_calculation = $this->get_calculation(true)) {
                     $grade_calculation->delete();
                 }
             }
-            $this->calculation = null;
-            $status = true;
+            $this->calculation = false; // cache no calculation present
+            $this->flag_for_update();
+            return true;
 
         } else { // We are updating or creating the calculation entry in the DB
-            $grade_calculation = $this->get_calculation();
+            if ($grade_calculation = $this->get_calculation(true)) {
+                $grade_calculation->calculation = $formula;
+                if ($grade_calculation->update()) {
+                    $this->flag_for_update();
+                    return true;                    
+                } else {
+                    $this->calculation = null; // remove cache
+                    debugging("Could not save the calculation in the database for this grade_item.");
+                    return false;
+                }
 
-            if (empty($grade_calculation)) { // Creating
+            } else {
                 $grade_calculation = new grade_calculation();
                 $grade_calculation->calculation = $formula;
                 $grade_calculation->itemid = $this->id;
 
                 if ($grade_calculation->insert()) {
-                    $this->calculation = $grade_calculation;
                     return true;
                 } else {
-                    debugging("Could not save the calculation in the database, for this grade_item.");
+                    $this->calculation = null; // remove cache
+                    debugging("Could not save the calculation in the database for this grade_item.");
                     return false;
                 }
-            } else { // Updating
-                $grade_calculation->calculation = $formula;
-                $grade_calculation = new grade_calculation($grade_calculation);
-                $this->calculation = $grade_calculation;
-                $status = $grade_calculation->update();
             }
         }
-
-        $this->flag_for_update();
-        return $status;
     }
 
     /**
@@ -1026,9 +1014,8 @@ class grade_item extends grade_object {
      */
     function dependson() {
 
-        if ($this->get_calculation()) {
-            $this->upgrade_calculation_to_object();
-            return $this->calculation->dependson();
+        if ($calculation = $this->get_calculation()) {
+            return $calculation->dependson();
 
         } else if ($this->itemtype == 'category') {
             $grade_category = grade_category::fetch('id', $this->iteminstance);
index e9dd1a4fe6b39be6fc041b68697f4e3b2dc9ee9d..8bb411ce3c1898ca5887c834a095545879284749 100644 (file)
@@ -722,7 +722,7 @@ class grade_test extends UnitTestCase {
         // Calculation for grade_item 2
         $grade_calculation = new stdClass();
         $grade_calculation->itemid = $this->grade_items[1]->id;
-        $grade_calculation->calculation = '= gi'.$this->grade_items[0]->id.'* + 30 ';
+        $grade_calculation->calculation = '= gi'.$this->grade_items[0]->id.' + 30 ';
         $grade_calculation->timecreated = mktime();
         $grade_calculation->timemodified = mktime();
         
@@ -920,7 +920,7 @@ class grade_test extends UnitTestCase {
         $grade_final->timemodified = mktime();
 
         if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) {
-            $this->grade_grades_final[] = $grade_final;
+            $this->grade_grades_final[0] = $grade_final;
         } 
         
         $grade_final = new stdClass();
@@ -932,7 +932,7 @@ class grade_test extends UnitTestCase {
         $grade_final->locked = true; 
 
         if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) {
-            $this->grade_grades_final[] = $grade_final;
+            $this->grade_grades_final[1] = $grade_final;
         }
 
         $grade_final = new stdClass();
@@ -944,7 +944,7 @@ class grade_test extends UnitTestCase {
         $grade_final->locked = false; 
 
         if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) {
-            $this->grade_grades_final[] = $grade_final;
+            $this->grade_grades_final[2] = $grade_final;
         } 
         
         // Grades for grade_item 2
@@ -952,37 +952,37 @@ class grade_test extends UnitTestCase {
         $grade_final = new stdClass();
         $grade_final->itemid = $this->grade_items[1]->id;
         $grade_final->userid = 1;
-        $grade_final->gradevalue = 70;
+        $grade_final->gradevalue = 60;
         $grade_final->timecreated = mktime();
         $grade_final->timemodified = mktime();
         $grade_final->locked = true; 
 
         if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) {
-            $this->grade_grades_final[] = $grade_final;
+            $this->grade_grades_final[3] = $grade_final;
         } 
         
         $grade_final = new stdClass();
         $grade_final->itemid = $this->grade_items[1]->id;
         $grade_final->userid = 2;
-        $grade_final->gradevalue = 100;
+        $grade_final->gradevalue = 70;
         $grade_final->timecreated = mktime();
         $grade_final->timemodified = mktime();
         $grade_final->locked = true; 
 
         if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) {
-            $this->grade_grades_final[] = $grade_final;
+            $this->grade_grades_final[4] = $grade_final;
         }
 
         $grade_final = new stdClass();
         $grade_final->itemid = $this->grade_items[1]->id;
         $grade_final->userid = 3;
-        $grade_final->gradevalue = 94;
+        $grade_final->gradevalue = 100;
         $grade_final->timecreated = mktime();
         $grade_final->timemodified = mktime();
         $grade_final->locked = false; 
 
         if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) {
-            $this->grade_grades_final[] = $grade_final;
+            $this->grade_grades_final[5] = $grade_final;
         } 
         
         // Grades for grade_item 3
index 1b608b96aec8b3e1cca52100782170052bb103c9..626233239c0563642217a58594be19343d9a2e9c 100644 (file)
@@ -43,7 +43,7 @@ class grade_calculation_test extends grade_test {
         $params = new stdClass();
 
         $params->itemid = $this->grade_items[0]->id;
-        $params->calculation = 'MEAN(1, 2)';
+        $params->calculation = '=MEAN(1, 2)';
 
         $grade_calculation = new grade_calculation($params, false);
         $this->assertEqual($params->itemid, $grade_calculation->itemid);
@@ -55,7 +55,7 @@ class grade_calculation_test extends grade_test {
         $this->assertTrue(method_exists($grade_calculation, 'insert'));
         
         $grade_calculation->itemid = $this->grade_items[0]->id;
-        $grade_calculation->calculation = 'MEAN(1, 2)';
+        $grade_calculation->calculation = '=MEAN(1, 2)';
 
         $grade_calculation->insert();
 
@@ -70,7 +70,7 @@ class grade_calculation_test extends grade_test {
     function test_grade_calculation_update() {
         $grade_calculation = new grade_calculation($this->grade_calculations[0]);
         $this->assertTrue(method_exists($grade_calculation, 'update'));
-        $grade_calculation->calculation = 'MEAN(1, 2)';        
+        $grade_calculation->calculation = '=MEAN(1, 2)';        
         $this->assertTrue($grade_calculation->update());
         $calculation = get_field('grade_calculations', 'calculation', 'id', $this->grade_calculations[0]->id);
         $this->assertEqual($grade_calculation->calculation, $calculation); 
@@ -93,5 +93,28 @@ class grade_calculation_test extends grade_test {
         $this->assertEqual($this->grade_calculations[0]->calculation, $grade_calculation->calculation); 
     } 
 
+    function test_grade_calculation_compute() {
+        $grade_calculation = new grade_calculation($this->grade_calculations[0]); 
+        $this->assertTrue(method_exists($grade_calculation, 'compute'));
+
+        $grade_item = $grade_calculation->get_grade_item();
+
+        $grade_grades_final = grade_grades_final::fetch('id', $this->grade_grades_final[3]->id);
+        $grade_grades_final->delete();
+        $grade_grades_final = grade_grades_final::fetch('id', $this->grade_grades_final[4]->id);
+        $grade_grades_final->delete();
+        $grade_grades_final = grade_grades_final::fetch('id', $this->grade_grades_final[5]->id);
+        $grade_grades_final->delete();
+
+        $grade_calculation->compute();
+
+        $grade_grades_final = grade_grades_final::fetch('userid', $this->grade_grades_final[3]->userid, 'itemid', $this->grade_grades_final[3]->itemid);
+        $this->assertEqual($this->grade_grades_final[3]->gradevalue, $grade_grades_final->gradevalue); 
+        $grade_grades_final = grade_grades_final::fetch('userid', $this->grade_grades_final[4]->userid, 'itemid', $this->grade_grades_final[4]->itemid);
+        $this->assertEqual($this->grade_grades_final[4]->gradevalue, $grade_grades_final->gradevalue); 
+        $grade_grades_final = grade_grades_final::fetch('userid', $this->grade_grades_final[5]->userid, 'itemid', $this->grade_grades_final[5]->itemid);
+        $this->assertEqual($this->grade_grades_final[5]->gradevalue, $grade_grades_final->gradevalue); 
+    } 
+
 } 
 ?>