MDL-41757 quiz statistics : limit subq and variant stat rows
[moodle.git] / question / classes / statistics / questions / calculated.php
CommitLineData
515b3ae6
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 * Question statistics calculations class. Used in the quiz statistics report but also available for use elsewhere.
19 *
20 * @package core
21 * @subpackage questionbank
22 * @copyright 2013 Open University
23 * @author Jamie Pratt <me@jamiep.org>
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
26
27namespace core_question\statistics\questions;
28defined('MOODLE_INTERNAL') || die();
29
30/**
31 * This class is used to return the stats as calculated by {@link \core_question\statistics\questions\calculator}
32 *
33 * @copyright 2013 Open University
34 * @author Jamie Pratt <me@jamiep.org>
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36 */
37class calculated {
38
39 public $questionid;
40
515b3ae6
JP
41 // These first fields are the final fields cached in the db and shown in reports.
42
43 // See : http://docs.moodle.org/dev/Quiz_statistics_calculations#Position_statistics .
44
45 public $slot = null;
46
1239d287
JP
47 /**
48 * @var null|integer if this property is not null then this is the stats for a variant of a question or when inherited by
49 * calculated_for_subquestion and not null then this is the stats for a variant of a sub question.
50 */
51 public $variant = null;
52
515b3ae6
JP
53 /**
54 * @var bool is this a sub question.
55 */
56 public $subquestion = false;
57
df9ddae6
JP
58 /**
59 * @var string if this stat has been picked as a min, median or maximum facility value then this string says which stat this
60 * is.
61 */
62 public $minmedianmaxnotice = '';
63
515b3ae6
JP
64 /**
65 * @var int total attempts at this question.
66 */
67 public $s = 0;
68
69 /**
70 * @var float effective weight of this question.
71 */
72 public $effectiveweight;
73
74 /**
75 * @var bool is covariance of this questions mark with other question marks negative?
76 */
77 public $negcovar;
78
79 /**
80 * @var float
81 */
82 public $discriminationindex;
83
84 /**
85 * @var float
86 */
87 public $discriminativeefficiency;
88
89 /**
90 * @var float standard deviation
91 */
92 public $sd;
93
94 /**
95 * @var float
96 */
97 public $facility;
98
99 /**
100 * @var float max mark achievable for this question.
101 */
102 public $maxmark;
103
104 /**
105 * @var string comma separated list of the positions in which this question appears.
106 */
107 public $positions;
108
109 /**
110 * @var null|float The average score that students would have got by guessing randomly. Or null if not calculable.
111 */
112 public $randomguessscore = null;
113
8e328617 114
515b3ae6
JP
115 // End of fields in db.
116
117 protected $fieldsindb = array('questionid', 'slot', 'subquestion', 's', 'effectiveweight', 'negcovar', 'discriminationindex',
1239d287 118 'discriminativeefficiency', 'sd', 'facility', 'subquestions', 'maxmark', 'positions', 'randomguessscore', 'variant');
515b3ae6
JP
119
120 // Fields used for intermediate calculations.
121
122 public $totalmarks = 0;
123
124 public $totalothermarks = 0;
125
8e328617
JP
126 /**
127 * @var float The total of marks achieved for all positions in all attempts where this item was seen.
128 */
129 public $totalsummarks = 0;
130
515b3ae6
JP
131 public $markvariancesum = 0;
132
133 public $othermarkvariancesum = 0;
134
135 public $covariancesum = 0;
136
137 public $covariancemaxsum = 0;
138
139 public $subquestions = '';
140
141 public $covariancewithoverallmarksum = 0;
142
143 public $markarray = array();
144
145 public $othermarksarray = array();
146
147 public $markaverage;
148
149 public $othermarkaverage;
150
8e328617
JP
151 /**
152 * @var float The average for all attempts, of the sum of the marks for all positions in which this item appeared.
153 */
154 public $summarksaverage;
155
515b3ae6
JP
156 public $markvariance;
157 public $othermarkvariance;
158 public $covariance;
159 public $covariancemax;
160 public $covariancewithoverallmark;
161
162 /**
163 * @var object full question data
164 */
165 public $question;
166
1239d287
JP
167 /**
168 * An array of calculated stats for each variant of the question. Even when there is just one variant we still calculate this
169 * data as there is no way to know if there are variants before we have finished going through the attempt data one time.
170 *
171 * @var calculated[] $variants
172 */
173 public $variantstats = array();
174
515b3ae6
JP
175 /**
176 * Set if this record has been retrieved from cache. This is the time that the statistics were calculated.
177 *
178 * @var integer
179 */
180 public $timemodified;
181
182 /**
183 * Cache calculated stats stored in this object in 'question_statistics' table.
184 *
185 * @param \qubaid_condition $qubaids
186 */
187 public function cache($qubaids) {
188 global $DB;
189 $toinsert = new \stdClass();
190 $toinsert->hashcode = $qubaids->get_hash_code();
191 $toinsert->timemodified = time();
192 foreach ($this->fieldsindb as $field) {
193 $toinsert->{$field} = $this->{$field};
194 }
195 $DB->insert_record('question_statistics', $toinsert, false);
1239d287
JP
196
197 if (count($this->variantstats) > 1) {
198 foreach ($this->variantstats as $variantstat) {
199 $variantstat->cache($qubaids);
200 }
201 }
515b3ae6
JP
202 }
203
204 /**
205 * @param object $record Given a record from 'question_statistics' copy stats from record to properties.
206 */
207 public function populate_from_record($record) {
208 foreach ($this->fieldsindb as $field) {
209 $this->$field = $record->$field;
210 }
211 $this->timemodified = $record->timemodified;
212 }
213
515b3ae6 214}