]> git.mjollnir.org Git - moodle.git/commitdiff
aggregation improvements; fixed aggregation of course category when changing type...
authorskodak <skodak>
Sat, 21 Jul 2007 10:09:57 +0000 (10:09 +0000)
committerskodak <skodak>
Sat, 21 Jul 2007 10:09:57 +0000 (10:09 +0000)
grade/edit/category_form.php
lang/en_utf8/grades.php
lib/grade/grade_category.php
lib/gradelib.php

index 2ceaac302f6c18e701109f0f54d7ef029d87c017..0b0890ca0fd062c61cc2f2a649229687eecf0cc9 100644 (file)
@@ -13,10 +13,14 @@ class edit_category_form extends moodleform {
 
         $options = array(GRADE_AGGREGATE_MEAN_ALL               =>get_string('aggregatemeanall', 'grades'),
                          GRADE_AGGREGATE_MEAN_GRADED            =>get_string('aggregatemeangraded', 'grades'),
-                         GRADE_AGGREGATE_MEDIAN                 =>get_string('aggregatemedian', 'grades'),
-                         GRADE_AGGREGATE_MIN                    =>get_string('aggregatemin', 'grades'),
-                         GRADE_AGGREGATE_MAX                    =>get_string('aggregatemax', 'grades'),
-                         GRADE_AGGREGATE_MODE                   =>get_string('aggregatemode', 'grades'),
+                         GRADE_AGGREGATE_MEDIAN_ALL             =>get_string('aggregatemedianall', 'grades'),
+                         GRADE_AGGREGATE_MEDIAN_GRADED          =>get_string('aggregatemediangraded', 'grades'),
+                         GRADE_AGGREGATE_MIN_ALL                =>get_string('aggregateminall', 'grades'),
+                         GRADE_AGGREGATE_MIN_GRADED             =>get_string('aggregatemingraded', 'grades'),
+                         GRADE_AGGREGATE_MAX_ALL                =>get_string('aggregatemaxall', 'grades'),
+                         GRADE_AGGREGATE_MAX_GRADED             =>get_string('aggregatemaxgraded', 'grades'),
+                         GRADE_AGGREGATE_MODE_ALL               =>get_string('aggregatemodeall', 'grades'),
+                         GRADE_AGGREGATE_MODE_GRADED            =>get_string('aggregatemodegraded', 'grades'),
                          GRADE_AGGREGATE_WEIGHTED_MEAN_ALL      =>get_string('aggregateweightedmeanall', 'grades'),
                          GRADE_AGGREGATE_WEIGHTED_MEAN_GRADED   =>get_string('aggregateweightedmeangraded', 'grades'),
                          GRADE_AGGREGATE_EXTRACREDIT_MEAN_ALL   =>get_string('aggregateextracreditmeanall', 'grades'),
index b8b541fcd9d90590c44960d55c18e7ad93d82d60..a3bba880ea5e4409074a104b151dbc75fe662127 100644 (file)
@@ -10,11 +10,15 @@ $string['additem'] = 'Add Grade Item';
 $string['aggregateextracreditmeanall'] = 'Mean of all grades (extra credits)';
 $string['aggregateextracreditmeangraded'] = 'Mean of non-empty grades (extra credits)';
 $string['aggregatemeanall'] = 'Mean of all grades';
-$string['aggregatemedian'] = 'Median of non-empty grades';
 $string['aggregatemeangraded'] = 'Mean of non-empty grades';
-$string['aggregatemin'] = 'Smallest grade';
-$string['aggregatemax'] = 'Highest grade';
-$string['aggregatemode'] = 'Mode of non-empty grades';
+$string['aggregatemedianall'] = 'Median of all grades';
+$string['aggregatemediangraded'] = 'Median of non-empty grades';
+$string['aggregateminall'] = 'Smallest grade of all grades';
+$string['aggregatemingraded'] = 'Smallest grade of non-empty grades';
+$string['aggregatemaxall'] = 'Highest grade of all grades';
+$string['aggregatemaxgraded'] = 'Highest grade of non-empty grades';
+$string['aggregatemodeall'] = 'Mode of non-empty grades of all grades';
+$string['aggregatemodegraded'] = 'Mode of non-empty grades';
 $string['aggregateweightedmeanall'] = 'Weighted mean of all grades';
 $string['aggregateweightedmeangraded'] = 'Weighted mean of non-empty grades';
 $string['aggregation'] = 'Aggregation';
index 436b44266b09d16f819641e1feddbf0a58553d0c..80b096bf487729425b94026abf7c5b8bfac0dcad 100644 (file)
@@ -433,7 +433,24 @@ class grade_category extends grade_object {
             $grade_values[$k] = grade_grade::standardise_score($v, $items[$k]->grademin, $items[$k]->grademax, 0, 1);
         }
 
-        //limit and sort
+        // use min grade if grade missing for these types
+        switch ($this->aggregation) {
+            case GRADE_AGGREGATE_MEAN_ALL:
+            case GRADE_AGGREGATE_MEDIAN_ALL:
+            case GRADE_AGGREGATE_MIN_ALL:
+            case GRADE_AGGREGATE_MAX_ALL:
+            case GRADE_AGGREGATE_MODE_ALL:
+            case GRADE_AGGREGATE_WEIGHTED_MEAN_ALL:
+            case GRADE_AGGREGATE_EXTRACREDIT_MEAN_ALL:
+                foreach($items as $itemid=>$value) {
+                    if (!isset($grade_values[$itemid])) {
+                        $grade_values[$itemid] = 0;
+                    }
+                }
+                break;
+        }
+
+        // limit and sort
         $this->apply_limit_rules($grade_values);
         asort($grade_values, SORT_NUMERIC);
 
@@ -450,7 +467,8 @@ class grade_category extends grade_object {
 
     /// start the aggregation
         switch ($this->aggregation) {
-            case GRADE_AGGREGATE_MEDIAN: // Middle point value in the set: ignores frequencies
+            case GRADE_AGGREGATE_MEDIAN_ALL: // Middle point value in the set: ignores frequencies
+            case GRADE_AGGREGATE_MEDIAN_GRADED:
                 $num = count($grade_values);
                 $grades = array_values($grade_values);
                 if ($num % 2 == 0) {
@@ -460,15 +478,18 @@ class grade_category extends grade_object {
                 }
                 break;
 
-            case GRADE_AGGREGATE_MIN:
+            case GRADE_AGGREGATE_MIN_ALL:
+            case GRADE_AGGREGATE_MIN_GRADED:
                 $rawgrade = reset($grade_values);
                 break;
 
-            case GRADE_AGGREGATE_MAX:
+            case GRADE_AGGREGATE_MAX_ALL:
+            case GRADE_AGGREGATE_MAX_GRADED:
                 $rawgrade = array_pop($grade_values);
                 break;
 
-            case GRADE_AGGREGATE_MODE:       // the most common value, the highest one if multimode
+            case GRADE_AGGREGATE_MODE_ALL:       // the most common value, average used if multimode
+            case GRADE_AGGREGATE_MODE_GRADED:
                 $freq = array_count_values($grade_values);
                 arsort($freq);                      // sort by frequency keeping keys
                 $top = reset($freq);               // highest frequency count
@@ -477,33 +498,16 @@ class grade_category extends grade_object {
                 $rawgrade = reset($modes);
                 break;
 
-            case GRADE_AGGREGATE_WEIGHTED_MEAN_ALL: // Weighted average of all possible final grades
-                $weightsum = 0;
-                $sum       = 0;
-                foreach($items as $key=>$value) {
-                    $grade_value = isset($grade_values[$key]) ? $grade_values[$key] : 0;
-                    if ($items[$key]->aggregationcoef <= 0) {
-                        continue;
-                    }
-                    $weightsum += $items[$key]->aggregationcoef;
-                    $sum       += $items[$key]->aggregationcoef * $grade_value;
-                }
-                if ($weightsum == 0) {
-                    $rawgrade = null;
-                } else {
-                    $rawgrade = $sum / $weightsum;
-                }
-                break;
-
             case GRADE_AGGREGATE_WEIGHTED_MEAN_GRADED: // Weighted average of all existing final grades
+            case GRADE_AGGREGATE_WEIGHTED_MEAN_ALL:
                 $weightsum = 0;
                 $sum       = 0;
-                foreach($grade_values as $key=>$grade_value) {
-                    if ($items[$key]->aggregationcoef <= 0) {
+                foreach($grade_values as $itemid=>$grade_value) {
+                    if ($items[$itemid]->aggregationcoef <= 0) {
                         continue;
                     }
-                    $weightsum += $items[$key]->aggregationcoef;
-                    $sum       += $items[$key]->aggregationcoef * $grade_value;
+                    $weightsum += $items[$itemid]->aggregationcoef;
+                    $sum       += $items[$itemid]->aggregationcoef * $grade_value;
                 }
                 if ($weightsum == 0) {
                     $rawgrade = null;
@@ -513,33 +517,15 @@ class grade_category extends grade_object {
                 break;
 
             case GRADE_AGGREGATE_EXTRACREDIT_MEAN_ALL: // special average
+            case GRADE_AGGREGATE_EXTRACREDIT_MEAN_GRADED:
                 $num = 0;
                 $sum = 0;
-                foreach($items as $key=>$value) {
-                    $grade_value = isset($grade_values[$key]) ? $grade_values[$key] : 0;
-                    if ($items[$key]->aggregationcoef == 0) {
+                foreach($grade_values as $itemid=>$grade_value) {
+                    if ($items[$itemid]->aggregationcoef == 0) {
                         $num += 1;
                         $sum += $grade_value;
-                    } else if ($items[$key]->aggregationcoef > 0) {
-                        $sum += $items[$key]->aggregationcoef * $grade_value;
-                    }
-                }
-                if ($num == 0) {
-                    $rawgrade = $sum; // only extra credits or wrong coefs
-                } else {
-                    $rawgrade = $sum / $num;
-                }
-                break;
-
-            case GRADE_AGGREGATE_EXTRACREDIT_MEAN_GRADED: // special average
-                $num = 0;
-                $sum = 0;
-                foreach($grade_values as $key=>$grade_value) {
-                    if ($items[$key]->aggregationcoef == 0) {
-                        $num += 1;
-                        $sum += $grade_value;
-                    } else if ($items[$key]->aggregationcoef > 0) {
-                        $sum += $items[$key]->aggregationcoef * $grade_value;
+                    } else if ($items[$itemid]->aggregationcoef > 0) {
+                        $sum += $items[$itemid]->aggregationcoef * $grade_value;
                     }
                 }
                 if ($num == 0) {
@@ -550,11 +536,6 @@ class grade_category extends grade_object {
                 break;
 
             case GRADE_AGGREGATE_MEAN_ALL:    // Arithmetic average of all grade items including even NULLs; NULL grade counted as minimum
-                $num = count($items);     // you can calculate sum from this one if you multiply it with count($this->depends_on() ;-)
-                $sum = array_sum($grade_values);
-                $rawgrade = $sum / $num;
-                break;
-
             case GRADE_AGGREGATE_MEAN_GRADED: // Arithmetic average of all final grades, unfinished are not calculated
             default:
                 $num = count($grade_values);
index e387db67ba76292df67e7208dbd04724d134dd0c..3e4b6dfbea1f5ba41f3e348b08ce8088561228ad 100644 (file)
  * @package moodlecore
  */
 
+// category aggregation types
 define('GRADE_AGGREGATE_MEAN_ALL', 0);
 define('GRADE_AGGREGATE_MEAN_GRADED', 1);
-define('GRADE_AGGREGATE_MEDIAN', 2);
-define('GRADE_AGGREGATE_MIN', 3);
-define('GRADE_AGGREGATE_MAX', 4);
-define('GRADE_AGGREGATE_MODE', 5);
-define('GRADE_AGGREGATE_WEIGHTED_MEAN_ALL', 6);
-define('GRADE_AGGREGATE_WEIGHTED_MEAN_GRADED', 7);
-define('GRADE_AGGREGATE_EXTRACREDIT_MEAN_ALL', 8);
-define('GRADE_AGGREGATE_EXTRACREDIT_MEAN_GRADED', 9);
-
-define('GRADE_CHILDTYPE_ITEM', 0);
-define('GRADE_CHILDTYPE_CAT', 1);
-
-define('GRADE_ITEM', 0); // Used to compare class names with CHILDTYPE values
-define('GRADE_CATEGORY', 1); // Used to compare class names with CHILDTYPE values
-
-define('GRADE_CATEGORY_CONTRACTED', 0); // The state of a category header in the grader report
-define('GRADE_CATEGORY_EXPANDED', 1); // The state of a category header in the grader report
-
+define('GRADE_AGGREGATE_MEDIAN_ALL', 2);
+define('GRADE_AGGREGATE_MEDIAN_GRADED', 3);
+define('GRADE_AGGREGATE_MIN_ALL', 4);
+define('GRADE_AGGREGATE_MIN_GRADED', 5);
+define('GRADE_AGGREGATE_MAX_ALL', 6);
+define('GRADE_AGGREGATE_MAX_GRADED', 7);
+define('GRADE_AGGREGATE_MODE_ALL', 8);
+define('GRADE_AGGREGATE_MODE_GRADED', 9);
+define('GRADE_AGGREGATE_WEIGHTED_MEAN_ALL', 10);
+define('GRADE_AGGREGATE_WEIGHTED_MEAN_GRADED', 11);
+define('GRADE_AGGREGATE_EXTRACREDIT_MEAN_ALL', 12);
+define('GRADE_AGGREGATE_EXTRACREDIT_MEAN_GRADED', 13);
+
+// grade types
 define('GRADE_TYPE_NONE', 0);
 define('GRADE_TYPE_VALUE', 1);
 define('GRADE_TYPE_SCALE', 2);
 define('GRADE_TYPE_TEXT', 3);
 
+// grade_update() return status
 define('GRADE_UPDATE_OK', 0);
 define('GRADE_UPDATE_FAILED', 1);
 define('GRADE_UPDATE_MULTIPLE', 2);
@@ -68,11 +66,10 @@ define('GRADE_HISTORY_INSERT', 1);
 define('GRADE_HISTORY_UPDATE', 2);
 define('GRADE_HISTORY_DELETE', 3);
 
-// Common directories
-define('GRADE_EDIT_DIR', $CFG->dirroot . '/grade/edit');
-define('GRADE_EDIT_URL', $CFG->wwwroot . '/grade/edit');
-
 // Grader reports
+define('GRADE_CATEGORY_CONTRACTED', 0); // The state of a category header in the grader report
+define('GRADE_CATEGORY_EXPANDED', 1); // The state of a category header in the grader report
+
 define('GRADE_REPORT_AGGREGATION_POSITION_LEFT', 0);
 define('GRADE_REPORT_AGGREGATION_POSITION_RIGHT', 1);
 define('GRADE_REPORT_AGGREGATION_VIEW_FULL', 0);
@@ -84,6 +81,10 @@ define('GRADE_REPORT_PREFERENCE_DEFAULT', 'default');
 define('GRADE_REPORT_PREFERENCE_INHERIT', 'inherit');
 define('GRADE_REPORT_PREFERENCE_UNUSED', -1);
 
+// Common directories
+define('GRADE_EDIT_DIR', $CFG->dirroot . '/grade/edit');
+define('GRADE_EDIT_URL', $CFG->wwwroot . '/grade/edit');
+
 require_once($CFG->libdir . '/grade/grade_category.php');
 require_once($CFG->libdir . '/grade/grade_item.php');
 require_once($CFG->libdir . '/grade/grade_grade.php');
@@ -351,7 +352,7 @@ function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null)
         if (!empty($updated_item) and $updated_item->id == $gid) {
             $grade_items[$gid]->needsupdate = 1;
 
-        } else if ($grade_items[$gid]->is_course_item() or $grade_items[$gid]->is_category_item() or $grade_items[$gid]->is_calculated()) {
+        } else if ($gitem->is_course_item() or $gitem->is_category_item() or $gitem->is_calculated()) {
             $grade_items[$gid]->needsupdate = 1;
         }
 
@@ -362,6 +363,7 @@ function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null)
     $errors = array();
     $finalids = array();
     $gids     = array_keys($grade_items);
+    $failed = 0;
 
     while (count($finalids) < count($gids)) { // work until all grades are final or error found
         $count = 0;
@@ -399,6 +401,12 @@ function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null)
         }
 
         if ($count == 0) {
+            $failed++;
+        } else {
+            $failed = 0;
+        }
+
+        if ($failed > 1) {
             foreach($gids as $gid) {
                 if (in_array($gid, $finalids)) {
                     continue; // this one is ok
@@ -661,35 +669,54 @@ function grade_get_legacy_grade_item($modinstance, $grademax, $scaleid) {
 
 /**
  * This function is used to migrade old date and settings from old gradebook into new grading system.
- *
- * TODO:
- *   - category weight not used - we would have to create extra top course grade calculated category
- *   - exta_credit item flag not used - does not fit all our aggregation types, could be used in SUM only
+ * @param int $courseid
  */
-function grade_oldgradebook_upgrade($courseid) {
+function grade_upgrade_oldgradebook($courseid) {
     global $CFG;
 
+    // regrade everything
+    grade_force_full_regrading($courseid);
+
+    // course grade data
+    $course_category = grade_category::fetch_course_category($courseid);
+    $course_item     = $course_category->get_grade_item();
+
+    // first create all categories if needed
     $categories = array();
-    if ($oldcats = get_records('grade_category', 'courseid', $courseid)) {
+    $oldcats = get_records('grade_category', 'courseid', $courseid, 'id');
+
+    if (empty($oldcats) or count($oldcats) == 1) {
+        $course_category->aggregation = GRADE_AGGREGATE_MEAN_ALL;
+        $course_category->update('upgrade');
+        if ($oldcats) {
+            $oldcat = reset($oldcats);
+            $categories[$oldcat->id] =& $course_category;
+        }
+
+    } else {
         foreach ($oldcats as $oldcat) {
             $newcat = new grade_category(array('courseid'=>$courseid, 'fullname'=>$oldcat->name));
             $newcat->droplow     = $oldcat->drop_x_lowest;
-            $newcat->aggregation = GRADE_AGGREGATE_MEAN_GRADED;
+            $newcat->aggregation = GRADE_AGGREGATE_MEAN_ALL;
 
             if (empty($newcat->id)) {
-                $newcat->insert();
+                $newcat->insert('upgrade');
             } else {
-                $newcat->update();
+                $newcat->update('upgrade');
             }
 
-            $categories[$oldcat->id] = $newcat;
+            $categories[$oldcat->id] =& $newcat;
 
             $catitem = $newcat->get_grade_item();
-            $catitem->gradetype  = GRADE_TYPE_VALUE;
-            $catitem->plusfactor = $oldcat->bonus_points;
-            $catitem->hidden     = $oldcat->hidden;
-            $catitem->update();
+            $catitem->gradetype       = GRADE_TYPE_VALUE;
+            $catitem->plusfactor      = $oldcat->bonus_points;
+            $catitem->hidden          = $oldcat->hidden;
+            $catitem->aggregationcoef = $oldcat->weight;
+            $catitem->update('upgrade');
         }
+
+        $course_category->aggregation = GRADE_AGGREGATE_WEIGHTED_MEAN_ALL;
+        $course_category->update('upgrade');
     }
 
     // get all grade items with mod details
@@ -701,19 +728,27 @@ function grade_oldgradebook_upgrade($courseid) {
     if ($olditems = get_records_sql($sql)) {
         foreach ($olditems as $olditem) {
             $newitem = new grade_item(array('courseid'=>$olditem->courseid, 'itemtype'=>'mod', 'itemmodule'=>$olditem->modname, 'iteminstance'=>$olditem->cminstance, 'itemnumber'=>0));
-            if (!empty($olditem->category)) {
-                // we do this low level stuff to get some speedup during upgrade
-                $newitem->set_parent($categories[$olditem->category]->id);
+            $newitem->multfactor      = $olditem->scale_grade;
+            $newitem->aggregationcoef = $olditem->extra_credit;
+            if ($olditem->extra_credit and $categories[$olditem->category]->aggregation != GRADE_AGGREGATE_EXTRACREDIT_MEAN_ALL) {
+                $categories[$olditem->category]->aggregation = GRADE_AGGREGATE_EXTRACREDIT_MEAN_ALL;
+                $categories[$olditem->category]->update('upgrade');
             }
-            $newitem->gradetype = GRADE_TYPE_NONE;
-            $newitem->multfactor = $olditem->scale_grade;
+
             if (empty($newitem->id)) {
-                $newitem->insert();
+                $newitem->gradetype = GRADE_TYPE_NONE; // type not known yet
+                $newitem->insert('upgrade');
             } else {
-                $newitem->update();
+                $newitem->update('upgrade');
+            }
+
+            if (!empty($olditem->category)) {
+                $newitem->set_parent($categories[$olditem->category]->id);
             }
         }
     }
+
+    // setup up exception handling
 }
 
 /**