function set_legend(&$table, &$q, &$value, &$question) { // $q is the question number // $value is the value (=text) of the answer // check the legend is required if (isset($table->legend) && isset($value)) { // create question details array, if necessary if (empty($table->legend[$q])) { $table->legend[$q] = array('name' => hotpot_get_question_name($question), 'answers' => array()); } // search for this $value in answers array for this $q(uestion) $i_max = count($table->legend[$q]['answers']); for ($i = 0; $i < $i_max; $i++) { if ($table->legend[$q]['answers'][$i] == $value) { break; } } // add $value to answers array, if it was not there if ($i == $i_max) { $table->legend[$q]['answers'][$i] = $value; } // convert $value to alphabetic index (A, B ... AA, AB ...) $value = $this->dec_to_ALPHA($i); } }
function hotpot_print_attempt_details(&$hotpot, &$attempt) { // define fields to print $textfields = array('correct', 'ignored', 'wrong'); $numfields = array('score', 'weighting', 'hints', 'clues', 'checks'); $fields = array_merge($textfields, $numfields); $q = array(); // questions $f = array(); // fields foreach ($fields as $field) { $name = get_string($field, 'hotpot'); $f[$field] = array('count' => 0, 'name' => $name); } // get questions and responses for this attempt $questions = get_records_select('hotpot_questions', "hotpot='{$hotpot->id}'", 'id'); $responses = get_records_select('hotpot_responses', "attempt='{$attempt->id}'", 'id'); if ($questions && $responses) { foreach ($responses as $response) { $id = $response->question; foreach ($fields as $field) { if (!isset($f[$field])) { $name = get_string($field, 'hotpot'); $f[$field] = array('count' => 0, 'name' => $name); } if (isset($response->{$field})) { $f[$field]['count']++; if (!isset($q[$id])) { $name = hotpot_get_question_name($questions[$id]); $q[$id] = array('name' => $name); } $q[$id][$field] = $response->{$field}; } } } } // count the number of columns required in the table $colspan = 0; foreach ($numfields as $field) { if ($f[$field]['count']) { $colspan += 2; } } $colspan = max(2, $colspan); // start table of questions and responses print_simple_box_start("center", "80%", "#ffffff", 0); print '<table width="100%" border="1" valign="top" align="center" cellpadding="2" cellspacing="2" class="generaltable">' . "\n"; if (empty($q)) { print '<tr><td align="center" class="generaltablecell"><b>' . get_string("noresponses", "hotpot") . "</b></td></tr>\n"; } else { // flag to ensure separators are only printed before the 2nd and subsequent questions $printseparator = false; foreach ($q as $i => $question) { // flag to ensure questions are only printed when there is at least one response $printedquestion = false; // add rows of text fields foreach ($textfields as $field) { if (isset($question[$field])) { $text = hotpot_strings($question[$field]); if (trim($text)) { // print question if necessary if (!$printedquestion) { if ($printseparator) { print '<tr><td colspan="' . $colspan . '"><div class="tabledivider"></div></td></tr>' . "\n"; } $printseparator = true; print '<tr><td colspan="' . $colspan . '" class="generaltablecell"><b>' . $question['name'] . '</b></td></tr>' . "\n"; $printedquestion = true; } // print response print '<tr><th align="right" width="100" class="generaltableheader" scope="row">' . $f[$field]['name'] . ':</th><td colspan="' . ($colspan - 1) . '" class="generaltablecell">' . $text . '</td></tr>' . "\n"; } } } // add row of numeric fields print '<tr>'; foreach ($numfields as $field) { if ($f[$field]['count']) { // print question if necessary if (!$printedquestion) { print '<td colspan="' . $colspan . '" class="generaltablecell"><b>' . $question['name'] . "</b></td></tr>\n<tr>"; $printedquestion = true; } // print numeric response $value = isset($question[$field]) ? $question[$field] : '-'; print '<th align="right" width="100" class="generaltableheader" scope="row">' . $f[$field]['name'] . ':</th><td class="generaltablecell">' . $value . '</td>'; } } print "</tr>\n"; } // foreach $q } // finish table print "</table>\n"; print_simple_box_end(); }
function create_analysis_table(&$users, &$attempts, &$questions, &$options, &$tables) { $is_html = $options['reportformat'] == 'htm'; // the fields we are interested in, in the order we want them $fields = array('correct', 'wrong', 'ignored', 'hints', 'clues', 'checks', 'weighting'); $string_fields = array('correct', 'wrong', 'ignored'); $q = array(); // statistics about the $q(uestions) $f = array(); // statistics about the $f(ields) //////////////////////////////////////////// // compile the statistics about the questions //////////////////////////////////////////// foreach ($questions as $id => $question) { // extract scores for attempts at this question $scores = array(); foreach ($question->attempts as $attempt) { $scores[] = $attempt->score; } // sort scores values (in ascending order) asort($scores); // get the borderline high and low scores $count = count($scores); switch ($count) { case 0: $lo_score = 0; $hi_score = 0; break; case 1: $lo_score = 0; $hi_score = $scores[0]; break; default: $lo_score = $scores[round($count * 1 / 3)]; $hi_score = $scores[round($count * 2 / 3)]; break; } // get statistics for each attempt which includes this question foreach ($question->attempts as $attempt) { $is_hi_score = $attempt->score >= $hi_score; $is_lo_score = $attempt->score < $lo_score; // reference to the response to the current question $response =& $attempt->responses[$id]; // update statistics for fields in this response foreach ($fields as $field) { if (!isset($q[$id])) { $q[$id] = array(); } if (!isset($f[$field])) { $f[$field] = array('count' => 0); } if (!isset($q[$id][$field])) { $q[$id][$field] = array('count' => 0); } $values = explode(',', $response->{$field}); $values = array_unique($values); foreach ($values as $value) { // $value should be an integer (string_id or count) if (is_numeric($value)) { $f[$field]['count']++; if (!isset($q[$id][$field][$value])) { $q[$id][$field][$value] = 0; } $q[$id][$field]['count']++; $q[$id][$field][$value]++; } } } // end foreach $field // initialize counters for this question, if necessary if (!isset($q[$id]['count'])) { $q[$id]['count'] = array('hi' => 0, 'lo' => 0, 'correct' => 0, 'total' => 0, 'sum' => 0); } // increment counters $q[$id]['count']['sum'] += $response->score; $q[$id]['count']['total']++; if ($response->score == 100) { $q[$id]['count']['correct']++; if ($is_hi_score) { $q[$id]['count']['hi']++; } else { if ($is_lo_score) { $q[$id]['count']['lo']++; } } } } // end foreach attempt } // end foreach question // check we have some details if (count($q)) { $showhideid = 'showhide'; // shortcuts for html tags $bold_start = $is_html ? '<strong>' : ""; $bold_end = $is_html ? '</strong>' : ""; $div_start = $is_html ? '<div id="' . $showhideid . '">' : ""; $div_end = $is_html ? '</div>' : ""; $font_red = $is_html ? '<font color="red" size="-2">' : ''; $font_blue = $is_html ? '<font color="blue" size="-2">' : ''; $font_green = $is_html ? '<font color="green" size="-2">' : ''; $font_brown = $is_html ? '<font color="brown" size="-2">' : ''; $font_end = $is_html ? '</font>' . "\n" : ''; $br = $is_html ? '<br />' : "\n"; $space = $is_html ? ' ' : ""; $no_value = $is_html ? '--' : ""; $help_button = $is_html ? helpbutton("discrimination", "", "quiz", true, false, "", true) : ""; // table properties unset($table); $table->border = 1; $table->width = '100%'; $table->caption = get_string('itemanal', 'quiz'); if ($is_html) { $table->caption .= helpbutton('analysistable', $table->caption, 'hotpot', true, false, '', true); } // initialize legend, if necessary if (!empty($options['reportshowlegend'])) { if (empty($tables) || empty($tables[0]->legend)) { $table->legend = array(); } else { $table->legend = $tables[0]->legend; unset($tables[0]->legend); } } // headings for name, attempt number and score/grade $table->head = array($space); $table->align = array('right'); $table->size = array(80); // question headings $this->add_question_headings($questions, $table, 'left', 0); // initialize statistics $table->stat = array(); $table->statheadercols = array(0); // add headings for the $foot of the $table $table->foot = array(); $table->foot[0] = array(get_string('average', 'hotpot')); $table->foot[1] = array(get_string('percentcorrect', 'quiz')); $table->foot[2] = array(get_string('discrimination', 'quiz') . $help_button); // maximum discrimination index (also default the default value) $max_d_index = 10; //////////////////////////////////////////// // format the statistics into the $table //////////////////////////////////////////// // add $stat(istics) and $foot of $table $questionids = array_keys($q); foreach ($questionids as $col => $id) { $row = 0; // print the question text if there is no legend if (empty($table->legend)) { // add button to show/hide question text if (!isset($table->stat[0])) { $button = $is_html ? hotpot_showhide_button($showhideid) : ""; $table->stat[0] = array(get_string('question', 'quiz') . $button); } // add the question name/text $name = hotpot_get_question_name($questions[$id]); $table->stat[$row++][$col + 1] = $div_start . $bold_start . $name . $bold_end . $div_end . $space; } // add details about each field foreach ($fields as $field) { // check this row is required if ($f[$field]['count']) { $values = array(); $string_type = array_search($field, $string_fields); // get the value of each response to this field // and the count of that value foreach ($q[$id][$field] as $value => $count) { if (is_numeric($value) && $count) { if (is_numeric($string_type)) { $value = hotpot_string($value); $this->set_legend($table, $col, $value, $questions[$id]); switch ($string_type) { case 0: // correct $font_start = $font_red; break; case 1: // wrong $font_start = $font_blue; break; case 2: // ignored $font_start = $font_brown; break; } } else { // numeric field $font_start = $font_green; } $values[] = $font_start . round(100 * $count / $q[$id]['count']['total']) . '%' . $font_end . ' ' . $value; } } // end foreach $value => $count // initialize stat(istics) row for this field, if required if (!isset($table->stat[$row])) { $table->stat[$row] = array(get_string($field, 'hotpot')); } // sort the values by frequency (using user-defined function) usort($values, "hotpot_sort_stat_values"); // add stat(istics) values for this field $table->stat[$row++][$col + 1] = count($values) ? implode($br, $values) : $space; } } // end foreach field // default percent correct and discrimination index for this question $average = $no_value; $percent = $no_value; $d_index = $no_value; if (isset($q[$id]['count'])) { // average and percent correct if ($q[$id]['count']['total']) { $average = round($q[$id]['count']['sum'] / $q[$id]['count']['total']) . '%'; $percent = round(100 * $q[$id]['count']['correct'] / $q[$id]['count']['total']) . '%'; $percent .= ' (' . $q[$id]['count']['correct'] . '/' . $q[$id]['count']['total'] . ')'; } // discrimination index if ($q[$id]['count']['lo']) { $d_index = min($max_d_index, round($q[$id]['count']['hi'] / $q[$id]['count']['lo'], 1)); } else { $d_index = $q[$id]['count']['hi'] ? $max_d_index : 0; } $d_index .= ' (' . $q[$id]['count']['hi'] . '/' . $q[$id]['count']['lo'] . ')'; } $table->foot[0][$col + 1] = $average; $table->foot[1][$col + 1] = $percent; $table->foot[2][$col + 1] = $d_index; } // end foreach $question ($col) // add javascript to show/hide question text if (isset($table->stat[0]) && $is_html && empty($table->legend)) { $i = count($table->stat[0]); $table->stat[0][$i - 1] .= hotpot_showhide_set($showhideid); } $tables[] =& $table; $this->create_legend_table($tables, $table); } // end if (empty($q) }