--- loncom/interface/statistics/lonproblemstatistics.pm 2003/03/26 15:19:16 1.42 +++ loncom/interface/statistics/lonproblemstatistics.pm 2003/03/28 15:20:59 1.48 @@ -1,6 +1,6 @@ # The LearningOnline Network with CAPA # -# $Id: lonproblemstatistics.pm,v 1.42 2003/03/26 15:19:16 matthew Exp $ +# $Id: lonproblemstatistics.pm,v 1.48 2003/03/28 15:20:59 matthew Exp $ # # Copyright Michigan State University Board of Trustees # @@ -26,7 +26,26 @@ # # (Navigate problems for statistical reports # -### +############################################### +############################################### + +=pod + +=head1 NAME + +lonproblemstatistics + +=head1 SYNOPSIS + +Routines to present problem statistics to instructors via tables, +Excel files, and plots. + +=over 4 + +=cut + +############################################### +############################################### package Apache::lonproblemstatistics; @@ -35,10 +54,22 @@ use Apache::lonnet(); use Apache::lonhtmlcommon; use Apache::loncoursedata; use Apache::lonstatistics; +use Spreadsheet::WriteExcel; -####################################################### -####################################################### +############################################### +############################################### + +=pod + +=item &CreateInterface() +Create the main intereface for the statistics page. Allows the user to +select sections, maps, and output. + +=cut + +############################################### +############################################### sub CreateInterface { my $Str = ''; $Str .= ''."\n"; @@ -76,6 +107,13 @@ sub CreateInterface { =item &CreateAndParseOutputSelector() +Construct a selection list of options for output and parse output selections. +The current output selected is indicated by the values of the two package +variables $output_mode and $show. @OutputOptions holds the descriptions of +the output options and the values for $output_mode and $show. + + Based on code from lonstudentassessment.pm. + =cut ####################################################### @@ -134,10 +172,10 @@ sub OutputDescriptions { sub CreateAndParseOutputSelector { my $Str = ''; - my $elementname = 'outputmode'; + my $elementname = 'statsoutputmode'; # # Format for output options is 'mode, restrictions'; - my $selected = 'html, with links'; + my $selected = 'HTML problem statistics grouped'; if (exists($ENV{'form.'.$elementname})) { if (ref($ENV{'form.'.$elementname} eq 'ARRAY')) { $selected = $ENV{'form.'.$elementname}->[0]; @@ -169,6 +207,14 @@ sub CreateAndParseOutputSelector { ############################################### ############################################### +=pod + +=item &Gather_Student_Data() + +Ensures all student data is up to date. + +=cut + ############################################### ############################################### sub Gather_Student_Data { @@ -199,6 +245,14 @@ sub Gather_Student_Data { ############################################### ############################################### +=pod + +=item &BuildProblemStatisticsPage() + +Main interface to problem statistics. + +=cut + ############################################### ############################################### sub BuildProblemStatisticsPage { @@ -212,6 +266,14 @@ sub BuildProblemStatisticsPage { $r->print(''); if (! exists($ENV{'form.statsfirstcall'})) { + $r->print(< + +Please make your selections in the boxes above and hit +the button marked "Update Display". + +

+ENDMSG return; } # @@ -229,14 +291,38 @@ sub BuildProblemStatisticsPage { } elsif ($show eq 'ungrouped') { &output_html_ungrouped($r); } + } elsif ($output_mode eq 'excel') { + $r->print("

Preparing Excel Spreadsheet

"); + &output_excel($r); + } elsif ($output_mode eq 'plot') { + if ($show eq 'deg of diff') { + &plot_statistics($r,'DoDiff'); + } elsif ($show eq 'per wrong') { + &plot_statistics($r,'%Wrng'); + } } else { $r->print("

Not implemented

