/** * Saves the mean/median of a question on a paper. * @param int $paperID - The ID of the paper we are dealing with. * @param array $q_medians - Array containing the statistics to be saved. */ public function save_median_question_marks($paperID, $q_medians) { $this->db->autocommit(false); $result = $this->db->prepare("REPLACE INTO cache_median_question_marks (paperID, questionID, median, mean) VALUES (?, ?, ?, ?)"); foreach ($q_medians as $q_id => $median_array) { $median = MathsUtils::median($median_array); $mean = MathsUtils::mean($median_array); $result->bind_param('iidd', $paperID, $q_id, $median, $mean); $result->execute(); } $result->close(); $this->db->commit(); $this->db->autocommit(true); }
function SaveCalculation(&$question) { // TODO : NO template // format the text for the question foreach ($question->variables as $var => $vairable) { ${$var} = MathsUtils::gen_random_no(checkVariables($vairable->min), checkVariables($vairable->max), $vairable->inc, $vairable->dec); } eval("\$answer = " . $question->formula . ";"); $q_text = $question->leadin; $q_text = str_ireplace("\$A", $A, $q_text); $q_text = str_ireplace("\$B", $B, $q_text); $q_text = str_ireplace("\$C", $C, $q_text); $q_text = str_ireplace("\$D", $D, $q_text); $q_text = str_ireplace("\$E", $E, $q_text); $q_text = str_ireplace("\$F", $F, $q_text); $q_text = str_ireplace("\$G", $G, $q_text); $q_text = str_ireplace("\$H", $H, $q_text); //echo $q_text."<BR>"; $question->leadin = $q_text; $headertext = $this->MakeQuestionHeader($question); $title = StripForTitle($question->leadin); $ob = new OB(); $ob->ClearAndSave(); include "qti20/tmpl/calculation.php"; $this->output .= $ob->GetContent(); $ob->Restore(); }
/** * Render the question in the format required when taking the paper * @param array $extra [description] */ public function generate_variables() { if (!isset($this->useranswer['vars']) or !is_array($this->useranswer['vars'])) { // Create an empty array to hold the generated variables $this->useranswer['vars'] = array(); } // Check to see if variables have been previously generated if not put them in an array to be generated foreach ($this->settings['vars'] as $key => $value) { if ((!isset($this->useranswer['vars'][$key]) or $this->useranswer['vars'][$key] === 'ERROR') and !$this->is_linked_ans($value['min'])) { $min = $this->variable_substitution($value['min'], $this->alluseranswers); if ($value['max'] == '') { //value for max not set force it to min to generate a fixed value. $value['max'] = $value['min']; } $max = $this->variable_substitution($value['max'], $this->alluseranswers); // Temporary fix ROGO-1468 until we introduce proper localisation we need to be able to handle ',' decimal places. $inc = $this->variable_substitution(str_replace(',', '.', $value['inc']), $this->alluseranswers); $dec = (int) $value['dec']; $this->useranswer['vars'][$key] = MathsUtils::gen_random_no($min, $max, $inc, $dec); } // Pull in the last userans every time if ($this->is_linked_ans($value['min'])) { $this->useranswer['vars'][$key] = $this->variable_substitution($value['min'], $this->alluseranswers); } } // Update the session $_SESSION['qid'][$this->id]['vars'] = $this->useranswer['vars']; }
/** * Save 'calculation' question type to QTI XML * @param ST_Question_Calculation $question Reference to the question object * @author Adam Clarke, Rob Ingram */ function SaveCalculation(&$question) { if ($question->q_type == 'enhancedcalc') { $this->SaveEnhancedCalc($question); return; } $question->formula = trim($question->formula); if (substr($question->formula, 0, 1) == "=") { $question->formula = substr($question->formula, 1); } $question->origleadin = $question->leadin; $q_text = $question->leadin; // format the text for the question // replace all variables in leadin with randomly generated values foreach ($question->variables as $var => $vairable) { ${$var} = MathsUtils::gen_random_no(checkVariables($vairable->min), checkVariables($vairable->max), $vairable->inc, $vairable->dec); $q_text = str_ireplace("\${$var}", ${$var}, $q_text); } eval("\$answer = " . $question->formula . ";"); //echo $q_text."<BR>"; $question->leadin = $q_text; list($headertext, $title) = $this->MakeQuestionHeader($question); $type = "Calculation"; $ob = new OB(); $ob->ClearAndSave(); include "qti12/tmpl/calculation.php"; $this->output .= $ob->GetContent(); $ob->Restore(); }
$total_mark = $user_data['total']; $recordID = $user_data['userID']; $checked = ''; if ($prev_remark) { if (isset($remark_array[$recordID])) { $checked = ' checked'; } } else { if (round($total_mark / $paper_total * 100) < $pass_mark) { $checked = ' checked'; } } if (round($total_mark / $paper_total * 100) < $pass_mark) { echo "<tr style=\"color:#C00000\"><td class=\"pad\"><input type=\"checkbox\" class=\"check\" name=\"student{$student_no}\" value=\"{$recordID}\"{$checked} /></td><td>{$username}</td><td>{$student_id}</td><td style=\"text-align:right\">{$total_mark}</td><td class=\"pad\">" . MathsUtils::formatNumber($total_mark / $paper_total * 100, $percent_decimals) . "%</td><td> </td></tr>\n"; } else { echo "<tr><td class=\"pad\"><input type=\"checkbox\" class=\"check\" name=\"student{$student_no}\" value=\"{$recordID}\"{$checked} /></td><td>{$username}</td><td>{$student_id}</td><td style=\"text-align:right\">{$total_mark}</td><td class=\"pad\">" . MathsUtils::formatNumber($total_mark / $paper_total * 100, $percent_decimals) . "%</td><td> </td></tr>\n"; } } ?> </table> <?php if ($student_no == 0) { $msg = sprintf($string['noattempts'], textbox_marking_utils::nicedate($startdate), textbox_marking_utils::nicedate($enddate)); echo $notice->info_strip($msg, 100); } else { ?> <br /> <input type="hidden" name="student_no" value="<?php echo $student_no; ?>
} $size_msg = $cohort_size < $user_no ? $cohort_size . $string['of'] . $user_no : $user_no; $csv .= $string['cohortsize'] . ",{$size_msg},,,,,,,,,,\n"; $csv .= $string['failureno'] . "," . $stats['failures'] . ",(" . round($percent_failures) . "% of cohort),,,,,,,,,\n"; $csv .= $string['passno'] . "," . $stats['passes'] . ",(" . round($percent_passes) . $string['percentofcohort'] . "),,,,,,,,,\n"; if (isset($ss_hon)) { $csv .= $string['distinctionno'] . "," . $stats['honours'] . ",(" . round($percent_honours) . "% of cohort),,,,,,,,,\n"; } $csv .= $string['totalmarks'] . "," . $report->get_total_marks() . ",,,,,,,,,,\n"; $csv .= $string['passmark'] . ",{$pass_mark}%,,,,,,,,,,\n"; if ($marking == '1') { $csv .= $string['randommark'] . "," . number_format($report->get_total_random_mark(), 2, '.', ',') . ",,,,,,,,,,\n"; } elseif (substr($marking, 0, 1) == '2') { $csv .= $string['ss'] . "," . round($report->get_ss_pass(), 2) . ",,,,,,,,,,\n"; $csv .= $string['ssdistinction'] . "," . round($report->get_ss_hon(), 2) . ",,,,,,,,,,\n"; } $csv .= $string['meanmark'] . "," . round($stats['mean_mark'], 1) . "," . MathsUtils::formatNumber($stats['mean_percent'], 1) . "%,,,,,,,,,\n"; $csv .= $string['medianmark'] . "," . round($stats['median_mark'], 1) . "," . MathsUtils::formatNumber($stats['median_percent'], 1) . "%,,,,,,,,,\n"; $csv .= $string['stdevmark'] . "," . number_format($stats['stddev_mark'], 2, '.', ',') . "," . MathsUtils::formatNumber($stats['stddev_percent'], 2) . "%,,,,,,,,,\n"; $csv .= $string['maxmark'] . "," . $stats['max_mark'] . "," . number_format($stats['max_percent']) . "%,,,,,,,,,\n"; $csv .= $string['maxmark'] . "," . $stats['min_mark'] . "," . number_format($stats['min_percent']) . "%,,,,,,,,,\n"; $csv .= $string['range'] . "," . $stats['range'] . "," . $stats['range_percent'] . "%,,,,,,,,,\n"; $avg_time = $stats['completed_no'] > 0 ? $report->formatsec(round($stats['total_time'] / $stats['completed_no'], 0)) : 'n/a'; $csv .= $string['averagetime'] . "," . $avg_time . ",,,,,,,,,,\n"; $csv .= $string['excludedquestions'] . "," . $report->get_display_excluded() . ",,,,,,,,,,\n"; $csv .= $string['skippedquestions'] . "," . $report->get_display_experimental() . ",,,,,,,,,,\n"; } else { $csv .= strip_tags(sprintf($string['noattempts'], $report->nicedate($startdate), $report->nicedate($enddate))); } echo mb_convert_encoding($csv, "UTF-16LE", "UTF-8"); $mysqli->close();
echo '<Row>'; echo '<Cell ss:StyleID="s23"><Data ss:Type="String">' . $string['maxmark'] . '</Data></Cell>'; echo '<Cell><Data ss:Type="Number">' . $stats['max_mark'] . '</Data></Cell>'; echo '</Row>'; echo '<Row>'; echo '<Cell ss:StyleID="s23"><Data ss:Type="String">' . $string['minmark'] . '</Data></Cell>'; echo '<Cell><Data ss:Type="Number">' . $stats['min_mark'] . '</Data></Cell>'; echo '</Row>'; echo '<Row>'; echo '<Cell ss:StyleID="s23"><Data ss:Type="String">' . $string['range'] . '</Data></Cell>'; echo '<Cell><Data ss:Type="Number">' . $stats['range'] . '</Data></Cell>'; echo '</Row>'; for ($i = 1; $i < 10; $i++) { echo '<Row>'; echo '<Cell ss:StyleID="s23"><Data ss:Type="String">Decile ' . $i . '</Data></Cell>'; echo '<Cell ss:StyleID="s69"><Data ss:Type="Number">' . MathsUtils::formatNumber($stats["decile{$i}"] / 100, $percent_decimals) . '</Data></Cell>'; echo '</Row>'; } echo '<Row>'; echo '<Cell ss:StyleID="s23"><Data ss:Type="String">' . $string['averagetime'] . '</Data></Cell>'; if ($stats['completed_no'] == 0) { echo '<Cell><Data ss:Type="String">' . $report->formatsec(0) . '</Data></Cell>'; } else { echo '<Cell><Data ss:Type="String">' . $report->formatsec(round($stats['total_time'] / $stats['completed_no'], 0)) . '</Data></Cell>'; } echo '</Row>'; echo '<Row>'; echo '<Cell ss:StyleID="s23"><Data ss:Type="String">' . $string['excludedquestions'] . '</Data></Cell>'; echo '<Cell><Data ss:Type="String">' . $report->get_display_excluded() . '</Data></Cell>'; echo '</Row>'; echo '<Row>';
echo "<td></td>"; // Deciles $suffix = array('', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th'); echo "<td colspan=\"2\" style=\"width:33%; vertical-align:top\"><table border=\"0\" style=\"font-size:110%\">\n"; for ($i = 1; $i < 10; $i++) { echo "<tr><td style=\"width:40px\">" . $i; echo $language == 'en' ? $suffix[$i] : '.'; echo "</td><td>" . MathsUtils::formatNumber($stats["decile{$i}"], 1) . "%</td></tr>\n"; } echo "</table></td>\n"; echo "<td></td>"; // Quartiles echo "<td colspan=\"2\" style=\"width:33%; vertical-align:top\"><table border=\"0\" style=\"font-size:110%\">\n"; echo "<tr><td style=\"width:40px\">Q1</td><td>" . MathsUtils::formatNumber($stats['q1'], 1) . "%</td></tr>\n"; echo "<tr><td style=\"width:40px\">Q2</td><td>" . MathsUtils::formatNumber($stats['q2'], 1) . "%</td></tr>\n"; echo "<tr><td style=\"width:40px\">Q3</td><td>" . MathsUtils::formatNumber($stats['q3'], 1) . "%</td></tr>\n"; echo "</table></td>\n"; echo "</tr></table>\n<br />"; // Email Class ----------------------------------------------------------------------------------------- if ($paper_type < 2 and isset($_POST['emailclass']) and $_POST['emailclass'] == 'yes') { // Save the latest template to disk. $file = fopen("../email_templates/" . $userObject->get_user_ID() . ".txt", "w"); fwrite($file, $userObject->get_email() . "\n"); fwrite($file, $_POST['ccaddress'] . "\n"); fwrite($file, $_POST['bccaddress'] . "\n"); fwrite($file, $_POST['subject'] . "\n"); fwrite($file, $_POST['emailtemplate'] . "\n"); fclose($file); for ($i = 0; $i < $user_no; $i++) { switch ($i) { case 25:
/** * Creates an array of basic statistics on the cohort performance. */ public function generate_stats() { $configObject = Config::get_instance(); $percent_decimals = $configObject->get('percent_decimals'); // Generate summary statistics. $this->set_user_no(); $mark_total = 0; $percent_total = 0; $this->stats['sum_of_marks'] = 0; $this->stats['out_of_range'] = 0; $this->stats['completed_no'] = 0; $this->stats['failures'] = 0; $this->stats['passes'] = 0; $this->stats['honours'] = 0; $this->stats['total_time'] = 0; $this->stats['max_mark'] = 0; $this->stats['min_mark'] = 9999; $this->stats['max_percent'] = 0; $this->stats['min_percent'] = 100; $median_mark_array = array(); $median_percent_array = array(); $marks_data = array(); for ($i = 0; $i < $this->user_no; $i++) { if (isset($this->user_results[$i]['percent']) and $this->user_results[$i]['questions'] >= $this->question_no and $this->user_results[$i]['visible']) { $this->stats['completed_no']++; $median_mark_array[] = round($this->user_results[$i]['mark'], $percent_decimals); $median_percent_array[] = round($this->user_results[$i]['percent'], $percent_decimals); $mark_total += round($this->user_results[$i]['mark'], $percent_decimals); $percent_total += round($this->user_results[$i]['percent'], $percent_decimals); // Round to the precision being displayed on screen. } if (isset($this->user_results[$i]['mark']) and $this->user_results[$i]['visible']) { $tmp_mark = round($this->user_results[$i]['mark'], $percent_decimals); $tmp_percent = round($this->user_results[$i]['percent'], $percent_decimals); $marks_data[] = $tmp_percent; if ($tmp_percent < $this->pass_mark) { $this->stats['failures']++; } if ($tmp_percent < $this->stats['min_percent']) { $this->stats['min_percent'] = $tmp_percent; } if ($tmp_percent > $this->stats['max_percent']) { $this->stats['max_percent'] = $tmp_percent; } if ($tmp_percent >= $this->pass_mark and $tmp_percent < $this->distinction_mark) { $this->stats['passes']++; } if ($tmp_percent >= $this->distinction_mark) { $this->stats['honours']++; } if ($tmp_mark < $this->stats['min_mark']) { $this->stats['min_mark'] = $tmp_mark; } if ($tmp_mark > $this->stats['max_mark']) { $this->stats['max_mark'] = $tmp_mark; } $this->stats['sum_of_marks'] += $tmp_mark; } if ($this->user_results[$i]['visible']) { $this->stats['total_time'] += $this->user_results[$i]['duration']; } else { $this->stats['out_of_range']++; } } if ($this->stats['min_mark'] == 9999) { $this->stats['min_mark'] = 0; } // Reset back to zero if still on default. $this->stats['range'] = $this->stats['max_mark'] - $this->stats['min_mark']; $this->stats['range_percent'] = $this->stats['max_percent'] - $this->stats['min_percent']; // Calculate StdDev. $xmean_total = 0; $xmean_percent_total = 0; for ($i = 0; $i < $this->user_no; $i++) { if (isset($this->user_results[$i]['questions']) and $this->user_results[$i]['questions'] >= $this->question_no and $this->user_results[$i]['visible'] and $this->stats['completed_no'] > 0) { $tmp_percent = round($this->user_results[$i]['percent'], $percent_decimals); $xmean_total += ($this->user_results[$i]['mark'] - $mark_total / $this->stats['completed_no']) * ($this->user_results[$i]['mark'] - $mark_total / $this->stats['completed_no']); $xmean_percent_total += ($tmp_percent - $percent_total / $this->stats['completed_no']) * ($tmp_percent - $percent_total / $this->stats['completed_no']); } } if ($this->stats['completed_no'] > 1) { $this->stats['stddev_mark'] = sqrt($xmean_total / ($this->stats['completed_no'] - 1)); $this->stats['stddev_percent'] = sqrt($xmean_percent_total / ($this->stats['completed_no'] - 1)); } else { $this->stats['stddev_mark'] = 0; $this->stats['stddev_percent'] = 0; } if ($this->stats['completed_no'] > 0) { $this->stats['mean_mark'] = $mark_total / $this->stats['completed_no']; $this->stats['mean_percent'] = $percent_total / $this->stats['completed_no']; $this->stats['median_mark'] = MathsUtils::median($median_mark_array); $this->stats['median_percent'] = MathsUtils::median($median_percent_array); } else { $this->stats['mean_mark'] = 0; $this->stats['mean_percent'] = 0; $this->stats['median_mark'] = 0; $this->stats['median_percent'] = 0; } $this->stats['q1'] = MathsUtils::percentile($marks_data, 0.75); $this->stats['q2'] = MathsUtils::percentile($marks_data, 0.5); $this->stats['q3'] = MathsUtils::percentile($marks_data, 0.25); for ($i = 1; $i < 10; $i++) { $this->stats["decile{$i}"] = MathsUtils::percentile($marks_data, $i / 10); } }