MDL-41751 changes to api of question_response_analyser
[moodle.git] / mod / quiz / report / statistics / classes / calculated.php
CommitLineData
7de1e35b
JP
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * The statistics calculator returns an instance of this class which contains the calculated statistics.
19 *
522bef80
JP
20 * These quiz statistics calculations are described here :
21 *
22 * http://docs.moodle.org/dev/Quiz_statistics_calculations#Test_statistics
23 *
7de1e35b
JP
24 * @package quiz_statistics
25 * @copyright 2013 The Open University
26 * @author James Pratt me@jamiep.org
27 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
28 */
29class quiz_statistics_calculated {
30
31 public function __construct($allattempts = null) {
32 if ($allattempts !== null) {
33 $this->allattempts = $allattempts;
34 }
35 }
36
37 /**
38 * @var bool whether we are calculating calculate stats from all attempts.
39 */
40 public $allattempts;
41
522bef80
JP
42 /* Following stats all described here : http://docs.moodle.org/dev/Quiz_statistics_calculations#Test_statistics */
43
7de1e35b
JP
44 public $firstattemptscount = 0;
45
46 public $allattemptscount = 0;
47
48 public $firstattemptsavg;
49
50 public $allattemptsavg;
51
7de1e35b
JP
52 public $median;
53
54 public $standarddeviation;
55
56 public $skewness;
57
58 public $kurtosis;
59
60 public $cic;
61
62 public $errorratio;
63
64 public $standarderror;
65
522bef80
JP
66 /**
67 * @var int time these stats where calculated and cached.
68 */
7de1e35b
JP
69 public $timemodified;
70
71 public function s() {
72 if ($this->allattempts) {
73 return $this->allattemptscount;
74 } else {
75 return $this->firstattemptscount;
76 }
77 }
78
79 public function avg() {
80 if ($this->allattempts) {
81 return $this->allattemptsavg;
82 } else {
83 return $this->firstattemptsavg;
84 }
85 }
86
7de1e35b
JP
87 /**
88 * @param $course
89 * @param $cm
90 * @param $quiz
91 * @return array to display in table or spreadsheet.
92 */
93 public function get_formatted_quiz_info_data($course, $cm, $quiz) {
94
95 // You can edit this array to control which statistics are displayed.
96 $todisplay = array('firstattemptscount' => 'number',
97 'allattemptscount' => 'number',
98 'firstattemptsavg' => 'summarks_as_percentage',
99 'allattemptsavg' => 'summarks_as_percentage',
100 'median' => 'summarks_as_percentage',
101 'standarddeviation' => 'summarks_as_percentage',
102 'skewness' => 'number_format',
103 'kurtosis' => 'number_format',
104 'cic' => 'number_format_percent',
105 'errorratio' => 'number_format_percent',
106 'standarderror' => 'summarks_as_percentage');
107
108 // General information about the quiz.
109 $quizinfo = array();
110 $quizinfo[get_string('quizname', 'quiz_statistics')] = format_string($quiz->name);
111 $quizinfo[get_string('coursename', 'quiz_statistics')] = format_string($course->fullname);
112 if ($cm->idnumber) {
113 $quizinfo[get_string('idnumbermod')] = $cm->idnumber;
114 }
115 if ($quiz->timeopen) {
116 $quizinfo[get_string('quizopen', 'quiz')] = userdate($quiz->timeopen);
117 }
118 if ($quiz->timeclose) {
119 $quizinfo[get_string('quizclose', 'quiz')] = userdate($quiz->timeclose);
120 }
121 if ($quiz->timeopen && $quiz->timeclose) {
122 $quizinfo[get_string('duration', 'quiz_statistics')] =
123 format_time($quiz->timeclose - $quiz->timeopen);
124 }
125
126 // The statistics.
127 foreach ($todisplay as $property => $format) {
933ac749 128 if (!isset($this->$property) || !$format) {
7de1e35b
JP
129 continue;
130 }
131 $value = $this->$property;
132
133 switch ($format) {
134 case 'summarks_as_percentage':
135 $formattedvalue = quiz_report_scale_summarks_as_percentage($value, $quiz);
136 break;
137 case 'number_format_percent':
138 $formattedvalue = quiz_format_grade($quiz, $value) . '%';
139 break;
140 case 'number_format':
141 // 2 extra decimal places, since not a percentage,
142 // and we want the same number of sig figs.
143 $formattedvalue = format_float($value, $quiz->decimalpoints + 2);
144 break;
145 case 'number':
146 $formattedvalue = $value + 0;
147 break;
148 default:
149 $formattedvalue = $value;
150 }
151
152 $quizinfo[get_string($property, 'quiz_statistics', $this->using_attempts_string())] = $formattedvalue;
153 }
154
155 return $quizinfo;
156 }
157
158 /**
159 * @return string the appropriate lang string to describe this option.
160 */
161 protected function using_attempts_string() {
162 if ($this->allattempts) {
163 return get_string('allattempts', 'quiz_statistics');
164 } else {
165 return get_string('firstattempts', 'quiz_statistics');
166 }
167 }
168
522bef80
JP
169 /**
170 * @var array of names of properties of this class that are cached in db record.
171 */
7de1e35b
JP
172 protected $fieldsindb = array('allattempts', 'firstattemptscount', 'allattemptscount', 'firstattemptsavg', 'allattemptsavg',
173 'median', 'standarddeviation', 'skewness',
174 'kurtosis', 'cic', 'errorratio', 'standarderror');
175
176 /**
522bef80
JP
177 * Cache the stats contained in this class.
178 *
7de1e35b
JP
179 * @param $qubaids qubaid_condition
180 */
181 public function cache($qubaids) {
182 global $DB;
183
184 $toinsert = new stdClass();
185
186 foreach ($this->fieldsindb as $field) {
187 $toinsert->{$field} = $this->{$field};
188 }
189
190 $toinsert->hashcode = $qubaids->get_hash_code();
191 $toinsert->timemodified = time();
192
193 // Fix up some dodgy data.
194 if (isset($toinsert->errorratio) && is_nan($toinsert->errorratio)) {
195 $toinsert->errorratio = null;
196 }
197 if (isset($toinsert->standarderror) && is_nan($toinsert->standarderror)) {
198 $toinsert->standarderror = null;
199 }
200
201 // Store the data.
202 $DB->insert_record('quiz_statistics', $toinsert);
203
204 }
205
522bef80
JP
206 /**
207 * Given a record from 'quiz_statistics' table load the data into the properties of this class.
208 *
209 * @param $record from db.
210 */
7de1e35b
JP
211 public function populate_from_record($record) {
212 foreach ($this->fieldsindb as $field) {
213 $this->$field = $record->$field;
214 }
215 $this->timemodified = $record->timemodified;
216 }
217}