Annotation of loncom/interface/lonstatistics.pm, revision 1.62
1.1 albertel 1: # The LearningOnline Network with CAPA
2: #
1.62 ! matthew 3: # $Id: lonstatistics.pm,v 1.61 2003/02/28 20:50:33 matthew Exp $
1.1 albertel 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
1.14 minaeibi 28: #
1.1 albertel 29: ###
30:
1.59 matthew 31: =pod
32:
33: =head1 NAME
34:
35: lonstatistics
36:
37: =head1 SYNOPSIS
38:
39: Main handler for statistics and chart.
40:
41: =head1 PACKAGES USED
42:
1.60 matthew 43: use strict;
44: use Apache::Constants qw(:common :http);
45: use Apache::lonnet();
46: use Apache::lonhomework;
47: use Apache::loncommon;
48: use Apache::loncoursedata;
49: use Apache::lonhtmlcommon;
50: use Apache::lonproblemanalysis;
51: use Apache::lonproblemstatistics;
52: use Apache::lonstudentassessment;
53: use Apache::lonpercentage;
54: use GDBM_File;
1.59 matthew 55:
56: =over 4
57:
58: =cut
59:
1.55 minaeibi 60: package Apache::lonstatistics;
1.1 albertel 61:
1.30 stredwic 62: use strict;
1.1 albertel 63: use Apache::Constants qw(:common :http);
1.61 matthew 64: use vars qw(
65: @FullClasslist
66: @Students
67: @Sections
68: @SelectedSections
69: %StudentData
70: @StudentDataOrder
71: @SelectedStudentData
72: $top_map
73: @Sequences
74: @SelectedMaps
75: @Assessments);
76:
1.1 albertel 77: use Apache::lonnet();
78: use Apache::lonhomework;
1.12 minaeibi 79: use Apache::loncommon;
1.29 stredwic 80: use Apache::loncoursedata;
81: use Apache::lonhtmlcommon;
1.61 matthew 82: use Apache::lonproblemanalysis();
83: use Apache::lonproblemstatistics();
84: use Apache::lonstudentassessment();
1.49 stredwic 85: use Apache::lonpercentage;
1.1 albertel 86: use GDBM_File;
87:
1.60 matthew 88:
89: #######################################################
90: #######################################################
91:
92: =pod
93:
94: =item Package Variables
95:
96: =item @FullClasslist The full classlist
97:
98: =item @Students The students we are concerned with for this invocation
99:
100: =item @Sections The sections available in this class
101:
102: =item $curr_student The student currently being examined
103:
104: =item $prev_student The student previous in the classlist
105:
106: =item $next_student The student next in the classlist
107:
108: =over
109:
110: =cut
111:
112: #######################################################
113: #######################################################
114: #
115: # Classlist variables
116: #
1.59 matthew 117: my $curr_student;
118: my $prev_student;
119: my $next_student;
120:
121: #######################################################
122: #######################################################
123:
124: =pod
125:
126: =item &clear_classlist_variables()
127:
128: undef the following package variables:
129:
130: =over
131:
1.60 matthew 132: =item @FullClasslist
133:
134: =item @Students
1.59 matthew 135:
1.60 matthew 136: =item @Sections
1.59 matthew 137:
1.60 matthew 138: =item @SelectedSections
1.59 matthew 139:
1.61 matthew 140: =item %StudentData
141:
142: =item @StudentDataOrder
143:
144: =item @SelectedStudentData
145:
1.60 matthew 146: =item $curr_student
1.59 matthew 147:
1.60 matthew 148: =item $prev_student
1.59 matthew 149:
1.60 matthew 150: =item $next_student
1.59 matthew 151:
152: =back
153:
154: =cut
155:
156: #######################################################
157: #######################################################
158: sub clear_classlist_variables {
159: undef(@FullClasslist);
160: undef(@Students);
161: undef(@Sections);
1.60 matthew 162: undef(@SelectedSections);
1.61 matthew 163: undef(%StudentData);
164: undef(@SelectedStudentData);
1.59 matthew 165: undef($curr_student);
166: undef($prev_student);
167: undef($next_student);
168: }
169:
170: #######################################################
171: #######################################################
172:
173: =pod
174:
175: =item &PrepareClasslist()
176:
177: Build up the classlist information. The classlist information is kept in
178: the following package variables:
179:
180: =over
181:
1.60 matthew 182: =item @FullClasslist
183:
184: =item @Students
1.59 matthew 185:
1.60 matthew 186: =item @Sections
1.59 matthew 187:
1.60 matthew 188: =item @SelectedSections
1.59 matthew 189:
1.61 matthew 190: =item %StudentData
191:
192: =item @SelectedStudentData
193:
1.60 matthew 194: =item $curr_student
1.59 matthew 195:
1.60 matthew 196: =item $prev_student
1.59 matthew 197:
1.60 matthew 198: =item $next_student
1.59 matthew 199:
200: =back
201:
202: $curr_student, $prev_student, and $next_student may not be defined, depending
203: upon the calling context.
204:
205: =cut
206:
207: #######################################################
208: #######################################################
209: sub PrepareClasslist {
210: my $r = shift;
211: my %Sections;
212: &clear_classlist_variables();
213: #
214: # Retrieve the classlist
215: my $cid = $ENV{'request.course.id'};
216: my $cdom = $ENV{'course.'.$cid.'.domain'};
217: my $cnum = $ENV{'course.'.$cid.'.num'};
218: my ($classlist,$field_names) = &Apache::loncoursedata::get_classlist($cid,
219: $cdom,$cnum);
1.60 matthew 220: if (exists($ENV{'form.Section'})) {
1.59 matthew 221: if (ref($ENV{'form.Section'})) {
1.61 matthew 222: @SelectedSections = @{$ENV{'form.Section'}};
223: } elsif ($ENV{'form.Section'} !~ /^\s*$/) {
224: @SelectedSections = ($ENV{'form.Section'});
225: }
226: }
227: @SelectedSections = ('all') if (! @SelectedSections);
228: foreach (@SelectedSections) {
229: if ($_ eq 'all') {
230: @SelectedSections = ('all');
1.59 matthew 231: }
232: }
1.61 matthew 233: #
234: # Set up %StudentData
235: @StudentDataOrder = qw/fullname username domain id section status/;
236: foreach my $field (@StudentDataOrder) {
237: $StudentData{$field}->{'title'} = $field;
238: $StudentData{$field}->{'base_width'} =
239: scalar (my @Tmp = split(//,$field));
240: $StudentData{$field}->{'width'} =
241: $StudentData{$field}->{'base_width'};
242: }
243:
1.59 matthew 244: #
245: # Process the classlist
246: while (my ($student,$student_data) = each (%$classlist)) {
247: my $studenthash = ();
248: for (my $i=0; $i< scalar(@$field_names);$i++) {
1.61 matthew 249: my $field = $field_names->[$i];
250: # Store the data
251: $studenthash->{$field}=$student_data->[$i];
252: # Keep track of the width of the fields
253: next if (! exists($StudentData{$field}));
254: my $length = scalar(my @Tmp1 = split(//,$student_data->[$i]));
255: if ($StudentData{$field}->{'width'} < $length) {
256: $StudentData{$field}->{'width'} = $length;
257: }
1.59 matthew 258: }
259: push (@FullClasslist,$studenthash);
260: #
261: # Build up a list of sections
262: my $section = $studenthash->{'section'};
1.60 matthew 263: if (! defined($section) || $section =~/^\s*$/ || $section == -1) {
264: $studenthash->{'section'} = 'none';
265: $section = $studenthash->{'section'};
266: }
1.59 matthew 267: $Sections{$section}++;
268: #
269: # Only put in the list those students we are interested in
1.60 matthew 270: foreach my $sect (@SelectedSections) {
1.61 matthew 271: if (($sect eq 'all') || ($section eq $sect)) {
1.60 matthew 272: push (@Students,$studenthash);
273: last;
274: }
1.59 matthew 275: }
276: }
277: #
278: # Put the consolidated section data in the right place
1.60 matthew 279: @Sections = sort {$a cmp $b} keys(%Sections);
1.61 matthew 280: unshift(@Sections,'all'); # Put 'all' at the front of the list
1.59 matthew 281: #
282: # Sort the Students
283: my $sortby = 'fullname';
1.60 matthew 284: $sortby = $ENV{'form.sort'} if (exists($ENV{'form.sort'}));
285: my @TmpStudents = sort { $a->{$sortby} cmp $b->{$sortby} ||
286: $a->{'fullname'} cmp $b->{'fullname'} } @Students;
287: @Students = @TmpStudents;
1.59 matthew 288: #
289: # Now deal with that current student thing....
290: if (exists($ENV{'form.StudentAssessmentStudent'})) {
291: my ($current_uname,$current_dom) =
292: split(':',$ENV{'form.StudentAssessmentStudent'});
293: my $i;
294: for ($i = 0; $i<=$#Students; $i++) {
295: next if (($Students[$i]->{'username'} ne $current_uname) ||
296: ($Students[$i]->{'domain'} ne $current_dom));
1.60 matthew 297: $curr_student = $Students[$i];
1.59 matthew 298: last; # If we get here, we have our student.
299: }
300: if ($i == 0) {
301: $prev_student = 'none';
302: } else {
303: $prev_student = $Students[$i-1];
304: }
305: if ($i == $#Students) {
306: $next_student = 'none';
307: } else {
308: $next_student = $Students[$i+1];
309: }
310: }
1.61 matthew 311: #
312: if (exists($ENV{'form.StudentData'})) {
313: if (ref($ENV{'form.StudentData'}) eq 'ARRAY') {
314: @SelectedStudentData = @{$ENV{'form.StudentData'}};
315: } else {
316: @SelectedStudentData = ($ENV{'form.StudentData'});
317: }
318: } else {
319: @SelectedStudentData = ('fullname');
320: }
321: foreach (@SelectedStudentData) {
322: if ($_ eq 'all') {
323: @SelectedStudentData = ('all');
324: last;
325: }
326: }
327: #
328: return;
329: }
330:
331: #######################################################
332: #######################################################
333:
334: =pod
335:
336: =item ¤t_student()
337:
338: Returns a pointer to a hash containing data about the currently
339: selected student.
340:
341: =cut
342:
343: #######################################################
344: #######################################################
345: sub current_student {
346: if (defined($curr_student)) {
347: return $curr_student;
348: } else {
349: return 'All Students';
350: }
351: }
352:
353: #######################################################
354: #######################################################
355:
356: =pod
357:
358: =item &previous_student()
359:
360: Returns a pointer to a hash containing data about the student prior
361: in the list of students. Or something.
362:
363: =cut
364:
365: #######################################################
366: #######################################################
367: sub previous_student {
368: if (defined($prev_student)) {
369: return $prev_student;
370: } else {
371: return 'No Student Selected';
372: }
1.59 matthew 373: }
374:
375: #######################################################
376: #######################################################
1.61 matthew 377:
378: =pod
379:
380: =item &next_student()
381:
382: Returns a pointer to a hash containing data about the next student
383: to be viewed.
384:
385: =cut
386:
387: #######################################################
388: #######################################################
389: sub next_student {
390: if (defined($next_student)) {
391: return $next_student;
392: } else {
393: return 'No Student Selected';
394: }
395: }
1.60 matthew 396:
397: #######################################################
398: #######################################################
399:
400: =pod
401:
402: =item &clear_sequence_variables()
403:
404: =cut
405:
406: #######################################################
407: #######################################################
408: sub clear_sequence_variables {
409: undef($top_map);
410: undef(@Sequences);
411: undef(@Assessments);
412: }
413:
414: #######################################################
415: #######################################################
416:
417: =pod
418:
1.61 matthew 419: =item &SetSelectedMaps($elementname)
420:
421: Sets the @SelectedMaps array from $ENV{'form.'.$elementname};
422:
423: =cut
424:
425: #######################################################
426: #######################################################
427: sub SetSelectedMaps {
428: my $elementname = shift;
429: if (exists($ENV{'form.'.$elementname})) {
430: if (ref($ENV{'form.'.$elementname})) {
431: @SelectedMaps = @{$ENV{'form.'.$elementname}};
432: } else {
433: @SelectedMaps = ($ENV{'form.'.$elementname});
434: }
435: } else {
436: @SelectedMaps = ('all');
437: }
438: }
439:
440: #######################################################
441: #######################################################
442:
443: =pod
444:
1.60 matthew 445: =item &PrepareCourseData($r)
446:
447: =cut
448:
449: #######################################################
450: #######################################################
451: sub PrepareCourseData {
452: my ($r) = @_;
453: &clear_sequence_variables();
1.61 matthew 454: my ($top,$sequences,$assessments) =
455: &Apache::loncoursedata::get_sequence_assessment_data();
1.60 matthew 456: if (! defined($top) || ! ref($top)) {
457: # There has been an error, better report it
458: &Apache::lonnet::logthis('top is undefined');
459: return;
460: }
461: $top_map = $top if (ref($top));
462: @Sequences = @{$sequences} if (ref($sequences) eq 'ARRAY');
1.61 matthew 463: @Assessments = @{$assessments} if (ref($assessments) eq 'ARRAY');
464: #
465: # Compute column widths
466: foreach my $seq (@Sequences) {
467: my $name_length = scalar(my @Tmp1 = split(//,$seq->{'title'}));
468: my $num_parts = $seq->{'num_assess_parts'};
469: #
470: # The number of columns needed for the summation text:
471: # " 1/5" = 1+3 columns, " 10/99" = 1+5 columns
472: my $sum_length = 1+1+2*(scalar(my @Tmp2 = split(//,$num_parts)));
473: my $num_col = $num_parts+$sum_length;
474: if ($num_col < $name_length) {
475: $num_col = $name_length;
476: }
477: $seq->{'base_width'} = $name_length;
478: $seq->{'width'} = $num_col;
479: }
480: return;
481: }
482:
483: #######################################################
484: #######################################################
1.60 matthew 485:
486: =pod
487:
1.61 matthew 488: =item &log_sequence($sequence,$recursive,$padding)
489:
490: Write data about the sequence to a logfile. If $recursive is not
491: undef the data is written recursively. $padding is used for recursive
492: calls.
493:
494: =cut
495:
496: #######################################################
497: #######################################################
498: sub log_sequence {
499: my ($seq,$recursive,$padding) = @_;
500: $padding = '' if (! defined($padding));
501: if (ref($seq) ne 'HASH') {
502: &Apache::lonnet::logthis('log_sequence passed bad sequnce');
503: return;
504: }
505: &Apache::lonnet::logthis($padding.'sequence '.$seq->{'title'});
506: while (my($key,$value) = each(%$seq)) {
507: next if ($key eq 'contents');
508: if (ref($value) eq 'ARRAY') {
509: for (my $i=0;$i< scalar(@$value);$i++) {
510: &Apache::lonnet::logthis($padding.$key.'['.$i.']='.
511: $value->[$i]);
512: }
513: } else {
514: &Apache::lonnet::logthis($padding.$key.'='.$value);
515: }
516: }
517: if (defined($recursive)) {
518: &Apache::lonnet::logthis($padding.'-'x20);
519: &Apache::lonnet::logthis($padding.'contains:');
520: foreach my $item (@{$seq->{'contents'}}) {
521: if ($item->{'type'} eq 'container') {
522: &log_sequence($item,$recursive,$padding.' ');
523: } else {
524: &Apache::lonnet::logthis($padding.'title = '.$item->{'title'});
525: while (my($key,$value) = each(%$item)) {
526: next if ($key eq 'title');
527: if (ref($value) eq 'ARRAY') {
528: for (my $i=0;$i< scalar(@$value);$i++) {
529: &Apache::lonnet::logthis($padding.$key.'['.$i.']='.
530: $value->[$i]);
531: }
532: } else {
533: &Apache::lonnet::logthis($padding.$key.'='.$value);
534: }
535: }
536: }
1.60 matthew 537: }
1.61 matthew 538: &Apache::lonnet::logthis($padding.'end contents of '.$seq->{'title'});
539: &Apache::lonnet::logthis($padding.'-'x20);
1.60 matthew 540: }
1.61 matthew 541: return;
542: }
543:
544: ##############################################
545: ##############################################
546:
547: =pod
548:
549: =item &StudentDataSelect($elementname,$status,$numvisible,$selected)
550:
551: Returns html for a selection box allowing the user to choose one (or more)
552: of the fields of student data available (fullname, username, id, section, etc)
553:
554: =over 4
555:
556: =item $elementname The name of the HTML form element
557:
558: =item $status 'multiple' or 'single' selection box
559:
560: =item $numvisible The number of options to be visible
561:
562: =back
1.60 matthew 563:
564: =cut
565:
1.61 matthew 566: ##############################################
567: ##############################################
568: sub StudentDataSelect {
569: my ($elementname,$status,$numvisible)=@_;
570: if ($numvisible < 1) {
571: return;
572: }
573: #
574: # Build the form element
575: my $Str = "\n";
576: $Str .= '<select name="'.$elementname.'" ';
577: if ($status ne 'single') {
578: $Str .= 'multiple="true" ';
579: }
580: $Str .= 'size="'.$numvisible.'" >'."\n";
581: #
582: # Deal with 'all'
583: $Str .= ' <option value="all" ';
584: foreach (@SelectedStudentData) {
585: if ($_ eq 'all') {
586: $Str .= 'selected ';
587: last;
588: }
589: }
590: $Str .= ">all</option>\n";
591: #
592: # Loop through the student data fields
593: foreach my $item (@StudentDataOrder) {
594: $Str .= ' <option value="'.$item.'" ';
595: foreach (@SelectedStudentData) {
596: if ($item eq $_ ) {
597: $Str .= 'selected ';
598: last;
599: }
600: }
601: $Str .= '>'.$item."</option>\n";
602: }
603: $Str .= "</select>\n";
604: return $Str;
1.60 matthew 605: }
606:
607: ##############################################
608: ##############################################
609:
610: =pod
611:
1.61 matthew 612: =item &MapSelect($elementname,$status,$numvisible,$restriction)
1.60 matthew 613:
614: Returns html for a selection box allowing the user to choose one (or more)
615: of the sequences in the course. The values of the sequences are the symbs.
616: If the top sequence is selected, the value 'top' will result.
617:
618: =over 4
619:
620: =item $elementname The name of the HTML form element
621:
622: =item $status 'multiple' or 'single' selection box
623:
624: =item $numvisible The number of options to be visible
625:
626: =item $restriction Code reference to subroutine which returns true or
627: false. The code must expect a reference to a sequence data structure.
628:
629: =back
630:
631: =cut
632:
633: ##############################################
634: ##############################################
635: sub MapSelect {
1.61 matthew 636: my ($elementname,$status,$numvisible,$restriction)=@_;
1.60 matthew 637: if ($numvisible < 1) {
638: return;
639: }
640: #
641: # Set up array of selected items
1.61 matthew 642: &SetSelectedMaps($elementname);
1.60 matthew 643: #
644: # Set up the restriction call
645: if (! defined($restriction)) {
646: $restriction = sub { 1; };
647: }
648: #
649: # Build the form element
650: my $Str = "\n";
651: $Str .= '<select name="'.$elementname.'" ';
652: if ($status ne 'single') {
653: $Str .= 'multiple="true" ';
654: }
655: $Str .= 'size="'.$numvisible.'" >'."\n";
656: #
1.61 matthew 657: # Deal with 'all'
658: foreach (@SelectedMaps) {
659: if ($_ eq 'all') {
660: @SelectedMaps = ('all');
661: last;
662: }
663: }
664: #
665: # Put in option for 'all'
666: $Str .= ' <option value="all" ';
667: foreach (@SelectedMaps) {
668: if ($_ eq 'all') {
669: $Str .= 'selected ';
670: last;
671: }
672: }
673: $Str .= ">all</option>\n";
674: #
1.60 matthew 675: # Loop through the sequences
1.61 matthew 676: foreach my $seq (@Sequences) {
677: next if (! $restriction->($seq));
678: $Str .= ' <option value="'.$seq->{'symb'}.'" ';
679: foreach (@SelectedMaps) {
680: if ($seq->{'symb'} eq $_) {
1.60 matthew 681: $Str .= 'selected ';
682: last;
683: }
684: }
1.61 matthew 685: $Str .= '>'.$seq->{'title'}."</option>\n";
1.60 matthew 686: }
687: $Str .= "</select>\n";
688: return $Str;
689: }
690:
691: ##############################################
692: ##############################################
693:
694: =pod
695:
696: =item &SectionSelect($elementname,$status,$numvisible)
697:
698: Returns html for a selection box allowing the user to choose one (or more)
699: of the sections in the course.
700:
701: =over 4
702:
703: =item $elementname The name of the HTML form element
704:
705: =item $status 'multiple' or 'single' selection box
706:
707: =item $numvisible The number of options to be visible
708:
709: =item $selected Array ref to the names of the already selected sections.
710: If undef, $ENV{'form.'.$elementname} is used.
711: If $ENV{'form.'.$elementname} is also empty, none will be selected.
712:
713: =item $restriction Code reference to subroutine which returns true or
714: false. The code must expect a reference to a sequence data structure.
715:
716: =back
717:
718: =cut
719:
720: ##############################################
721: ##############################################
722: sub SectionSelect {
723: my ($elementname,$status,$numvisible)=@_;
724: if ($numvisible < 1) {
725: return;
726: }
727: #
728: # Build the form element
729: my $Str = "\n";
730: $Str .= '<select name="'.$elementname.'" ';
731: if ($status ne 'single') {
732: $Str .= 'multiple="true" ';
733: }
734: $Str .= 'size="'.$numvisible.'" >'."\n";
735: #
736: # Loop through the sequences
737: foreach my $s (@Sections) {
738: $Str .= ' <option value="'.$s.'" ';
739: foreach (@SelectedSections) {
1.61 matthew 740: if ($s eq $_) {
1.60 matthew 741: $Str .= 'selected ';
742: last;
743: }
744: }
745: $Str .= '>'.$s."</option>\n";
746: }
747: $Str .= "</select>\n";
748: return $Str;
749: }
750:
751: ##############################################
752: ##############################################
1.27 stredwic 753:
754: sub CheckFormElement {
755: my ($cache, $ENVName, $cacheName, $default)=@_;
756:
757: if(defined($ENV{'form.'.$ENVName})) {
758: $cache->{$cacheName} = $ENV{'form.'.$ENVName};
759: } elsif(!defined($cache->{$cacheName})) {
760: $cache->{$cacheName} = $default;
1.60 matthew 761: } else {
762: $ENV{'form.'.$ENVName} = $cache->{$cacheName};
1.27 stredwic 763: }
764: return;
765: }
766:
767: sub ProcessFormData{
1.29 stredwic 768: my ($cache)=@_;
1.27 stredwic 769:
1.29 stredwic 770: $cache->{'reportKey'} = 'false';
1.27 stredwic 771:
1.29 stredwic 772: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.60 matthew 773: ['download',
1.34 stredwic 774: 'reportSelected',
1.41 stredwic 775: 'StudentAssessmentStudent',
776: 'ProblemStatisticsSort']);
1.56 matthew 777: &CheckFormElement($cache, 'DownloadAll', 'DownloadAll', 'false');
778: if ($cache->{'DownloadAll'} ne 'false') {
779: # Clean the hell out of that cache!
780: # We cannot untie the hash at this scope (stupid libgd :( )
781: # So, remove every single key. What a waste of time....
782: # Of course, if you are doing this you are probably resigned
783: # to waiting a while.
784: &Apache::lonnet::logthis("Cleaning out the cache file");
785: while (my ($key,undef)=each(%$cache)) {
786: next if ($key eq 'DownloadAll');
787: delete($cache->{$key});
788: }
789: }
1.29 stredwic 790: &CheckFormElement($cache, 'Status', 'Status', 'Active');
791: &CheckFormElement($cache, 'postdata', 'reportSelected', 'Class list');
792: &CheckFormElement($cache, 'reportSelected', 'reportSelected',
793: 'Class list');
1.30 stredwic 794: $cache->{'reportSelected'} =
795: &Apache::lonnet::unescape($cache->{'reportSelected'});
1.29 stredwic 796: &CheckFormElement($cache, 'sort', 'sort', 'fullname');
797: &CheckFormElement($cache, 'download', 'download', 'false');
1.44 stredwic 798: &CheckFormElement($cache, 'StatisticsMaps',
799: 'StatisticsMaps', 'All Maps');
1.49 stredwic 800: &CheckFormElement($cache, 'StatisticsProblemSelect',
801: 'StatisticsProblemSelect', 'All Problems');
802: &CheckFormElement($cache, 'StatisticsPartSelect',
803: 'StatisticsPartSelect', 'All Parts');
1.44 stredwic 804: if(defined($ENV{'form.Section'})) {
805: my @sectionsSelected = (ref($ENV{'form.Section'}) ?
806: @{$ENV{'form.Section'}} :
807: ($ENV{'form.Section'}));
808: $cache->{'sectionsSelected'} = join(':', @sectionsSelected);
809: } elsif(!defined($cache->{'sectionsSelected'})) {
810: $cache->{'sectionsSelected'} = $cache->{'sectionList'};
811: }
1.29 stredwic 812:
1.38 stredwic 813: # student assessment
1.29 stredwic 814: if(defined($ENV{'form.CreateStudentAssessment'}) ||
815: defined($ENV{'form.NextStudent'}) ||
816: defined($ENV{'form.PreviousStudent'})) {
817: $cache->{'reportSelected'} = 'Student Assessment';
818: }
819: if(defined($ENV{'form.NextStudent'})) {
820: $cache->{'StudentAssessmentMove'} = 'next';
821: } elsif(defined($ENV{'form.PreviousStudent'})) {
822: $cache->{'StudentAssessmentMove'} = 'previous';
823: } else {
824: $cache->{'StudentAssessmentMove'} = 'selected';
825: }
826: &CheckFormElement($cache, 'StudentAssessmentStudent',
1.30 stredwic 827: 'StudentAssessmentStudent', 'All Students');
828: $cache->{'StudentAssessmentStudent'} =
829: &Apache::lonnet::unescape($cache->{'StudentAssessmentStudent'});
1.34 stredwic 830: &CheckFormElement($cache, 'DefaultColumns', 'DefaultColumns', 'false');
1.29 stredwic 831:
1.38 stredwic 832: # Problem analysis
833: &CheckFormElement($cache, 'Interval', 'Interval', '1');
834:
835: # ProblemStatistcs
836: &CheckFormElement($cache, 'DisplayCSVFormat',
837: 'DisplayFormat', 'Display Table Format');
838: &CheckFormElement($cache, 'ProblemStatisticsAscend',
839: 'ProblemStatisticsAscend', 'Ascending');
1.41 stredwic 840: &CheckFormElement($cache, 'ProblemStatisticsSort',
841: 'ProblemStatisticsSort', 'Homework Sets Order');
1.49 stredwic 842: &CheckFormElement($cache, 'DisplayLegend', 'DisplayLegend',
843: 'Hide Legend');
1.45 stredwic 844: &CheckFormElement($cache, 'SortProblems', 'SortProblems',
845: 'Sort Within Sequence');
1.38 stredwic 846:
847: # Search only form elements
1.34 stredwic 848: my @headingColumns=();
849: my @sequenceColumns=();
850: my $foundColumn = 0;
851: if(defined($ENV{'form.ReselectColumns'})) {
852: my @reselected = (ref($ENV{'form.ReselectColumns'}) ?
853: @{$ENV{'form.ReselectColumns'}}
854: : ($ENV{'form.ReselectColumns'}));
855: foreach (@reselected) {
856: if(/HeadingColumn/) {
857: push(@headingColumns, $_);
858: $foundColumn = 1;
859: } elsif(/SequenceColumn/) {
860: push(@sequenceColumns, $_);
861: $foundColumn = 1;
862: }
863: }
864: }
865:
1.37 stredwic 866: $cache->{'reportKey'} = 'false';
867: if($cache->{'reportSelected'} eq 'Analyze') {
868: $cache->{'reportKey'} = 'Analyze';
1.38 stredwic 869: } elsif($cache->{'reportSelected'} eq 'DoDiffGraph') {
870: $cache->{'reportKey'} = 'DoDiffGraph';
871: } elsif($cache->{'reportSelected'} eq 'PercentWrongGraph') {
872: $cache->{'reportKey'} = 'PercentWrongGraph';
873: }
874:
875: if(defined($ENV{'form.DoDiffGraph'})) {
876: $cache->{'reportSelected'} = 'DoDiffGraph';
877: $cache->{'reportKey'} = 'DoDiffGraph';
878: } elsif(defined($ENV{'form.PercentWrongGraph'})) {
879: $cache->{'reportSelected'} = 'PercentWrongGraph';
880: $cache->{'reportKey'} = 'PercentWrongGraph';
1.37 stredwic 881: }
882:
1.29 stredwic 883: foreach (keys(%ENV)) {
1.37 stredwic 884: if(/form\.Analyze/) {
885: $cache->{'reportSelected'} = 'Analyze';
886: $cache->{'reportKey'} = 'Analyze';
887: my $data;
888: (undef, $data)=split(':::', $_);
889: $cache->{'AnalyzeInfo'}=$data;
1.34 stredwic 890: } elsif(/form\.HeadingColumn/) {
891: my $value = $_;
892: $value =~ s/form\.//;
893: push(@headingColumns, $value);
894: $foundColumn=1;
895: } elsif(/form\.SequenceColumn/) {
896: my $value = $_;
897: $value =~ s/form\.//;
898: push(@sequenceColumns, $value);
899: $foundColumn=1;
1.27 stredwic 900: }
1.29 stredwic 901: }
1.27 stredwic 902:
1.34 stredwic 903: if($foundColumn) {
904: $cache->{'HeadingsFound'} = join(':', @headingColumns);
905: $cache->{'SequencesFound'} = join(':', @sequenceColumns);;
906: }
907: if(!defined($cache->{'HeadingsFound'}) ||
908: $cache->{'DefaultColumns'} ne 'false') {
909: $cache->{'HeadingsFound'}='HeadingColumnFull Name';
910: }
911: if(!defined($cache->{'SequencesFound'}) ||
912: $cache->{'DefaultColumns'} ne 'false') {
913: $cache->{'SequencesFound'}='All Sequences';
914: }
915: $cache->{'DefaultColumns'} = 'false';
916:
1.29 stredwic 917: return;
1.27 stredwic 918: }
919:
1.61 matthew 920: ##################################################
921: ##################################################
922:
1.27 stredwic 923: =pod
924:
925: =item &SortStudents()
926:
927: Determines which students to display and in which order. Which are
928: displayed are determined by their status(active/expired). The order
929: is determined by the sort button pressed (default to username). The
930: type of sorting is username, lastname, or section.
931:
932: =over 4
933:
934: Input: $students, $CacheData
935:
936: $students: A array pointer to a list of students (username:domain)
937:
938: $CacheData: A pointer to the hash tied to the cached data
939:
940: Output: \@order
941:
942: @order: An ordered list of students (username:domain)
943:
944: =back
945:
946: =cut
947:
948: sub SortStudents {
1.29 stredwic 949: my ($cache)=@_;
1.27 stredwic 950:
1.29 stredwic 951: my @students = split(':::',$cache->{'NamesOfStudents'});
1.27 stredwic 952: my @sorted1Students=();
1.29 stredwic 953: foreach (@students) {
954: if($cache->{'Status'} eq 'Any' ||
955: $cache->{$_.':Status'} eq $cache->{'Status'}) {
956: push(@sorted1Students, $_);
957: }
1.1 albertel 958: }
1.27 stredwic 959:
1.29 stredwic 960: my $sortBy = '';
961: if(defined($cache->{'sort'})) {
962: $sortBy = ':'.$cache->{'sort'};
1.54 matthew 963: } else {
964: $sortBy = ':fullname';
1.27 stredwic 965: }
1.54 matthew 966: my @order = sort { lc($cache->{$a.$sortBy}) cmp lc($cache->{$b.$sortBy}) ||
967: lc($cache->{$a.':fullname'}) cmp lc($cache->{$b.':fullname'}) }
1.29 stredwic 968: @sorted1Students;
1.27 stredwic 969:
970: return \@order;
971: }
972:
1.32 stredwic 973: =pod
974:
975: =item &SpaceColumns()
976:
977: Determines the width of all the columns in the chart. It is based on
978: the max of the data for that column and its header.
979:
980: =over 4
981:
982: Input: $students, $studentInformation, $headings, $ChartDB
983:
984: $students: An array pointer to a list of students (username:domain)
985:
986: $studentInformatin: The type of data for the student information. It is
987: used as part of the key in $CacheData.
988:
989: $headings: The name of the student information columns.
990:
991: $ChartDB: The name of the cache database which is opened for read/write.
992:
993: Output: None - All data stored in cache.
994:
995: =back
996:
997: =cut
998:
999: sub SpaceColumns {
1000: my ($students,$studentInformation,$headings,$cache)=@_;
1001:
1002: # Initialize Lengths
1003: for(my $index=0; $index<(scalar @$headings); $index++) {
1004: my @titleLength=split(//,$headings->[$index]);
1005: $cache->{$studentInformation->[$index].':columnWidth'}=
1006: scalar @titleLength;
1007: }
1008:
1009: foreach my $name (@$students) {
1010: foreach (@$studentInformation) {
1011: my @dataLength=split(//,$cache->{$name.':'.$_});
1012: my $length=(scalar @dataLength);
1013: if($length > $cache->{$_.':columnWidth'}) {
1014: $cache->{$_.':columnWidth'}=$length;
1015: }
1016: }
1017: }
1018:
1019: return;
1020: }
1021:
1.27 stredwic 1022: sub PrepareData {
1.38 stredwic 1023: my ($c, $cacheDB, $studentInformation, $headings,$r)=@_;
1.27 stredwic 1024:
1025: # Test for access to the cache data
1026: my $courseID=$ENV{'request.course.id'};
1027: my $isRecalculate=0;
1.29 stredwic 1028: if(defined($ENV{'form.Recalculate'})) {
1.27 stredwic 1029: $isRecalculate=1;
1030: }
1031:
1.55 minaeibi 1032: my $isCached = &Apache::loncoursedata::TestCacheData($cacheDB,
1.29 stredwic 1033: $isRecalculate);
1.27 stredwic 1034: if($isCached < 0) {
1035: return "Unable to tie hash to db file.";
1036: }
1037:
1038: # Download class list information if not using cached data
1039: my %cache;
1.38 stredwic 1040: unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_WRCREAT(),0640)) {
1.29 stredwic 1041: return "Unable to tie hash to db file.";
1042: }
1043:
1.50 stredwic 1044: # if(!$isCached) {
1.27 stredwic 1045: my $processTopResourceMapReturn=
1.50 stredwic 1046: &Apache::loncoursedata::ProcessTopResourceMap(\%cache, $c);
1.27 stredwic 1047: if($processTopResourceMapReturn ne 'OK') {
1048: untie(%cache);
1049: return $processTopResourceMapReturn;
1050: }
1.50 stredwic 1051: # }
1.27 stredwic 1052:
1.29 stredwic 1053: if($c->aborted()) {
1054: untie(%cache);
1055: return 'aborted';
1056: }
1.27 stredwic 1057:
1.29 stredwic 1058: my $classlist=&Apache::loncoursedata::DownloadClasslist($courseID,
1059: $cache{'ClasslistTimestamp'},
1060: $c);
1061: foreach (keys(%$classlist)) {
1062: if(/^(con_lost|error|no_such_host)/i) {
1.27 stredwic 1063: untie(%cache);
1064: return "Error getting student data.";
1065: }
1.29 stredwic 1066: }
1.27 stredwic 1067:
1.29 stredwic 1068: if($c->aborted()) {
1069: untie(%cache);
1070: return 'aborted';
1071: }
1072:
1073: # Active is a temporary solution, remember to change
1074: Apache::loncoursedata::ProcessClasslist(\%cache,$classlist,$courseID,$c);
1075: if($c->aborted()) {
1076: untie(%cache);
1077: return 'aborted';
1078: }
1.27 stredwic 1079:
1.29 stredwic 1080: &ProcessFormData(\%cache);
1081: my $students = &SortStudents(\%cache);
1.32 stredwic 1082: &SpaceColumns($students, $studentInformation, $headings, \%cache);
1083: $cache{'updateTime:columnWidth'}=24;
1.27 stredwic 1084:
1.48 stredwic 1085: my $download = $cache{'download'};
1086: my $downloadAll = $cache{'DownloadAll'};
1087: my @allStudents=();
1088: if($download ne 'false') {
1.29 stredwic 1089: $cache{'download'} = 'false';
1.48 stredwic 1090: } elsif($downloadAll ne 'false') {
1091: $cache{'DownloadAll'} = 'false';
1092: if($downloadAll eq 'sorted') {
1093: @allStudents = @$students;
1094: } else {
1095: @allStudents = split(':::', $cache{'NamesOfStudents'});
1096: }
1097: }
1098:
1099: untie(%cache);
1100:
1101: if($download ne 'false') {
1102: my @who = ($download);
1.55 minaeibi 1103: if(&Apache::loncoursedata::DownloadStudentCourseData(\@who, 'false',
1104: $cacheDB, 'true',
1.41 stredwic 1105: 'false', $courseID,
1106: $r, $c) ne 'OK') {
1107: return 'Stop at download individual';
1108: }
1.48 stredwic 1109: } elsif($downloadAll ne 'false') {
1.55 minaeibi 1110: if(&Apache::loncoursedata::DownloadStudentCourseData(\@allStudents,
1111: 'false',
1112: $cacheDB, 'true',
1.41 stredwic 1113: 'true', $courseID,
1114: $r, $c) ne 'OK') {
1115: return 'Stop at download all';
1.27 stredwic 1116: }
1.29 stredwic 1117: }
1118:
1119: return ('OK', $students);
1.27 stredwic 1120: }
1121:
1.60 matthew 1122: sub DisplayClasslist {
1123: my ($r)=@_;
1124: #
1125: my @Fields = ('fullname','username','domain','id','section');
1126: #
1127: my $Str='';
1128: $Str .= '<table border="0"><tr><td bgcolor="#777777">'."\n";
1129: $Str .= '<table border="0" cellpadding="3"><tr bgcolor="#e6ffff">'."\n";
1130: foreach my $field (@Fields) {
1131: $Str .= '<th><a href="/adm/statistics?sort='.$field.'">'.$field.
1132: '</a></th>';
1133: }
1134: $Str .= '</tr>'."\n";
1135: #
1136: my $alternate = 0;
1137: foreach my $student (@Students) {
1138: my $sname = $student->{'username'}.':'.$student->{'domain'};
1139: if($alternate) {
1140: $Str .= '<tr bgcolor="#ffffe6">';
1141: } else {
1142: $Str .= '<tr bgcolor="#ffffc6">';
1143: }
1144: $alternate = ($alternate + 1) % 2;
1145: #
1146: foreach my $field (@Fields) {
1147: $Str .= '<td>';
1148: if ($field eq 'fullname') {
1149: $Str .= '<a href="/adm/statistics?reportSelected=';
1150: $Str .= &Apache::lonnet::escape('Student Assessment');
1151: $Str .= '&StudentAssessmentStudent=';
1.61 matthew 1152: $Str .= &Apache::lonnet::escape($sname).'">';
1.60 matthew 1153: $Str .= $student->{$field}.' ';
1154: $Str .= '</a>';
1155: } else {
1156: $Str .= $student->{$field};
1157: }
1158: $Str .= '</td>';
1159: }
1160: $Str .= "</tr>\n";
1161: }
1162: $Str .= '</table></td></tr></table>'."\n";
1163: #
1164: $r->print($Str);
1165: $r->rflush();
1166: #
1167: return;
1168: }
1169:
1.29 stredwic 1170: sub BuildClasslist {
1.39 stredwic 1171: my ($cacheDB,$students,$studentInformation,$headings,$r)=@_;
1.29 stredwic 1172:
1173: my %cache;
1.38 stredwic 1174: unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
1.29 stredwic 1175: return '<html><body>Unable to tie database.</body></html>';
1.1 albertel 1176: }
1177:
1.55 minaeibi 1178: # my $Ptr = '';
1179: # $Ptr .= '<table border="0"><tbody>';
1180: # $Ptr .= '<tr><td align="right"><b>Select Sections</b>';
1181: # $Ptr .= '</td>'."\n";
1182: # $Ptr .= '<td align="left">'."\n";
1183: # my @sectionsSelected = split(':',$cache{'sectionsSelected'});
1184: # my @sections = split(':',$cache{'sectionList'});
1185: # $Ptr .= &Apache::lonhtmlcommon::MultipleSectionSelect(\@sections,
1186: # \@sectionsSelected,
1187: # 'Statistics');
1188: # $Ptr .= '</td></tr></table><br>';
1189: # $r->print($Ptr);
1190: # $r->rflush();
1191: # my %mySections = ();
1192: # foreach (@sections) { $mySections{$_} = 'True'; }
1193: # $r->print("<br>$cache{'sectionsSelected'}<br>");
1194:
1.29 stredwic 1195: my $Str='';
1196: $Str .= '<table border="0"><tr><td bgcolor="#777777">'."\n";
1197: $Str .= '<table border="0" cellpadding="3"><tr bgcolor="#e6ffff">'."\n";
1198:
1199: my $displayString = '<td align="left"><a href="/adm/statistics?';
1200: $displayString .= 'sort=LINKDATA">DISPLAYDATA </a></td>'."\n";
1.55 minaeibi 1201: $Str .= &Apache::lonhtmlcommon::CreateHeadings(\%cache,
1.39 stredwic 1202: $studentInformation,
1.32 stredwic 1203: $headings, $displayString);
1.29 stredwic 1204: $Str .= '</tr>'."\n";
1.39 stredwic 1205:
1.29 stredwic 1206: my $alternate=0;
1207: foreach (@$students) {
1.55 minaeibi 1208: # if ($mySections{$cache{$_.':'.'section'}} ne 'True') {next;}
1.29 stredwic 1209: my ($username, $domain) = split(':', $_);
1210: if($alternate) {
1.32 stredwic 1211: $Str .= '<tr bgcolor="#ffffe6">';
1.29 stredwic 1212: } else {
1.32 stredwic 1213: $Str .= '<tr bgcolor="#ffffc6">';
1.29 stredwic 1214: }
1215: $alternate = ($alternate + 1) % 2;
1216: foreach my $data (@$studentInformation) {
1.32 stredwic 1217: $Str .= '<td>';
1.29 stredwic 1218: if($data eq 'fullname') {
1219: $Str .= '<a href="/adm/statistics?reportSelected=';
1.30 stredwic 1220: $Str .= &Apache::lonnet::escape('Student Assessment');
1221: $Str .= '&StudentAssessmentStudent=';
1222: $Str .= &Apache::lonnet::escape($cache{$_.':'.$data}).'">';
1.32 stredwic 1223: $Str .= $cache{$_.':'.$data}.' ';
1.29 stredwic 1224: $Str .= '</a>';
1.32 stredwic 1225: } elsif($data eq 'updateTime') {
1226: $Str .= '<a href="/adm/statistics?reportSelected=';
1227: $Str .= &Apache::lonnet::escape('Class list');
1228: $Str .= '&download='.$_.'">';
1229: $Str .= $cache{$_.':'.$data}.' ';
1230: $Str .= ' </a>';
1231: } else {
1232: $Str .= $cache{$_.':'.$data}.' ';
1.29 stredwic 1233: }
1234:
1.32 stredwic 1235: $Str .= '</td>'."\n";
1.29 stredwic 1236: }
1.1 albertel 1237: }
1.29 stredwic 1238:
1.32 stredwic 1239: $Str .= '</tr>'."\n";
1.29 stredwic 1240: $Str .= '</table></td></tr></table>'."\n";
1.39 stredwic 1241: $r->print($Str);
1242: $r->rflush();
1.29 stredwic 1243:
1.27 stredwic 1244: untie(%cache);
1.1 albertel 1245:
1.39 stredwic 1246: return;
1.1 albertel 1247: }
1248:
1.33 stredwic 1249: sub CreateMainMenu {
1250: my ($status, $reports)=@_;
1251:
1252: my $Str = '';
1253:
1254: $Str .= '<table border="0"><tbody><tr>'."\n";
1255: $Str .= '<td></td><td></td>'."\n";
1.57 minaeibi 1256: $Str .= '<td align="center"><b>Select a Report</b></td>'."\n";
1257: $Str .= '<td align="center"><b>Student Status</b></td></tr>'."\n";
1.33 stredwic 1258: $Str .= '<tr>'."\n";
1259: $Str .= '<td align="center"><input type="submit" name="Refresh" ';
1260: $Str .= 'value="Refresh" /></td>'."\n";
1261: $Str .= '<td align="center"><input type="submit" name="DownloadAll" ';
1262: $Str .= 'value="Update All Student Data" /></td>'."\n";
1263: $Str .= '<td align="center">';
1264: $Str .= '<select name="reportSelected" onchange="document.';
1265: $Str .= 'Statistics.submit()">'."\n";
1266:
1267: foreach (sort(keys(%$reports))) {
1268: next if($_ eq 'reportSelected');
1269: $Str .= '<option name="'.$_.'"';
1270: if($reports->{'reportSelected'} eq $reports->{$_}) {
1271: $Str .= ' selected=""';
1272: }
1273: $Str .= '>'.$reports->{$_}.'</option>'."\n";
1274: }
1275: $Str .= '</select></td>'."\n";
1276:
1277: $Str .= '<td align="center">';
1278: $Str .= &Apache::lonhtmlcommon::StatusOptions($status, 'Statistics');
1279: $Str .= '</td>'."\n";
1280:
1281: $Str .= '</tr></tbody></table>'."\n";
1282: $Str .= '<hr>'."\n";
1283:
1284: return $Str;
1285: }
1286:
1.29 stredwic 1287: sub BuildStatistics {
1288: my ($r)=@_;
1289:
1290: my $c = $r->connection;
1.32 stredwic 1291: my @studentInformation=('fullname','section','id','domain','username',
1292: 'updateTime');
1293: my @headings=('Full Name', 'Section', 'PID', 'Domain', 'User Name',
1294: 'Last Updated');
1.55 minaeibi 1295: my $spacing = ' ';
1.52 minaeibi 1296:
1.29 stredwic 1297: my %reports = ('classlist' => 'Class list',
1298: 'problem_statistics' => 'Problem Statistics',
1299: 'student_assessment' => 'Student Assessment',
1.58 minaeibi 1300: 'percentage' => 'Correct-problems Plot',
1.40 minaeibi 1301: # 'activitylog' => 'Activity Log',
1.29 stredwic 1302: 'reportSelected' => 'Class list');
1.27 stredwic 1303:
1304: my %cache;
1.29 stredwic 1305: my $courseID=$ENV{'request.course.id'};
1306: my $cacheDB = "/home/httpd/perl/tmp/$ENV{'user.name'}".
1307: "_$ENV{'user.domain'}_$courseID\_statistics.db";
1308:
1.47 www 1309: $r->print(&Apache::lonhtmlcommon::Title('Course Statistics and Charts'));
1.41 stredwic 1310:
1.55 minaeibi 1311: my ($returnValue, $students) = &PrepareData($c, $cacheDB,
1312: \@studentInformation,
1.38 stredwic 1313: \@headings,$r);
1.29 stredwic 1314: if($returnValue ne 'OK') {
1.41 stredwic 1315: $r->print($returnValue."\n".'</body></html>');
1.29 stredwic 1316: return OK;
1317: }
1.41 stredwic 1318: if(!$c->aborted()) {
1.55 minaeibi 1319: &Apache::loncoursedata::CheckForResidualDownload($cacheDB,
1.41 stredwic 1320: 'true', 'true',
1321: $courseID,
1322: $r, $c);
1323: }
1.29 stredwic 1324:
1325: my $GoToPage;
1.38 stredwic 1326: if(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
1.29 stredwic 1327: $GoToPage = $cache{'reportSelected'};
1328: $reports{'reportSelected'} = $cache{'reportSelected'};
1.55 minaeibi 1329: if(defined($cache{'reportKey'}) &&
1330: !exists($reports{$cache{'reportKey'}}) &&
1.37 stredwic 1331: $cache{'reportKey'} ne 'false') {
1332: $reports{$cache{'reportKey'}} = $cache{'reportSelected'};
1333: }
1.29 stredwic 1334:
1335: if(defined($cache{'OptionResponses'})) {
1.46 stredwic 1336: $reports{'problem_analysis'} = 'Option Response Analysis';
1.29 stredwic 1337: }
1338:
1339: $r->print('<form name="Statistics" ');
1340: $r->print('method="post" action="/adm/statistics">');
1.33 stredwic 1341: $r->print(&CreateMainMenu($cache{'Status'}, \%reports));
1.39 stredwic 1342: $r->rflush();
1.29 stredwic 1343: untie(%cache);
1344: } else {
1.27 stredwic 1345: $r->print('<html><body>Unable to tie database.</body></html>');
1.29 stredwic 1346: return OK;
1347: }
1348:
1349: if($GoToPage eq 'Activity Log') {
1.30 stredwic 1350: &Apache::lonproblemstatistics::Activity();
1.29 stredwic 1351: } elsif($GoToPage eq 'Problem Statistics') {
1.55 minaeibi 1352: &Apache::lonproblemstatistics::BuildProblemStatisticsPage($cacheDB,
1353: $students,
1354: $courseID,
1.36 minaeibi 1355: $c,$r);
1.46 stredwic 1356: } elsif($GoToPage eq 'Option Response Analysis') {
1.39 stredwic 1357: &Apache::lonproblemanalysis::BuildProblemAnalysisPage($cacheDB, $r);
1.29 stredwic 1358: } elsif($GoToPage eq 'Student Assessment') {
1.62 ! matthew 1359: &Apache::lonstudentassessment::BuildStudentAssessmentPage($r, $c);
1.29 stredwic 1360: } elsif($GoToPage eq 'Analyze') {
1.55 minaeibi 1361: &Apache::lonproblemanalysis::BuildAnalyzePage($cacheDB, $students,
1.39 stredwic 1362: $courseID, $r);
1.40 minaeibi 1363: } elsif($GoToPage eq 'DoDiffGraph' || $GoToPage eq 'PercentWrongGraph') {
1.43 stredwic 1364: my $courseDescription = $ENV{'course.'.$courseID.'.description'};
1365: $courseDescription =~ s/\ /"_"/eg;
1366: &Apache::lonproblemstatistics::BuildGraphicChart($GoToPage, $cacheDB,
1367: $courseDescription,
1.45 stredwic 1368: $students, $courseID,
1369: $r, $c);
1.29 stredwic 1370: } elsif($GoToPage eq 'Class list') {
1.60 matthew 1371: &DisplayClasslist($r);
1372: # &BuildClasslist($cacheDB, $students, \@studentInformation,
1373: # \@headings, $r);
1.58 minaeibi 1374: } elsif($GoToPage eq 'Correct-problems Plot') {
1.49 stredwic 1375: &Apache::lonpercentage::BuildPercentageGraph($cacheDB, $students,
1376: $courseID, $c, $r);
1.27 stredwic 1377: }
1378:
1379: $r->print('</form>'."\n");
1.29 stredwic 1380: $r->print("\n".'</body>'."\n".'</html>');
1381: $r->rflush();
1.27 stredwic 1382:
1.29 stredwic 1383: return OK;
1.27 stredwic 1384: }
1.1 albertel 1385:
1386: # ================================================================ Main Handler
1387:
1388: sub handler {
1.31 minaeibi 1389: my $r=shift;
1.34 stredwic 1390:
1391: # $jr = $r;
1.51 www 1392:
1393: my $loaderror=&Apache::lonnet::overloaderror($r);
1394: if ($loaderror) { return $loaderror; }
1395: $loaderror=
1396: &Apache::lonnet::overloaderror($r,
1397: $ENV{'course.'.$ENV{'request.course.id'}.'.home'});
1398: if ($loaderror) { return $loaderror; }
1.1 albertel 1399:
1.27 stredwic 1400: unless(&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'})) {
1401: $ENV{'user.error.msg'}=
1402: $r->uri.":vgr:0:0:Cannot view grades for complete course";
1.55 minaeibi 1403: return HTTP_NOT_ACCEPTABLE;
1.27 stredwic 1404: }
1405:
1406: # Set document type for header only
1407: if($r->header_only) {
1408: if ($ENV{'browser.mathml'}) {
1409: $r->content_type('text/xml');
1410: } else {
1411: $r->content_type('text/html');
1412: }
1413: &Apache::loncommon::no_cache($r);
1414: $r->send_http_header;
1415: return OK;
1416: }
1417:
1418: unless($ENV{'request.course.fn'}) {
1.1 albertel 1419: my $requrl=$r->uri;
1.27 stredwic 1420: $ENV{'user.error.msg'}="$requrl:bre:0:0:Course not initialized";
1.55 minaeibi 1421: return HTTP_NOT_ACCEPTABLE;
1.27 stredwic 1422: }
1.1 albertel 1423:
1.27 stredwic 1424: $r->content_type('text/html');
1425: $r->send_http_header;
1.1 albertel 1426:
1.60 matthew 1427: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.61 matthew 1428: ['sort',
1429: 'StudentAssessmentStudent']);
1.60 matthew 1430:
1.59 matthew 1431: &PrepareClasslist($r);
1.60 matthew 1432:
1433: &PrepareCourseData($r);
1.59 matthew 1434:
1.29 stredwic 1435: &BuildStatistics($r);
1.27 stredwic 1436:
1437: return OK;
1.1 albertel 1438: }
1439: 1;
1.59 matthew 1440:
1441: =pod
1442:
1443: =back
1444:
1445: =cut
1446:
1.1 albertel 1447: __END__
1.31 minaeibi 1448:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>