}
// limit and sort
- $this->apply_limit_rules($grade_values);
+ $this->apply_limit_rules($grade_values, $items);
asort($grade_values, SORT_NUMERIC);
// let's see we have still enough grades to do any statistics
}
}
// apply droplow and keephigh
- $this->apply_limit_rules($maxes);
+ $this->apply_limit_rules($maxes, $items);
$max = array_sum($maxes);
// update db if anything changed
}
}
- $this->apply_limit_rules($grade_values);
+ $this->apply_limit_rules($grade_values, $items);
$sum = array_sum($grade_values);
$grade->finalgrade = $this->grade_item->bounded_grade($sum);
/**
* Given an array of grade values (numerical indices), applies droplow or keephigh
* rules to limit the final array.
- * @param array $grade_values
+ * @param array $grade_values itemid=>$grade_value float
+ * @param array $items grade titem objects
* @return array Limited grades.
*/
- public function apply_limit_rules(&$grade_values) {
- arsort($grade_values, SORT_NUMERIC);
+ public function apply_limit_rules(&$grade_values, $items) {
+ $extraused = $this->is_extracredit_used();
+
if (!empty($this->droplow)) {
- for ($i = 0; $i < $this->droplow; $i++) {
- if (empty($grade_values)) {
- // nothing to remove
- return;
+ asort($grade_values, SORT_NUMERIC);
+ $dropped = 0;
+ foreach ($grade_values as $itemid=>$value) {
+ if ($dropped < $this->droplow) {
+ if ($extraused and $items[$itemid]->aggregationcoef > 0) {
+ // no drop low for extra credits
+ } else {
+ unset($grade_values[$itemid]);
+ $dropped++;
+ }
+ } else {
+ // we have dropped enough
+ break;
}
- array_pop($grade_values);
}
- } elseif (!empty($this->keephigh)) {
- while (count($grade_values) > $this->keephigh) {
- array_pop($grade_values);
+
+ } else if (!empty($this->keephigh)) {
+ arsort($grade_values, SORT_NUMERIC);
+ $kept = 0;
+ foreach ($grade_values as $itemid=>$value) {
+ if ($extraused and $items[$itemid]->aggregationcoef > 0) {
+ // we keep all extra credits
+ } else if ($kept < $this->keephigh) {
+ $kept++;
+ } else {
+ unset($grade_values[$itemid]);
+ }
}
}
}
-
/**
* Returns true if category uses special aggregation coeficient
* @return boolean true if coeficient used
}
function test_grade_category_apply_limit_rules() {
- $category = new grade_category();
- $grades = array(5.374, 9.4743, 2.5474, 7.3754);
+ $items[$this->grade_items[0]->id] = new grade_item($this->grade_items[0], false);
+ $items[$this->grade_items[1]->id] = new grade_item($this->grade_items[1], false);
+ $items[$this->grade_items[2]->id] = new grade_item($this->grade_items[2], false);
+ $items[$this->grade_items[4]->id] = new grade_item($this->grade_items[4], false);
+ $category = new grade_category();
$category->droplow = 2;
- $category->apply_limit_rules($grades);
- sort($grades, SORT_NUMERIC);
- $this->assertEqual(array(7.3754, 9.4743), $grades);
+ $grades = array($this->grade_items[0]->id=>5.374,
+ $this->grade_items[1]->id=>9.4743,
+ $this->grade_items[2]->id=>2.5474,
+ $this->grade_items[4]->id=>7.3754);
+ $category->apply_limit_rules($grades, $items);
+ $this->assertEqual(count($grades), 2);
+ $this->assertEqual($grades[$this->grade_items[1]->id], 9.4743);
+ $this->assertEqual($grades[$this->grade_items[4]->id], 7.3754);
$category = new grade_category();
- $grades = array(5.374, 9.4743, 2.5474, 7.3754);
-
$category->keephigh = 1;
$category->droplow = 0;
- $category->apply_limit_rules($grades);
+ $grades = array($this->grade_items[0]->id=>5.374,
+ $this->grade_items[1]->id=>9.4743,
+ $this->grade_items[2]->id=>2.5474,
+ $this->grade_items[4]->id=>7.3754);
+ $category->apply_limit_rules($grades, $items);
$this->assertEqual(count($grades), 1);
$grade = reset($grades);
$this->assertEqual(9.4743, $grade);
+
+ $category = new grade_category();
+ $category->droplow = 2;
+ $category->aggregation = GRADE_AGGREGATE_SUM;
+ $items[$this->grade_items[2]->id]->aggregationcoef = 1;
+ $grades = array($this->grade_items[0]->id=>5.374,
+ $this->grade_items[1]->id=>9.4743,
+ $this->grade_items[2]->id=>2.5474,
+ $this->grade_items[4]->id=>7.3754);
+
+ $category->apply_limit_rules($grades, $items);
+ $this->assertEqual(count($grades), 2);
+ $this->assertEqual($grades[$this->grade_items[1]->id], 9.4743);
+ $this->assertEqual($grades[$this->grade_items[2]->id], 2.5474);
+
+ $category = new grade_category();
+ $category->keephigh = 1;
+ $category->droplow = 0;
+ $category->aggregation = GRADE_AGGREGATE_SUM;
+ $items[$this->grade_items[2]->id]->aggregationcoef = 1;
+ $grades = array($this->grade_items[0]->id=>5.374,
+ $this->grade_items[1]->id=>9.4743,
+ $this->grade_items[2]->id=>2.5474,
+ $this->grade_items[4]->id=>7.3754);
+ $category->apply_limit_rules($grades, $items);
+ $this->assertEqual(count($grades), 2);
+ $this->assertEqual($grades[$this->grade_items[1]->id], 9.4743);
+ $this->assertEqual($grades[$this->grade_items[2]->id], 2.5474);
}
/**