2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Question statistics calculations class. Used in the quiz statistics report but also available for use elsewhere.
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
27 namespace core_question\statistics\questions;
28 defined('MOODLE_INTERNAL') || die();
31 * This class is used to return the stats as calculated by {@link \core_question\statistics\questions\calculator}
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
41 // These first fields are the final fields cached in the db and shown in reports.
43 // See : http://docs.moodle.org/dev/Quiz_statistics_calculations#Position_statistics .
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.
51 public $variant = null;
54 * @var bool is this a sub question.
56 public $subquestion = false;
59 * @var int total attempts at this question.
64 * @var float effective weight of this question.
66 public $effectiveweight;
69 * @var bool is covariance of this questions mark with other question marks negative?
76 public $discriminationindex;
81 public $discriminativeefficiency;
84 * @var float standard deviation
94 * @var float max mark achievable for this question.
99 * @var string comma separated list of the positions in which this question appears.
104 * @var null|float The average score that students would have got by guessing randomly. Or null if not calculable.
106 public $randomguessscore = null;
109 // End of fields in db.
111 protected $fieldsindb = array('questionid', 'slot', 'subquestion', 's', 'effectiveweight', 'negcovar', 'discriminationindex',
112 'discriminativeefficiency', 'sd', 'facility', 'subquestions', 'maxmark', 'positions', 'randomguessscore', 'variant');
114 // Fields used for intermediate calculations.
116 public $totalmarks = 0;
118 public $totalothermarks = 0;
121 * @var float The total of marks achieved for all positions in all attempts where this item was seen.
123 public $totalsummarks = 0;
125 public $markvariancesum = 0;
127 public $othermarkvariancesum = 0;
129 public $covariancesum = 0;
131 public $covariancemaxsum = 0;
133 public $subquestions = '';
135 public $covariancewithoverallmarksum = 0;
137 public $markarray = array();
139 public $othermarksarray = array();
143 public $othermarkaverage;
146 * @var float The average for all attempts, of the sum of the marks for all positions in which this item appeared.
148 public $summarksaverage;
150 public $markvariance;
151 public $othermarkvariance;
153 public $covariancemax;
154 public $covariancewithoverallmark;
157 * @var object full question data
162 * An array of calculated stats for each variant of the question. Even when there is just one variant we still calculate this
163 * data as there is no way to know if there are variants before we have finished going through the attempt data one time.
165 * @var calculated[] $variants
167 public $variantstats = array();
170 * Set if this record has been retrieved from cache. This is the time that the statistics were calculated.
174 public $timemodified;
177 * Cache calculated stats stored in this object in 'question_statistics' table.
179 * @param \qubaid_condition $qubaids
181 public function cache($qubaids) {
183 $toinsert = new \stdClass();
184 $toinsert->hashcode = $qubaids->get_hash_code();
185 $toinsert->timemodified = time();
186 foreach ($this->fieldsindb as $field) {
187 $toinsert->{$field} = $this->{$field};
189 $DB->insert_record('question_statistics', $toinsert, false);
191 if (count($this->variantstats) > 1) {
192 foreach ($this->variantstats as $variantstat) {
193 $variantstat->cache($qubaids);
199 * @param object $record Given a record from 'question_statistics' copy stats from record to properties.
201 public function populate_from_record($record) {
202 foreach ($this->fieldsindb as $field) {
203 $this->$field = $record->$field;
205 $this->timemodified = $record->timemodified;