id; $qs_in_order =qr_getqs($thisquizid); $qcount = 0; $max_choices = 0; //for printing tallies we need to know how many rows to print $table_colcount = 0; foreach ($qs_in_order as $qid){ $table_colcount++; //Get the question type and text and append to object $question_data = get_records_select("quiz_questions",$select="id='$qid'","","qtype,questiontext"); foreach($question_data as $thiskey => $thisq){ $quests[$qid]["qtype"] = $thiskey; $quests[$qid]["qtext"] = $question_data[$thiskey]->questiontext; } if($quests[$qid][qtype] == 5){ //for MATCH items we need to know how many items there are $thismatch = get_record("quiz_match","question","$qid"); $temparray = explode(",",$thismatch->subquestions); $match_number[$qid] = count($temparray); $match_start[$qid] = $temparray[0]; $table_colcount = $table_colcount + $match_number[$qid] - 1; } $choice_data = get_records_select("quiz_answers",$select="question='$qid'","","id as cid,answer,fraction"); if($quests[$qid][qtype] == 8){ $thismin[$qid] = get_field("quiz_numerical","min","question","$qid"); $thismax[$qid] = get_field("quiz_numerical","max","question","$qid"); $quests[$qid]["correct"] = $thismin[$qid] ."< $choice_data->answer >" . $thismax[$qid]; } if($quests[$qid][qtype] >3) {continue;} //only get choices here if type is SHORTANSWER,TRUEFALSE or MULTICHOICE //Get the choices for each question and add to object[choice] each choicd ID and text $choice_count=0; foreach($choice_data as $thiscid=>$thischoice){ $choice_count++; $quests[$qid]["choice"]["$thiscid"]["answer"] = $thischoice->answer; $quests[$qid]["choice"]["$thiscid"]["choiceno"] = $choice_count; //if the fraction = 1, then set this choice number as the correct answer if ($thischoice->fraction == 1){ //append answer if more than one if($quests[$qid]["correct"]){ $quests[$qid]["correct"] .= "," . $thischoice->answer; } else { if($quests[$qid][qtype] == 3) { $quests[$qid]["correct"] = $choice_count; } else { $quests[$qid]["correct"] = $thischoice->answer; } } } } } if($debug and !$download){ print("

Quests

"); print_object($quests); } $user_resps = qr_quiz_responses($thisquizid); // //print_object($user_resps); foreach($user_resps as $thiskey => $thisresp){ $userdata[$thisresp->userid][$thisresp->attemptno]['response'][$thisresp->question]=$thisresp->answer; $userdata[$thisresp->userid][$thisresp->attemptno]['grade']=$thisresp->sumgrades; $userdata[$thisresp->userid][$thisresp->attemptno]['name']=$thisresp->lastname . ", " . $thisresp->firstname; $userdata[$thisresp->userid][$thisresp->attemptno][attemptid]=$thisresp->aid; } if($debug and !$download){ print("

User Data

