Skip to content

Commit

Permalink
workshop: fixed two grading evaluation errors
Browse files Browse the repository at this point in the history
The first one was caused by the wrong rounding. The second one caused
the best assessment not being recognized properly.
  • Loading branch information
mudrd8mz committed Jan 4, 2010
1 parent d864fdf commit f0ec02a
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 11 deletions.
10 changes: 6 additions & 4 deletions mod/workshop/eval/best/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ protected function process_assessments(array $assessments, array $diminfo, stdCl
$best = $assessments[$bestid];
foreach ($assessments as $asid => $assessment) {
$d = $this->assessments_distance($assessment, $best, $diminfo, $settings);
if (!isset($distances[$asid]) or $d < $distances[$asid]) {
if (!is_null($d) and (!isset($distances[$asid]) or $d < $distances[$asid])) {
$distances[$asid] = $d;
}
}
Expand Down Expand Up @@ -353,12 +353,14 @@ protected function weighted_variance(array $assessments) {
* The passed data structures must contain ->dimgrades property. The referential
* assessment is supposed to be close to the average assessment. All dimension grades are supposed to be
* normalized to the interval 0 - 100.
* Returned value is rounded to 4 valid decimals to prevent some rounding issues - see the unit test
* for an example.
*
* @param stdClass $assessment the assessment being measured
* @param stdClass $referential assessment
* @param array $diminfo of stdClass(->weight ->min ->max ->variance) indexed by dimension id
* @param stdClass $settings
* @return float|null rounded to 5 valid decimals
* @return float|null rounded to 4 valid decimals
*/
protected function assessments_distance(stdClass $assessment, stdClass $referential, array $diminfo, stdClass $settings) {
$distance = 0;
Expand All @@ -368,18 +370,18 @@ protected function assessments_distance(stdClass $assessment, stdClass $referent
$rgrade = $referential->dimgrades[$dimid];
$var = $diminfo[$dimid]->variance;
$weight = $diminfo[$dimid]->weight;
$n += $weight;

// variations very close to zero are too sensitive to a small change of data values
if ($var > 0.01 and $agrade != $rgrade) {
$absdelta = abs($agrade - $rgrade);
$reldelta = pow($agrade - $rgrade, 2) / ($settings->comparison * $var);
$distance += $absdelta * $reldelta * $weight;
$n += $weight;
}
}
if ($n > 0) {
// average distance across all dimensions
return grade_floatval($distance / $n);
return round($distance / $n, 4);
} else {
return null;
}
Expand Down
73 changes: 66 additions & 7 deletions mod/workshop/eval/best/simpletest/testlib.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ public function average_assessment(array $assessments) {
public function weighted_variance(array $assessments) {
return parent::weighted_variance($assessments);
}

public function assessments_distance(stdClass $assessment, stdClass $referential, array $diminfo, stdClass $settings) {
return parent::assessments_distance($assessment, $referential, $diminfo, $settings);
}
}

class workshop_best_evaluation_test extends UnitTestCase {
Expand Down Expand Up @@ -131,23 +133,39 @@ public function test_normalize_grades_max_equals_min() {
$this->assertEqual($norm[1]->dimgrades[3], 100);
}

public function test_average_assessment() {
public function test_average_assessment_same_weights() {
// fixture set-up
$assessments = array();
$assessments[18] = (object)array(
'weight' => 1,
'dimgrades' => array(1 => 50, 2 => 33.33333),
);
$assessments[16] = (object)array(
'weight' => 1,
'dimgrades' => array(1 => 0, 2 => 66.66667),
);
// excersise SUT
$average = $this->evaluator->average_assessment($assessments);
// validate
$this->assertIsA($average->dimgrades, 'array');
$this->assertEqual(grade_floatval($average->dimgrades[1]), grade_floatval(25));
$this->assertEqual(grade_floatval($average->dimgrades[2]), grade_floatval(50));
}

public function test_average_assessment_different_weights() {
// fixture set-up
$assessments = array();
$assessments[11] = (object)array(
'weight' => 1,
'dimgrades' => array(3 => 10.0, 4 => 13.4, 5 => 95.0),
'dimweights' => array(3 => 1, 4 => 1, 5 => 1)
);
$assessments[13] = (object)array(
'weight' => 3,
'dimgrades' => array(3 => 11.0, 4 => 10.1, 5 => 92.0),
'dimweights' => array(3 => 1, 4 => 1, 5 => 1)
);
$assessments[17] = (object)array(
'weight' => 1,
'dimgrades' => array(3 => 11.0, 4 => 8.1, 5 => 88.0),
'dimweights' => array(3 => 1, 4 => 1, 5 => 1)
);
// excersise SUT
$average = $this->evaluator->average_assessment($assessments);
Expand All @@ -164,12 +182,10 @@ public function test_average_assessment_noweight() {
$assessments[11] = (object)array(
'weight' => 0,
'dimgrades' => array(3 => 10.0, 4 => 13.4, 5 => 95.0),
'dimweights' => array(3 => 1, 4 => 1, 5 => 1)
);
$assessments[17] = (object)array(
'weight' => 0,
'dimgrades' => array(3 => 11.0, 4 => 8.1, 5 => 88.0),
'dimweights' => array(3 => 1, 4 => 1, 5 => 1)
);
// excersise SUT
$average = $this->evaluator->average_assessment($assessments);
Expand Down Expand Up @@ -207,4 +223,47 @@ public function test_weighted_variance() {
// dimension [4] represents data 2, 4, 4, 4, 5, 5, 7, 9 having stdev=2 (stdev is sqrt of variance)
$this->assertEqual($variance[4], 4);
}

public function test_assessments_distance_zero() {
// fixture set-up
$diminfo = array(
3 => (object)array('weight' => 1, 'min' => 0, 'max' => 100, 'variance' => 12.34567),
4 => (object)array('weight' => 1, 'min' => 1, 'max' => 5, 'variance' => 98.76543),
);
$assessment1 = (object)array('dimgrades' => array(3 => 15, 4 => 2));
$assessment2 = (object)array('dimgrades' => array(3 => 15, 4 => 2));
$settings = (object)array('comparison' => 5);
// excersise SUT and validate
$this->assertEqual($this->evaluator->assessments_distance($assessment1, $assessment2, $diminfo, $settings), 0);
}

public function test_assessments_distance_equals() {
/*
// fixture set-up
$diminfo = array(
3 => (object)array('weight' => 1, 'min' => 0, 'max' => 100, 'variance' => 12.34567),
4 => (object)array('weight' => 1, 'min' => 0, 'max' => 100, 'variance' => 12.34567),
);
$assessment1 = (object)array('dimgrades' => array(3 => 25, 4 => 4));
$assessment2 = (object)array('dimgrades' => array(3 => 75, 4 => 2));
$referential = (object)array('dimgrades' => array(3 => 50, 4 => 3));
$settings = (object)array('comparison' => 5);
// excersise SUT and validate
$this->assertEqual($this->evaluator->assessments_distance($assessment1, $referential, $diminfo, $settings),
$this->evaluator->assessments_distance($assessment2, $referential, $diminfo, $settings));
*/
// fixture set-up
$diminfo = array(
1 => (object)array('min' => 0, 'max' => 2, 'weight' => 1, 'variance' => 625),
2 => (object)array('min' => 0, 'max' => 3, 'weight' => 1, 'variance' => 277.7778888889),
);
$assessment1 = (object)array('dimgrades' => array(1 => 0, 2 => 66.66667));
$assessment2 = (object)array('dimgrades' => array(1 => 50, 2 => 33.33333));
$referential = (object)array('dimgrades' => array(1 => 25, 2 => 50));
$settings = (object)array('comparison' => 9);
// excersise SUT and validate
$this->assertEqual($this->evaluator->assessments_distance($assessment1, $referential, $diminfo, $settings),
$this->evaluator->assessments_distance($assessment2, $referential, $diminfo, $settings));

}
}

0 comments on commit f0ec02a

Please sign in to comment.