]> git.mjollnir.org Git - moodle.git/commitdiff
workshop: fixed two grading evaluation errors
authorDavid Mudrak <david.mudrak@gmail.com>
Mon, 4 Jan 2010 18:26:02 +0000 (18:26 +0000)
committerDavid Mudrak <david.mudrak@gmail.com>
Mon, 4 Jan 2010 18:26:02 +0000 (18:26 +0000)
The first one was caused by the wrong rounding. The second one caused
the best assessment not being recognized properly.

mod/workshop/eval/best/lib.php
mod/workshop/eval/best/simpletest/testlib.php

index 45d6a439fe9e126dedc35d8d025c3f3f17decc06..256b13cb911b5c2ee58cf15904fcee68fd4248a8 100644 (file)
@@ -173,7 +173,7 @@ class workshop_best_evaluation implements workshop_evaluation {
             $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;
                 }
             }
@@ -353,12 +353,14 @@ class workshop_best_evaluation implements workshop_evaluation {
      * 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;
@@ -368,18 +370,18 @@ class workshop_best_evaluation implements workshop_evaluation {
             $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;
         }
index 16d9caa187d18a268c0c15f90f83ff45885a6ce0..7756ceaef9057c3385b56115b604a34ede614832 100644 (file)
@@ -47,7 +47,9 @@ class testable_workshop_best_evaluation extends workshop_best_evaluation {
     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 {
@@ -131,23 +133,39 @@ class workshop_best_evaluation_test extends UnitTestCase {
         $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);
@@ -164,12 +182,10 @@ class workshop_best_evaluation_test extends UnitTestCase {
         $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);
@@ -207,4 +223,47 @@ class workshop_best_evaluation_test extends UnitTestCase {
         // 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));
+
+    }
 }