"); print_object($userdata); } //now go through $userdata and create tally by user, attempt, question storing both response and if correct $reportline = 0; foreach($userdata as $thisuser){ foreach($thisuser as $thiskey=>$thisattempt){ // //print_object($thisattempt); $reportline++; $data_tally[$reportline][$thisattempt[attemptid]][] = $thisattempt[name]; $data_tally[$reportline][$thisattempt[attemptid]][] = $thisattempt[grade]; //raw grade needs to be divided by total grades possible //now for each question, record response as it should be printed and whether right, wrong or skipped //SHORTASNSWER the answer as in $userdata; TF or MULTI need response looked by from cid from $quests //MATCH needs elaborate processing //We need to go through the responses in the order Qs presented thus the use of $qs_in_order not just $thisattempt foreach ($qs_in_order as $qid){ $thisanswer = $thisattempt[response][$qid]; if($quests[$qid][qtype]==5) { //for MATCH processing. Treat each match couplet as an item for $data_tally //builds an array of all questions and answers for match questions $quiz_matches = qr_match_array($qid); $matchsets = explode(",",$thisanswer); //sort needed so that same items line up vertically sort($matchsets); $matchcnt = 0; foreach($matchsets as $thisset){ $matchcnt++; $nowpair = explode("-",$thisset); $phrasepair[0] = $quiz_matches[$nowpair[0]][Q]; $phrasepair[1] = $quiz_matches[$nowpair[1]][A]; //$match_answers keeps the correct answers for use in Response Analysis //This will operate redundantly for each user but better than setting up separate routine to run once(?) $match_answers[$qid][$nowpair[0]] = $phrasepair[1]; $match_qs[$qid][$nowpair[0]] = $phrasepair[0]; $rid = $nowpair[1]; $qtally[$qid][$nowpair[0]][$nowpair[1]][tally]++; $qtally[$qid][$nowpair[0]][$nowpair[1]][answer] = $phrasepair[1]; if ($quiz_matches[$nowpair[0]] == $quiz_matches[$nowpair[1]]) { $pairdata[score] = 1; $qtally[$qid][$nowpair[0]][correct]++; } else { $pairdata[score] = 0; } $pairdata[data] = $phrasepair; $pairdata[qtype] = 5; $pairdata[qid] = $qid; $data_tally[$reportline][$thisattempt[attemptid]][] = $pairdata; } } elseif ($quests[$qid][qtype]==8) { $thisdata = qr_answer_lookup($qid,$thisanswer); $data_tally[$reportline][$thisattempt[attemptid]][] = $thisdata; } else { $thisdata = qr_answer_lookup($qid,$thisanswer); //$thisdata returns couplet of display string and right/wrong if(!$thisdata[data]) {$thisdata[data] = "--";} if($thisdata) { $data_tally[$reportline][$thisattempt[attemptid]][] = $thisdata; } } } } } $total_user_count = $reportline; //prepare headers (must do now because $table_colcount calculated here if($debug and !$download){ print("

Data Tally

"); print_object($data_tally); } //Create here an array with the response analysis data for use with both screen display & Excel // 2 dimensional array has as many cells across as items + title, as many down as $max_choices // plus one row [0] for correct items // Populate array first with "--" in each cell $analysis[] = "--"; $analysis0 = array_pad($analysis,$table_colcount+1,"--"); for ($i = 1; $i <= $max_choices+1; $i++){ $analysis[$i] = $analysis0; } $pct_correct = qr_make_footers(); if($debug and !$download){ print("

Footers

"); print_object($pct_correct); } // //display a row for each possible multiple choice with $max_choices being highest row for ($i = 1; $i<= $max_choices;$i++){ //prepare answer tallies //2 columns already spoken for $current_column = 0; foreach ($qs_in_order as $qid){ $current_column++; switch ($quests[$qid][qtype]) { case 1: if(!$sa_tally[$qid]){ $sa_tally[$qid] = qr_make_satally($qid,$current_column); } break; case 2: if(!$tf_tally[$qid]){ $tf_tally[$qid] = qr_make_tftally($qid,$current_column); } break; case 3: if($qtally[$qid][$i]){ $analysis[$i][$current_column] = $qtally[$qid][$i]; } break; case 8: if(!$num_tally[$qid]){ $num_tally[$qid] = qr_make_numtally($qid,$current_column); } break; case 5: //Make the inverted array if not already made if(! $match_tally[$qid]){ $match_tally[$qid] = qr_make_matchtally($qid); } $match_end = $match_start[$qid] + $match_number[$qid] -1; $colcounter = 0; for ($j = $match_start[$qid];$j <= $match_end;$j++){ $colcounter++; if($match_tally[$qid][$i][$colcounter]) { $tallytext = $match_tally[$qid][$i][$colcounter][answer]; $tallycount = $match_tally[$qid][$i][$colcounter][tally]; //Two slashes used to represent location of a break since one slash might appear in data $analysis[$i][$current_column + $colcounter-1] = $tallytext . "//" . $tallycount ; } } $current_column += $match_number[$qid] -1; break; default: break; } } } if($debug and !$download){ print("

Analysis

