mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 00:46:50 +02:00
MDL-47430 core_grades: Handle negative grademin with natural weighting
Part of: MDL-46576
This commit is contained in:
parent
11c93e286b
commit
0b2e8ae07b
2 changed files with 34 additions and 8 deletions
|
@ -706,8 +706,15 @@ class grade_report_user extends grade_report {
|
||||||
if (isset($this->aggregationhints[$itemid])) {
|
if (isset($this->aggregationhints[$itemid])) {
|
||||||
|
|
||||||
// Normalise the gradeval.
|
// Normalise the gradeval.
|
||||||
$graderange = $this->aggregationhints[$itemid]['grademax'] - $this->aggregationhints[$itemid]['grademin'];
|
$gradecat = $grade_object->load_parent_category();
|
||||||
$gradeval = ($this->aggregationhints[$itemid]['grade'] - $this->aggregationhints[$itemid]['grademin']) / $graderange;
|
if ($gradecat->aggregation == GRADE_AGGREGATE_SUM) {
|
||||||
|
// Natural aggregation/Sum of grades does not consider the mingrade.
|
||||||
|
$graderange = $this->aggregationhints[$itemid]['grademax'];
|
||||||
|
$gradeval = $this->aggregationhints[$itemid]['grade'] / $graderange;
|
||||||
|
} else {
|
||||||
|
$graderange = $this->aggregationhints[$itemid]['grademax'] - $this->aggregationhints[$itemid]['grademin'];
|
||||||
|
$gradeval = ($this->aggregationhints[$itemid]['grade'] - $this->aggregationhints[$itemid]['grademin']) / $graderange;
|
||||||
|
}
|
||||||
|
|
||||||
// Multiply the normalised value by the weight
|
// Multiply the normalised value by the weight
|
||||||
// of all the categories higher in the tree.
|
// of all the categories higher in the tree.
|
||||||
|
|
|
@ -661,7 +661,13 @@ class grade_category extends grade_object {
|
||||||
if (isset($grademaxoverrides[$itemid])) {
|
if (isset($grademaxoverrides[$itemid])) {
|
||||||
$usergrademax = $grademaxoverrides[$itemid];
|
$usergrademax = $grademaxoverrides[$itemid];
|
||||||
}
|
}
|
||||||
$grade_values[$itemid] = grade_grade::standardise_score($v, $usergrademin, $usergrademax, 0, 1);
|
if ($this->aggregation == GRADE_AGGREGATE_SUM) {
|
||||||
|
// Assume that the grademin is 0 when standardising the score, to preserve negative grades.
|
||||||
|
$grade_values[$itemid] = grade_grade::standardise_score($v, 0, $usergrademax, 0, 1);
|
||||||
|
} else {
|
||||||
|
$grade_values[$itemid] = grade_grade::standardise_score($v, $usergrademin, $usergrademax, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For items with no value, and not excluded - either set their grade to 0 or exclude them.
|
// For items with no value, and not excluded - either set their grade to 0 or exclude them.
|
||||||
|
@ -715,16 +721,29 @@ class grade_category extends grade_object {
|
||||||
$grademaxoverrides);
|
$grademaxoverrides);
|
||||||
$agg_grade = $result['grade'];
|
$agg_grade = $result['grade'];
|
||||||
|
|
||||||
|
// Set the actual grademin and max to bind the grade properly.
|
||||||
|
$this->grade_item->grademin = $result['grademin'];
|
||||||
|
$this->grade_item->grademax = $result['grademax'];
|
||||||
|
|
||||||
|
if ($this->aggregation == GRADE_AGGREGATE_SUM) {
|
||||||
|
// The natural aggregation always displays the range as coming from 0 for categories.
|
||||||
|
// However, when we bind the grade we allow for negative values.
|
||||||
|
$result['grademin'] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Recalculate the grade back to requested range.
|
// Recalculate the grade back to requested range.
|
||||||
$finalgrade = grade_grade::standardise_score($agg_grade, 0, 1, $result['grademin'], $result['grademax']);
|
$finalgrade = grade_grade::standardise_score($agg_grade, 0, 1, $result['grademin'], $result['grademax']);
|
||||||
|
|
||||||
$grade->finalgrade = $this->grade_item->bounded_grade($finalgrade);
|
$grade->finalgrade = $this->grade_item->bounded_grade($finalgrade);
|
||||||
|
|
||||||
|
$oldrawgrademin = $grade->rawgrademin;
|
||||||
$oldrawgrademax = $grade->rawgrademax;
|
$oldrawgrademax = $grade->rawgrademax;
|
||||||
|
$grade->rawgrademin = $result['grademin'];
|
||||||
$grade->rawgrademax = $result['grademax'];
|
$grade->rawgrademax = $result['grademax'];
|
||||||
|
|
||||||
// update in db if changed
|
// Update in db if changed.
|
||||||
if (grade_floats_different($grade->finalgrade, $oldfinalgrade) ||
|
if (grade_floats_different($grade->finalgrade, $oldfinalgrade) ||
|
||||||
grade_floats_different($grade->rawgrademax, $oldrawgrademax)) {
|
grade_floats_different($grade->rawgrademax, $oldrawgrademax) ||
|
||||||
|
grade_floats_different($grade->rawgrademin, $oldrawgrademin)) {
|
||||||
$grade->update('aggregation');
|
$grade->update('aggregation');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1046,11 +1065,11 @@ class grade_category extends grade_object {
|
||||||
if (isset($grademaxoverrides[$itemid])) {
|
if (isset($grademaxoverrides[$itemid])) {
|
||||||
$usergrademax = $grademaxoverrides[$itemid];
|
$usergrademax = $grademaxoverrides[$itemid];
|
||||||
}
|
}
|
||||||
$gradeitemrange = $usergrademax - $usergrademin;
|
|
||||||
|
|
||||||
// Ignore extra credit and items with a weight of 0.
|
// Ignore extra credit and items with a weight of 0.
|
||||||
if ($items[$itemid]->aggregationcoef <= 0 && $items[$itemid]->aggregationcoef2 > 0) {
|
if ($items[$itemid]->aggregationcoef <= 0 && $items[$itemid]->aggregationcoef2 > 0) {
|
||||||
$grademax += $gradeitemrange;
|
$grademin += $usergrademin;
|
||||||
|
$grademax += $usergrademax;
|
||||||
$sumweights += $items[$itemid]->aggregationcoef2;
|
$sumweights += $items[$itemid]->aggregationcoef2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue