See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401]
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. 19 * 20 * @package core_question 21 * @copyright 2018 Ryan Wyllie <ryan@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core_question\statistics\questions; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 require_once($CFG->dirroot . '/question/engine/lib.php'); 30 31 /** 32 * Class calculated_question_summary 33 * 34 * This class is used to indicate the statistics for a random question slot should 35 * be rendered with a link to a summary of the displayed questions. 36 * 37 * It's used in the limited view of the statistics calculation in lieu of adding 38 * the stats for each subquestion individually. 39 * 40 * @copyright 2018 Ryan Wyllie <ryan@moodle.com> 41 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 42 */ 43 class calculated_question_summary extends calculated { 44 45 /** 46 * @var int only set immediately before display in the table. The order of display in the table. 47 */ 48 public $subqdisplayorder; 49 50 /** 51 * @var calculated[] The instances storing the calculated stats of the questions that are being summarised. 52 */ 53 protected $subqstats; 54 55 /** 56 * calculated_question_summary constructor. 57 * 58 * @param \stdClass $question 59 * @param int $slot 60 * @param calculated[] $subqstats The instances of the calculated stats of the questions that are being summarised. 61 */ 62 public function __construct($question, $slot, $subqstats) { 63 parent::__construct($question, $slot); 64 65 $this->subqstats = $subqstats; 66 $this->subquestions = implode(',', array_column($subqstats, 'questionid')); 67 } 68 69 /** 70 * This is a summary stat so never breakdown by variant. 71 * 72 * @return bool 73 */ 74 public function break_down_by_variant() { 75 return false; 76 } 77 78 /** 79 * Returns the minimum and maximum values of the given attribute in the summarised calculated stats. 80 * 81 * @param string $attribute The attribute that we are looking for its extremums. 82 * @return array An array of [min,max] 83 */ 84 public function get_min_max_of($attribute) { 85 $getmethod = 'get_min_max_of_' . $attribute; 86 if (method_exists($this, $getmethod)) { 87 return $this->$getmethod(); 88 } else { 89 $min = $max = null; 90 $set = false; 91 92 // We cannot simply use min or max functions because, in theory, some attributes might be non-scalar. 93 foreach (array_column($this->subqstats, $attribute) as $value) { 94 if (is_scalar($value) || is_null($value)) { 95 if (!$set) { // It is not good enough to check if (!isset($min)), 96 // because $min might have been set to null in an earlier iteration. 97 $min = $value; 98 $max = $value; 99 $set = true; 100 } 101 102 $min = $this->min($min, $value); 103 $max = $this->max($max, $value); 104 } 105 } 106 107 return [$min, $max]; 108 } 109 } 110 111 /** 112 * Returns the minimum and maximum values of the standard deviation in the summarised calculated stats. 113 * @return array An array of [min,max] 114 */ 115 protected function get_min_max_of_sd() { 116 $min = $max = null; 117 $set = false; 118 119 foreach ($this->subqstats as $subqstat) { 120 if (isset($subqstat->sd) && $subqstat->maxmark > \question_utils::MARK_TOLERANCE) { 121 $value = $subqstat->sd / $subqstat->maxmark; 122 } else { 123 $value = null; 124 } 125 126 if (!$set) { // It is not good enough to check if (!isset($min)), 127 // because $min might have been set to null in an earlier iteration. 128 $min = $value; 129 $max = $value; 130 $set = true; 131 } 132 133 $min = $this->min($min, $value); 134 $max = $this->max($max, $value); 135 } 136 137 return [$min, $max]; 138 } 139 140 /** 141 * Find higher value. 142 * A zero value is almost considered equal to zero in comparisons. The only difference is that when being compared to zero, 143 * zero is higher than null. 144 * 145 * @param float|null $value1 146 * @param float|null $value2 147 * @return float|null 148 */ 149 protected function max(float $value1 = null, float $value2 = null) { 150 $temp1 = $value1 ?: 0; 151 $temp2 = $value2 ?: 0; 152 153 $tempmax = max($temp1, $temp2); 154 155 if (!$tempmax && $value1 !== 0 && $value2 !== 0) { 156 $max = null; 157 } else { 158 $max = $tempmax; 159 } 160 161 return $max; 162 } 163 164 /** 165 * Find lower value. 166 * A zero value is almost considered equal to zero in comparisons. The only difference is that when being compared to zero, 167 * zero is lower than null. 168 * 169 * @param float|null $value1 170 * @param float|null $value2 171 * @return mixed|null 172 */ 173 protected function min(float $value1 = null, float $value2 = null) { 174 $temp1 = $value1 ?: 0; 175 $temp2 = $value2 ?: 0; 176 177 $tempmin = min($temp1, $temp2); 178 179 if (!$tempmin && $value1 !== 0 && $value2 !== 0) { 180 $min = null; 181 } else { 182 $min = $tempmin; 183 } 184 185 return $min; 186 } 187 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body