From: skodak Date: Mon, 18 Jun 2007 22:52:55 +0000 (+0000) Subject: MDL-9137 calculated grades should work now, some other minor cleanup X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=df3cb76fc43def9bdb280f5c321220678a36cf4b;p=moodle.git MDL-9137 calculated grades should work now, some other minor cleanup --- diff --git a/lib/grade/grade_calculation.php b/lib/grade/grade_calculation.php index b9a6b17e94..ac2b342797 100644 --- a/lib/grade/grade_calculation.php +++ b/lib/grade/grade_calculation.php @@ -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; } } diff --git a/lib/grade/grade_item.php b/lib/grade/grade_item.php index 73b0011dcc..46c74194c1 100644 --- a/lib/grade/grade_item.php +++ b/lib/grade/grade_item.php @@ -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); diff --git a/lib/simpletest/fixtures/gradetest.php b/lib/simpletest/fixtures/gradetest.php index e9dd1a4fe6..8bb411ce3c 100644 --- a/lib/simpletest/fixtures/gradetest.php +++ b/lib/simpletest/fixtures/gradetest.php @@ -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 diff --git a/lib/simpletest/grade/simpletest/testgradecalculation.php b/lib/simpletest/grade/simpletest/testgradecalculation.php index 1b608b96ae..626233239c 100644 --- a/lib/simpletest/grade/simpletest/testgradecalculation.php +++ b/lib/simpletest/grade/simpletest/testgradecalculation.php @@ -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); + } + } ?>