]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-14204 "Content for Quiz Statistics report table - Random_guess_score" added metho...
authorjamiesensei <jamiesensei>
Mon, 16 Jun 2008 13:29:00 +0000 (13:29 +0000)
committerjamiesensei <jamiesensei>
Mon, 16 Jun 2008 13:29:00 +0000 (13:29 +0000)
12 files changed:
lang/en_utf8/quiz_statistics.php
lib/questionlib.php
mod/quiz/report/statistics/report.php
mod/quiz/report/statistics/statistics_table.php
question/type/match/questiontype.php
question/type/multianswer/questiontype.php
question/type/multichoice/questiontype.php
question/type/questiontype.php
question/type/random/questiontype.php
question/type/randomsamatch/questiontype.php
question/type/shortanswer/questiontype.php
question/type/truefalse/questiontype.php

index f6341df9f35a43ab1cb655011c004e0aad6a0819..7e2ef1abb402654eeb05537629e289d766dc32f7 100644 (file)
@@ -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';
 ?>
\ No newline at end of file
index 153d7bf1a655958a2d5f6a3545ab9779ea5b8bb1..d47bace320313bf2fb6d1749d9ec805c2cb4527b 100644 (file)
@@ -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 /////////////////////////////////////////////////////////////////
 
 /**
index ea931266da3852651487cea235010785360225de..50a4fd4d272435c422fb93bd4c92d033677ef06a 100644 (file)
@@ -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,8 +54,12 @@ 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'),
                     "$course->shortname ".format_string($quiz->name,true));
@@ -170,97 +173,105 @@ class quiz_report extends quiz_default_report {
                 $median += array_shift($mediangrades);
                 $median = $median /2;
             }
-            //fetch sum of squared, cubed and power 4d 
-            //differences between grades and mean grade
-            $mean = $usingattempts->total / $usingattempts->countrecs;
-            $sql = "SELECT " .
-                "SUM(POWER((qa.sumgrades - ?),2)) AS power2, " .
-                "SUM(POWER((qa.sumgrades - ?),3)) AS power3, ".
-                "SUM(POWER((qa.sumgrades - ?),4)) AS power4 ".
-                'FROM ' .$fromqa.
-                'WHERE ' .$whereqa.
-                $usingattempts->sql;
-            $params = array($mean, $mean, $mean, $quiz->id);
-            if (!$powers = $DB->get_record_sql($sql, $params)){
-                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));
-            
-            //Skewness_and_Kurtosis
-            //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));
-            $k4= (($s*$s*$s)/(($s-1)*($s-2)*($s-3)))*((($s+1)*$m4)-(3*($s-1)*$m2*$m2));
-            
-            $skewness = $k3 / (pow($k2, 2/3));
-            $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 " .
-                    "{question_sessions} qns, " .
-                    "{question_states} qs, " .
-                    "{question} q, " .
-                    $fromqa.' '.
-                    'WHERE ' .$whereqa.
-                    'AND qns.attemptid = qa.uniqueid '.
-                    'AND qs.question = q.id ' .
-                    'AND q.length > 0 '.
-                    $usingattempts->sql.
-                    'AND qns.newgraded = qs.id GROUP BY qs.question';
-            $qgradeavgs = $DB->get_records_sql_menu($qgradeavgsql, array($quiz->id));
-            $sum = 0;
-            $sql = 'SELECT ' .
-                    'SUM(POWER((qs.grade - ?),2)) AS power2 ' .
-                    'FROM ' .
-                    '{question_sessions} qns, ' .
-                    '{question_states} qs, ' .
-                    '{question} q, ' .
-                    $fromqa.' '.
+            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;
+                $sql = "SELECT " .
+                    "SUM(POWER((qa.sumgrades - ?),2)) AS power2, " .
+                    "SUM(POWER((qa.sumgrades - ?),3)) AS power3, ".
+                    "SUM(POWER((qa.sumgrades - ?),4)) AS power4 ".
+                    'FROM ' .$fromqa.
                     'WHERE ' .$whereqa.
-                    'AND qns.attemptid = qa.uniqueid '.
-                    'AND qs.question = ? ' .
-                    $usingattempts->sql.
-                    'AND qns.newgraded = qs.id';
-            foreach ($qgradeavgs as $qid => $qgradeavg){
-                $params = array($qgradeavg, $quiz->id, $qid);
-                $power = $DB->get_field_sql($sql, $params);
-                if ($power === false){
-                    print_error('errorpowerquestions', 'quiz_statistics');
+                    $usingattempts->sql;
+                $params = array($mean, $mean, $mean, $quiz->id);
+                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
+                
+                $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;
+                    $m4= $powers->power4 / $s;
+                    
+                    $k2= $s*$m2/($s-1);
+                    $k3= $s*$s*$m3/(($s-1)*($s-2));
+                    
+                    $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->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 " .
+                        "{question_sessions} qns, " .
+                        "{question_states} qs, " .
+                        "{question} q, " .
+                        $fromqa.' '.
+                        'WHERE ' .$whereqa.
+                        'AND qns.attemptid = qa.uniqueid '.
+                        'AND qs.question = q.id ' .
+                        'AND q.length > 0 '.
+                        $usingattempts->sql.
+                        'AND qns.newgraded = qs.id GROUP BY qs.question';
+                $qgradeavgs = $DB->get_records_sql_menu($qgradeavgsql, array($quiz->id));
+                $sum = 0;
+                $sql = 'SELECT ' .
+                        'SUM(POWER((qs.grade - ?),2)) AS power2 ' .
+                        'FROM ' .
+                        '{question_sessions} qns, ' .
+                        '{question_states} qs, ' .
+                        '{question} q, ' .
+                        $fromqa.' '.
+                        'WHERE ' .$whereqa.
+                        'AND qns.attemptid = qa.uniqueid '.
+                        'AND qs.question = ? ' .
+                        $usingattempts->sql.
+                        'AND qns.newgraded = qs.id';
+                foreach ($qgradeavgs as $qid => $qgradeavg){
+                    $params = array($qgradeavg, $quiz->id, $qid);
+                    $power = $DB->get_field_sql($sql, $params);
+                    if ($power === false){
+                        print_error('errorpowerquestions', 'quiz_statistics');
+                    }
+                    $sum += $power;
                 }
-                $sum += $power;
+                $sumofvarianceforallpositions = $sum / ($usingattempts->countrecs -1);
+                $p = count($qgradeavgs);//no of positions
+                $cic = (100 * $p / ($p -1)) * (1 - ($sumofvarianceforallpositions/$k2));
+                $quizattsstatistics->data[] = array(get_string('cic', 'quiz_statistics'), number_format($cic, $quiz->decimalpoints).' %');
+                $errorratio = 100 * sqrt(1-($cic/100));
+                $quizattsstatistics->data[] = array(get_string('errorratio', 'quiz_statistics'), number_format($errorratio, $quiz->decimalpoints).' %');
+                $standarderror = ($errorratio * $sd / 100);
+                $quizattsstatistics->data[] = array(get_string('standarderror', 'quiz_statistics'), 
+                    quiz_report_scale_sumgrades_as_percentage($standarderror, $quiz));
+                print_table($quizattsstatistics);
             }
-            $sumofvarianceforallpositions = $sum / ($usingattempts->countrecs -1);
-            $p = count($qgradeavgs);//no of positions
-            $cic = (100 * $p / ($p -1)) * (1 - ($sumofvarianceforallpositions/$k2));
-            $quizattsstatistics->data[] = array(get_string('cic', 'quiz_statistics'), number_format($cic, $quiz->decimalpoints).' %');
-            $errorratio = 100 * sqrt(1-($cic/100));
-            $quizattsstatistics->data[] = array(get_string('errorratio', 'quiz_statistics'), number_format($errorratio, $quiz->decimalpoints).' %');
-            $standarderror = ($errorratio * $sd / 100);
-            $quizattsstatistics->data[] = array(get_string('standarderror', 'quiz_statistics'), 
-                quiz_report_scale_sumgrades_as_percentage($standarderror, $quiz));
-            print_table($quizattsstatistics);
             
         }
         if (!$table->is_downloading()){
index 6d4889c36a29a6ff033726d90e37c6939b084703..6d308a1b31df2cc051f208e8be1cc675a738ebc3 100644 (file)
@@ -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).' %';
+    }
+            
 
 }
 ?>
index 9eb5893696d4bc5e7f032d088c88b01db1e646fe..f0c56b55cfdb857175765a4457c30c7a97320fb5 100644 (file)
@@ -425,6 +425,16 @@ class question_match_qtype extends default_questiontype {
         // This should almost certainly be overridden
         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 ////////////////////////////
 
index b92324f8a60adf50de2a89fca39b3b2b40e1a171..7e01145c9436aa519e3fade1e3a4767d7d0f3ea6 100644 (file)
@@ -514,6 +514,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 ////////////////////////////
 
index f5da87a84a68ee140e0e6647aeeadf711f31f140..d81ff88d28480d99b1d7e252fed0b6a302db7425 100644 (file)
@@ -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 ////////////////////////////
 
     /*
index 3118e4d5343ea98598b493c201402a2ffccb1d47..9c8d20209bc7736daee7c1a21905cd5cf799fd4b 100644 (file)
@@ -674,7 +674,15 @@ class default_questiontype {
             return null;
         }
     }
-
+    
+    /**
+     * @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
index a4ab63a73867c3433782940e834e0b03db0aa468..e0dbb459e8e0b06f6b2dd890f9f6caee11be49ff 100644 (file)
@@ -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 {
index 3350f67baf9b1fa260af71bc89c393d6f9ee34a0..cf034ece1f633f09b8311ca41181fa247c52ce39 100644 (file)
@@ -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 ////////////////////////////
 
     /*
index c6e0904be418dbcb80198b91370917142fb82fd3..99b10546565d2cac735fd079d4b5e9bcbb9b68d7 100644 (file)
@@ -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 ////////////////////////////
 
     /*
index 5f3c00eb5f4c4f6ca1e7d4eb28e953ccd850e204..8017f5fa4d886bb2068bb64f7c97511bbc1d16bd 100644 (file)
@@ -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 ////////////////////////////