"); print_object($analysis); } /// If spreadsheet is wanted, produce one if ($download == "xls") { require_once("$CFG->libdir/excel/Worksheet.php"); require_once("$CFG->libdir/excel/Workbook.php"); header("Content-type: application/vnd.ms-excel"); header("Content-Disposition: attachment; filename=$course->shortname ".$quiz->name.".xls"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0,pre-check=0"); header("Pragma: public"); $workbook = new Workbook("-"); // Creating the first worksheet $myxls = &$workbook->add_worksheet('Responses for each student'); /// format types $format =& $workbook->add_format(); $format->set_bold(0); $formaty =& $workbook->add_format(); $formaty->set_bg_color('yellow'); $formatyc =& $workbook->add_format(); $formatyc->set_bg_color('yellow'); //bold text on yellow bg $formatyc->set_bold(1); $formatyc->set_align('center'); $formatc =& $workbook->add_format(); $formatc->set_align('center'); $formatb =& $workbook->add_format(); $formatb->set_bold(1); $formatbc =& $workbook->add_format(); $formatbc->set_bold(1); $formatbc->set_align('center'); $formatbrt =& $workbook->add_format(); $formatbrt->set_bold(1); $formatbrt->set_align('right'); $formatred =& $workbook->add_format(); $formatred->set_bold(1); $formatred->set_color('red'); $formatred->set_align('center'); $formatblue =& $workbook->add_format(); $formatblue->set_bold(1); $formatblue->set_color('blue'); $formatblue->set_align('center'); $myxls->write_string(0,0,$quiz->name); $myxls->set_column(0,0,25); $row=2; $qcount=0; // $myxls->write_string(0,2,$choiceMax,$formatyc); //You might expect the headers to be written at this point, but we are saving it till last $highest_Q_no = 0; $totcolcount = $table_colcount+2; $myxls->write_string(0,2,"Responses of Individuals to Each Item",$formatyc); // qr_xls_headers("Name","Grade"); //This should have been a function but there is an 'incurable' error: // "Call to a member function on a non-object" It is repeated below for the 2nd worksheet with // only minor variations $nm = "Name";$Item="Grade"; $row = 1; $col = 0; $qcount = 0; $myxls->write_string($row,$col,$nm,$formatbc); if($Item == "Grade") { $col++; $myxls->write_string($row,$col,$Item,$formatbc); } foreach($qs_in_order as $qid){ $qcount++; $col++; if($quests[$qid][qtype] == 5) { $i = 0; foreach ($match_qs[$qid] as $nowq){ $i++; $qm = "Q-$qcount M-$i"; $myxls->write_string($row,$col,$qm,$formatbc); $myxls->write_string(2,$col,$nowq,$formatyc); $col++; } $col--; } else { $myxls->write_string($row,$col,"Q-$qcount",$formatbc); } } //now print the lines of answers $row = 2; foreach ($data_tally as $thisuserno=>$thisuser){ foreach($thisuser as $thisattemptno=>$thisattempt){ $row++; foreach($thisattempt as $thisitemkey=>$thisitem) { //$thisitemkeys 1 & 2 are name and total score //There needs to be a 3-way branch, keys0 & 1 just print $thisitem //else if $thisitem[qtype] = 5, then processing for MATCH is needed //else the data to be printed is in $thisitem[data] and //$thisitem[score] == 1 shows that the item was correct if ($thisitem[score] < 1) {$thiscolor = $formatred;} else {$thiscolor = $formatblue;} $col++; if ($thisitemkey == 0){ $col = 0; $myxls->write_string($row,$col,$thisitem,$formatb); } elseif ($thisitemkey == 1){ $myxls->write_number($row,$col,$thisitem,$formatb); } elseif ($thisitemkey[qtype] == 2){ $myxls->write_string($row,$col,$thisitem[data][answer],$thiscolor); } elseif ($thisitem[qtype] == 5) { if ($thisitem[score] == 1) {$thiscolor = $formatblue;} else {$thiscolor = $formatred;} if(!$thisitem[data][1]){$thisitem[data][1]="(No Response)";} // $myxls->write_string(2,$col,$thisitem[data][0],$formatb); $myxls->write_string($row,$col,$thisitem[data][1],$thiscolor); } else { $myxls->write_string($row,$col,$thisitem[data],$thiscolor); } } } } // } $myxls = &$workbook->add_worksheet('Item Response Analysis'); $sheettitle = "Item Response Analysis"; $myxls->write_string(0,0,$sheettitle,$formatb); $itemcount = 0; $nm = "Question"; $row = 1; $col = 0; $qcount = 0; $myxls->write_string($row,$col,$nm,$formatbc); foreach($qs_in_order as $qid){ $qcount++; $col++; if($quests[$qid][qtype] == 5) { $i = 0; foreach ($match_qs[$qid] as $nowq){ $i++; $qm = "Q-$qcount M-$i"; $myxls->write_string($row,$col,$qm,$formatbc); $myxls->write_string($row+1,$col,$nowq,$formatbc); $col++; } $col--; } else { $myxls->write_string($row,$col,"Q-$qcount",$formatbc); } } // Now write tally data $row = $row+2; $myxls->write_string($row,1,"Correct Response:",$formatbc); $col=1; foreach ($qs_in_order as $qid){ $col++; if ($quests[$qid][qtype] == 5) { foreach($match_answers[$qid] as $thisans){ $myxls->write_string($row,1,$thisans,$formatbc); $col++; } $col--; } else { $myxls->write_string($row,1,$quests[$qid][correct],$formatbc); } } //display a row for each possible multiple choice with $max_choices being highest row,$table_colcount is the width for ($i = 1; $i<= $max_choices;$i++){ $label="M/C #$i"; $myxls->write_string($row,0,$label,$formatbrt); //display answer tallies for ($j = 1; $j <= $table_colcount; $j++){ //substitute "
" for a "//" $nowdata = $analysis[$i][$j]; if($slashpos = strpos($nowdata,"//")){ $text = substr($nowdata,0,$slashpos); $value = substr($nowdata,$slashpos+2); $myxls->write_string($row,$j,$text,$formatc); $myxls->write_string($row+1,$j,$value,$formatbc); } else { $myxls->write_string($row,$j,$nowdata,$formatc); } } $row = $row+2; } //Finally output the total percent correct $row++; $myxls->write_string($row,1,"Percent Correct:",$formatbrt); for ($i = 1; $i<= $table_colcount;$i++){ $myxls->write_string($row,$i,$pct_correct[$i],$formatbc); } //Print the questions with responses on a new worksheet $myxls = &$workbook->add_worksheet('Questions and Responses'); $sheettitle = "Questions and Responses"; $myxls->write_string(0,0,$sheettitle,$formatb); $itemcount = 0; //Now printout the questions (and M/C answers if $containsMC $qcount = 0; $row = 1; foreach ($qs_in_order as $qid){ $row++; $qcount++; $label = "Q-$qcount"; $myxls->write_string($row,0,$label,$formatb); $myxls->write_string($row,1,$quests[$qid][qtext],$formatb); $itemcount = 0; if($quests[$qid][qtype]==3){ $nowchoices = $quests[$qid][choice]; foreach($nowchoices as $thischoice){ $row++; $label = "A-$thischoice[choiceno]"; $myxls->write_string($row,2,$label,$formatb); $myxls->write_string($row,3,$thischoice[answer],$formatb); } } } $workbook->close(); exit; } ////////--------------------------- /// If a text file is wanted, produce one if ($download == "txt") { /// Print header to force download header("Content-Type: application/download\n"); header("Content-Disposition: attachment; filename=\"$course->shortname $quiz->name.txt\""); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0,pre-check=0"); header("Pragma: public"); /// Print names of all the fields echo "$quiz->name"; echo "\n"; /// Print all the user data $colcount = count($question_ids); foreach ($data_tally as $thisuserno=>$thisuser){ foreach($thisuser as $thisattemptno=>$thisattempt){ foreach($thisattempt as $thisitemkey=>$thisitem) { if ($thisitem[score] < 1) {$mark = "";} else {$mark = "*";} //First two items are name & grade if ($thisitemkey < 2){ echo $thisitem . "\t"; } elseif ($thisitemkey[qtype] == 2){ echo $thisitem[data][answer] . "\t"; } elseif ($thisitem[qtype] == 5) { if ($thisitem[score] == 1) {$mark = "*";} else {$mark="";} if(!$thisitem[data][1]){$thisitem[data][1]="(No Response)";} echo "{$thisitem[data][0]} -- $mark{$thisitem[data][1]}\t"; } else { echo "$mark{$thisitem[data]}\t"; } } } echo " \n"; } echo " \n"; echo "* Asterisk indicates correct response"; echo " \n"; //Question numbers for ($i = 1;$i <= $colcount;$i++) { echo "Q-$i\t"; } echo " \n"; //Q numbers foreach($qs_in_order as $qid){ $qcount++; if($quests[$qid][qtype] == 5) { $i = 0; foreach ($match_qs[$qid] as $nowq){ $i++; echo "Q-$qcount M-$i\t"; } } else { echo "Q-$qcount\t"; } } echo " \n"; //Repeat for q answers foreach($qs_in_order as $qid){ $qcount++; if($quests[$qid][qtype] == 5) { foreach ($match_qs[$qid] as $nowq){ echo $nowq . "\t"; } } else { echo "\t"; } } echo " \n"; for ($i = 1; $i<= $max_choices;$i++){ echo "M/C #$i\t"; //display answer tallies for ($j = 1; $j <= $table_colcount; $j++){ //substitute "
" for a "//" $nowdata = $analysis[$i][$j]; if (strpos($nowdata,"//")>0) { $nowdata = str_replace("//"," : ",$nowdata); } echo $nowdata . "\t"; } echo " \n"; } exit; } ////////--------------------------- If it falls through both of the $download choices, print on screen //Print user responses print ("\n"); $totcolcount = $table_colcount+2; print(""); qr_print_headers($data_tally,"Name","Grade"); //now print the lines of answers foreach ($data_tally as $thisuserno=>$thisuser){ foreach($thisuser as $thisattemptno=>$thisattempt){ print(""); foreach($thisattempt as $thisitemkey=>$thisitem) { //$thisitemkeys 1 & 2 are name and total score //There needs to be a 3-way branch, keys0 & 1 just print $thisitem //else if $thisitem[qtype] = 5, then processing for MATCH is needed //else the data to be printed is in $thisitem[data] and $thisitem[score] == 1 shows that the item was correct if ($thisitem[score] < 1) {$thiscolor = "ff0000";} else {$thiscolor = "000000";} if ($thisitemkey == 0){ print(""); } elseif ($thisitemkey[qtype] == 2){ print(""); } elseif ($thisitem[qtype] == 5) { if ($thisitem[score] == 1) {$thiscolor = "blue";} if(!$thisitem[data][1]){$thisitem[data][1]="(No Response)";} print(""); } else { print(""); } } } print("\n"); } if($debug and !$download){ print("