"); } return; } +############################################### +############################################### + +=pod + +=item &output_html_grouped_by_sequence() + +Presents the statistics data as an html table organized by the order +the assessments appear in the course. + +=cut + +############################################### +############################################### sub output_html_grouped_by_sequence { my ($r) = @_; + my $problem_num = 0; #$r->print(&ProblemStatisticsLegend()); my @Header = ("Title","Part","#Stdnts","Tries","Mod", "Mean","#YES","#yes","%Wrng","DoDiff", @@ -252,20 +338,21 @@ sub output_html_grouped_by_sequence { foreach my $resource (@{$sequence->{'contents'}}) { next if ($resource->{'type'} ne 'assessment'); foreach my $part (@{$resource->{'parts'}}) { - if ($part == 0) { - $part = ' '; - } + $problem_num++; my ($num,$tries,$mod,$mean,$Solved,$solved,$DegOfDiff,$STD, - $SKEW) = &Apache::loncoursedata::get_problem_statistics - (undef,$resource->{'symb'},$part, - $ENV{'request.course.id'}); + $SKEW) = &get_statistics($resource->{'symb'},$part); + # + $part = ' ' if ($part == 0); + # my $wrongpercent = 0; if (defined($num) && $num > 0) { $wrongpercent=int(10*100*($num-$Solved+$solved)/$num)/10; } + my $option = ''; $r->print('
'.&statistics_html_table_data ($resource,$part,$num,$tries,$mod,$mean,$Solved, - $solved,$wrongpercent,$DegOfDiff,$STD,$SKEW). + $solved,$wrongpercent,$DegOfDiff,$STD,$SKEW, + $option). "\n"); } } @@ -277,20 +364,30 @@ sub output_html_grouped_by_sequence { return; } - ############################################### ############################################### +=pod + +=item &output_html_ungrouped() + +Presents the statistics data in a single html table which can be sorted by +different columns. + +=cut + ############################################### ############################################### sub output_html_ungrouped { - my ($r) = @_; + my ($r,$option) = @_; # + my $problem_num = 0; my $show_container = 0; + my $show_part = 0; #$r->print(&ProblemStatisticsLegend()); my @Header = ("Title","Part","#Stdnts","Tries","Mod", "Mean","#YES","#yes","%Wrng","DoDiff", - "S.D.","Skew.");#,"D.F.1st","D.F.2nd"); + "S.D.","Skew");#,"D.F.1st","D.F.2nd"); # my $sortby = undef; foreach (@Header) { @@ -301,49 +398,42 @@ sub output_html_ungrouped { if (! defined($sortby) || $sortby eq '') { $sortby = 'Container'; } - # #FFFFE6 #EEFFCC #DDFFFF FFDDDD #DDFFDD #FFDDFF + # If there is more than one sequence, list their titles my @Sequences = &Apache::lonstatistics::Sequences_with_Assess(); if (@Sequences > 1) { unshift(@Header,"Container"); $show_container = 1; } + # + # If the option for showing the problem number is needed, push that + # on the list too + if (defined($option) && $option =~ /show probnum/) { + unshift(@Header,"P#"); + } # $r->print('
'."\n"); - $r->print(''."\n"); - my $Str = ''; - foreach (@Header) { - if (/^(Part)$/) { # Do not allow sorting on this field - $Str .= ''; - } else { - $Str .= ''; - } - } - $r->print(''.$Str."\n"); $r->rflush(); # # Compile the data - my %Statshash; my @Statsarray; foreach my $sequence (@Sequences) { next if ($sequence->{'num_assess'}<1); foreach my $resource (@{$sequence->{'contents'}}) { next if ($resource->{'type'} ne 'assessment'); foreach my $part (@{$resource->{'parts'}}) { + $problem_num++; my ($num,$tries,$mod,$mean,$Solved,$solved,$DegOfDiff,$STD, - $SKEW) = &Apache::loncoursedata::get_problem_statistics - (undef,$resource->{'symb'},$part, - $ENV{'request.course.id'}); + $SKEW) = &get_statistics($resource->{'symb'},$part); + # + $show_part = 1 if ($part ne '0'); + $part = ' ' if ($part == 0); + # my $wrongpercent = 0; if (defined($num) && $num > 0) { $wrongpercent=int(10*100*($num-$Solved+$solved)/$num)/10; } - my $key = $resource->{'symb'}.':'.$part; - $Statshash{$key} = - { - 'sequence' => $sequence, + push (@Statsarray, + { 'sequence' => $sequence, 'resource' => $resource, 'Title' => $resource->{'title'}, 'Part' => $part, @@ -357,39 +447,41 @@ sub output_html_ungrouped { 'DoDiff' => $DegOfDiff, 'S.D.' => $STD, 'Skew' => $SKEW, - }; - push (@Statsarray,$Statshash{$key}); + 'problem_num' => $problem_num, + }); } } } # + # Table Headers + $r->print('
'.$_.''. - ''. - $_.'
'."\n"); + my $Str = ''; + foreach (@Header) { + next if ($_ eq 'Part' && !$show_part); + # Do not allow sorting on some fields + if ($_ eq $sortby || /^(Part|P\#)$/) { + $Str .= ''; + } else { + $Str .= ''; + } + } + $r->print(''.$Str."\n"); + # # Sort the data + my @OutputOrder; if ($sortby eq 'Container') { - foreach my $sequence (@Sequences) { - next if ($sequence->{'num_assess'}<1); - foreach my $resource (@{$sequence->{'contents'}}) { - next if ($resource->{'type'} ne 'assessment'); - foreach my $part (@{$resource->{'parts'}}) { - my $key = $resource->{'symb'}.':'.$part; - $r->print(''); - if ($show_container) { - $r->print(''); - } - $r->print(&stats_row_from_hash($Statshash{$key})); - $r->print("\n"); - } - } - } + @OutputOrder = @Statsarray; } else { # $sortby is already defined, so we can charge ahead - my @OutputOrder; if ($sortby =~ /^(title|part)$/i) { # Alpha comparison @OutputOrder = sort { - $b->{$sortby} cmp $a->{$sortby} || - $b->{'Title'} cmp $a->{'Title'} || - $b->{'Part'} cmp $a->{'Part'}; + lc($a->{$sortby}) cmp lc($b->{$sortby}) || + lc($a->{'Title'}) cmp lc($b->{'Title'}) || + lc($a->{'Part'}) cmp lc($b->{'Part'}); } @Statsarray; } else { # Numerical comparison @@ -409,21 +501,30 @@ sub output_html_ungrouped { } if ($retvalue eq '0') { $retvalue = $b->{$sortby} <=> $a->{$sortby} || - $b->{'Title'} <=> $a->{'Title'} || - $b->{'Part'} <=> $a->{'Part'}; + lc($a->{'Title'}) <=> lc($b->{'Title'}) || + lc($a->{'Part'}) <=> lc($b->{'Part'}); } $retvalue; } @Statsarray; } - foreach my $row (@OutputOrder) { - $r->print(''); - if ($show_container) { - $r->print(''); - } - $r->print(&stats_row_from_hash($row)); - $r->print("\n"); - } + } + $option .= ',no part' if (! $show_part); + foreach my $row (@OutputOrder) { + $r->print(''); + if (defined($option) && $option =~ /show probnum/) { + $r->print(''); + } + if ($show_container) { + $r->print(''); + } + $r->print(&statistics_html_table_data + ($row->{'resource'},$row->{'Part'},$row->{'#Stdnts'}, + $row->{'Tries'},$row->{'Mod'},$row->{'Mean'}, + $row->{'#YES'},$row->{'#yes'},$row->{"\%Wrng"}, + $row->{'DoDiff'},$row->{'S.D.'},$row->{'Skew'}, + $option)); + $r->print("\n"); } $r->print("
'.$_.''. + ''. + $_.'
' - .$sequence->{'title'}.'
' - .$row->{'sequence'}->{'title'}.'
'.$row->{'problem_num'}.'' + .$row->{'sequence'}->{'title'}.'
\n"); $r->print("
\n"); @@ -432,38 +533,162 @@ sub output_html_ungrouped { return; } -sub stats_row_from_hash { - my ($data) = @_; - if (ref($data) ne 'HASH') { - my %Tmp = @_; - $data = \%Tmp; - } - return &statistics_html_table_data($data->{'resource'},$data->{'Part'}, - $data->{'#Stdnts'}, $data->{'Tries'}, - $data->{'Mod'}, $data->{'Mean'}, - $data->{'#YES'}, $data->{'#yes'}, - $data->{"\%Wrng"}, $data->{'DoDiff'}, - $data->{'S.D.'}, $data->{'Skew'}); +############################################### +############################################### + +=pod + +=item &output_excel() + +Presents the statistical data in an Excel 95 compatable spreadsheet file. + +=cut + +############################################### +############################################### +sub output_excel { + my ($r) = @_; + my $filename = '/prtspool/'. + $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'. + time.'_'.rand(1000000000).'.xls'; + # + my $excel_workbook = undef; + my $excel_sheet = undef; + # + my $rows_output = 0; + my $cols_output = 0; + # + # Create sheet + $excel_workbook = Spreadsheet::WriteExcel->new('/home/httpd'.$filename); + # + # Check for errors + if (! defined($excel_workbook)) { + $r->log_error("Error creating excel spreadsheet $filename: $!"); + $r->print("Problems creating new Excel file. ". + "This error has been logged. ". + "Please alert your LON-CAPA administrator"); + return ; + } + # + # The excel spreadsheet stores temporary data in files, then put them + # together. If needed we should be able to disable this (memory only). + # The temporary directory must be specified before calling 'addworksheet'. + # File::Temp is used to determine the temporary directory. + $excel_workbook->set_tempdir($Apache::lonnet::tmpdir); + # + # Add a worksheet + my $sheetname = $ENV{'course.'.$ENV{'request.course.id'}.'.description'}; + if (length($sheetname) > 31) { + $sheetname = substr($sheetname,0,31); + } + $excel_sheet = $excel_workbook->addworksheet($sheetname); + # + # Put the course description in the header + $excel_sheet->write($rows_output,$cols_output++, + $ENV{'course.'.$ENV{'request.course.id'}.'.description'}); + $cols_output += 3; + # + # Put a description of the sections listed + my $sectionstring = ''; + my @Sections = @Apache::lonstatistics::SelectedSections; + if (scalar(@Sections) > 1) { + if (scalar(@Sections) > 2) { + my $last = pop(@Sections); + $sectionstring = "Sections ".join(', ',@Sections).', and '.$last; + } else { + $sectionstring = "Sections ".join(' and ',@Sections); + } + } else { + if ($Sections[0] eq 'all') { + $sectionstring = "All sections"; + } else { + $sectionstring = "Section ".$Sections[0]; + } + } + $excel_sheet->write($rows_output,$cols_output++,$sectionstring); + $cols_output += scalar(@Sections); + # + # Put the date in there too + $excel_sheet->write($rows_output,$cols_output++, + 'Compiled on '.localtime(time)); + # + $rows_output++; + $cols_output=0; + # + # Add the headers + my @Header = ("Container","Title","Part","#Stdnts","Tries","Mod", + "Mean","#YES","#yes","%Wrng","DoDiff", + "S.D.","Skew.");#,"D.F.1st","D.F.2nd"); + foreach (@Header) { + $excel_sheet->write($rows_output,$cols_output++,$_); + } + $rows_output++; + # + # Write the data + foreach my $sequence (&Apache::lonstatistics::Sequences_with_Assess()) { + next if ($sequence->{'num_assess'}<1); + foreach my $resource (@{$sequence->{'contents'}}) { + next if ($resource->{'type'} ne 'assessment'); + foreach my $part (@{$resource->{'parts'}}) { + $cols_output=0; + my ($num,$tries,$mod,$mean,$Solved,$solved,$DegOfDiff,$STD, + $SKEW) = &get_statistics($resource->{'symb'},$part); + # + if (!defined($part) || $part eq '') { + $part = ' '; + } + my $wrongpercent = 0; + if (defined($num) && $num > 0) { + $wrongpercent=int(10*100*($num-$Solved+$solved)/$num)/10; + } + foreach ($sequence->{'title'},$resource->{'title'},$part, + $num,$tries,$mod,$mean,$Solved,$solved,$wrongpercent, + $DegOfDiff,$STD,$SKEW) { + $excel_sheet->write($rows_output,$cols_output++,$_); + } + $rows_output++; + } + } + } + # + # Write the excel file + $excel_workbook->close(); + # Tell the user where to get their excel file + $r->print('
'. + 'Your Excel spreadsheet.'."\n"); + $r->rflush(); + return; } ############################################### ############################################### +=pod + +=item &statistics_html_table_data() + +Help function used to format the rows for HTML table output. + +=cut + ############################################### ############################################### sub statistics_html_table_data { my ($resource,$part,$num,$tries,$mod,$mean,$Solved,$solved,$wrongpercent, - $DegOfDiff,$STD,$SKEW) = @_; + $DegOfDiff,$STD,$SKEW,$options) = @_; my $row = ''; $row .= ''. ''. $resource->{'title'}.''. ''; - $row .= ''.$part.'' if (defined($part)); + $row .= ''.$part.'' if ($options !~ /no part/); foreach ($num,$tries) { $row .= ''.$_.''; } - foreach ($mod,$mean) { + foreach ($mod) { + $row .= ''.$_.''; + } + foreach ($mean) { $row .= ''. sprintf("%5.2f",$_).''; } @@ -481,71 +706,124 @@ sub statistics_html_table_data { return $row; } - ############################################### ############################################### -sub BuildGraphicChart { - my ($graph,$cacheDB,$courseDescription,$students,$courseID,$r,$c)=@_; - my %cache; - my $max; - my $title = ''; - if($graph eq 'DoDiffGraph') { - $title = 'Degree-of-Difficulty'; - } else { - $title = 'Wrong-Percentage'; - } - my $currentSequence = -1; - my $sortProblems = 'Sort Within Sequence'; - my ($result, $orderedProblems) = - &InitializeProblemStatistics($cacheDB, $students, $courseID, $c, $r); - if($result ne 'OK') { - return; +=pod + +=item &plot_statistics() + +=cut + +############################################### +############################################### +sub plot_statistics { + my ($r,$datafield) = @_; + my @Data; + # + my %Fields = ('#Stdnts'=> 0, + 'Tries' => 1, + 'Mod' => 2, + 'Mean' => 3, + '#YES' => 4, + '#yes' => 5, + '%Wrng' => 9, + 'DoDiff' => 6, + 'S.D.' => 7, + 'Skew' => 8,); + # + my $field = '%Wrng'; + foreach (keys(%Fields)) { + $field = $_ if ($datafield eq $_); } - my @values = (); - unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) { - return 'Unable to tie database.7'; - } - foreach(@$orderedProblems) { - my ($sequence,$problem,$part)=split(':', $_); - if($cache{'StatisticsMaps'} ne 'All Maps' && - $cache{'StatisticsMaps'} ne $cache{$sequence.':title'}) { - next; - } - if( $currentSequence == -1 || - ($sortProblems eq 'Sort Within Sequence' && - $currentSequence != $sequence)) { - if($currentSequence != -1) { - &DrawGraph(\@values,$courseDescription,$title,$max,$r); - } - if($sortProblems eq 'Sort Within Sequence') { - $r->print('
'.$cache{$sequence.':title'}.''."\n"); + my $fieldindex = $Fields{$field}; + # + my $Max = 0; + foreach my $sequence (&Apache::lonstatistics::Sequences_with_Assess()) { + next if ($sequence->{'num_assess'}<1); + foreach my $resource (@{$sequence->{'contents'}}) { + next if ($resource->{'type'} ne 'assessment'); + foreach my $part (@{$resource->{'parts'}}) { + my @Results= &get_statistics($resource->{'symb'},$part); + my ($num,$Solved,$solved) = @Results[0,4,5]; + my $wrongpercent = 0; + if (defined($num) && $num > 0) { + $wrongpercent=int(10*100*($num-$Solved+$solved)/$num)/10; + } + push (@Results,$wrongpercent); + my $data = $Results[$fieldindex]; + $data = 0 if ($data eq 'nan'); + $Max = $data if ($Max<$data); + push (@Data,$data); } - $currentSequence = $sequence; - @values = (); - $max=0; - } - my $data = 0; - if($graph eq 'DoDiffGraph') { - $data = sprintf("%.2f", $cache{$_.':degreeOfDifficulty'}), - } else { - $data = sprintf("%.1f", $cache{$_.':percentWrong'}), } - if($max < $data) { - $max = $data; + } + # + # Print out plot request + my $title = 'Percent Wrong'; + if ($field eq 'DoDiff') { + $title = 'Degree of Difficulty'; + } + my $yaxis = 'Percent'; + if ($field eq 'DoDiff') { + $yaxis = ''; + } elsif ($field ne '%Wrng') { + $yaxis = ''; + } + # + # Determine appropriate value for $Max + if ($field eq 'DoDiff') { + if ($Max > 0.5) { + $Max = 1; + } elsif ($Max > 0.2) { + $Max = 0.5; + } elsif ($Max > 0.1) { + $Max = 0.2; + } + } elsif ($field eq '%Wrng') { + if ($Max > 50) { + $Max = 100; + } elsif ($Max > 25) { + $Max = 50; + } elsif ($Max > 20) { + $Max = 25; + } elsif ($Max > 10) { + $Max = 20; + } elsif ($Max > 5) { + $Max = 10; + } else { + $Max = 5; } - push(@values, $data); } - untie(%cache); - &DrawGraph(\@values,$courseDescription,$title,$max,$r); + + $r->print("

