mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 00:46:50 +02:00
MDL-14204 "Content for Quiz Statistics report table - Random_guess_score" added method random_guess_score to question type objects and a new function in questionlib that calls the question type method.
This commit is contained in:
parent
ed48af75b4
commit
6f51ed72be
12 changed files with 201 additions and 96 deletions
|
@ -32,4 +32,5 @@ $string['questionnumber'] = 'Q#';
|
|||
$string['quizstructureanalysis'] = 'Quiz structure analysis';
|
||||
$string['questiontype'] = 'Q type';
|
||||
$string['intended_weight'] = 'Intended question weight';
|
||||
$string['random_guess_score'] = 'Random guess score';
|
||||
?>
|
|
@ -1794,8 +1794,16 @@ function get_question_fraction_grade($question, $state) {
|
|||
$r = $QTYPES[$question->qtype]->get_fractional_grade($question, $state);
|
||||
return $r;
|
||||
}
|
||||
/**
|
||||
* @return integer grade out of 1 that a random guess by a student might score.
|
||||
*/
|
||||
// ULPGc ecastro
|
||||
function get_random_guess_score($question) {
|
||||
global $QTYPES;
|
||||
|
||||
|
||||
$r = $QTYPES[$question->qtype]->get_random_guess_score($question);
|
||||
return $r;
|
||||
}
|
||||
/// CATEGORY FUNCTIONS /////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
* @package quiz
|
||||
*//** */
|
||||
|
||||
require_once($CFG->libdir.'/tablelib.php');
|
||||
require_once($CFG->dirroot.'/mod/quiz/report/statistics/statistics_form.php');
|
||||
require_once($CFG->dirroot.'/mod/quiz/report/statistics/statistics_table.php');
|
||||
|
||||
|
@ -55,7 +54,11 @@ class quiz_report extends quiz_default_report {
|
|||
$allowedlist = $groupstudentslist;
|
||||
}
|
||||
|
||||
$questions = question_load_questions(quiz_questions_in_quiz($quiz->questions));
|
||||
$questions = quiz_report_load_questions($quiz);
|
||||
// Load the question type specific information
|
||||
if (!get_question_options($questions)) {
|
||||
print_error('cannotloadquestion', 'question');
|
||||
}
|
||||
|
||||
$table = new quiz_report_statistics_table();
|
||||
$table->is_downloading($download, get_string('reportstatistics','quiz_statistics'),
|
||||
|
@ -170,6 +173,15 @@ class quiz_report extends quiz_default_report {
|
|||
$median += array_shift($mediangrades);
|
||||
$median = $median /2;
|
||||
}
|
||||
|
||||
$s = $usingattempts->countrecs;
|
||||
if ($s>1){
|
||||
$quizattsstatistics = new object();
|
||||
$quizattsstatistics->align = array('center', 'center');
|
||||
$quizattsstatistics->width = '60%';
|
||||
$quizattsstatistics->class = 'generaltable titlesleft';
|
||||
$quizattsstatistics->data = array();
|
||||
$quizattsstatistics->data[] = array(get_string('median', 'quiz_statistics'), quiz_report_scale_sumgrades_as_percentage($median, $quiz));
|
||||
//fetch sum of squared, cubed and power 4d
|
||||
//differences between grades and mean grade
|
||||
$mean = $usingattempts->total / $usingattempts->countrecs;
|
||||
|
@ -185,14 +197,15 @@ class quiz_report extends quiz_default_report {
|
|||
print_error('errorpowers', 'quiz_statistics');
|
||||
}
|
||||
|
||||
$s = $usingattempts->countrecs;
|
||||
|
||||
//Standard_Deviation
|
||||
//see http://docs.moodle.org/en/Development:Quiz_item_analysis_calculations_in_practise#Standard_Deviation
|
||||
|
||||
$sd = sqrt($powers->power2 / ($s -1));
|
||||
$quizattsstatistics->data[] = array(get_string('standarddeviation', 'quiz_statistics'), quiz_report_scale_sumgrades_as_percentage($sd, $quiz));
|
||||
|
||||
|
||||
//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;
|
||||
|
@ -200,22 +213,19 @@ class quiz_report extends quiz_default_report {
|
|||
|
||||
$k2= $s*$m2/($s-1);
|
||||
$k3= $s*$s*$m3/(($s-1)*($s-2));
|
||||
$k4= (($s*$s*$s)/(($s-1)*($s-2)*($s-3)))*((($s+1)*$m4)-(3*($s-1)*$m2*$m2));
|
||||
|
||||
$skewness = $k3 / (pow($k2, 2/3));
|
||||
$quizattsstatistics->data[] = array(get_string('skewness', 'quiz_statistics'), $skewness);
|
||||
}
|
||||
|
||||
|
||||
if ($s>3){
|
||||
$k4= (($s*$s*$s)/(($s-1)*($s-2)*($s-3)))*((($s+1)*$m4)-(3*($s-1)*$m2*$m2));
|
||||
|
||||
$kurtosis = $k4 / ($k2*$k2);
|
||||
|
||||
$quizattsstatistics = new object();
|
||||
$quizattsstatistics->align = array('center', 'center');
|
||||
$quizattsstatistics->width = '60%';
|
||||
$quizattsstatistics->class = 'generaltable titlesleft';
|
||||
$quizattsstatistics->data = array();
|
||||
|
||||
$quizattsstatistics->data[] = array(get_string('median', 'quiz_statistics'), quiz_report_scale_sumgrades_as_percentage($median, $quiz));
|
||||
$quizattsstatistics->data[] = array(get_string('standarddeviation', 'quiz_statistics'), quiz_report_scale_sumgrades_as_percentage($sd, $quiz));
|
||||
$quizattsstatistics->data[] = array(get_string('skewness', 'quiz_statistics'), $skewness);
|
||||
$quizattsstatistics->data[] = array(get_string('kurtosis', 'quiz_statistics'), $kurtosis);
|
||||
|
||||
}
|
||||
//CIC, ER and SE.
|
||||
//http://docs.moodle.org/en/Development:Quiz_item_analysis_calculations_in_practise#CIC.2C_ER_and_SE
|
||||
$qgradeavgsql = "SELECT qs.question, AVG(qs.grade) FROM " .
|
||||
|
@ -261,6 +271,7 @@ class quiz_report extends quiz_default_report {
|
|||
$quizattsstatistics->data[] = array(get_string('standarderror', 'quiz_statistics'),
|
||||
quiz_report_scale_sumgrades_as_percentage($standarderror, $quiz));
|
||||
print_table($quizattsstatistics);
|
||||
}
|
||||
|
||||
}
|
||||
if (!$table->is_downloading()){
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php // $Id$
|
||||
require_once($CFG->libdir.'/tablelib.php');
|
||||
|
||||
class quiz_report_statistics_table extends flexible_table {
|
||||
|
||||
|
@ -37,6 +38,9 @@ class quiz_report_statistics_table extends flexible_table {
|
|||
$columns[]= 'intended_weight';
|
||||
$headers[]= get_string('intended_weight', 'quiz_statistics');
|
||||
|
||||
$columns[]= 'random_guess_score';
|
||||
$headers[]= get_string('random_guess_score', 'quiz_statistics');
|
||||
|
||||
$this->define_columns($columns);
|
||||
$this->define_headers($headers);
|
||||
$this->sortable(false);
|
||||
|
@ -59,6 +63,7 @@ class quiz_report_statistics_table extends flexible_table {
|
|||
$this->column_class('sumgrades', 'bold');*/
|
||||
|
||||
$this->column_class('intended_weight', 'numcol');
|
||||
$this->column_class('random_guess_score', 'numcol');
|
||||
|
||||
$this->set_attribute('id', 'questionstatistics');
|
||||
$this->set_attribute('class', 'generaltable generalbox boxaligncenter');
|
||||
|
@ -89,6 +94,10 @@ class quiz_report_statistics_table extends flexible_table {
|
|||
return quiz_report_scale_sumgrades_as_percentage($question->grade, $this->quiz);
|
||||
}
|
||||
|
||||
function col_random_guess_score($question){
|
||||
return number_format(get_random_guess_score($question) * 100, 2).' %';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -426,6 +426,16 @@ class question_match_qtype extends default_questiontype {
|
|||
return substr(implode(', ', $this->get_actual_response($question, $state)), 0, $length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param object $question
|
||||
* @return integer a score out of 1 that the average random guess by a
|
||||
* student might give.
|
||||
*/
|
||||
function get_random_guess_score($question) {
|
||||
return 1 / count($question->options->subquestions);
|
||||
}
|
||||
|
||||
/// BACKUP FUNCTIONS ////////////////////////////
|
||||
|
||||
/*
|
||||
|
|
|
@ -515,6 +515,19 @@ class embedded_cloze_qtype extends default_questiontype {
|
|||
return $responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $question
|
||||
* @return integer a score out of 1 that the average random guess by a
|
||||
* student might give.
|
||||
*/
|
||||
function get_random_guess_score($question) {
|
||||
$totalfraction = 0;
|
||||
foreach (array_keys($question->options->questions) as $key){
|
||||
$totalfraction += get_random_guess_score($question->options->questions[$key]);
|
||||
}
|
||||
return $totalfraction / count($question->options->questions);
|
||||
}
|
||||
|
||||
/// BACKUP FUNCTIONS ////////////////////////////
|
||||
|
||||
/*
|
||||
|
|
|
@ -396,7 +396,18 @@ class question_multichoice_qtype extends default_questiontype {
|
|||
function response_summary($question, $state, $length = 80) {
|
||||
return implode(',', $this->get_actual_response($question, $state));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $question
|
||||
* @return integer a score out of 1 that the average random guess by a
|
||||
* student might give.
|
||||
*/
|
||||
function get_random_guess_score($question) {
|
||||
$totalfraction = 0;
|
||||
foreach ($question->options->answers as $answer){
|
||||
$totalfraction += $answer->fraction;
|
||||
}
|
||||
return $totalfraction / count($question->options->answers);
|
||||
}
|
||||
/// BACKUP FUNCTIONS ////////////////////////////
|
||||
|
||||
/*
|
||||
|
|
|
@ -675,6 +675,14 @@ class default_questiontype {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $question
|
||||
* @return integer a score out of 1 that the average random guess by a
|
||||
* student might give.
|
||||
*/
|
||||
function get_random_guess_score($question) {
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Return the actual response to the question in a given state
|
||||
* for the question
|
||||
|
|
|
@ -101,7 +101,7 @@ class random_qtype extends default_questiontype {
|
|||
AND parent = '0'
|
||||
AND hidden = '0'
|
||||
AND id NOT IN ($cmoptions->questionsinuse)
|
||||
AND qtype NOT IN ($QTYPE_EXCLUDE_FROM_RANDOM)", '', 'id')) {
|
||||
AND qtype NOT IN ($QTYPE_EXCLUDE_FROM_RANDOM)", array(), '', 'id')) {
|
||||
$this->catrandoms[$question->category][$question->questiontext] =
|
||||
draw_rand_array($catrandoms, count($catrandoms));
|
||||
} else {
|
||||
|
|
|
@ -272,7 +272,20 @@ class question_randomsamatch_qtype extends question_match_qtype {
|
|||
$result->responses = $answers;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $question
|
||||
* @return integer a score out of 1 that the average random guess by a
|
||||
* student might give.
|
||||
*/
|
||||
function get_random_guess_score($question) {
|
||||
//Effectively $subquestions multi choice questions with equal weighting
|
||||
//assuming a student has the intelligence to not select the same answer twice
|
||||
//there is in each subquestion factorial($subquestions-1) chance of getting
|
||||
//the answer right. There are factorial($subquestions) possible combinations of
|
||||
//answers and it works out to an average grade of 1/$subquestions.
|
||||
$subquestions = count($question->options->subquestions);
|
||||
return 1/$subquestions;
|
||||
}
|
||||
/// BACKUP FUNCTIONS ////////////////////////////
|
||||
|
||||
/*
|
||||
|
|
|
@ -239,7 +239,20 @@ class question_shortanswer_qtype extends default_questiontype {
|
|||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $question
|
||||
* @return integer a score out of 1 that the average random guess by a
|
||||
* student might give.
|
||||
*/
|
||||
function get_random_guess_score($question) {
|
||||
$answers = &$question->options->answers;
|
||||
foreach($answers as $aid => $answer) {
|
||||
if ('*' == trim($answer->answer)){
|
||||
return $answer->fraction;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/// BACKUP FUNCTIONS ////////////////////////////
|
||||
|
||||
/*
|
||||
|
|
|
@ -245,6 +245,14 @@ class question_truefalse_qtype extends default_questiontype {
|
|||
}
|
||||
return $responses;
|
||||
}
|
||||
/**
|
||||
* @param object $question
|
||||
* @return integer a score out of 1 that the average random guess by a
|
||||
* student might give.
|
||||
*/
|
||||
function get_random_guess_score($question) {
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
/// BACKUP FUNCTIONS ////////////////////////////
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue