Skip to content

Commit

Permalink
MDL-41954 Fix the grade for assessment calculation in the Workshop mo…
Browse files Browse the repository at this point in the history
…dule

In a pretty rare case of zero variance of received assessments, the "distance"
of the evaluated assessment from the referential ("best") one was not increased
regardless it's actual value. This led to higher grades for assessments in
certain situations (see the tracker for a particular example).
  • Loading branch information
mudrd8mz committed Sep 24, 2013
1 parent ca1c4ba commit b5b5838
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 1 deletion.
4 changes: 3 additions & 1 deletion mod/workshop/eval/best/lib.php
Expand Up @@ -386,7 +386,9 @@ protected function assessments_distance(stdclass $assessment, stdclass $referent
$n += $weight;

// variations very close to zero are too sensitive to a small change of data values
if ($var > 0.01 and $agrade != $rgrade) {
$var = max($var, 0.01);

if ($agrade != $rgrade) {
$absdelta = abs($agrade - $rgrade);
$reldelta = pow($agrade - $rgrade, 2) / ($settings->comparison * $var);
$distance += $absdelta * $reldelta * $weight;
Expand Down
76 changes: 76 additions & 0 deletions mod/workshop/eval/best/tests/lib_test.php
Expand Up @@ -239,6 +239,82 @@ public function test_assessments_distance_equals() {
$this->evaluator->assessments_distance($assessment2, $referential, $diminfo, $settings));

}

public function test_assessments_distance_zero_variance() {
// Fixture set-up: an assessment form of the strategy "Number of errors",
// three assertions, same weight.
$diminfo = array(
1 => (object)array('min' => 0, 'max' => 1, 'weight' => 1),
2 => (object)array('min' => 0, 'max' => 1, 'weight' => 1),
3 => (object)array('min' => 0, 'max' => 1, 'weight' => 1),
);

// Simulate structure returned by {@link workshop_best_evaluation::prepare_data_from_recordset()}
$assessments = array(
// The first assessment has weight 0 and the assessment was No, No, No.
10 => (object)array(
'assessmentid' => 10,
'weight' => 0,
'reviewerid' => 56,
'gradinggrade' => null,
'submissionid' => 99,
'dimgrades' => array(
1 => 0,
2 => 0,
3 => 0,
),
),
// The second assessment has weight 1 and assessments was Yes, Yes, Yes.
20 => (object)array(
'assessmentid' => 20,
'weight' => 1,
'reviewerid' => 76,
'gradinggrade' => null,
'submissionid' => 99,
'dimgrades' => array(
1 => 1,
2 => 1,
3 => 1,
),
),
// The third assessment has weight 1 and assessments was Yes, Yes, Yes too.
30 => (object)array(
'assessmentid' => 30,
'weight' => 1,
'reviewerid' => 97,
'gradinggrade' => null,
'submissionid' => 99,
'dimgrades' => array(
1 => 1,
2 => 1,
3 => 1,
),
),
);

// Process assessments in the same way as in the {@link workshop_best_evaluation::process_assessments()}
$assessments = $this->evaluator->normalize_grades($assessments, $diminfo);
$average = $this->evaluator->average_assessment($assessments);
$variances = $this->evaluator->weighted_variance($assessments);
foreach ($variances as $dimid => $variance) {
$diminfo[$dimid]->variance = $variance;
}

// Simulate the chosen comparison of assessments "fair" (does not really matter here but we need something).
$settings = (object)array('comparison' => 5);

// Exercise SUT: for every assessment, calculate its distance from the average one.
$distances = array();
foreach ($assessments as $asid => $assessment) {
$distances[$asid] = $this->evaluator->assessments_distance($assessment, $average, $diminfo, $settings);
}

// Validate: the first assessment is far far away from the average one ...
$this->assertTrue($distances[10] > 0);
// ... while the two others were both picked as the referential ones.
$this->assertTrue($distances[20] == 0);
$this->assertTrue($distances[30] == 0);
}
}


Expand Down

0 comments on commit b5b5838

Please sign in to comment.