Qtally

"); print_object($qtally); } //print tally of how many selected each choice print(""); qr_print_headers($data_tally,"Item"," "); //display row with correct answers print(""); foreach ($qs_in_order as $qid){ if ($quests[$qid][qtype] == 5) { foreach($match_answers[$qid] as $thisans){ print(""); } } else { print(""); } } print("\n"); //display a row for each possible multiple choice with $max_choices being highest row,$table_colcount is the width for ($i = 1; $i<= $max_choices;$i++){ print(""); } } print("\n"); //Finally display the total percent correct print(""); for ($i = 0; $i< $table_colcount;$i++){ print (" "); } print("\n"); print("
Responses of Individuals to Each Item
$thisitem "); } elseif ($thisitemkey == 1){ print("  $thisitem    $thisitem[data][answer]  {$thisitem[data][0]}
{$thisitem[data][1]}
  {$thisitem[data]}  
Item Response Analysis
Correct Response: $thisans  {$quests[$qid][correct]} 
 M/C #$i"); //display answer tallies for ($j = 1; $j <= $table_colcount; $j++){ //substitute "
" for a "//" $nowdata = $analysis[$i][$j]; if (strpos($nowdata,"//")>0) {$nowdata = str_replace("//","
",$nowdata);} print("
 $nowdata
