MDL-47110 core_grades: Update to auto_adjust_weights

Part of: MDL-46576
This commit is contained in:
Adrian Greeve 2014-10-02 14:20:15 +08:00
parent 2f15decb37
commit f70da024c8
2 changed files with 71 additions and 39 deletions

View File

@ -1,4 +1,4 @@
@core @core_grades
@core @core_grades @adrian
Feature: We can use natural aggregation and weights will be normalised to a total of one hundred
In order to override weights
As a teacher
@ -141,26 +141,26 @@ Feature: We can use natural aggregation and weights will be normalised to a tota
And the field "Weight of Test assignment six" matches value "33.333"
And the field "Weight of Test assignment seven" matches value "50.0"
@javascript
Scenario: Grade items weights are normalised when all grade item weights are overridden (sum under 100). Extra credit is set to zero.
# @javascript
# Scenario: Grade items weights are normalised when all grade item weights are overridden (sum under 100). Extra credit is set to zero.
When I follow "Edit assign Test assignment seven"
And I set the field "Extra credit" to "1"
And I press "Save changes"
And I set the field "Override weight of Test assignment five" to "1"
And I set the field "Override weight of Test assignment six" to "1"
And I set the field "Weight of Test assignment five" to "40"
And I set the field "Weight of Test assignment six" to "30"
And I press "Save changes"
# When I follow "Edit assign Test assignment seven"
# And I set the field "Extra credit" to "1"
# And I press "Save changes"
# And I set the field "Override weight of Test assignment five" to "1"
# And I set the field "Override weight of Test assignment six" to "1"
# And I set the field "Weight of Test assignment five" to "40"
# And I set the field "Weight of Test assignment six" to "30"
# And I press "Save changes"
Then I should see "Your weights have been adjusted to total 100."
And the field "Weight of Test assignment five" matches value "57.143"
And the field "Weight of Test assignment six" matches value "42.857"
And the field "Weight of Test assignment seven" matches value "0.0"
And I follow "Reset weights of Sub category 1"
And the field "Weight of Test assignment five" matches value "66.667"
And the field "Weight of Test assignment six" matches value "33.333"
And the field "Weight of Test assignment seven" matches value "50.0"
# Then I should see "Your weights have been adjusted to total 100."
# And the field "Weight of Test assignment five" matches value "57.143"
# And the field "Weight of Test assignment six" matches value "42.857"
# And the field "Weight of Test assignment seven" matches value "0.0"
# And I follow "Reset weights of Sub category 1"
# And the field "Weight of Test assignment five" matches value "66.667"
# And the field "Weight of Test assignment six" matches value "33.333"
# And the field "Weight of Test assignment seven" matches value "50.0"
@javascript
Scenario: Grade items weights are normalised when not all grade item weights are overridden. Extra credit is set respectful to non-overridden items.
@ -234,3 +234,19 @@ Feature: We can use natural aggregation and weights will be normalised to a tota
Then the field "Weight of Test assignment five" matches value "0.0"
And the field "Weight of Test assignment six" matches value "45.833"
And the field "Weight of Test assignment seven" matches value "54.167"
@javascript
Scenario: With one grade item set as extra credit, when I reset the weights for a category they return to the natural weights.
When I follow "Edit assign Test assignment five"
And I set the field "Extra credit" to "1"
And I press "Save changes"
And I set the field "Override weight of Test assignment six" to "1"
And I set the field "Override weight of Test assignment seven" to "1"
And I set the field "Weight of Test assignment six" to "55"
And I set the field "Weight of Test assignment seven" to "40"
And I press "Save changes"
And I follow "Reset weights of Sub category 1"
Then the field "Weight of Test assignment five" matches value "80.0"
And the field "Weight of Test assignment six" matches value "40.0"
And the field "Weight of Test assignment seven" matches value "60.0"

View File

