Example #1
0
 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);
     }
 }
Example #2
0
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();
}
Example #3
0
 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 ? '&nbsp;' : "";
         $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)
 }