".&DrawGraph(\@Data,$title,'Problem Number',$yaxis, + $Max)."

\n"); + # + # Print out the data + $ENV{'form.sortby'} = 'Contents'; + &output_html_ungrouped($r,'show probnum'); return; } +############################################### +############################################### + +=pod + +=item &DrawGraph() + +=cut + +############################################### +############################################### sub DrawGraph { - my ($values,$courseDescription,$title,$Max,$r)=@_; + my ($values,$title,$xaxis,$yaxis,$Max)=@_; + $title = '' if (! defined($title)); + $xaxis = '' if (! defined($xaxis)); + $yaxis = '' if (! defined($yaxis)); + # my $sendValues = join(',', @$values); my $sendCount = scalar(@$values); - $r->print("
The Maximum Value is: $Max"); if ( $Max > 1 ) { if ($Max % 10) { if ( int($Max) < $Max ) { @@ -553,196 +831,39 @@ sub DrawGraph { $Max = int($Max); } } - #(10 - $Max % 10); - } else { $Max = 1; } - my @GData = ('','Problem_number',$title,$Max,$sendCount,$sendValues); -# $r->print(''."\n"); - $r->print('
'."\n"); - $r->print(''); -# $r->print('
'."\n"); - $r->print('
'."\n"); -} - -#---- Problem Statistics Web Page --------------------------------------- -sub CreateProblemStatisticsTableHeading { - my ($headings,$r)=@_; - my $Str=''; - $Str .= ''."\n"; - $Str .= 'P#'."\n"; - foreach(@$headings) { - $Str .= ''; - $Str .= ''.$_.' '."\n"; + } else { + $Max = 1; } - $Str .= "\n".''."\n"; - return $Str; + my @GData = ($title,$xaxis,$yaxis,$Max,$sendCount,$sendValues); + return ''; } -sub BuildStatisticsTable { - my ($cache,$displayFormat,$sortProblems,$orderedProblems,$headings, - $r,$color)=@_; - my $count = 1; - my $currentSequence = -1; - foreach(@$orderedProblems) { - my ($sequence,$problem,$part)=split(':', $_); - if($cache->{'StatisticsMaps'} ne 'All Maps' && - $cache->{'StatisticsMaps'} ne $cache->{$sequence.':title'}) { - next; - } - if($currentSequence == -1 || - ($sortProblems eq 'Sort Within Sequence' && - $currentSequence != $sequence)) { - if($displayFormat ne 'Display CSV Format') { - if($currentSequence ne -1) { - $r->print(''); - $r->print('
'); - } - if($sortProblems eq 'Sort Within Sequence') { - $r->print(''.$cache->{$sequence.':title'}.''); - } - $r->print('
'."\n"); - $r->print(''."\n"); - $r->print(&CreateProblemStatisticsTableHeading($headings, $r)); - } else { - if($sortProblems eq 'Sort Within Sequence') { - $r->print('"'.$cache->{$sequence.':title'}.'"'); - } - $r->print('
'); - } - $currentSequence = $sequence; - } - my $ref = ''.$cache->{$problem.':title'}.''; - my $title = $cache->{$problem.':title'}; - if($part != 0) { - $title .= ' Part '.$part; - } - my $source = $cache->{$problem.':source'}; - my $tableData = join('&', $ref, $title, $source, - $cache->{$_.':studentCount'}, - $cache->{$_.':totalTries'}, - $cache->{$_.':maxTries'}, - $cache->{$_.':mean'}, - $cache->{$_.':correct'}, - $cache->{$_.':correctByOverride'}, - $cache->{$_.':percentWrong'}, - $cache->{$_.':degreeOfDifficulty'}, - $cache->{$_.':standardDeviation'}, - $cache->{$_.':skewness'}, - $cache->{$_.':discriminationFactor1'}, - $cache->{$_.':discriminationFactor2'}); - &TableRow($displayFormat,$tableData,$count,$r,$color); - $count++; - } - if($displayFormat ne 'Display CSV Format') { - $r->print('
'."\n"); - $r->print('
'); - } else { - $r->print('
'); +sub get_statistics { + my ($symb,$part) = @_; + # + my $courseid = $ENV{'request.course.id'}; + # + my $students = \@Apache::lonstatistics::Students; + if ($Apache::lonstatistics::SelectedSections[0] eq 'all') { + $students = undef; } - return; + my @Results = &Apache::loncoursedata::get_problem_statistics + ($students,$symb,$part,$courseid); + return @Results; } -sub TableRow { - my ($displayFormat,$Str,$RealIdx,$r,$color)=@_; - my($ref,$title,$source,$StdNo,$TotalTries,$MxTries,$Avg,$YES,$Override, - $Wrng,$DoD,$SD,$Sk,$_D1,$_D2)=split(/\&/,$Str); - my $Ptr; - if($displayFormat eq 'Display CSV Format') { - $Ptr='"'.$RealIdx.'",'."\n". - '"'.$title.'",'."\n". - '"'.$source.'",'."\n". - '"'.$StdNo.'",'."\n". - '"'.$TotalTries.'",'."\n". - '"'.$MxTries.'",'."\n". - '"'.$Avg.'",'."\n". - '"'.$YES.'",'."\n". - '"'.$Override.'",'."\n". - '"'.$Wrng.'",'."\n". - '"'.$DoD.'",'."\n". - '"'.$SD.'",'."\n". - '"'.$Sk.'",'."\n". - '"'.$_D1.'",'."\n". - '"'.$_D2.'"'."\n". - "
\n"; - $r->print("\n".$Ptr); - } else { - $Ptr=''."\n". - ''.$RealIdx.''."\n". - ''.$ref.''."\n". - ' '.$StdNo.''."\n". - ''.$TotalTries.''."\n". - ''.$MxTries.''."\n". - ''.$Avg.''."\n". - ' '.$YES.''."\n". - ' '.$Override.''."\n". - ' '.$Wrng.''."\n". - ' '.$DoD.''."\n". - ' '.$SD.''."\n". - ' '.$Sk.''."\n". - ' '.$_D1.''."\n". - ' '.$_D2.''."\n"; - $r->print($Ptr.''."\n"); - } - return; -} +############################################### +############################################### -# For loading the colored table for display or un-colored for print -sub setbgcolor { - my $PrintTable=shift; - my %color; - if ($PrintTable){ - $color{"gb"}="#FFFFFF"; - $color{"red"}="#FFFFFF"; - $color{"yellow"}="#FFFFFF"; - $color{"green"}="#FFFFFF"; - $color{"purple"}="#FFFFFF"; - } else { - $color{"gb"}="#DDFFFF"; - $color{"red"}="#FFDDDD"; - $color{"yellow"}="#EEFFCC"; - $color{"green"}="#DDFFDD"; - $color{"purple"}="#FFDDFF"; - } - return \%color; -} - -sub ProblemStatisticsButtons { - my ($displayFormat, $displayLegend, $sortProblems)=@_; - my $Ptr = ''; - $Ptr .= '