[ Index ]

PHP Cross Reference of moodle-2.8

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, $questionstat->question, $this->baseurl);
 173      }
 174  
 175      /**
 176       * The question type name.
 177       *
 178       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 179       * @return string contents of this table cell.
 180       */
 181      protected function col_qtype($questionstat) {
 182          return question_bank::get_qtype_name($questionstat->question->qtype);
 183      }
 184  
 185      /**
 186       * The question name.
 187       *
 188       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 189       * @return string contents of this table cell.
 190       */
 191      protected function col_name($questionstat) {
 192          $name = $questionstat->question->name;
 193  
 194          if (!is_null($questionstat->variant)) {
 195              $a = new stdClass();
 196              $a->name = $name;
 197              $a->variant = $questionstat->variant;
 198              $name = get_string('nameforvariant', 'quiz_statistics', $a);
 199          }
 200  
 201          if ($this->is_downloading()) {
 202              return $name;
 203          }
 204  
 205          $baseurl = new moodle_url($this->baseurl);
 206          if (!is_null($questionstat->variant)) {
 207              if ($questionstat->subquestion) {
 208                  // Variant of a sub-question.
 209                  $url = new moodle_url($baseurl, array('qid' => $questionstat->questionid, 'variant' => $questionstat->variant));
 210                  $name = html_writer::link($url, $name, array('title' => get_string('detailedanalysisforvariant',
 211                                                                                     'quiz_statistics',
 212                                                                                     $questionstat->variant)));
 213              } else if ($questionstat->slot) {
 214                  // Variant of a question in a slot.
 215                  $url = new moodle_url($baseurl, array('slot' => $questionstat->slot, 'variant' => $questionstat->variant));
 216                  $name = html_writer::link($url, $name, array('title' => get_string('detailedanalysisforvariant',
 217                                                                                     'quiz_statistics',
 218                                                                                     $questionstat->variant)));
 219              }
 220          } else {
 221              if ($questionstat->subquestion && !$questionstat->get_variants()) {
 222                  // Sub question without variants.
 223                  $url = new moodle_url($baseurl, array('qid' => $questionstat->questionid));
 224                  $name = html_writer::link($url, $name, array('title' => get_string('detailedanalysis', 'quiz_statistics')));
 225              } else if ($baseurl->param('slot') === null && $questionstat->slot) {
 226                  // Question in a slot, we are not on a page showing structural analysis of one slot,
 227                  // we don't want linking on those pages.
 228                  $number = $questionstat->question->number;
 229                  $url = new moodle_url($baseurl, array('slot' => $questionstat->slot));
 230                  if ($questionstat->get_variants() || $questionstat->get_sub_question_ids()) {
 231                      // Question can be broken down into sub-questions or variants. Link will show structural analysis page.
 232                      $name = html_writer::link($url,
 233                                                $name,
 234                                                array('title' => get_string('slotstructureanalysis', 'quiz_statistics', $number)));
 235                  } else {
 236                      // Question cannot be broken down into sub-questions or variants. Link will show response analysis page.
 237                      $name = html_writer::link($url,
 238                                                $name,
 239                                                array('title' => get_string('detailedanalysis', 'quiz_statistics')));
 240                  }
 241              }
 242          }
 243  
 244  
 245          if ($this->is_dubious_question($questionstat)) {
 246              $name = html_writer::tag('div', $name, array('class' => 'dubious'));
 247          }
 248  
 249          if (!empty($questionstat->minmedianmaxnotice)) {
 250              $name = get_string($questionstat->minmedianmaxnotice, 'quiz_statistics') . '<br />' . $name;
 251          }
 252  
 253          return $name;
 254      }
 255  
 256      /**
 257       * The number of attempts at this question.
 258       *
 259       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 260       * @return string contents of this table cell.
 261       */
 262      protected function col_s($questionstat) {
 263          if (!isset($questionstat->s)) {
 264              return 0;
 265          }
 266  
 267          return $questionstat->s;
 268      }
 269  
 270      /**
 271       * The facility index (average fraction).
 272       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 273       * @return string contents of this table cell.
 274       */
 275      protected function col_facility($questionstat) {
 276          if (is_null($questionstat->facility)) {
 277              return '';
 278          }
 279  
 280          return number_format($questionstat->facility*100, 2) . '%';
 281      }
 282  
 283      /**
 284       * The standard deviation of the fractions.
 285       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 286       * @return string contents of this table cell.
 287       */
 288      protected function col_sd($questionstat) {
 289          if (is_null($questionstat->sd) || $questionstat->maxmark == 0) {
 290              return '';
 291          }
 292  
 293          return number_format($questionstat->sd*100 / $questionstat->maxmark, 2) . '%';
 294      }
 295  
 296      /**
 297       * An estimate of the fraction a student would get by guessing randomly.
 298       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 299       * @return string contents of this table cell.
 300       */
 301      protected function col_random_guess_score($questionstat) {
 302          if (is_null($questionstat->randomguessscore)) {
 303              return '';
 304          }
 305  
 306          return number_format($questionstat->randomguessscore * 100, 2).'%';
 307      }
 308  
 309      /**
 310       * The intended question weight. Maximum mark for the question as a percentage
 311       * of maximum mark for the quiz. That is, the indended influence this question
 312       * on the student's overall mark.
 313       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 314       * @return string contents of this table cell.
 315       */
 316      protected function col_intended_weight($questionstat) {
 317          return quiz_report_scale_summarks_as_percentage($questionstat->maxmark, $this->quiz);
 318      }
 319  
 320      /**
 321       * The effective question weight. That is, an estimate of the actual
 322       * influence this question has on the student's overall mark.
 323       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 324       * @return string contents of this table cell.
 325       */
 326      protected function col_effective_weight($questionstat) {
 327          global $OUTPUT;
 328  
 329          if (is_null($questionstat->effectiveweight)) {
 330              return '';
 331          }
 332  
 333          if ($questionstat->negcovar) {
 334              $negcovar = get_string('negcovar', 'quiz_statistics');
 335  
 336              if (!$this->is_downloading()) {
 337                  $negcovar = html_writer::tag('div',
 338                          $negcovar . $OUTPUT->help_icon('negcovar', 'quiz_statistics'),
 339                          array('class' => 'negcovar'));
 340              }
 341  
 342              return $negcovar;
 343          }
 344  
 345          return number_format($questionstat->effectiveweight, 2) . '%';
 346      }
 347  
 348      /**
 349       * Discrimination index. This is the product moment correlation coefficient
 350       * between the fraction for this question, and the average fraction for the
 351       * other questions in this quiz.
 352       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 353       * @return string contents of this table cell.
 354       */
 355      protected function col_discrimination_index($questionstat) {
 356          if (!is_numeric($questionstat->discriminationindex)) {
 357              return $questionstat->discriminationindex;
 358          }
 359  
 360          return number_format($questionstat->discriminationindex, 2) . '%';
 361      }
 362  
 363      /**
 364       * Discrimination efficiency, similar to, but different from, the Discrimination index.
 365       *
 366       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 367       * @return string contents of this table cell.
 368       */
 369      protected function col_discriminative_efficiency($questionstat) {
 370          if (!is_numeric($questionstat->discriminativeefficiency)) {
 371              return '';
 372          }
 373  
 374          return number_format($questionstat->discriminativeefficiency, 2) . '%';
 375      }
 376  
 377      /**
 378       * This method encapsulates the test for wheter a question should be considered dubious.
 379       * @param \core_question\statistics\questions\calculated $questionstat stats for the question.
 380       * @return bool is this question possibly not pulling it's weight?
 381       */
 382      protected function is_dubious_question($questionstat) {
 383          if (!is_numeric($questionstat->discriminativeefficiency)) {
 384              return false;
 385          }
 386  
 387          return $questionstat->discriminativeefficiency < 15;
 388      }
 389  
 390      public function  wrap_html_start() {
 391          // Horrible Moodle 2.0 wide-content work-around.
 392          if (!$this->is_downloading()) {
 393              echo html_writer::start_tag('div', array('id' => 'tablecontainer',
 394                      'class' => 'statistics-tablecontainer'));
 395          }
 396      }
 397  
 398      public function wrap_html_finish() {
 399          if (!$this->is_downloading()) {
 400              echo html_writer::end_tag('div');
 401          }
 402      }
 403  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1