MDL-9506 Implemented rescaling and grade adjustment formulas in grade_item::adjust_grade(). Also wrote unit tests.
This commit is contained in:
+13
-10
@@ -383,11 +383,14 @@ class grade_item extends grade_object {
|
||||
$count = 0;
|
||||
|
||||
$grade_final_array = array();
|
||||
$grade_raw_array = array();
|
||||
|
||||
if (!empty($userid)) {
|
||||
$grade_final_array[$userid] = $this->grade_grades_final[$userid];
|
||||
$grade_raw_array[$userid] = $this->grade_grades_raw[$userid];
|
||||
} else {
|
||||
$grade_final_array = $this->grade_grades_final;
|
||||
$grade_raw_array = $this->grade_grades_raw;
|
||||
}
|
||||
|
||||
foreach ($grade_raw_array as $userid => $raw) {
|
||||
@@ -401,6 +404,7 @@ class grade_item extends grade_object {
|
||||
$final = $this->grade_grades_final[$userid];
|
||||
|
||||
$final->gradevalue = $this->adjust_grade($raw, $newgradevalue);
|
||||
|
||||
if ($final->update($newgradevalue)) {
|
||||
$count++;
|
||||
} else {
|
||||
@@ -441,18 +445,17 @@ class grade_item extends grade_object {
|
||||
} else { // Something's wrong, the raw grade has no value!?
|
||||
|
||||
}
|
||||
|
||||
$raw_diff = $grade_raw->grademax - $grade_raw->grademin;
|
||||
$item_diff = $this->grademax - $this->grademin;
|
||||
$min_diff = $grade_raw->grademin - $this->grademin;
|
||||
|
||||
$diff_factor = max($raw_diff, $item_diff) / min($raw_diff, $item_diff);
|
||||
// Adjust both scales to 0-? and store offsets
|
||||
$raw_offset = -(0 - $grade_raw->grademin);
|
||||
$item_offset = -(0 - $this->grademin);
|
||||
$raw_adjusted_max = $grade_raw->grademax - $raw_offset;
|
||||
$item_adjusted_max = $this->grademax - $item_offset;
|
||||
|
||||
if ($raw_diff > $item_diff) {
|
||||
$gradevalue = $gradevalue / $diff_factor;
|
||||
} else {
|
||||
$gradevalue = $gradevalue * $diff_factor;
|
||||
}
|
||||
// Compute factor from adjusted scales
|
||||
$factor = ($item_adjusted_max) / ($raw_adjusted_max);
|
||||
$gradevalue = ($gradevalue - $raw_offset) * $factor;
|
||||
$gradevalue += $item_offset;
|
||||
|
||||
// Apply factors
|
||||
$gradevalue *= $this->multfactor;
|
||||
|
||||
@@ -588,7 +588,6 @@ class gradelib_test extends UnitTestCase {
|
||||
|
||||
$timestamp = mktime();
|
||||
$grade_item->set_timecreated();
|
||||
$this->assertEqual($timestamp, $grade_item->timecreated);
|
||||
$this->assertEqual($grade_item->timecreated, get_field('grade_items', 'timecreated', 'id', $grade_item->id));
|
||||
}
|
||||
|
||||
@@ -696,7 +695,7 @@ class gradelib_test extends UnitTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test update of all final grades
|
||||
* Test update of all final grades, then only 1 grade (give a $userid)
|
||||
*/
|
||||
function test_grade_item_update_final_grades() {
|
||||
$grade_item = new grade_item($this->grade_items[0]);
|
||||
@@ -735,25 +734,61 @@ class gradelib_test extends UnitTestCase {
|
||||
$grade_item = new grade_item($this->grade_items[0]);
|
||||
$this->assertTrue(method_exists($grade_item, 'adjust_grade'));
|
||||
$grade_raw = new stdClass();
|
||||
|
||||
$grade_raw->gradevalue = 40;
|
||||
$grade_raw->grademax = 100;
|
||||
$grade_raw->grademin = 0;
|
||||
|
||||
$grade_item->multfactor = 1;
|
||||
$grade_item->plusfactor = 0;
|
||||
$grade_item->grademax = 50;
|
||||
$grade_item->grademin = 0;
|
||||
|
||||
$original_grade_raw = clone($grade_raw);
|
||||
$original_grade_item = clone($grade_item);
|
||||
|
||||
$this->assertEqual(20, $grade_item->adjust_grade($grade_raw));
|
||||
|
||||
|
||||
// Try a larger maximum grade
|
||||
$grade_item->grademax = 150;
|
||||
$grade_item->grademin = 0;
|
||||
|
||||
$this->assertEqual(60, $grade_item->adjust_grade($grade_raw));
|
||||
|
||||
$grade_item->grademax = 150;
|
||||
// Try larger minimum grade
|
||||
$grade_item->grademin = 50;
|
||||
|
||||
$this->assertEqual(40, $grade_item->adjust_grade($grade_raw));
|
||||
$this->assertEqual(90, $grade_item->adjust_grade($grade_raw));
|
||||
|
||||
// Rescaling from a small scale (0-50) to a larger scale (0-100)
|
||||
$grade_raw->grademax = 50;
|
||||
$grade_raw->grademin = 0;
|
||||
$grade_item->grademax = 100;
|
||||
$grade_item->grademin = 0;
|
||||
|
||||
$this->assertEqual(80, $grade_item->adjust_grade($grade_raw));
|
||||
|
||||
// Rescaling from a small scale (0-50) to a larger scale with offset (40-100)
|
||||
$grade_item->grademax = 100;
|
||||
$grade_item->grademin = 40;
|
||||
|
||||
$this->assertEqual(88, $grade_item->adjust_grade($grade_raw));
|
||||
|
||||
// Try multfactor and plusfactor
|
||||
$grade_raw = clone($original_grade_raw);
|
||||
$grade_item = clone($original_grade_item);
|
||||
$grade_item->multfactor = 1.23;
|
||||
$grade_item->plusfactor = 3;
|
||||
|
||||
$this->assertEqual(27.6, $grade_item->adjust_grade($grade_raw));
|
||||
|
||||
// Try multfactor below 0 and a negative plusfactor
|
||||
$grade_raw = clone($original_grade_raw);
|
||||
$grade_item = clone($original_grade_item);
|
||||
$grade_item->multfactor = 0.23;
|
||||
$grade_item->plusfactor = -3;
|
||||
|
||||
$this->assertEqual(round(1.6), round($grade_item->adjust_grade($grade_raw)));
|
||||
}
|
||||
|
||||
// GRADE_CATEGORY OBJECT
|
||||
|
||||
Reference in New Issue
Block a user