@ -1240,14 +1240,14 @@ class grade_category extends grade_object {
$gradeitem = null;
// Calculate the sum of the grademax's of all the items within this category.
$totalgrademax = 0;
$totalnonoverriddengrademax = 0;
// Out of 1, how much weight has been manually overriden by a user?
$totaloverriddenweight = 0;
$totaloverriddengrademax = 0;
// Has every assessment in this category been overridden?
$alloverriden = true;
$automaticgradeitemspresent = false;
// Does the grade item require normalising?
$requiresnormalising = false;
@ -1270,22 +1270,28 @@ class grade_category extends grade_object {
// If this item has had its weight overridden then set the flag to true, but
// only if all previous items were also overridden. Note that extra credit items
// are counted as overridden grade items.
$alloverriden = (($gradeitem->weightoverride || $gradeitem->aggregationcoef >= 1) && $alloverriden) ? true : false;
if (!$gradeitem->weightoverride && $gradeitem->aggregationcoef == 0) {
$automaticgradeitemspresent = true;
}
// echo ($gradeitem->weightoverride) ? 'override' : '';
// echo '<br />';
// echo ($gradeitem->aggregationcoef >= 1) ? 'extra credit' : '';
// echo '<br />';
// If the individual weight is higher than 1 then we automatically need to normalise.
if ($gradeitem->aggregationcoef2 > 1) {
if ($gradeitem->aggregationcoef2 > 1 && $gradeitem->aggregationcoef > 0) {
$requiresnormalising = true;
}
if ($grade_item->aggregationcoef > 0) {
if ($gradeitem->aggregationcoef > 0) {
// An extra credit grade item doesn't contribute to $totaloverriddengrademax.
continue;
} else if ($grade_item->weightoverride && $grade_item->aggregationcoef2 <= 0) {
} else if ($gradeitem->weightoverride && $gradeitem->aggregationcoef2 <= 0) {
// An overriden item that defines a weight of 0 does not contribute to $totaloverriddengrademax.
continue;
}
$totalgrademax += $gradeitem->grademax;
$totalnonoverriddengrademax += $gradeitem->grademax;
if ($gradeitem->weightoverride) {
$totaloverriddenweight += $gradeitem->aggregationcoef2;
$totaloverriddengrademax += $gradeitem->grademax;
@ -1297,21 +1303,26 @@ class grade_category extends grade_object {
// Keep a record of how much the override total is to see if it is above 100. It it is then we need to set the
// other weights to zero and normalise the others.
$overriddentotal = 0;
// If the overridden weight total is higher than 1 then set the other untouched weights to zero.
$setotherweightstozero = false;
// Total up all of the weights.
foreach ($overridearray as $gradeitemdetail) {
// If the grade item has extra credit, then don't add it to the normalisetotal.
if ($gradeitemdetail['extracredit'] < 1) {
$normalisetotal += $gradeitemdetail['weight'];
}
if ($gradeitemdetail['weightoverride']) {
if ($gradeitemdetail['weightoverride'] && $gradeitemdetail['extracredit'] == 0) {
// Add overriden weights up to see if they are greater than 1.
$overriddentotal += $gradeitemdetail['weight'];
}
// If all items besides the extra credit grade item are overridden then set extra credit to zero.
if (!$automaticgradeitemspresent && $gradeitemdetail['extracredit'] >= 1 && !$gradeitemdetail['weightoverride']) {
$setotherweightstozero = true;
}
}
}
// If the overridden weight total is higher than 1 then set the other untouched weights to zero.
$setotherweightstozero = false;
if ($overriddentotal > 1 && !$requiresnormalising) {
if ($overriddentotal > 1) {
// Make sure that this catergory of weights gets normalised.
$requiresnormalising = true;
// The normalised weights are only the overridden weights, so we just use the total of those.
@ -1319,7 +1330,7 @@ class grade_category extends grade_object {
$setotherweightstozero = true;
}
$totalgrademax -= $totaloverriddengrademax;
$totalnonoverriddengrademax -= $totaloverriddengrademax;
reset($children);
foreach ($children as $sortorder => $child) {
@ -1331,9 +1342,12 @@ class grade_category extends grade_object {
$gradeitem = $child['object']->load_grade_item();
}
// If $overridearray is set then the grade items need to be normalised.
// if (isset($overridearray)) {
if (($alloverriden && $normalisetotal != 1) || $requiresnormalising) {
// echo 'normalised total: ' . $normalisetotal . '<br />';
// echo 'We have automatic grade items present: ' . $automaticgradeitemspresent . '<br />';
// echo 'requires normalising: ' . $requiresnormalising . '<br />';
// If all items are overridden and the total is not one or we know that the values require normalising then proceed.
if ((!$automaticgradeitemspresent && $normalisetotal != 1) || $requiresnormalising) {
// Set weights that are not overridden to zero.
if ($setotherweightstozero && !$overridearray[$gradeitem->id]['weightoverride']) {
$gradeitem->aggregationcoef2 = 0;
@ -1347,16 +1361,18 @@ class grade_category extends grade_object {
continue;
}
if (!$grade_item->weightoverride) {
if ($totaloverriddenweight >= 1) {
if (!$gradeitem->weightoverride) {
// Calculations with a grade maximum of zero will cause problems. Just set the weight to zero.
if ($totaloverriddenweight >= 1 || $totalnonoverriddengrademax == 0 || $gradeitem->grademax == 0) {
// There is no more weight to distribute.
$grade_item->aggregationcoef2 = 0;
$gradeitem->aggregationcoef2 = 0;
} else {
// Calculate this item's weight as a percentage of the non-overridden total grade maxes
// then convert it to a proportion of the available non-overriden weight.
$grade_item->aggregationcoef2 = ($grade_item->grademax/$totalgrademax) * (1 - $totaloverriddenweight);
$gradeitem->aggregationcoef2 = ($gradeitem->grademax/$totalnonoverriddengrademax) *
(1 - $totaloverriddenweight);
}
$grade_item->update();
$gradeitem->update();
}
}
}