Skip to content

Commit

Permalink
MDL-9506 Lots more unit tests, and work on grade_item::update method …
Browse files Browse the repository at this point in the history
…and associated functionality. 3 unit tests currently fail, so more work needed.
  • Loading branch information
nicolasconnault committed Apr 30, 2007
1 parent 896f1e0 commit b3f1116
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 9 deletions.
15 changes: 15 additions & 0 deletions lib/grade/grade_calculation.php
Expand Up @@ -59,7 +59,22 @@ class grade_calculation extends grade_object {
* @var int $usermodified
*/
var $usermodified;

/**
* A formula parser object.
* @var object $parser
* @TODO implement parsing of formula and calculation MDL-9643
*/
var $parser;

/**
* Applies the formula represented by this object to the value given, and returns the result.
* @param float $oldvalue
* @return float result
*/
function compute($oldvalue) {
return $oldvalue; // TODO implement computation using parser
}

/**
* Finds and returns a grade_calculation object based on 1-3 field values.
Expand Down
97 changes: 88 additions & 9 deletions lib/grade/grade_item.php
Expand Up @@ -174,6 +174,12 @@ class grade_item extends grade_object {
*/
var $grade_grades_raw = array();

/**
* Array of grade_grades_final objects linked to this grade_item. They are indexed by userid.
* @var array $grade_grades_final
*/
var $grade_grades_final = array();

/**
* Finds and returns a grade_item object based on 1-3 field values.
*
Expand Down Expand Up @@ -364,22 +370,95 @@ function is_locked($userid=NULL) {
* requested. Also resets the needs_update flag once successfully performed.
*
* @param int $userid
* @param string $howmodified What caused the modification? manual/module/import/cron...
* @param string $note A note attached to this modification.
* @return boolean Success or failure
* @return int Number of grades updated, or false if error
*/
function update_final_grade($userid=NULL, $howmodified='manual', $note=NULL) {
function update_final_grade($userid=NULL) {
if (empty($this->grade_grades_final)) {
$this->load_final();
}
if (empty($this->grade_grades_raw)) {
$this->load_raw();
}

// TODO implement parsing of formula and calculation MDL-9643
foreach ($this->grade_grades_final as $f) {
$newgradevalue = 0; // TODO replace '0' with calculated value
$f->update($newgradevalue, $howmodified, $note);
$count = 0;

$grade_final_array = array();

if (!empty($userid)) {
$grade_final_array[$userid] = $this->grade_grades_final[$userid];
} else {
$grade_final_array = $this->grade_grades_final;
}

return true;
foreach ($grade_raw_array as $userid => $raw) {
$newgradevalue = $raw->gradevalue;

if (!empty($this->calculation)) {
$this->upgrade_calculation_to_object();
$newgradevalue = $this->calculation->compute($raw->gradevalue);
}

$final = $this->grade_grades_final[$userid];

$final->gradevalue = $this->adjust_grade($raw, $newgradevalue);
if ($final->update($newgradevalue)) {
$count++;
} else {
return false;
}
}

return $count;
}

/**
* Use this when the calculation object is a stdClass (rare) and you need it to have full
* object status (with methods and all).
*/
function upgrade_calculation_to_object() {
if (!is_a($this->calculation, 'grade_calculation')) {
$this->calculation = new grade_calculation($this->calculation, false);
}
}

/**
* Given a float grade value or integer grade scale, applies a number of adjustment based on
* grade_item variables and returns the result.
* @param object $grade_raw The raw object to compare with this grade_item's rules
* @param mixed $gradevalue The new gradevalue (after calculations are performed)
* @return mixed
*/
function adjust_grade($grade_raw, $gradevalue=NULL) {
if (!empty($grade_raw->gradevalue)) { // Dealing with numerical grade
if (empty($gradevalue)) {
$gradevalue = $grade_raw->gradevalue;
}
} elseif(!empty($grade_raw->gradescale)) { // Dealing with a scale value
if (empty($gradevalue)) {
$gradevalue = $grade_raw->gradescale;
}

} 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);

if ($raw_diff > $item_diff) {
$gradevalue = $gradevalue / $diff_factor;
} else {
$gradevalue = $gradevalue * $diff_factor;
}

// Apply factors
$gradevalue *= $this->multfactor;
$gradevalue += $this->plusfactor;

return $gradevalue;
}
}
?>
61 changes: 61 additions & 0 deletions lib/simpletest/testgradelib.php
Expand Up @@ -695,6 +695,67 @@ function test_grade_item_get_category() {
$this->assertEqual($this->grade_categories[0]->fullname, $category->fullname);
}

/**
* Test update of all final grades
*/
function test_grade_item_update_final_grades() {
$grade_item = new grade_item($this->grade_items[0]);
$this->assertTrue(method_exists($grade_item, 'update_final_grade'));
$this->assertEqual(3, $grade_item->update_final_grade());
$this->assertEqual(1, $grade_item->update_final_grade(1));
}

/**
* Test loading of raw and final items into grade_item.
*/
function test_grade_item_load() {
$grade_item = new grade_item($this->grade_items[0]);
$this->assertTrue(method_exists($grade_item, 'load_final'));
$this->assertTrue(method_exists($grade_item, 'load_raw'));

// Check that final and raw items are not yet loaded
$this->assertTrue(empty($grade_item->grade_grades_final));
$this->assertTrue(empty($grade_item->grade_grades_raw));

// Load raw and final grades
$grade_item->load_final();
$grade_item->load_raw();

// Check that final and raw grades are now loaded
$this->assertFalse(empty($grade_item->grade_grades_final));
$this->assertFalse(empty($grade_item->grade_grades_raw));
$this->assertEqual($this->grade_grades_final[0]->gradevalue, $grade_item->grade_grades_final[1]->gradevalue);
$this->assertEqual($this->grade_grades_raw[0]->gradevalue, $grade_item->grade_grades_raw[1]->gradevalue);
}

/**
* Test the adjust_grade method
*/
function test_grade_item_adjust_grade() {
$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;

$this->assertEqual(20, $grade_item->adjust_grade($grade_raw));

$grade_item->grademax = 150;
$grade_item->grademin = 0;

$this->assertEqual(60, $grade_item->adjust_grade($grade_raw));

$grade_item->grademax = 150;
$grade_item->grademin = 50;

$this->assertEqual(40, $grade_item->adjust_grade($grade_raw));
}

// GRADE_CATEGORY OBJECT

function test_grade_category_construct() {
Expand Down

0 comments on commit b3f1116

Please sign in to comment.