Annotation of loncom/interface/statistics/lonproblemstatistics.pm, revision 1.41
1.1 stredwic 1: # The LearningOnline Network with CAPA
2: #
1.41 ! matthew 3: # $Id: lonproblemstatistics.pm,v 1.40 2003/02/25 20:47:47 matthew Exp $
1.1 stredwic 4: #
5: # Copyright Michigan State University Board of Trustees
6: #
7: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
8: #
9: # LON-CAPA is free software; you can redistribute it and/or modify
10: # it under the terms of the GNU General Public License as published by
11: # the Free Software Foundation; either version 2 of the License, or
12: # (at your option) any later version.
13: #
14: # LON-CAPA is distributed in the hope that it will be useful,
15: # but WITHOUT ANY WARRANTY; without even the implied warranty of
16: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17: # GNU General Public License for more details.
18: #
19: # You should have received a copy of the GNU General Public License
20: # along with LON-CAPA; if not, write to the Free Software
21: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22: #
23: # /home/httpd/html/adm/gpl.txt
24: #
25: # http://www.lon-capa.org/
26: #
27: # (Navigate problems for statistical reports
28: #
29: ###
30:
1.36 minaeibi 31: package Apache::lonproblemstatistics;
1.1 stredwic 32:
33: use strict;
34: use Apache::lonnet();
35: use Apache::lonhtmlcommon;
36: use Apache::loncoursedata;
1.41 ! matthew 37: use Apache::lonstatistics;
1.1 stredwic 38:
1.41 ! matthew 39: #######################################################
! 40: #######################################################
1.1 stredwic 41:
1.41 ! matthew 42: sub CreateInterface {
! 43: my $Str = '';
! 44: $Str .= '<table cellspacing="5">'."\n";
! 45: $Str .= '<tr>';
! 46: $Str .= '<td align="center"><b>Sections</b></td>';
! 47: $Str .= '<td align="center"><b>Sequences and Folders</b></td>';
! 48: $Str .= '<td align="center"><b>Output</b></td>';
! 49: $Str .= '</tr>'."\n";
! 50: #
! 51: $Str .= '<tr><td align="center">'."\n";
! 52: $Str .= &Apache::lonstatistics::SectionSelect('Section','multiple',5);
! 53: $Str .= '</td><td align="center">';
! 54: #
! 55: my $only_seq_with_assessments = sub {
! 56: my $s=shift;
! 57: if ($s->{'num_assess'} < 1) {
! 58: return 0;
! 59: } else {
! 60: return 1;
! 61: }
! 62: };
! 63: $Str .= &Apache::lonstatistics::MapSelect('Maps','multiple,all',5,
! 64: $only_seq_with_assessments);
! 65: $Str .= '</td><td>'."\n";
! 66: $Str .= &CreateAndParseOutputSelector();
! 67: $Str .= '</td></tr>'."\n";
! 68: $Str .= '</table>'."\n";
! 69: return $Str;
! 70: }
! 71:
! 72: #######################################################
! 73: #######################################################
! 74:
! 75: =pod
! 76:
! 77: =item &CreateAndParseOutputSelector()
! 78:
! 79: =cut
1.16 minaeibi 80:
1.41 ! matthew 81: #######################################################
! 82: #######################################################
! 83: my $output_mode;
! 84: my $show;
! 85:
! 86: my @OutputOptions =
! 87: (
! 88: { name => 'problem statistics grouped by sequence',
! 89: value => 'HTML problem statistics grouped',
! 90: description => 'Output statistics for the problem parts.',
! 91: mode => 'html',
! 92: show => 'grouped',
! 93: },
! 94: { name => 'problem statistics ungrouped',
! 95: value => 'HTML problem statistics ungrouped',
! 96: description => 'Output statistics for the problem parts.',
! 97: mode => 'html',
! 98: show => 'ungrouped',
! 99: },
! 100: { name => 'problem statistics, Excel',
! 101: value => 'Excel problem statistics',
! 102: description => 'Output statistics for the problem parts '.
! 103: 'in an Excel workbook',
! 104: mode => 'excel',
! 105: show => 'all',
! 106: },
! 107: { name => 'Degree of Difficulty Plot',
! 108: value => 'plot deg diff',
! 109: description => 'Generate a plot of the degree of difficulty of each '.
! 110: 'problem part.',
! 111: mode => 'plot',
! 112: show => 'deg of diff',
! 113: },
! 114: { name => 'Percent Wrong Plot',
! 115: value => 'plot per wrong',
! 116: description => 'Generate a plot showing the percent of students who '.
! 117: 'were unable to complete each problem part',
! 118: mode => 'plot',
! 119: show => 'per wrong',
! 120: },
! 121: );
! 122:
! 123: sub OutputDescriptions {
! 124: my $Str = '';
! 125: $Str .= "<h2>Output Modes</h2>\n";
! 126: $Str .= "<dl>\n";
! 127: foreach my $outputmode (@OutputOptions) {
! 128: $Str .=" <dt>".$outputmode->{'name'}."</dt>\n";
! 129: $Str .=" <dd>".$outputmode->{'description'}."</dd>\n";
1.1 stredwic 130: }
1.41 ! matthew 131: $Str .= "</dl>\n";
! 132: return $Str;
! 133: }
1.1 stredwic 134:
1.41 ! matthew 135: sub CreateAndParseOutputSelector {
! 136: my $Str = '';
! 137: my $elementname = 'outputmode';
! 138: #
! 139: # Format for output options is 'mode, restrictions';
! 140: my $selected = 'html, with links';
! 141: if (exists($ENV{'form.'.$elementname})) {
! 142: if (ref($ENV{'form.'.$elementname} eq 'ARRAY')) {
! 143: $selected = $ENV{'form.'.$elementname}->[0];
! 144: } else {
! 145: $selected = $ENV{'form.'.$elementname};
1.25 stredwic 146: }
147: }
1.41 ! matthew 148: #
! 149: # Set package variables describing output mode
! 150: $output_mode = 'html';
! 151: $show = 'all';
! 152: foreach my $option (@OutputOptions) {
! 153: next if ($option->{'value'} ne $selected);
! 154: $output_mode = $option->{'mode'};
! 155: $show = $option->{'show'};
! 156: }
! 157: #
! 158: # Build the form element
! 159: $Str = qq/<select size="5" name="$elementname">/;
! 160: foreach my $option (@OutputOptions) {
! 161: $Str .= "\n".' <option value="'.$option->{'value'}.'"';
! 162: $Str .= " selected " if ($option->{'value'} eq $selected);
! 163: $Str .= ">".$option->{'name'}."<\/option>";
! 164: }
! 165: $Str .= "\n</select>";
! 166: return $Str;
! 167: }
1.25 stredwic 168:
1.41 ! matthew 169: ###############################################
! 170: ###############################################
1.28 stredwic 171:
1.41 ! matthew 172: ###############################################
! 173: ###############################################
! 174: sub Gather_Student_Data {
! 175: my ($r) = @_;
! 176: my $c = $r->connection();
! 177: #
! 178: my @Sequences = &Apache::lonstatistics::Sequences_with_Assess();
! 179: #
! 180: my @Students = @Apache::lonstatistics::Students;
! 181: #
! 182: # Open the progress window
! 183: my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin
! 184: ($r,'Statistics Compilation Status',
! 185: 'Statistics Compilation Progress', scalar(@Students));
! 186: #
! 187: while (my $student = shift @Students) {
! 188: return if ($c->aborted());
! 189: my ($status,undef) = &Apache::loncoursedata::ensure_current_data
! 190: ($student->{'username'},$student->{'domain'},
! 191: $ENV{'request.course.id'});
! 192: &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
! 193: 'last student');
1.28 stredwic 194: }
1.41 ! matthew 195: &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
! 196: $r->rflush();
! 197: }
1.28 stredwic 198:
1.41 ! matthew 199: ###############################################
! 200: ###############################################
1.21 stredwic 201:
1.41 ! matthew 202: ###############################################
! 203: ###############################################
! 204: sub BuildProblemStatisticsPage {
! 205: my ($r,$c)=@_;
! 206: #
! 207: $output_mode = 'html';
! 208: $show = 'grouped';
! 209: #
! 210: $r->print(&CreateInterface());
! 211: $r->print('<input type="hidden" name="statsfirstcall" value="no" />');
! 212: $r->print('<input type="hidden" name="sortby" value="'.$ENV{'form.sortby'}.
! 213: '" />');
! 214: if (! exists($ENV{'form.statsfirstcall'})) {
! 215: return;
1.28 stredwic 216: }
1.41 ! matthew 217: #
! 218: &Gather_Student_Data($r);
! 219: #
! 220: #
! 221: if ($output_mode eq 'html') {
! 222: $r->print("<h2>".
! 223: $ENV{'course.'.$ENV{'request.course.id'}.'.description'}.
! 224: "</h2>\n");
! 225: $r->print("<h3>".localtime(time)."</h3>");
! 226: $r->rflush();
! 227: if ($show eq 'grouped') {
! 228: &output_html_grouped_by_sequence($r);
! 229: } elsif ($show eq 'ungrouped') {
! 230: &output_html_ungrouped($r);
! 231: }
! 232: } else {
! 233: $r->print("<h1>Not implemented</h1>");
1.28 stredwic 234: }
1.41 ! matthew 235: return;
! 236: }
1.21 stredwic 237:
1.41 ! matthew 238: sub output_html_grouped_by_sequence {
! 239: my ($r) = @_;
! 240: #$r->print(&ProblemStatisticsLegend());
! 241: my @Header = ("Title","Part","#Stdnts","Tries","Mod",
! 242: "Mean","#YES","#yes","%Wrng","DoDiff",
! 243: "S.D.","Skew.");#,"D.F.1st","D.F.2nd");
! 244: # #FFFFE6 #EEFFCC #DDFFFF FFDDDD #DDFFDD #FFDDFF
! 245: foreach my $sequence (&Apache::lonstatistics::Sequences_with_Assess()) {
! 246: next if ($sequence->{'num_assess'}<1);
! 247: $r->print("<h3>".$sequence->{'title'}."</h3>");
! 248: $r->print('<table border="0"><tr><td bgcolor="#777777">'."\n");
! 249: $r->print('<table border="0" cellpadding="3">'."\n");
! 250: $r->print('<tr bgcolor="#FFFFE6"><th>'.
! 251: join("</th><th>",@Header)."</th></tr>\n");
! 252: foreach my $resource (@{$sequence->{'contents'}}) {
! 253: next if ($resource->{'type'} ne 'assessment');
! 254: foreach my $part (@{$resource->{'parts'}}) {
! 255: if ($part == 0) {
! 256: $part = ' ';
! 257: }
! 258: my ($num,$tries,$mod,$mean,$Solved,$solved,$DegOfDiff,$STD,
! 259: $SKEW) = &Apache::loncoursedata::get_problem_statistics
! 260: (undef,$resource->{'symb'},$part,
! 261: $ENV{'request.course.id'});
! 262: my $wrongpercent = 0;
! 263: if (defined($num) && $num > 0) {
! 264: $wrongpercent=int(10*100*($num-$Solved+$solved)/$num)/10;
! 265: }
! 266: $r->print('<tr>'.&statistics_html_table_data
! 267: ($resource,$part,$num,$tries,$mod,$mean,$Solved,
! 268: $solved,$wrongpercent,$DegOfDiff,$STD,$SKEW).
! 269: "</tr>\n");
! 270: }
! 271: }
! 272: $r->print("</table>\n");
! 273: $r->print("</td></tr></table>\n");
! 274: $r->rflush();
1.21 stredwic 275: }
1.41 ! matthew 276: #
! 277: return;
! 278: }
1.25 stredwic 279:
1.28 stredwic 280:
1.41 ! matthew 281: ###############################################
! 282: ###############################################
1.26 stredwic 283:
1.41 ! matthew 284: ###############################################
! 285: ###############################################
! 286: sub output_html_ungrouped {
! 287: my ($r) = @_;
! 288: #
! 289: my $sortby = $ENV{'form.sortby'};
! 290: if (! defined($sortby) || $sortby eq '') {
! 291: $sortby = 'sequence';
! 292: }
! 293: #
! 294: my $show_container = 0;
! 295: #$r->print(&ProblemStatisticsLegend());
! 296: my @Header = ("Title","Part","#Stdnts","Tries","Mod",
1.26 stredwic 297: "Mean","#YES","#yes","%Wrng","DoDiff",
1.41 ! matthew 298: "S.D.","Skew.");#,"D.F.1st","D.F.2nd");
! 299: # #FFFFE6 #EEFFCC #DDFFFF FFDDDD #DDFFDD #FFDDFF
! 300: my @Sequences = &Apache::lonstatistics::Sequences_with_Assess();
! 301: if (@Sequences > 1) {
! 302: unshift(@Header,"Container");
! 303: $show_container = 1;
! 304: }
! 305: #
! 306: $r->print('<table border="0"><tr><td bgcolor="#777777">'."\n");
! 307: $r->print('<table border="0" cellpadding="3">'."\n");
! 308: my $Str = '';
! 309: foreach (@Header) {
! 310: $Str .= '<th>'.
! 311: '<a href="javascript:document.Statistics.sortby.value='."'$_'".
! 312: ';document.Statistics.submit();">'.
! 313: $_.'</a></th>';
1.26 stredwic 314: }
1.41 ! matthew 315: $r->print('<tr bgcolor="#FFFFE6">'.$Str."</tr>\n");
! 316: $r->rflush();
! 317: #
! 318: foreach my $sequence (@Sequences) {
! 319: next if ($sequence->{'num_assess'}<1);
! 320: foreach my $resource (@{$sequence->{'contents'}}) {
! 321: next if ($resource->{'type'} ne 'assessment');
! 322: foreach my $part (@{$resource->{'parts'}}) {
! 323: my ($num,$tries,$mod,$mean,$Solved,$solved,$DegOfDiff,$STD,
! 324: $SKEW) = &Apache::loncoursedata::get_problem_statistics
! 325: (undef,$resource->{'symb'},$part,
! 326: $ENV{'request.course.id'});
! 327: if ($part == 0) {
! 328: $part = ' ';
! 329: }
! 330: my $wrongpercent = 0;
! 331: if (defined($num) && $num > 0) {
! 332: $wrongpercent=int(10*100*($num-$Solved+$solved)/$num)/10;
! 333: }
! 334: if ($show_container) {
! 335: $r->print('<tr>'.
! 336: '<td bgcolor="#FFFFE6">'.$sequence->{'title'}.
! 337: '</td>'.
! 338: &statistics_html_table_data
! 339: ($resource,$part,$num,$tries,$mod,$mean,$Solved,
! 340: $solved,$wrongpercent,$DegOfDiff,$STD,$SKEW).
! 341: "</tr>\n");
! 342: } else {
! 343: $r->print('<tr>'.&statistics_html_table_data
! 344: ($resource,$part,$num,$tries,$mod,$mean,$Solved,
! 345: $solved,$wrongpercent,$DegOfDiff,$STD,$SKEW).
! 346: "</tr>\n");
! 347: }
! 348: }
! 349: }
1.26 stredwic 350: }
1.41 ! matthew 351: $r->print("</table>\n");
! 352: $r->print("</td></tr></table>\n");
1.26 stredwic 353: $r->rflush();
1.41 ! matthew 354: #
! 355: return;
! 356: }
! 357:
! 358: ###############################################
! 359: ###############################################
1.26 stredwic 360:
1.41 ! matthew 361: ###############################################
! 362: ###############################################
! 363: sub statistics_html_table_data {
! 364: my ($resource,$part,$num,$tries,$mod,$mean,$Solved,$solved,$wrongpercent,
! 365: $DegOfDiff,$STD,$SKEW) = @_;
! 366: my $row = '';
! 367: $row .= '<td bgcolor="#FFFFE6">'.
! 368: '<a href="'.$resource->{'src'}.'" target="_blank" >'.
! 369: $resource->{'title'}.'</a>'.
! 370: '</td>';
! 371: $row .= '<td bgcolor="#FFFFE6">'.$part.'</td>' if (defined($part));
! 372: foreach ($num,$tries) {
! 373: $row .= '<td bgcolor="#EEFFCC" align="right">'.$_.'</td>';
! 374: }
! 375: foreach ($mod,$mean) {
! 376: $row .= '<td bgcolor="#DDFFFF" align="right">'.
! 377: sprintf("%5.2f",$_).'</td>';
! 378: }
! 379: foreach ($Solved,$solved) {
! 380: $row .= '<td bgcolor="#DDFFFF" align="right">'.$_.'</td>';
! 381: }
! 382: foreach ($wrongpercent) {
! 383: $row .= '<td bgcolor="#DDFFFF" align="right">'.
! 384: sprintf("%5.1f",$_).'</td>';
! 385: }
! 386: foreach ($DegOfDiff,$STD,$SKEW) {
! 387: $row .= '<td bgcolor="#FFDDDD" align="right">'.
! 388: sprintf("%5.2f",$_).'</td>';
1.26 stredwic 389: }
1.41 ! matthew 390: return $row;
! 391: }
1.26 stredwic 392:
1.12 minaeibi 393:
1.41 ! matthew 394: ###############################################
! 395: ###############################################
1.1 stredwic 396:
1.24 stredwic 397: sub BuildGraphicChart {
1.26 stredwic 398: my ($graph,$cacheDB,$courseDescription,$students,$courseID,$r,$c)=@_;
1.24 stredwic 399: my %cache;
1.36 minaeibi 400: my $max;
1.34 minaeibi 401: my $title = '';
402: if($graph eq 'DoDiffGraph') {
403: $title = 'Degree-of-Difficulty';
404: } else {
405: $title = 'Wrong-Percentage';
406: }
407: my $currentSequence = -1;
408: my $sortProblems = 'Sort Within Sequence';
409: my ($result, $orderedProblems) =
1.26 stredwic 410: &InitializeProblemStatistics($cacheDB, $students, $courseID, $c, $r);
411: if($result ne 'OK') {
412: return;
413: }
1.24 stredwic 414: my @values = ();
1.38 albertel 415: unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
416: return 'Unable to tie database.7';
417: }
1.34 minaeibi 418: foreach(@$orderedProblems) {
419: my ($sequence,$problem,$part)=split(':', $_);
420: if($cache{'StatisticsMaps'} ne 'All Maps' &&
421: $cache{'StatisticsMaps'} ne $cache{$sequence.':title'}) {
1.35 minaeibi 422: next;
1.34 minaeibi 423: }
1.35 minaeibi 424: if( $currentSequence == -1 ||
425: ($sortProblems eq 'Sort Within Sequence' &&
1.34 minaeibi 426: $currentSequence != $sequence)) {
1.35 minaeibi 427: if($currentSequence != -1) {
428: &DrawGraph(\@values,$courseDescription,$title,$max,$r);
429: }
1.34 minaeibi 430: if($sortProblems eq 'Sort Within Sequence') {
1.36 minaeibi 431: $r->print('<br><b>'.$cache{$sequence.':title'}.'</b>'."\n");
1.34 minaeibi 432: }
433: $currentSequence = $sequence;
434: @values = ();
1.36 minaeibi 435: $max=0;
1.34 minaeibi 436: }
1.24 stredwic 437: my $data = 0;
438: if($graph eq 'DoDiffGraph') {
439: $data = sprintf("%.2f", $cache{$_.':degreeOfDifficulty'}),
440: } else {
441: $data = sprintf("%.1f", $cache{$_.':percentWrong'}),
442: }
443: if($max < $data) {
444: $max = $data;
445: }
446: push(@values, $data);
447: }
1.35 minaeibi 448: untie(%cache);
449: &DrawGraph(\@values,$courseDescription,$title,$max,$r);
1.24 stredwic 450: return;
451: }
1.1 stredwic 452:
1.35 minaeibi 453: sub DrawGraph {
454: my ($values,$courseDescription,$title,$Max,$r)=@_;
455: my $sendValues = join(',', @$values);
456: my $sendCount = scalar(@$values);
1.36 minaeibi 457: $r->print("<br>The Maximum Value is: $Max");
1.35 minaeibi 458: if ( $Max > 1 ) {
459: if ($Max % 10) {
1.36 minaeibi 460: if ( int($Max) < $Max ) {
461: $Max++;
462: $Max = int($Max);
463: }
1.35 minaeibi 464: }
1.36 minaeibi 465: #(10 - $Max % 10);
1.35 minaeibi 466: } else { $Max = 1; }
1.36 minaeibi 467: my @GData = ('','Problem_number',$title,$Max,$sendCount,$sendValues);
468: # $r->print('</form>'."\n");
469: $r->print('<br>'."\n");
1.39 albertel 470: $r->print('<IMG src="/cgi-bin/graph.png?'.
1.35 minaeibi 471: (join('&', @GData)).'" border="1" />');
1.36 minaeibi 472: # $r->print('<form>'."\n");
473: $r->print('<br>'."\n");
1.35 minaeibi 474: }
475:
1.1 stredwic 476: #---- Problem Statistics Web Page ---------------------------------------
477: sub CreateProblemStatisticsTableHeading {
1.19 stredwic 478: my ($headings,$r)=@_;
479: my $Str='';
480: $Str .= '<tr>'."\n";
481: $Str .= '<th bgcolor="#ffffe6">P#</th>'."\n";
482: foreach(@$headings) {
1.27 stredwic 483: $Str .= '<th bgcolor="#ffffe6">';
484: $Str .= '<a href="/adm/statistics?reportSelected=';
1.19 stredwic 485: $Str .= &Apache::lonnet::escape('Problem Statistics');
486: $Str .= '&ProblemStatisticsSort=';
487: $Str .= &Apache::lonnet::escape($_).'">'.$_.'</a> </th>'."\n";
1.1 stredwic 488: }
1.34 minaeibi 489: $Str .= "\n".'</tr>'."\n";
1.19 stredwic 490: return $Str;
1.1 stredwic 491: }
1.12 minaeibi 492:
1.1 stredwic 493: sub BuildStatisticsTable {
1.26 stredwic 494: my ($cache,$displayFormat,$sortProblems,$orderedProblems,$headings,
495: $r,$color)=@_;
1.19 stredwic 496: my $count = 1;
1.26 stredwic 497: my $currentSequence = -1;
1.21 stredwic 498: foreach(@$orderedProblems) {
1.36 minaeibi 499: my ($sequence,$problem,$part)=split(':', $_);
1.25 stredwic 500: if($cache->{'StatisticsMaps'} ne 'All Maps' &&
501: $cache->{'StatisticsMaps'} ne $cache->{$sequence.':title'}) {
1.23 stredwic 502: next;
503: }
1.34 minaeibi 504: if($currentSequence == -1 ||
505: ($sortProblems eq 'Sort Within Sequence' &&
1.26 stredwic 506: $currentSequence != $sequence)) {
507: if($displayFormat ne 'Display CSV Format') {
508: if($currentSequence ne -1) {
509: $r->print('</table>');
510: $r->print('</td></tr></table><br>');
511: }
512: if($sortProblems eq 'Sort Within Sequence') {
513: $r->print('<b>'.$cache->{$sequence.':title'}.'</b>');
514: }
515: $r->print('<table border="0"><tr><td bgcolor="#777777">'."\n");
516: $r->print('<table border="0" cellpadding="3">'."\n");
517: $r->print(&CreateProblemStatisticsTableHeading($headings, $r));
518: } else {
519: if($sortProblems eq 'Sort Within Sequence') {
520: $r->print('"'.$cache->{$sequence.':title'}.'"');
521: }
522: $r->print('<br>');
523: }
524: $currentSequence = $sequence;
525: }
1.21 stredwic 526: my $ref = '<a href="'.$cache->{$problem.':source'}.
527: '" target="_blank">'.$cache->{$problem.':title'}.'</a>';
1.19 stredwic 528: my $title = $cache->{$problem.':title'};
1.27 stredwic 529: if($part != 0) {
530: $title .= ' Part '.$part;
531: }
1.26 stredwic 532: my $source = $cache->{$problem.':source'};
1.19 stredwic 533: my $tableData = join('&', $ref, $title, $source,
1.21 stredwic 534: $cache->{$_.':studentCount'},
535: $cache->{$_.':totalTries'},
536: $cache->{$_.':maxTries'},
1.27 stredwic 537: $cache->{$_.':mean'},
1.21 stredwic 538: $cache->{$_.':correct'},
539: $cache->{$_.':correctByOverride'},
1.27 stredwic 540: $cache->{$_.':percentWrong'},
541: $cache->{$_.':degreeOfDifficulty'},
542: $cache->{$_.':standardDeviation'},
543: $cache->{$_.':skewness'},
544: $cache->{$_.':discriminationFactor1'},
545: $cache->{$_.':discriminationFactor2'});
1.19 stredwic 546: &TableRow($displayFormat,$tableData,$count,$r,$color);
547: $count++;
548: }
1.26 stredwic 549: if($displayFormat ne 'Display CSV Format') {
1.19 stredwic 550: $r->print('</table>'."\n");
1.26 stredwic 551: $r->print('</td></tr></table>');
552: } else {
553: $r->print('<br>');
1.1 stredwic 554: }
1.21 stredwic 555: return;
1.1 stredwic 556: }
557:
558: sub TableRow {
1.19 stredwic 559: my ($displayFormat,$Str,$RealIdx,$r,$color)=@_;
560: my($ref,$title,$source,$StdNo,$TotalTries,$MxTries,$Avg,$YES,$Override,
1.27 stredwic 561: $Wrng,$DoD,$SD,$Sk,$_D1,$_D2)=split(/\&/,$Str);
1.8 minaeibi 562: my $Ptr;
1.19 stredwic 563: if($displayFormat eq 'Display CSV Format') {
1.26 stredwic 564: $Ptr='"'.$RealIdx.'",'."\n".
565: '"'.$title.'",'."\n".
566: '"'.$source.'",'."\n".
567: '"'.$StdNo.'",'."\n".
568: '"'.$TotalTries.'",'."\n".
569: '"'.$MxTries.'",'."\n".
570: '"'.$Avg.'",'."\n".
571: '"'.$YES.'",'."\n".
572: '"'.$Override.'",'."\n".
573: '"'.$Wrng.'",'."\n".
574: '"'.$DoD.'",'."\n".
575: '"'.$SD.'",'."\n".
576: '"'.$Sk.'",'."\n".
577: '"'.$_D1.'",'."\n".
578: '"'.$_D2.'"'."\n".
579: "<br>\n";
1.1 stredwic 580: $r->print("\n".$Ptr);
1.8 minaeibi 581: } else {
1.26 stredwic 582: $Ptr='<tr>'."\n".
583: '<td bgcolor="#ffffe6">'.$RealIdx.'</td>'."\n".
584: '<td bgcolor="#ffffe6">'.$ref.'</td>'."\n".
585: '<td bgcolor='.$color->{"yellow"}.'> '.$StdNo.'</td>'."\n".
586: '<td bgcolor='.$color->{"yellow"}.'>'.$TotalTries.'</td>'."\n".
587: '<td bgcolor='.$color->{"yellow"}.'>'.$MxTries.'</td>'."\n".
588: '<td bgcolor='.$color->{"gb"}.'>'.$Avg.'</td>'."\n".
589: '<td bgcolor='.$color->{"gb"}.'> '.$YES.'</td>'."\n".
590: '<td bgcolor='.$color->{"gb"}.'> '.$Override.'</td>'."\n".
591: '<td bgcolor='.$color->{"red"}.'> '.$Wrng.'</td>'."\n".
592: '<td bgcolor='.$color->{"red"}.'> '.$DoD.'</td>'."\n".
593: '<td bgcolor='.$color->{"green"}.'> '.$SD.'</td>'."\n".
594: '<td bgcolor='.$color->{"green"}.'> '.$Sk.'</td>'."\n".
595: '<td bgcolor='.$color->{"purple"}.'> '.$_D1.'</td>'."\n".
1.27 stredwic 596: '<td bgcolor='.$color->{"purple"}.'> '.$_D2.'</td>'."\n";
1.26 stredwic 597: $r->print($Ptr.'</tr>'."\n");
1.1 stredwic 598: }
1.19 stredwic 599: return;
1.1 stredwic 600: }
1.5 minaeibi 601:
602: # For loading the colored table for display or un-colored for print
603: sub setbgcolor {
604: my $PrintTable=shift;
605: my %color;
606: if ($PrintTable){
607: $color{"gb"}="#FFFFFF";
608: $color{"red"}="#FFFFFF";
609: $color{"yellow"}="#FFFFFF";
610: $color{"green"}="#FFFFFF";
611: $color{"purple"}="#FFFFFF";
612: } else {
613: $color{"gb"}="#DDFFFF";
614: $color{"red"}="#FFDDDD";
615: $color{"yellow"}="#EEFFCC";
616: $color{"green"}="#DDFFDD";
617: $color{"purple"}="#FFDDFF";
618: }
619: return \%color;
620: }
621:
1.1 stredwic 622: sub ProblemStatisticsButtons {
1.26 stredwic 623: my ($displayFormat, $displayLegend, $sortProblems)=@_;
1.1 stredwic 624: my $Ptr = '<tr><td></td><td align="left">';
625: $Ptr .= '<input type="submit" name="DoDiffGraph" ';
1.33 minaeibi 626: $Ptr .= 'value="Plot Degree of Difficulty" />'."\n";
1.27 stredwic 627: $Ptr .= '</td><td align="left">';
1.1 stredwic 628: $Ptr .= '<input type="submit" name="PercentWrongGraph" ';
1.33 minaeibi 629: $Ptr .= 'value="Plot Percent Wrong" />'."\n";
1.20 stredwic 630: $Ptr .= '</td></tr><tr><td></td><td>'."\n";
1.26 stredwic 631: $Ptr .= '<input type="submit" name="SortProblems" ';
632: if($sortProblems eq 'Sort All Problems') {
633: $Ptr .= 'value="Sort Within Sequence" />'."\n";
634: } else {
635: $Ptr .= 'value="Sort All Problems" />'."\n";
636: }
1.27 stredwic 637: $Ptr .= '</td><td align="left">';
1.20 stredwic 638: $Ptr .= '<input type="submit" name="DisplayLegend" ';
639: if($displayLegend eq 'Show Legend') {
640: $Ptr .= 'value="Hide Legend" />'."\n";
641: } else {
642: $Ptr .= 'value="Show Legend" />'."\n";
643: }
1.27 stredwic 644: $Ptr .= '</td><td align="left">';
1.1 stredwic 645: $Ptr .= '<input type="submit" name="DisplayCSVFormat" ';
646: if($displayFormat eq 'Display CSV Format') {
1.9 stredwic 647: $Ptr .= 'value="Display Table Format" />'."\n";
648: } else {
1.1 stredwic 649: $Ptr .= 'value="Display CSV Format" />'."\n";
650: }
651: $Ptr .= '</td></tr>';
652: return $Ptr;
653: }
654:
655: sub ProblemStatisticsLegend {
656: my $Ptr = '';
657: $Ptr = '<table border="0">';
658: $Ptr .= '<tr><td>';
1.6 minaeibi 659: $Ptr .= '<b>#Stdnts</b></td>';
1.19 stredwic 660: $Ptr .= '<td>Total number of students attempted the problem.';
1.1 stredwic 661: $Ptr .= '</td></tr><tr><td>';
1.6 minaeibi 662: $Ptr .= '<b>Tries</b></td>';
1.19 stredwic 663: $Ptr .= '<td>Total number of tries for solving the problem.';
1.1 stredwic 664: $Ptr .= '</td></tr><tr><td>';
1.6 minaeibi 665: $Ptr .= '<b>Mod</b></td>';
1.19 stredwic 666: $Ptr .= '<td>Largest number of tries for solving the problem by a student.';
1.1 stredwic 667: $Ptr .= '</td></tr><tr><td>';
1.6 minaeibi 668: $Ptr .= '<b>Mean</b></td>';
1.19 stredwic 669: $Ptr .= '<td>Average number of tries. [ Tries / #Stdnts ]';
1.1 stredwic 670: $Ptr .= '</td></tr><tr><td>';
1.6 minaeibi 671: $Ptr .= '<b>#YES</b></td>';
1.1 stredwic 672: $Ptr .= '<td>Number of students solved the problem correctly.';
673: $Ptr .= '</td></tr><tr><td>';
1.6 minaeibi 674: $Ptr .= '<b>#yes</b></td>';
1.1 stredwic 675: $Ptr .= '<td>Number of students solved the problem by override.';
676: $Ptr .= '</td></tr><tr><td>';
1.19 stredwic 677: $Ptr .= '<b>%Wrong</b></td>';
678: $Ptr .= '<td>Percentage of students who tried to solve the problem ';
679: $Ptr .= 'but is still incorrect. [ 100*((#Stdnts-(#YES+#yes))/#Stdnts) ]';
1.1 stredwic 680: $Ptr .= '</td></tr><tr><td>';
1.6 minaeibi 681: $Ptr .= '<b>DoDiff</b></td>';
1.1 stredwic 682: $Ptr .= '<td>Degree of Difficulty of the problem. ';
683: $Ptr .= '[ 1 - ((#YES+#yes) / Tries) ]';
684: $Ptr .= '</td></tr><tr><td>';
1.6 minaeibi 685: $Ptr .= '<b>S.D.</b></td>';
1.1 stredwic 686: $Ptr .= '<td>Standard Deviation of the tries. ';
687: $Ptr .= '[ sqrt(sum((Xi - Mean)^2)) / (#Stdnts-1) ';
688: $Ptr .= 'where Xi denotes every student\'s tries ]';
689: $Ptr .= '</td></tr><tr><td>';
1.6 minaeibi 690: $Ptr .= '<b>Skew.</b></td>';
1.1 stredwic 691: $Ptr .= '<td>Skewness of the students tries.';
692: $Ptr .= '[(sqrt( sum((Xi - Mean)^3) / #Stdnts)) / (S.D.^3)]';
693: $Ptr .= '</td></tr><tr><td>';
1.6 minaeibi 694: $Ptr .= '<b>Dis.F.</b></td>';
1.1 stredwic 695: $Ptr .= '<td>Discrimination Factor: A Standard for evaluating the ';
696: $Ptr .= 'problem according to a Criterion<br>';
1.31 stredwic 697: $Ptr .= '<b>[Criterion to group students into %27 Upper Students - ';
698: $Ptr .= 'and %27 Lower Students]</b><br>';
1.1 stredwic 699: $Ptr .= '<b>1st Criterion</b> for Sorting the Students: ';
700: $Ptr .= '<b>Sum of Partial Credit Awarded / Total Number of Tries</b><br>';
701: $Ptr .= '<b>2nd Criterion</b> for Sorting the Students: ';
702: $Ptr .= '<b>Total number of Correct Answers / Total Number of Tries</b>';
703: $Ptr .= '</td></tr>';
704: $Ptr .= '<tr><td><b>Disc.</b></td>';
705: $Ptr .= '<td>Number of Students had at least one discussion.';
706: $Ptr .= '</td></tr></table>';
707: return $Ptr;
708: }
1.24 stredwic 709:
710: #---- END Problem Statistics Web Page ----------------------------------------
1.4 minaeibi 711:
1.1 stredwic 712: 1;
713: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>