Percent Correct:{$pct_correct[$i]}
\n"); //Now printout the questions (and M/C answers if $containsMC print ("

\n"); print("\n"); $qcount = 0; foreach ($qs_in_order as $qid){ $qcount++; print("\n"); if($quests[$qid][qtype]==3){ $nowchoices = $quests[$qid][choice]; foreach($nowchoices as $thischoice){ print(""); print("\n"); } } } print("
QUIZ: $quiz->name   --   Listing of Items in This Quiz
Q-$qcount{$quests[$qid][qtext]}
 A-{$thischoice[choiceno]}{$thischoice[answer]}
\n"); echo "
\n"; echo "\n"; echo "
"; unset($options); $options["id"] = "$cm->id"; $options["mode"] = "fullstat"; $options["noheader"] = "yes"; $options["download"] = "xls"; print_single_button("report.php", $options, get_string("downloadexcel")); echo ""; $options["download"] = "txt"; print_single_button("report.php", $options, get_string("downloadtext")); echo "
"; ////////--------------------------- return true; } } ////just functions below here---------------------------------------------- function qr_quiz_responses($quiz) { // Given any quiz number, get all responses and place in // $response object global $CFG; $resp_recs =get_records_sql("SELECT r.id as rid, r.attempt, r.answer, r.question, a.attempt as attemptno, a.id as aid, a.quiz, a.userid, a.sumgrades, u.id as uid, u.lastname, u.firstname FROM {$CFG->prefix}quiz_responses r, {$CFG->prefix}quiz_attempts a, {$CFG->prefix}user u WHERE a.id = r.attempt AND a.quiz = '$quiz' AND a.userid = u.id ORDER BY u.lastname ASC, u.firstname ASC, r.id ASC"); return $resp_recs; } function qr_make_satally($qid,$col){ global $analysis, $qtally,$max_choices; $this_sa = $qtally[$qid][response]; $rowcnt = 0; if ($this_sa){ foreach($this_sa as $thistext =>$thistally){ $rowcnt++; $analysis[$rowcnt][$col] = $thistext . "//" . $thistally; } } if ($rowcnt > $max_choices) {$max_choices = $rowcnt;} return 1; } function qr_make_tftally($qid,$col){ global $analysis, $qtally; $this_tf = $qtally[$qid]; foreach($this_tf as $thiskey=>$tallycnt){ if ($thiskey == "True") { $analysis[1][$col] = "True: " . $tallycnt; } else if ($thiskey == "False") { $analysis[2][$col] = "False: " . $tallycnt; } } return 1; } function qr_make_numtally($qid,$col){ global $analysis, $qtally; $this_num = $qtally[$qid]; $rowcnt = 0; if ($this_num){ foreach($this_num[response] as $thisans=>$thistally){ if($thisans){ $rowcnt++; $analysis[$rowcnt][$col] = $thisans . "//" . $thistally; } } } if ($rowcnt > $max_choices) {$max_choices = $rowcnt;} return 1; } function qr_make_matchtally($qid){ //The MATCH items need to be inverted so that the 1st of each match can be printed in the first row, then the second, etc. global $qtally; $itemcntA = 0; foreach ($qtally[$qid] as $thiskey=>$thisitem){ if($thiskey != "correct"){ $itemcntA++; $itemcntB = 0; if (gettype($thisitem) == "array"){ foreach ($thisitem as $thisrid=>$thisans){ if (!$thisans[answer]){continue;} $itemcntB++; $inverted[$itemcntB][$itemcntA][answer] = $thisans[answer]; $inverted[$itemcntB][$itemcntA][tally] = $thisans[tally]; } } } } return $inverted; } function qr_print_headers($data_tally,$nm,$gd){ global $qs_in_order,$qtally,$quests,$total_user_count,$match_number; $qcount = 0; if($nm == "Item") { print("Question:"); } else { print("$nm$gd"); } foreach($qs_in_order as $qid){ $qcount++; if($quests[$qid][qtype] == 5) { $colcount = $match_number[$qid]; } else { $colcount = 1; } print("Q-$qcount"); } print("\n"); } function qr_make_footers(){ //Create the percent correct for the footer global $qs_in_order,$qtally,$quests,$total_user_count; foreach($qs_in_order as $qid){ if($quests[$qid][qtype] == 5) { foreach ($qtally[$qid] as $thisitem){ $this_correct = $thisitem[correct]; $footers[] = qr_make_pct($this_correct); } } else { $this_correct = $qtally[$qid][correct]; $footers[] = qr_make_pct($this_correct); } } return $footers; } function qr_make_pct($this_correct){ global $qs_in_order,$qtally,$quests,$total_user_count; if($this_correct>0){ $pct_cor =round(($this_correct/$total_user_count)*100,1); } else { $pct_cor = 0; } return $pct_cor ."%"; } function qr_answer_lookup($qid,$thisanswer){ //For each type of question, this needs to determine answer string to report and whether right or wrong global $quests,$qtally,$max_choices,$thismin,$thismax; $thistype = $quests[$qid][qtype]; $returndata[data] = "--"; $returndata[score] = 0; $returndata[qtype] = $thistype; $returndata[qid] = $qid; $qtally[$qid][qtype] = $thistype; switch ($thistype) { case 1: //SHORTANSWER $returndata[data] = $thisanswer; $qtally[$qid][response][$thisanswer]++; //convert all to lowercase to allow for mismatching cases to be correct if (strpos(strtolower($quests[$qid][correct]),trim(strtolower($thisanswer))) >-1){ $qtally[$qid][correct]++; $returndata[score] = 1; } break; case 2: //TRUEFALSE $returndata[data] = $quests[$qid][choice][$thisanswer][answer]; $qtally[$qid][$quests[$qid][choice][$thisanswer][answer]]++; if ($quests[$qid][correct]==$quests[$qid][choice][$thisanswer][answer]){ $returndata[score] = 1; $qtally[$qid][correct]++; } break; case 3: //MULTICHOICE $returndata[data] = $quests[$qid][choice][$thisanswer][choiceno]; if($max_choices < $returndata[data]) {$max_choices = $returndata[data];} $qtally[$qid][$quests[$qid][choice][$thisanswer][choiceno]]++; if (strtolower($quests[$qid][correct])==strtolower($quests[$qid][choice][$thisanswer][choiceno])){ $returndata[score] = 1; $qtally[$qid][correct]++; } break; case 8: //NUMERICAL $returndata[data] = $thisanswer; // $returndata[data] = $thismin . "<" . $thisanswer . ">" . $thismax; $qtally[$qid][response][$thisanswer]++; if ($thisanswer >= $thismin[$qid] and $thisanswer <= $thismax[$qid]){ $qtally[$qid][correct]++; $returndata[score] = 1; } break; } return $returndata; } function qr_getqs($quiz){ // Returns a list of question numbers for a specific quiz if (!$questions = get_record("quiz","id",$quiz)) { notify("Could not find any questions for quiz $quiz"); return false; } $qlist = array(); $qlist = explode(",",$questions->questions); return $qlist; } function qr_match_array($nowQ){ //builds an array of all questions and answers for match questions in the quiz for use in qr_match_table global $quiz_matches,$quiz_match_hdrs; //make an array of all Q & As for match questions //format: $quiz_matches[quiz_match_sub_id][Q or A] $allmatch = get_records("quiz_match_sub","question",$nowQ); // //print_object($allmatch); $hdrcnt=0; foreach($allmatch as $thismatchitemno =>$thismatchitem){ $hdrcnt++; $quiz_matches[$thismatchitemno]["Q"] = $thismatchitem->questiontext; $quiz_matches[$thismatchitemno]["A"] = $thismatchitem->answertext; } //needed so that we know how many column headers to create $quiz_match_hdrs[$nowQ]=$hdrcnt; return $quiz_matches; } function qr_match_table($resplist){ global $quiz_matches; $tbl = "\n"; $resp_array = explode(",",$resplist); $q_cnt=0; foreach ($resp_array as $resp_pair){ $q_cnt++; $tbl = $tbl .""; } $tbl = $tbl . "\n"; foreach ($resp_array as $resp_pair){ $resp_QA = explode("-",$resp_pair); if ($resp_QA[0] == $resp_QA[1]){ $qa = " {$quiz_matches[$resp_QA[0]]['Q']} - {$quiz_matches[$resp_QA[1]]['A']}"; } else{ $qa = " {$quiz_matches[$resp_QA[0]]['Q']} - {$quiz_matches[$resp_QA[1]]['A']}"; } // $qa = $resp_QA[0] . "=" . $resp_QA[1] ; $tbl = $tbl . ""; } $tbl = $tbl . "\n
$q_cnt
$qa
\n"; return $tbl; } ?>