mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 00:46:50 +02:00
New version of item analysis from Enrique
This commit is contained in:
parent
cf74468046
commit
a472ce5960
9 changed files with 243 additions and 119 deletions
|
@ -377,14 +377,18 @@ class quiz_default_questiontype {
|
|||
* for the question
|
||||
*
|
||||
* All answers are found and their text values isolated
|
||||
* @return array An array of values giving the responses corresponding
|
||||
* to all answers to the question. Answer ids are used as keys
|
||||
* @return object A mixed object
|
||||
* ->id question id. Needed to manage random questions:
|
||||
* it's the id of the actual question presented to user in a given attempt
|
||||
* ->responses An array of values giving the responses corresponding
|
||||
* to all answers to the question. Answer ids are used as keys.
|
||||
* The text and partial credit are the object components
|
||||
* @param object $question The question for which the answers are to
|
||||
* be retrieved. Question type specific information is
|
||||
* available.
|
||||
*/
|
||||
// ULPGC ecastro
|
||||
function get_all_responses($question, $state) {
|
||||
function get_all_responses(&$question, &$state) {
|
||||
unset($answers);
|
||||
if (is_array($question->options->answers)) {
|
||||
foreach ($question->options->answers as $aid=>$answer) {
|
||||
|
@ -405,8 +409,8 @@ class quiz_default_questiontype {
|
|||
* Return the actual response to the question in a given state
|
||||
* for the question
|
||||
*
|
||||
* @return compond object fractiongrade & actual response .
|
||||
*
|
||||
* @return mixed An array containing the response or reponses (multiple answer, match)
|
||||
* given by the user in a particular attempt.
|
||||
* @param object $question The question for which the correct answer is to
|
||||
* be retrieved. Question type specific information is
|
||||
* available.
|
||||
|
@ -415,7 +419,7 @@ class quiz_default_questiontype {
|
|||
* type specific information is included.
|
||||
*/
|
||||
// ULPGC ecastro
|
||||
function get_actual_response($question, $state) {
|
||||
function get_actual_response(&$question, &$state) {
|
||||
/* The default implementation only returns the raw ->responses.
|
||||
may be overridden by each type*/
|
||||
//unset($resp);
|
||||
|
@ -427,7 +431,7 @@ class quiz_default_questiontype {
|
|||
}
|
||||
|
||||
// ULPGC ecastro
|
||||
function get_fractional_grade($question, $state) {
|
||||
function get_fractional_grade(&$question, &$state) {
|
||||
$maxgrade = $question->maxgrade;
|
||||
$grade = $state->grade;
|
||||
if ($maxgrade) {
|
||||
|
@ -437,6 +441,24 @@ class quiz_default_questiontype {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the response given is correct and returns the id
|
||||
*
|
||||
* @return int The ide number for the stored answer that matches the response
|
||||
* given by the user in a particular attempt.
|
||||
* @param object $question The question for which the correct answer is to
|
||||
* be retrieved. Question type specific information is
|
||||
* available.
|
||||
* @param object $state The state object that corresponds to the question,
|
||||
* for which a correct answer is needed. Question
|
||||
* type specific information is included.
|
||||
*/
|
||||
// ULPGC ecastro
|
||||
function check_response(&$question, &$state){
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the question including the number, grading details, content,
|
||||
* feedback and interactions
|
||||
|
@ -1776,6 +1798,7 @@ function quiz_print_question_icon($question, $editlink=true, $return = false) {
|
|||
function quiz_get_question_review($quiz, $question) {
|
||||
// returns a question icon
|
||||
$qnum = $question->id;
|
||||
$strpreview = get_string('previewquestion', 'quiz');
|
||||
$context = $quiz->id ? '&contextquiz='.$quiz->id : '';
|
||||
$quiz_id = $quiz->id ? '&quizid=' . $quiz->id : '';
|
||||
return "<a title=\"$strpreview\" href=\"javascript:void();\" onClick=\"openpopup('/mod/quiz/preview.php?id=$qnum$quiz_id','$strpreview','scrollbars=yes,resizable=yes,width=700,height=480', false)\">
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
/// QUESTION TYPE CLASS //////////////////
|
||||
|
||||
require_once("$CFG->dirroot/mod/quiz/questiontypes/datasetdependent/abstractqtype.php");
|
||||
|
||||
class quiz_calculated_qtype extends quiz_dataset_dependent_questiontype {
|
||||
|
||||
// Used by the function custom_generator_tools:
|
||||
|
@ -153,6 +154,49 @@ class quiz_calculated_qtype extends quiz_dataset_dependent_questiontype {
|
|||
}
|
||||
return parent::grade_responses($question, $state, $quiz);
|
||||
}
|
||||
|
||||
// ULPGC ecastro
|
||||
function check_response(&$question, &$state) {
|
||||
// Forward the checking to the virtual qtype
|
||||
foreach ($question->options->answers as $key => $answer) {
|
||||
$answer = &$question->options->answers[$key]; // for PHP 4.x
|
||||
$answer->answer = $this->substitute_variables($answer->answer,
|
||||
$state->options->dataset);
|
||||
}
|
||||
//return false;
|
||||
return parent::check_response($question, $state);
|
||||
}
|
||||
|
||||
// ULPGC ecastro
|
||||
function get_actual_response(&$question, &$state) {
|
||||
// Substitute variables in questiontext before giving the data to the
|
||||
// virtual type
|
||||
$virtualqtype = $this->get_virtual_qtype();
|
||||
$unit = $virtualqtype->get_default_numerical_unit($question);
|
||||
foreach ($question->options->answers as $key => $answer) {
|
||||
$answer = &$question->options->answers[$key]; // for PHP 4.x
|
||||
$answer->answer = $this->substitute_variables($answer->answer,
|
||||
$state->options->dataset);
|
||||
// apply_unit
|
||||
}
|
||||
$question->questiontext = parent::substitute_variables(
|
||||
$question->questiontext, $state->options->dataset);
|
||||
$responses = $virtualqtype->get_all_responses($question, $state);
|
||||
$response = reset($responses->responses);
|
||||
$correct = $response->answer.' : ';
|
||||
|
||||
$responses = $virtualqtype->get_actual_response($question, $state);
|
||||
|
||||
foreach ($responses as $key=>$response){
|
||||
$responses[$key] = $correct.$response;
|
||||
}
|
||||
|
||||
return $responses;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function create_virtual_qtype() {
|
||||
global $CFG;
|
||||
|
@ -419,6 +463,10 @@ class quiz_calculated_qtype extends quiz_dataset_dependent_questiontype {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function substitute_variables($str, $dataset) {
|
||||
$formula = parent::substitute_variables($str, $dataset);
|
||||
if ($error = quiz_qtype_calculated_find_formula_errors($formula)) {
|
||||
|
|
|
@ -113,6 +113,20 @@ class quiz_dataset_dependent_questiontype extends quiz_default_questiontype {
|
|||
$virtualqtype = $this->get_virtual_qtype();
|
||||
return $virtualqtype->grade_responses($question, $state, $quiz) ;
|
||||
}
|
||||
|
||||
// ULPGC ecastro
|
||||
function check_response(&$question, &$state) {
|
||||
// Forward the checking to the virtual qtype
|
||||
foreach ($question->options->answers as $answer) {
|
||||
$answer->answer = $this->substitute_variables($answer->answer,
|
||||
$state->options->dataset);
|
||||
}
|
||||
$virtualqtype = $this->get_virtual_qtype();
|
||||
return $virtualqtype->check_response($question, $state) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function substitute_variables($str, $dataset) {
|
||||
foreach ($dataset as $name => $value) {
|
||||
|
|
|
@ -351,22 +351,13 @@ class quiz_multichoice_qtype extends quiz_default_questiontype {
|
|||
// ULPGC ecastro
|
||||
function get_actual_response($question, $state) {
|
||||
$answers = $question->options->answers;
|
||||
/*
|
||||
if (!$question->options->single) {
|
||||
echo "Objeto State-responses: <br>tamaño= ".count($state->responses)."<br> ";
|
||||
print_object($state->responses);
|
||||
foreach ($state->responses as $resp){
|
||||
echo "esto es response id= ".$rid." <br>";
|
||||
print_object($resp);
|
||||
echo " Tamaño interno=".count($resp);
|
||||
foreach ($resp as $r){
|
||||
print_object($r);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
foreach ($state->responses as $rid){
|
||||
$answer = $answers[$rid]->answer;
|
||||
$responses[] = $answer;
|
||||
if (!empty($state->responses)) {
|
||||
foreach ($state->responses as $aid =>$rid){
|
||||
$answer = $answers[$rid]->answer;
|
||||
$responses[] = $answer;
|
||||
}
|
||||
} else {
|
||||
$responses[] = '';
|
||||
}
|
||||
return $responses;
|
||||
}
|
||||
|
|
|
@ -229,6 +229,17 @@ class quiz_numerical_qtype extends quiz_shortanswer_qtype {
|
|||
return ($response == $answer->answer);
|
||||
}
|
||||
}
|
||||
|
||||
// ULPGC ecastro
|
||||
function check_response(&$question, &$state){
|
||||
$answers = &$question->options->answers;
|
||||
foreach($answers as $aid => $answer) {
|
||||
if($this->test_response($question, $state, $answer)) {
|
||||
return $aid;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function print_question_formulation_and_controls(&$question, &$state, $quiz, $options) {
|
||||
/// This implementation is very similar to the code used by question type SHORTANSWER
|
||||
|
@ -308,6 +319,34 @@ class quiz_numerical_qtype extends quiz_shortanswer_qtype {
|
|||
return $correct;
|
||||
}
|
||||
|
||||
// ULPGC ecastro
|
||||
function get_all_responses(&$question, &$state) {
|
||||
unset($answers);
|
||||
$unit = $this->get_default_numerical_unit($question);
|
||||
if (is_array($question->options->answers)) {
|
||||
foreach ($question->options->answers as $aid=>$answer) {
|
||||
unset ($r);
|
||||
$r->answer = $answer->answer;
|
||||
$r->credit = $answer->fraction;
|
||||
$this->get_tolerance_interval($answer);
|
||||
if ($unit) {
|
||||
$r->answer .= ' '.$unit->unit;
|
||||
}
|
||||
if ($answer->max != $answer->min) {
|
||||
$max = "$answer->max"; //format_float($answer->max, 2);
|
||||
$min = "$answer->min"; //format_float($answer->max, 2);
|
||||
$r->answer .= ' ('.$min.'..'.$max.')';
|
||||
}
|
||||
$answers[$aid] = $r;
|
||||
}
|
||||
} else {
|
||||
$answers[]="error"; // just for debugging, eliminate
|
||||
}
|
||||
$result->id = $question->id;
|
||||
$result->responses = $answers;
|
||||
return $result;
|
||||
}
|
||||
|
||||
function get_tolerance_interval(&$answer) {
|
||||
// No tolerance
|
||||
if (empty($answer->tolerance)) {
|
||||
|
|
|
@ -171,7 +171,7 @@ class quiz_random_qtype extends quiz_default_questiontype {
|
|||
}
|
||||
|
||||
// ULPGC ecastro
|
||||
function get_all_responses($question, $state){
|
||||
function get_all_responses(&$question, &$state){
|
||||
global $QUIZ_QTYPES;
|
||||
$wrappedquestion = &$state->options->question;
|
||||
return $QUIZ_QTYPES[$wrappedquestion->qtype]
|
||||
|
@ -179,7 +179,7 @@ class quiz_random_qtype extends quiz_default_questiontype {
|
|||
}
|
||||
|
||||
// ULPGC ecastro
|
||||
function get_actual_response($question, $state){
|
||||
function get_actual_response(&$question, &$state){
|
||||
global $QUIZ_QTYPES;
|
||||
$wrappedquestion = &$state->options->question;
|
||||
return $QUIZ_QTYPES[$wrappedquestion->qtype]
|
||||
|
|
|
@ -150,6 +150,20 @@ class quiz_shortanswer_qtype extends quiz_default_questiontype {
|
|||
}
|
||||
}
|
||||
|
||||
// ULPGC ecastro
|
||||
function check_response(&$question, &$state) {
|
||||
$answers = &$question->options->answers;
|
||||
$testedstate = clone($state);
|
||||
$teststate = clone($state);
|
||||
foreach($answers as $aid => $answer) {
|
||||
$teststate->responses[''] = trim($answer->answer);
|
||||
if($this->compare_responses($question, $testedstate, $teststate)) {
|
||||
return $aid;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function grade_responses(&$question, &$state, $quiz) {
|
||||
$answers = &$question->options->answers;
|
||||
$testedstate = clone($state);
|
||||
|
|
|
@ -1,28 +1,8 @@
|
|||
<?php // $Id$
|
||||
|
||||
/// Item analysis displays a table of quiz questions and their performance
|
||||
|
||||
require_once($CFG->libdir.'/tablelib.php');
|
||||
|
||||
|
||||
function stats_sumx($sum, $data){
|
||||
$sum[0] += $data[0];
|
||||
$sum[1] += $data[1];
|
||||
return $sum;
|
||||
}
|
||||
|
||||
function stats_sumx2($sum, $data){
|
||||
$sum[0] += $data[0]*$data[0];
|
||||
$sum[1] += $data[1]*$data[1];
|
||||
return $sum;
|
||||
}
|
||||
|
||||
function stats_sumxy($sum, $data){
|
||||
$sum[0] += $data[0]*$data[1];
|
||||
return $sum;
|
||||
}
|
||||
|
||||
|
||||
/// Item analysis displays a table of quiz questions and their performance
|
||||
|
||||
class quiz_report extends quiz_default_report {
|
||||
|
@ -80,7 +60,7 @@ class quiz_report extends quiz_default_report {
|
|||
|
||||
$scorelimit = $quiz->grade * $lowmarklimit/ 100;
|
||||
|
||||
// ULPGC ecastro DEBUG this is here to allow for differnt SQL to select attempts
|
||||
// ULPGC ecastro DEBUG this is here to allow for different SQL to select attempts
|
||||
switch ($attemptselection) {
|
||||
case QUIZ_ALLATTEMPTS :
|
||||
$limit = '';
|
||||
|
@ -103,33 +83,40 @@ class quiz_report extends quiz_default_report {
|
|||
$select = 'SELECT qa.* '.$limit;
|
||||
$sql = 'FROM '.$CFG->prefix.'user u '.
|
||||
'LEFT JOIN '.$CFG->prefix.'quiz_attempts qa ON u.id = qa.userid '.
|
||||
'LEFT JOIN '.$CFG->prefix.'quiz_states qr ON qr.attempt = qa.id '. // es posible
|
||||
'WHERE u.id IN ('.implode(',', array_keys($users)).') AND ( qa.quiz = '.$quiz->id.') '. // ULPGC ecastro
|
||||
' AND ( qa.sumgrades >= '.$scorelimit.' ) ';
|
||||
// ^^^^^^ es posible seleccionar aquí TODOS los quizzes, como quiere Jussi,
|
||||
// pero habría que llevar la cuenta ed cada quiz para restaura las preguntas (quizquestions, states)
|
||||
/// Fetch the attempts
|
||||
$attempts = get_records_sql($select.$sql.$group);
|
||||
|
||||
|
||||
if(empty($attempts)) {
|
||||
$this->print_header_and_tabs($cm, $course, $quiz, $reportmode="analysis");
|
||||
print_heading($strnoattempts);
|
||||
$this->print_options_form($quiz, $cm, $attemptselection, $lowmarklimit, $pagesize);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Here we rewiew all attempts and record data to construct the table
|
||||
unset($questions);
|
||||
unset($statstable);
|
||||
$questions = array();
|
||||
$statstable = array();
|
||||
$questionarray = array();
|
||||
foreach ($attempts as $attempt) {
|
||||
$questionarray[] = quiz_questions_in_quiz($attempt->layout);
|
||||
}
|
||||
$questionlist = quiz_questions_in_quiz(implode(",", $questionarray));
|
||||
$questionarray = array_unique(explode(",",$questionlist));
|
||||
$questionlist = implode(",", $questionarray);
|
||||
unset($questionarray);
|
||||
$accepted_qtypes = array(SHORTANSWER, TRUEFALSE, MULTICHOICE, MATCH, NUMERICAL, CALCULATED);
|
||||
|
||||
foreach ($attempts as $attempt) {
|
||||
//print_object($attempt); // ULPGC ecastro debug eliminar
|
||||
// print "<br/>Layout= ".$attempt->layout." <br/>";
|
||||
$questionlist = quiz_questions_in_quiz($attempt->layout);
|
||||
$sql = "SELECT q.*, i.grade AS maxgrade, i.id AS instance".
|
||||
" FROM {$CFG->prefix}quiz_questions q,".
|
||||
" {$CFG->prefix}quiz_question_instances i".
|
||||
" WHERE i.quiz = '$quiz->id' AND q.id = i.question".
|
||||
" AND q.id IN ($questionlist)";
|
||||
|
||||
|
||||
if (!$quizquestions = get_records_sql($sql)) {
|
||||
error('No questions found');
|
||||
}
|
||||
|
@ -145,13 +132,12 @@ class quiz_report extends quiz_default_report {
|
|||
error('Could not restore question sessions');
|
||||
}
|
||||
$numbers = explode(',', $questionlist);
|
||||
unset($statsrow);
|
||||
$statsrow = array();
|
||||
foreach ($numbers as $i) {
|
||||
$accepted = array(SHORTANSWER, TRUEFALSE, MULTICHOICE, RANDOM, MATCH, NUMERICAL, CALCULATED);
|
||||
if (!in_array ($quizquestions[$i]->qtype, $accepted)){
|
||||
foreach ($numbers as $i) {
|
||||
$qtype = ($quizquestions[$i]->qtype==4) ? $states[$i]->options->question->qtype : $quizquestions[$i]->qtype;
|
||||
if (!in_array ($qtype, $accepted_qtypes)){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$q = quiz_get_question_responses($quizquestions[$i], $states[$i]);
|
||||
$qid = $q->id;
|
||||
if (!isset($questions[$qid])) {
|
||||
|
@ -167,16 +153,18 @@ class quiz_report extends quiz_default_report {
|
|||
}
|
||||
$responses = quiz_get_question_actual_response($quizquestions[$i], $states[$i]);
|
||||
foreach ($responses as $resp){
|
||||
if ($key = array_search($resp, $questions[$qid]['responses'])) {
|
||||
$questions[$qid]['rcounts'][$key]++;
|
||||
} else {
|
||||
$questions[$qid]['responses'][] = $resp;
|
||||
$questions[$qid]['rcounts'][] = 1;
|
||||
$test->responses[''] = $resp;
|
||||
if ($QUIZ_QTYPES[$quizquestions[$i]->qtype]->compare_responses($quizquestions[$i], $states[$i], $test)) {
|
||||
$questions[$qid]['credits'][] = 1;
|
||||
if ($resp) {
|
||||
if ($key = array_search($resp, $questions[$qid]['responses'])) {
|
||||
$questions[$qid]['rcounts'][$key]++;
|
||||
} else {
|
||||
$questions[$qid]['credits'][] = 0;
|
||||
$test->responses = $QUIZ_QTYPES[$quizquestions[$i]->qtype]->get_correct_responses($quizquestions[$i], $states[$i]);
|
||||
if ($key = $QUIZ_QTYPES[$quizquestions[$i]->qtype]->check_response($quizquestions[$i], $states[$i], $test)) {
|
||||
$questions[$qid]['rcounts'][$key]++;
|
||||
} else {
|
||||
$questions[$qid]['responses'][] = $resp;
|
||||
$questions[$qid]['rcounts'][] = 1;
|
||||
$questions[$qid]['credits'][] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -204,42 +192,21 @@ class quiz_report extends quiz_default_report {
|
|||
|
||||
/// Now check if asked download of data
|
||||
if ($download = optional_param('download', NULL)) {
|
||||
//$dir = make_upload_directory($course->id."/quiz_reports");
|
||||
$filename = clean_filename("$course->shortname ".format_string($quiz->name,true));
|
||||
switch ($download) {
|
||||
case "Excel" :
|
||||
$downloadfilename = $filename.".xls";
|
||||
$this->Export_Excel($questions, $downloadfilename);
|
||||
$this->Export_Excel($questions, $filename);
|
||||
break;
|
||||
case "OOo":
|
||||
$downloadfilename = $filename.".sxw";
|
||||
$this->Export_OOo($questions, $downloadfilename);
|
||||
$this->Export_OOo($questions, $filename);
|
||||
break;
|
||||
case "CSV":
|
||||
$downloadfilename = $filename.".txt";
|
||||
$this->Export_CSV($questions, $downloadfilename);
|
||||
$this->Export_CSV($questions, $filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// Define some strings
|
||||
|
||||
$strquizzes = get_string("modulenameplural", "quiz");
|
||||
$strquiz = get_string("modulename", "quiz");
|
||||
|
||||
/// Print the page header
|
||||
|
||||
print_header_simple(format_string($quiz->name), "",
|
||||
"<a href=\"index.php?id=$course->id\">$strquizzes</a>
|
||||
-> ".format_string($quiz->name),
|
||||
"", "", true, update_module_button($cm->id, $course->id, $strquiz), navmenu($course, $cm));
|
||||
|
||||
/// Print the tabs
|
||||
|
||||
$currenttab = 'reports';
|
||||
$mode = 'anaylis';
|
||||
include('tabs.php');
|
||||
|
||||
$this->print_header_and_tabs($cm, $course, $quiz, $reportmode="analysis");
|
||||
/// Construct the table for this particular report
|
||||
|
||||
$tablecolumns = array('id', 'qname', 'answers', 'credits', 'rcounts', 'rpercent', 'facility', 'sd','discrimination_index', 'discrimination_coeff');
|
||||
|
@ -285,8 +252,8 @@ class quiz_report extends quiz_default_report {
|
|||
$tablesort = $table->get_sql_sort();
|
||||
$sorts = explode(",",trim($tablesort));
|
||||
if ($tablesort and is_array($sorts)) {
|
||||
unset($sortindex);
|
||||
unset($sortorder);
|
||||
$sortindex = array();
|
||||
$sortorder = array ();
|
||||
foreach ($sorts as $sort) {
|
||||
$data = explode(" ",trim($sort));
|
||||
$sortindex[] = trim($data[0]);
|
||||
|
@ -363,8 +330,6 @@ class quiz_report extends quiz_default_report {
|
|||
$table->data[$i][$col] = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
echo '<div id="titlecontainer" class="quiz-report-title">';
|
||||
|
@ -376,13 +341,6 @@ class quiz_report extends quiz_default_report {
|
|||
$table->print_html();
|
||||
|
||||
$this->print_options_form($quiz, $cm, $attemptselection, $lowmarklimit, $pagesize);
|
||||
|
||||
/*
|
||||
if ($download) {
|
||||
echo "<script language='Javascript'> window.open('".$CFG->wwwroot."/files/index.php?id=".$course->id."&wdir=/".
|
||||
get_string('quizreportdir', 'quiz_analysis')."', '".get_string('reportanalysis', 'quiz_analysis')."'); \n</script>";
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -427,9 +385,12 @@ class quiz_report extends quiz_default_report {
|
|||
print_single_button("report.php", $options, get_string("downloadexcel"));
|
||||
echo "</td>\n";
|
||||
echo '<td>';
|
||||
$options["download"] = "OOo";
|
||||
print_single_button("report.php", $options, get_string("downloadooo", "quiz_analysis"));
|
||||
echo "</td>\n";
|
||||
|
||||
if (file_exists("$CFG->libdir/phpdocwriter/lib/include.php")) {
|
||||
$options["download"] = "OOo";
|
||||
print_single_button("report.php", $options, get_string("downloadooo", "quiz_analysis"));
|
||||
echo "</td>\n";
|
||||
}
|
||||
echo '<td>';
|
||||
$options["download"] = "CSV";
|
||||
print_single_button('report.php', $options, get_string("downloadtext"));
|
||||
|
@ -441,7 +402,7 @@ class quiz_report extends quiz_default_report {
|
|||
}
|
||||
|
||||
function report_question_stats(&$q, &$attemptscores, &$questionscores, $top, $bottom) {
|
||||
unset($qstats);
|
||||
$qstats = array();
|
||||
$qid = $q['id'];
|
||||
$top_scores = $top_count = 0;
|
||||
$bottom_scores = $bottom_count = 0;
|
||||
|
@ -459,6 +420,9 @@ class quiz_report extends quiz_default_report {
|
|||
}
|
||||
}
|
||||
|
||||
//$sumx = array_reduce($qscores, "sumx");
|
||||
|
||||
|
||||
$n = count($qstats);
|
||||
$sumx = array_reduce($qstats, "stats_sumx");
|
||||
$sumg = $sumx[0];
|
||||
|
@ -492,7 +456,8 @@ class quiz_report extends quiz_default_report {
|
|||
global $CFG;
|
||||
require_once("$CFG->libdir/excel/Worksheet.php");
|
||||
require_once("$CFG->libdir/excel/Workbook.php");
|
||||
|
||||
|
||||
$filename .= ".xls";
|
||||
header("Content-Type: application/vnd.ms-excel");
|
||||
header("Content-Disposition: attachment; filename=\"$filename\"");
|
||||
header("Expires: 0");
|
||||
|
@ -571,6 +536,10 @@ class quiz_report extends quiz_default_report {
|
|||
|
||||
function Export_OOo(&$questions, $filename) {
|
||||
global $CFG;
|
||||
require_once("$CFG->libdir/phpdocwriter/lib/include.php");
|
||||
import('phpdocwriter.pdw_document');
|
||||
|
||||
$filename .= ".sxw";
|
||||
|
||||
header("Content-Type: application/download\n");
|
||||
header("Content-Disposition: attachment; filename=\"$filename\"");
|
||||
|
@ -579,8 +548,6 @@ class quiz_report extends quiz_default_report {
|
|||
header("Pragma: public");
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
|
||||
require_once("$CFG->libdir/phpdocwriter/lib/include.php");
|
||||
import('phpdocwriter.pdw_document');
|
||||
$filename = substr($filename, 0, -4);
|
||||
|
||||
$sxw = new pdw_document;
|
||||
|
@ -628,6 +595,8 @@ class quiz_report extends quiz_default_report {
|
|||
get_string('dicsindextitle','quiz_analysis'), get_string('disccoefftitle','quiz_analysis'));
|
||||
|
||||
$text = implode("\t", $headers)." \n";
|
||||
|
||||
$filename .= ".txt";
|
||||
|
||||
header("Content-Type: application/download\n");
|
||||
header("Content-Disposition: attachment; filename=\"$filename\"");
|
||||
|
@ -690,13 +659,25 @@ class quiz_report extends quiz_default_report {
|
|||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
function stats_sumx($sum, $data){
|
||||
$sum[0] += $data[0];
|
||||
$sum[1] += $data[1];
|
||||
return $sum;
|
||||
}
|
||||
|
||||
function stats_sumx2($sum, $data){
|
||||
$sum[0] += $data[0]*$data[0];
|
||||
$sum[1] += $data[1]*$data[1];
|
||||
return $sum;
|
||||
}
|
||||
|
||||
function stats_sumxy($sum, $data){
|
||||
$sum[0] += $data[0]*$data[1];
|
||||
return $sum;
|
||||
}
|
||||
|
||||
?>
|
|
@ -21,6 +21,20 @@ class quiz_default_report {
|
|||
return true;
|
||||
}
|
||||
|
||||
function print_header_and_tabs($cm, $course, $quiz, $reportmode="simplestat"){
|
||||
/// Define some strings
|
||||
$strquizzes = get_string("modulenameplural", "quiz");
|
||||
$strquiz = get_string("modulename", "quiz");
|
||||
/// Print the page header
|
||||
print_header_simple(format_string($quiz->name), "",
|
||||
"<a href=\"index.php?id=$course->id\">$strquizzes</a>
|
||||
-> ".format_string($quiz->name),
|
||||
"", "", true, update_module_button($cm->id, $course->id, $strquiz), navmenu($course, $cm));
|
||||
/// Print the tabs
|
||||
$currenttab = 'reports';
|
||||
$mode = $reportmode;
|
||||
include('tabs.php');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue