Merge branch 'MDL-43369-26' of git://github.com/jamiepratt/moodle into MOODLE_26_STABLE
This commit is contained in:
@@ -53,10 +53,10 @@ class testable_question_statistics extends \core_question\statistics\questions\c
|
||||
|
||||
/**
|
||||
* @param $qubaids qubaid_condition is ignored in this test
|
||||
* @return array with three items
|
||||
* @return array with two items
|
||||
* - $lateststeps array of latest step data for the question usages
|
||||
* - $summarks array of total marks for each usage, indexed by usage id
|
||||
* - $summarksavg the average of the total marks over all the usages */
|
||||
*/
|
||||
protected function get_latest_steps($qubaids) {
|
||||
$summarks = array();
|
||||
$fakeusageid = 0;
|
||||
@@ -72,8 +72,7 @@ class testable_question_statistics extends \core_question\statistics\questions\c
|
||||
$step->questionusageid = $fakeusageid;
|
||||
}
|
||||
|
||||
$summarksavg = array_sum($summarks) / count($summarks);
|
||||
return array($this->lateststeps, $summarks, $summarksavg);
|
||||
return array($this->lateststeps, $summarks);
|
||||
}
|
||||
|
||||
protected function cache_stats($qubaids) {
|
||||
|
||||
@@ -32,7 +32,6 @@ require_once($CFG->dirroot . '/mod/quiz/report/default.php');
|
||||
require_once($CFG->dirroot . '/mod/quiz/report/statistics/report.php');
|
||||
require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php');
|
||||
|
||||
|
||||
/**
|
||||
* Quiz attempt walk through using data from csv file.
|
||||
*
|
||||
@@ -42,7 +41,7 @@ require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php');
|
||||
* @author Jamie Pratt <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class quiz_report_statistics_from_steps extends mod_quiz_attempt_walkthrough_from_csv_testcase {
|
||||
class quiz_report_statistics_from_steps_testcase extends mod_quiz_attempt_walkthrough_from_csv_testcase {
|
||||
|
||||
/**
|
||||
* @var quiz_statistics_report object to do stats calculations.
|
||||
@@ -103,9 +102,11 @@ class quiz_report_statistics_from_steps extends mod_quiz_attempt_walkthrough_fro
|
||||
$this->assertTimeCurrent($responesstats->get_last_analysed_time($qubaids));
|
||||
}
|
||||
|
||||
// These quiz stats and the question stats found in qstats00.csv were calculated independently in spreadsheet which is
|
||||
// These quiz stats and the question stats found in qstats00.csv were calculated independently in spreadsheets which are
|
||||
// available in open document or excel format here :
|
||||
// https://github.com/jamiepratt/moodle-quiz-tools/tree/master/statsspreadsheet
|
||||
|
||||
// These quiz stats and the position stats here are calculated in stats.xls and stats.ods available, see above github URL.
|
||||
$quizstatsexpected = array(
|
||||
'median' => 4.5,
|
||||
'firstattemptsavg' => 4.617333332,
|
||||
@@ -128,22 +129,62 @@ class quiz_report_statistics_from_steps extends mod_quiz_attempt_walkthrough_fro
|
||||
$slotqstats = $csvdata['qstats']->getRow($rowno);
|
||||
foreach ($slotqstats as $statname => $slotqstat) {
|
||||
if ($statname !== 'slot') {
|
||||
switch ($statname) {
|
||||
case 'covariance' :
|
||||
case 'discriminationindex' :
|
||||
case 'discriminativeefficiency' :
|
||||
case 'effectiveweight' :
|
||||
$precision = 1e-5;
|
||||
break;
|
||||
default :
|
||||
$precision = 1e-6;
|
||||
}
|
||||
$slot = $slotqstats['slot'];
|
||||
$delta = abs($slotqstat) * $precision;
|
||||
$actual = $questionstats[$slot]->{$statname};
|
||||
$this->assertEquals(floatval($slotqstat), $actual, "$statname for slot $slot", $delta);
|
||||
$this->assert_stat_equals($questionstats, $subquestionstats, $slotqstats['slot'],
|
||||
null, null, $statname, (float)$slotqstat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$itemstats = array('s' => 12,
|
||||
'effectiveweight' => null,
|
||||
'discriminationindex' => 35.803933,
|
||||
'discriminativeefficiency' => 39.39393939,
|
||||
'sd' => 0.514928651,
|
||||
'facility' => 0.583333333,
|
||||
'maxmark' => 1,
|
||||
'positions' => '1',
|
||||
'slot' => null,
|
||||
'subquestion' => true);
|
||||
foreach ($itemstats as $statname => $expected) {
|
||||
$this->assert_stat_equals($questionstats, $subquestionstats, 1, null, 'numerical', $statname, $expected);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the stat is as expected within a reasonable tolerance.
|
||||
*
|
||||
* @param \core_question\statistics\questions\calculated[] $questionstats
|
||||
* @param \core_question\statistics\questions\calculated_for_subquestion[] $subquestionstats
|
||||
* @param int $slot
|
||||
* @param int|null $variant if null then not a variant stat.
|
||||
* @param string|null $subqname if null then not an item stat.
|
||||
* @param string $statname
|
||||
* @param float $expected
|
||||
*/
|
||||
protected function assert_stat_equals($questionstats, $subquestionstats, $slot, $variant, $subqname, $statname, $expected) {
|
||||
|
||||
if ($variant === null && $subqname === null) {
|
||||
$actual = $questionstats[$slot]->{$statname};
|
||||
} else if ($subqname !== null) {
|
||||
$actual = $subquestionstats[$this->randqids[$slot][$subqname]]->{$statname};
|
||||
} else {
|
||||
$actual = $questionstats[$slot]->variantstats[$variant]->{$statname};
|
||||
}
|
||||
if (is_bool($expected) || is_string($expected)) {
|
||||
$this->assertEquals($expected, $actual, "$statname for slot $slot");
|
||||
} else {
|
||||
switch ($statname) {
|
||||
case 'covariance' :
|
||||
case 'discriminationindex' :
|
||||
case 'discriminativeefficiency' :
|
||||
case 'effectiveweight' :
|
||||
$precision = 1e-5;
|
||||
break;
|
||||
default :
|
||||
$precision = 1e-6;
|
||||
}
|
||||
$delta = abs($expected) * $precision;
|
||||
$this->assertEquals(floatval($expected), $actual, "$statname for slot $slot", $delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ class calculated {
|
||||
*/
|
||||
public $randomguessscore = null;
|
||||
|
||||
|
||||
// End of fields in db.
|
||||
|
||||
protected $fieldsindb = array('questionid', 'slot', 'subquestion', 's', 'effectiveweight', 'negcovar', 'discriminationindex',
|
||||
@@ -110,6 +111,11 @@ class calculated {
|
||||
|
||||
public $totalothermarks = 0;
|
||||
|
||||
/**
|
||||
* @var float The total of marks achieved for all positions in all attempts where this item was seen.
|
||||
*/
|
||||
public $totalsummarks = 0;
|
||||
|
||||
public $markvariancesum = 0;
|
||||
|
||||
public $othermarkvariancesum = 0;
|
||||
@@ -130,6 +136,11 @@ class calculated {
|
||||
|
||||
public $othermarkaverage;
|
||||
|
||||
/**
|
||||
* @var float The average for all attempts, of the sum of the marks for all positions in which this item appeared.
|
||||
*/
|
||||
public $summarksaverage;
|
||||
|
||||
public $markvariance;
|
||||
public $othermarkvariance;
|
||||
public $covariance;
|
||||
|
||||
@@ -78,7 +78,7 @@ class calculator {
|
||||
public function calculate($qubaids) {
|
||||
set_time_limit(0);
|
||||
|
||||
list($lateststeps, $summarks, $summarksavg) = $this->get_latest_steps($qubaids);
|
||||
list($lateststeps, $summarks) = $this->get_latest_steps($qubaids);
|
||||
|
||||
if ($lateststeps) {
|
||||
|
||||
@@ -169,10 +169,10 @@ class calculator {
|
||||
|
||||
// Go through the records one more time.
|
||||
foreach ($lateststeps as $step) {
|
||||
$this->secondary_steps_walker($step, $this->questionstats[$step->slot], $summarks, $summarksavg);
|
||||
$this->secondary_steps_walker($step, $this->questionstats[$step->slot], $summarks);
|
||||
|
||||
if ($this->questionstats[$step->slot]->subquestions) {
|
||||
$this->secondary_steps_walker($step, $this->subquestionstats[$step->questionid], $summarks, $summarksavg);
|
||||
$this->secondary_steps_walker($step, $this->subquestionstats[$step->questionid], $summarks);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,10 +268,9 @@ class calculator {
|
||||
|
||||
/**
|
||||
* @param $qubaids \qubaid_condition
|
||||
* @return array with three items
|
||||
* @return array with two items
|
||||
* - $lateststeps array of latest step data for the question usages
|
||||
* - $summarks array of total marks for each usage, indexed by usage id
|
||||
* - $summarksavg the average of the total marks over all the usages
|
||||
*/
|
||||
protected function get_latest_steps($qubaids) {
|
||||
$dm = new \question_engine_data_mapper();
|
||||
@@ -292,12 +291,9 @@ class calculator {
|
||||
}
|
||||
$summarks[$step->questionusageid] += $step->mark;
|
||||
}
|
||||
$summarksavg = array_sum($summarks) / count($summarks);
|
||||
} else {
|
||||
$summarksavg = null;
|
||||
}
|
||||
|
||||
return array($lateststeps, $summarks, $summarksavg);
|
||||
return array($lateststeps, $summarks);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -341,6 +337,8 @@ class calculator {
|
||||
|
||||
$stats->othermarkaverage = $stats->totalothermarks / $stats->s;
|
||||
|
||||
$stats->summarksaverage = $stats->totalsummarks / $stats->s;
|
||||
|
||||
sort($stats->markarray, SORT_NUMERIC);
|
||||
sort($stats->othermarksarray, SORT_NUMERIC);
|
||||
}
|
||||
@@ -352,16 +350,15 @@ class calculator {
|
||||
* @param object $step the state to add to the statistics.
|
||||
* @param calculated $stats the question statistics we are accumulating.
|
||||
* @param array $summarks of the sum of marks for each question usage, indexed by question usage id
|
||||
* @param float $summarksavg the average sum of marks for all question usages
|
||||
*/
|
||||
protected function secondary_steps_walker($step, $stats, $summarks, $summarksavg) {
|
||||
protected function secondary_steps_walker($step, $stats, $summarks) {
|
||||
$markdifference = $step->mark - $stats->markaverage;
|
||||
if ($stats->subquestion) {
|
||||
$othermarkdifference = $summarks[$step->questionusageid] - $stats->othermarkaverage;
|
||||
} else {
|
||||
$othermarkdifference = $summarks[$step->questionusageid] - $step->mark - $stats->othermarkaverage;
|
||||
}
|
||||
$overallmarkdifference = $summarks[$step->questionusageid] - $summarksavg;
|
||||
$overallmarkdifference = $summarks[$step->questionusageid] - $stats->summarksaverage;
|
||||
|
||||
$sortedmarkdifference = array_shift($stats->markarray) - $stats->markaverage;
|
||||
$sortedothermarkdifference = array_shift($stats->othermarksarray) - $stats->othermarkaverage;
|
||||
|
||||
Reference in New Issue
Block a user