function get_records($quizid, $currentgroup, $groupstudents, $allattempts) { global $DB; list($qsql, $qparams) = $DB->get_in_or_equal(array_keys($this->questions), SQL_PARAMS_NAMED, 'q0000'); list($fromqa, $whereqa, $qaparams) = quiz_report_attempts_sql($quizid, $currentgroup, $groupstudents, $allattempts); $sql = 'SELECT qs.id, ' . 'qs.question, ' . 'qa.sumgrades, ' . 'qs.grade, ' . 'qs.answer ' . 'FROM ' . '{question_sessions} qns, ' . '{question_states} qs, ' . $fromqa . ' ' . 'WHERE ' . $whereqa . 'AND qs.question ' . $qsql . ' ' . 'AND qns.attemptid = qa.uniqueid ' . 'AND qns.newgraded = qs.id'; $this->states = $DB->get_records_sql($sql, $qaparams + $qparams); if ($this->states === false) { print_error('errorstatisticsquestions', 'quiz_statistics'); } }
function quiz_stats($nostudentsingroup, $quizid, $currentgroup, $groupstudents, $questions, $useallattempts) { global $CFG, $DB; if (!$nostudentsingroup) { //Calculating_MEAN_of_grades_for_all_attempts_by_students //http://docs.moodle.org/en/Development:Quiz_item_analysis_calculations_in_practise#Calculating_MEAN_of_grades_for_all_attempts_by_students list($fromqa, $whereqa, $qaparams) = quiz_report_attempts_sql($quizid, $currentgroup, $groupstudents); $sql = 'SELECT (CASE WHEN attempt=1 THEN 1 ELSE 0 END) AS isfirst, COUNT(1) AS countrecs, SUM(sumgrades) AS total ' . 'FROM ' . $fromqa . 'WHERE ' . $whereqa . 'GROUP BY (attempt=1)'; if (!($attempttotals = $DB->get_records_sql($sql, $qaparams))) { $s = 0; $usingattemptsstring = ''; } else { $firstattempt = $attempttotals[1]; $allattempts = new object(); $allattempts->countrecs = $firstattempt->countrecs + (isset($attempttotals[0]) ? $attempttotals[0]->countrecs : 0); $allattempts->total = $firstattempt->total + (isset($attempttotals[0]) ? $attempttotals[0]->total : 0); if ($useallattempts) { $usingattempts = $allattempts; $usingattempts->attempts = get_string('allattempts', 'quiz_statistics'); $usingattempts->sql = ''; } else { $usingattempts = $firstattempt; $usingattempts->attempts = get_string('firstattempts', 'quiz_statistics'); $usingattempts->sql = 'AND qa.attempt=1 '; } $usingattemptsstring = $usingattempts->attempts; $s = $usingattempts->countrecs; $sumgradesavg = $usingattempts->total / $usingattempts->countrecs; } } else { $s = 0; } $quizstats = new object(); if ($s == 0) { $quizstats->firstattemptscount = 0; $quizstats->allattemptscount = 0; } else { $quizstats->firstattemptscount = $firstattempt->countrecs; $quizstats->allattemptscount = $allattempts->countrecs; $quizstats->firstattemptsavg = $firstattempt->total / $firstattempt->countrecs; $quizstats->allattemptsavg = $allattempts->total / $allattempts->countrecs; } //recalculate sql again this time possibly including test for first attempt. list($fromqa, $whereqa, $qaparams) = quiz_report_attempts_sql($quizid, $currentgroup, $groupstudents, $useallattempts); //get the median if ($s) { if ($s % 2 == 0) { //even number of attempts $limitoffset = $s / 2 - 1; $limit = 2; } else { $limitoffset = floor($s / 2); $limit = 1; } $sql = 'SELECT id, sumgrades ' . 'FROM ' . $fromqa . 'WHERE ' . $whereqa . 'ORDER BY sumgrades'; if (!($mediangrades = $DB->get_records_sql_menu($sql, $qaparams, $limitoffset, $limit))) { print_error('errormedian', 'quiz_statistics'); } $quizstats->median = array_sum($mediangrades) / count($mediangrades); if ($s > 1) { //fetch sum of squared, cubed and power 4d //differences between grades and mean grade $mean = $usingattempts->total / $s; $sql = "SELECT " . "SUM(POWER((qa.sumgrades - :mean1),2)) AS power2, " . "SUM(POWER((qa.sumgrades - :mean2),3)) AS power3, " . "SUM(POWER((qa.sumgrades - :mean3),4)) AS power4 " . 'FROM ' . $fromqa . 'WHERE ' . $whereqa; $params = array('mean1' => $mean, 'mean2' => $mean, 'mean3' => $mean) + $qaparams; if (!($powers = $DB->get_record_sql($sql, $params))) { print_error('errorpowers', 'quiz_statistics'); } //Standard_Deviation //see http://docs.moodle.org/en/Development:Quiz_item_analysis_calculations_in_practise#Standard_Deviation $quizstats->standarddeviation = sqrt($powers->power2 / ($s - 1)); //Skewness_and_Kurtosis if ($s > 2) { //see http://docs.moodle.org/en/Development:Quiz_item_analysis_calculations_in_practise#Skewness_and_Kurtosis $m2 = $powers->power2 / $s; $m3 = $powers->power3 / $s; $m4 = $powers->power4 / $s; $k2 = $s * $m2 / ($s - 1); $k3 = $s * $s * $m3 / (($s - 1) * ($s - 2)); if ($k2) { $quizstats->skewness = $k3 / pow($k2, 3 / 2); } } if ($s > 3) { $k4 = $s * $s * (($s + 1) * $m4 - 3 * ($s - 1) * $m2 * $m2) / (($s - 1) * ($s - 2) * ($s - 3)); if ($k2) { $quizstats->kurtosis = $k4 / ($k2 * $k2); } } } } if ($s) { require_once "{$CFG->dirroot}/mod/quiz/report/statistics/qstats.php"; $qstats = new qstats($questions, $s, $sumgradesavg); $qstats->get_records($quizid, $currentgroup, $groupstudents, $useallattempts); $qstats->process_states(); $qstats->process_responses(); } else { $qstats = false; } if ($s > 1) { $p = count($qstats->questions); //no of positions if ($p > 1) { if (isset($k2)) { $quizstats->cic = 100 * $p / ($p - 1) * (1 - $qstats->sum_of_grade_variance() / $k2); $quizstats->errorratio = 100 * sqrt(1 - $quizstats->cic / 100); $quizstats->standarderror = $quizstats->errorratio * $quizstats->standarddeviation / 100; } } } return array($s, $usingattemptsstring, $quizstats, $qstats); }