[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/quiz/report/statistics/ -> statistics_table.php (source)

   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   * Quiz statistics report, table for showing statistics of each question in the quiz.
  19   *
  20   * @package   quiz_statistics
  21   * @copyright 2008 Jamie Pratt
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  require_once($CFG->libdir.'/tablelib.php');
  28  
  29  /**
  30   * This table has one row for each question in the quiz, with sub-rows when
  31   * random questions and variants appear.
  32   *
  33   * There are columns for the various item and position statistics.
  34   *
  35   * @copyright 2008 Jamie Pratt
  36   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  37   */
  38  class quiz_statistics_table extends flexible_table {
  39      /** @var object the quiz settings. */
  40      protected $quiz;
  41  
  42      /** @var integer the quiz course_module id. */
  43      protected $cmid;
  44  
  45      /**
  46       * Constructor.
  47       */
  48      public function __construct() {
  49          parent::__construct('mod-quiz-report-statistics-report');
  50      }
  51  
  52      /**
  53       * Set up the columns and headers and other properties of the table and then
  54       * call flexible_table::setup() method.
  55       *
  56       * @param object $quiz the quiz settings
  57       * @param int $cmid the quiz course_module id
  58       * @param moodle_url $reporturl the URL to redisplay this report.
  59       * @param int $s number of attempts included in the statistics.
  60       */
  61      public function statistics_setup($quiz, $cmid, $reporturl, $s) {
  62          $this->quiz = $quiz;
  63          $this->cmid = $cmid;
  64  
  65          // Define the table columns.
  66          $columns = array();
  67          $headers = array();
  68  
  69          $columns[] = 'number';
  70          $headers[] = get_string('questionnumber', 'quiz_statistics');
  71  
  72          if (!$this->is_downloading()) {
  73              $columns[] = 'icon';
  74              $headers[] = '';
  75              $columns[] = 'actions';
  76              $headers[] = '';
  77          } else {
  78              $columns[] = 'qtype';
  79              $headers[] = get_string('questiontype', 'quiz_statistics');
  80          }
  81  
  82          $columns[] = 'name';
  83          $headers[] = get_string('questionname', 'quiz');
  84  
  85          $columns[] = 's';
  86          $headers[] = get_string('attempts', 'quiz_statistics');
  87  
  88          if ($s > 1) {
  89              $columns[] = 'facility';
  90              $headers[] = get_string('facility', 'quiz_statistics');
  91  
  92              $columns[] = 'sd';
  93              $headers[] = get_string('standarddeviationq', 'quiz_statistics');
  94          }
  95  
  96          $columns[] = 'random_guess_score';
  97          $headers[] = get_string('random_guess_score', 'quiz_statistics');
  98  
  99          $columns[] = 'intended_weight';
 100          $headers[] = get_string('intended_weight', 'quiz_statistics');
 101  
 102          $columns[] = 'effective_weight';
 103          $headers[] = get_string('effective_weight', 'quiz_statistics');
 104  
 105          $columns[] = 'discrimination_index';
 106          $headers[] = get_string('discrimination_index', 'quiz_statistics');
 107  
 108          $columns[] = 'discriminative_efficiency';
 109          $headers[] = get_string('discriminative_efficiency', 'quiz_statistics');
 110  
 111          $this->define_columns($columns);
 112          $this->define_headers($headers);
 113          $this->sortable(false);
 114  
 115          $this->column_class('s', 'numcol');
 116          $this->column_class('facility', 'numcol');
 117          $this->column_class('sd', 'numcol');
 118          $this->column_class('random_guess_score', 'numcol');
 119          $this->column_class('intended_weight', 'numcol');
 120          $this->column_class('effective_weight', 'numcol');
 121          $this->column_class('discrimination_index', 'numcol');
 122          $this->column_class('discriminative_efficiency', 'numcol');
 123  
 124          // Set up the table.
 125          $this->define_baseurl($reporturl->out());
 126  
 127          $this->collapsible(true);
 128  
 129          $this->set_attribute('id', 'questionstatistics');
 130          $this->set_attribute('class', 'generaltable generalbox boxaligncenter');
 131  
 132          parent::setup();
 133      }
 134  
 135      /**
 136       * The question number.
 137       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 138       * @return string contents of this table cell.
 139       */
 140      protected function col_number($questionstat) {
 141          if (!isset($questionstat->question->number)) {
 142              return '';
 143          }
 144          $number = $questionstat->question->number;
 145  
 146          if (isset($questionstat->subqdisplayorder)) {
 147              $number = $number . '.'.$questionstat->subqdisplayorder;
 148          }
 149  
 150          if ($questionstat->question->qtype != 'random' && !is_null($questionstat->variant)) {
 151              $number = $number . '.'.$questionstat->variant;
 152          }
 153  
 154          return $number;
 155      }
 156  
 157      /**
 158       * The question type icon.
 159       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 160       * @return string contents of this table cell.
 161       */
 162      protected function col_icon($questionstat) {
 163          return print_question_icon($questionstat->question, true);
 164      }
 165  
 166      /**
 167       * Actions that can be performed on the question by this user (e.g. edit or preview).
 168       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 169       * @return string contents of this table cell.
 170       */
 171      protected function col_actions($questionstat) {
 172          return quiz_question_action_icons($this->quiz, $this->cmid,
 173                  $questionstat->question, $this->baseurl, $questionstat->variant);
 174      }
 175  
 176      /**
 177       * The question type name.
 178       *
 179       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 180       * @return string contents of this table cell.
 181       */
 182      protected function col_qtype($questionstat) {
 183          return question_bank::get_qtype_name($questionstat->question->qtype);
 184      }
 185  
 186      /**
 187       * The question name.
 188       *
 189       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 190       * @return string contents of this table cell.
 191       */
 192      protected function col_name($questionstat) {
 193          $name = $questionstat->question->name;
 194  
 195          if (!is_null($questionstat->variant)) {
 196              $a = new stdClass();
 197              $a->name = $name;
 198              $a->variant = $questionstat->variant;
 199              $name = get_string('nameforvariant', 'quiz_statistics', $a);
 200          }
 201  
 202          if ($this->is_downloading()) {
 203              return $name;
 204          }
 205  
 206          $baseurl = new moodle_url($this->baseurl);
 207          if (!is_null($questionstat->variant)) {
 208              if ($questionstat->subquestion) {
 209                  // Variant of a sub-question.
 210                  $url = new moodle_url($baseurl, array('qid' => $questionstat->questionid, 'variant' => $questionstat->variant));
 211                  $name = html_writer::link($url, $name, array('title' => get_string('detailedanalysisforvariant',
 212                                                                                     'quiz_statistics',
 213                                                                                     $questionstat->variant)));
 214              } else if ($questionstat->slot) {
 215                  // Variant of a question in a slot.
 216                  $url = new moodle_url($baseurl, array('slot' => $questionstat->slot, 'variant' => $questionstat->variant));
 217                  $name = html_writer::link($url, $name, array('title' => get_string('detailedanalysisforvariant',
 218                                                                                     'quiz_statistics',
 219                                                                                     $questionstat->variant)));
 220              }
 221          } else {
 222              if ($questionstat->subquestion && !$questionstat->get_variants()) {
 223                  // Sub question without variants.
 224                  $url = new moodle_url($baseurl, array('qid' => $questionstat->questionid));
 225                  $name = html_writer::link($url, $name, array('title' => get_string('detailedanalysis', 'quiz_statistics')));
 226              } else if ($baseurl->param('slot') === null && $questionstat->slot) {
 227                  // Question in a slot, we are not on a page showing structural analysis of one slot,
 228                  // we don't want linking on those pages.
 229                  $number = $questionstat->question->number;
 230                  $url = new moodle_url($baseurl, array('slot' => $questionstat->slot));
 231                  if ($questionstat->get_variants() || $questionstat->get_sub_question_ids()) {
 232                      // Question can be broken down into sub-questions or variants. Link will show structural analysis page.
 233                      $name = html_writer::link($url,
 234                                                $name,
 235                                                array('title' => get_string('slotstructureanalysis', 'quiz_statistics', $number)));
 236                  } else {
 237                      // Question cannot be broken down into sub-questions or variants. Link will show response analysis page.
 238                      $name = html_writer::link($url,
 239                                                $name,
 240                                                array('title' => get_string('detailedanalysis', 'quiz_statistics')));
 241                  }
 242              }
 243          }
 244  
 245  
 246          if ($this->is_dubious_question($questionstat)) {
 247              $name = html_writer::tag('div', $name, array('class' => 'dubious'));
 248          }
 249  
 250          if (!empty($questionstat->minmedianmaxnotice)) {
 251              $name = get_string($questionstat->minmedianmaxnotice, 'quiz_statistics') . '<br />' . $name;
 252          }
 253  
 254          return $name;
 255      }
 256  
 257      /**
 258       * The number of attempts at this question.
 259       *
 260       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 261       * @return string contents of this table cell.
 262       */
 263      protected function col_s($questionstat) {
 264          if (!isset($questionstat->s)) {
 265              return 0;
 266          }
 267  
 268          return $questionstat->s;
 269      }
 270  
 271      /**
 272       * The facility index (average fraction).
 273       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 274       * @return string contents of this table cell.
 275       */
 276      protected function col_facility($questionstat) {
 277          if (is_null($questionstat->facility)) {
 278              return '';
 279          }
 280  
 281          return number_format($questionstat->facility*100, 2) . '%';
 282      }
 283  
 284      /**
 285       * The standard deviation of the fractions.
 286       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 287       * @return string contents of this table cell.
 288       */
 289      protected function col_sd($questionstat) {
 290          if (is_null($questionstat->sd) || $questionstat->maxmark == 0) {
 291              return '';
 292          }
 293  
 294          return number_format($questionstat->sd*100 / $questionstat->maxmark, 2) . '%';
 295      }
 296  
 297      /**
 298       * An estimate of the fraction a student would get by guessing randomly.
 299       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 300       * @return string contents of this table cell.
 301       */
 302      protected function col_random_guess_score($questionstat) {
 303          if (is_null($questionstat->randomguessscore)) {
 304              return '';
 305          }
 306  
 307          return number_format($questionstat->randomguessscore * 100, 2).'%';
 308      }
 309  
 310      /**
 311       * The intended question weight. Maximum mark for the question as a percentage
 312       * of maximum mark for the quiz. That is, the indended influence this question
 313       * on the student's overall mark.
 314       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 315       * @return string contents of this table cell.
 316       */
 317      protected function col_intended_weight($questionstat) {
 318          return quiz_report_scale_summarks_as_percentage($questionstat->maxmark, $this->quiz);
 319      }
 320  
 321      /**
 322       * The effective question weight. That is, an estimate of the actual
 323       * influence this question has on the student's overall mark.
 324       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 325       * @return string contents of this table cell.
 326       */
 327      protected function col_effective_weight($questionstat) {
 328          global $OUTPUT;
 329  
 330          if (is_null($questionstat->effectiveweight)) {
 331              return '';
 332          }
 333  
 334          if ($questionstat->negcovar) {
 335              $negcovar = get_string('negcovar', 'quiz_statistics');
 336  
 337              if (!$this->is_downloading()) {
 338                  $negcovar = html_writer::tag('div',
 339                          $negcovar . $OUTPUT->help_icon('negcovar', 'quiz_statistics'),
 340                          array('class' => 'negcovar'));
 341              }
 342  
 343              return $negcovar;
 344          }
 345  
 346          return number_format($questionstat->effectiveweight, 2) . '%';
 347      }
 348  
 349      /**
 350       * Discrimination index. This is the product moment correlation coefficient
 351       * between the fraction for this question, and the average fraction for the
 352       * other questions in this quiz.
 353       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 354       * @return string contents of this table cell.
 355       */
 356      protected function col_discrimination_index($questionstat) {
 357          if (!is_numeric($questionstat->discriminationindex)) {
 358              return $questionstat->discriminationindex;
 359          }
 360  
 361          return number_format($questionstat->discriminationindex, 2) . '%';
 362      }
 363  
 364      /**
 365       * Discrimination efficiency, similar to, but different from, the Discrimination index.
 366       *
 367       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 368       * @return string contents of this table cell.
 369       */
 370      protected function col_discriminative_efficiency($questionstat) {
 371          if (!is_numeric($questionstat->discriminativeefficiency)) {
 372              return '';
 373          }
 374  
 375          return number_format($questionstat->discriminativeefficiency, 2) . '%';
 376      }
 377  
 378      /**
 379       * This method encapsulates the test for wheter a question should be considered dubious.
 380       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 381       * @return bool is this question possibly not pulling it's weight?
 382       */
 383      protected function is_dubious_question($questionstat) {
 384          if (!is_numeric($questionstat->discriminativeefficiency)) {
 385              return false;
 386          }
 387  
 388          return $questionstat->discriminativeefficiency < 15;
 389      }
 390  
 391      public function  wrap_html_start() {
 392          // Horrible Moodle 2.0 wide-content work-around.
 393          if (!$this->is_downloading()) {
 394              echo html_writer::start_tag('div', array('id' => 'tablecontainer',
 395                      'class' => 'statistics-tablecontainer'));
 396          }
 397      }
 398  
 399      public function wrap_html_finish() {
 400          if (!$this->is_downloading()) {
 401              echo html_writer::end_tag('div');
 402          }
 403      }
 404  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1