\n");
+ my ($starttime,$endtime) = &Apache::lonstathelpers::get_time_limits();
+ if (defined($starttime) || defined($endtime)) {
+ # Inform the user what the time limits on the data are.
+ $r->print('
'.&mt('Statistics on submissions from [_1] to [_2]',
+ &Apache::lonlocal::locallocaltime($starttime),
+ &Apache::lonlocal::locallocaltime($endtime)).
+ '
');
+ }
+ $r->print("
".&mt('Compiled on [_1]',
+ &Apache::lonlocal::locallocaltime(time))."
');
}
- $r->print($Ptr);
- $r->rflush();
+ return;
+}
+
+###############################################
+###############################################
+
+=pod
- my @Header = ("Homework Sets Order","#Stdnts","Tries","Mod",
- "Mean","#YES","#yes","%Wrng","DoDiff",
- "S.D.","Skew.","D.F.1st","D.F.2nd","Disc.");
- my $color=&setbgcolor(0);
-
-# my %Discuss=&Apache::loncoursedata::LoadDiscussion($courseID);
-# my ($upper, $lower) = &Discriminant(\%discriminant,$r);
- if(!defined($cache{'StatisticsCached'})) {
- untie(%cache);
- &Apache::loncoursedata::DownloadStudentCourseDataSeparate($students,
- 'true',
- $cacheDB,
- 'true',
- 'true',
- $courseID,
- $r, $c);
- if($c->aborted()) { return; }
-
- unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
- $r->print('Unable to tie database.');
- return;
- }
- my ($problemData) = &ExtractStudentData(\%cache, $students);
- &CalculateStatistics($problemData);
- untie(%cache);
-
- unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_WRCREAT(),0640)) {
- $r->print('Unable to tie database.');
- return;
- }
- foreach(keys(%$problemData)) {
- $cache{$_} = $problemData->{$_};
- }
- $cache{'StatisticsCached'} = 'true';
- untie(%cache);
-
- unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
- $r->print('Unable to tie database.');
- return;
- }
- }
- my $orderedProblems = &SortProblems(\%cache,
- $cache{'ProblemStatisticsSort'},
- $cache{'ProblemStatisticsAscend'});
- &BuildStatisticsTable(\%cache, $cache{'DisplayFormat'}, $orderedProblems,
- \@Header, $r, $color);
- untie(%cache);
+=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());
+ foreach my $sequence (&Apache::lonstatistics::Sequences_with_Assess()) {
+ next if ($sequence->{'num_assess'}<1);
+ $r->print("
".$sequence->{'title'}."
");
+ $r->print('
'."\n");
+ $r->print('
'."\n");
+ $r->print('
');
+ my $Str = &statistics_table_header('no container no plots');
+ $r->print('
'.$Str."
\n");
+ foreach my $resource (@{$sequence->{'contents'}}) {
+ next if ($resource->{'type'} ne 'assessment');
+ foreach my $part (@{$resource->{'parts'}}) {
+ $problem_num++;
+ my $data = &get_statistics($sequence,$resource,$part,
+ $problem_num);
+ my $option = '';
+ $r->print('
'."\n");
- $r->print(&CreateProblemStatisticsTableHeading($headings, $r));
+=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 ($starttime,$endtime) = &Apache::lonstathelpers::get_time_limits();
+ #
+ 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(&mt("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(
+ &Apache::loncommon::clean_excel_name($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 {
- $r->print(' ');
+ if ($Sections[0] eq 'all') {
+ $sectionstring = "All sections";
+ } else {
+ $sectionstring = "Section ".$Sections[0];
+ }
}
-
- my $count = 1;
- foreach(@$orderedProblems) {
- my ($sequence,$problem,$part)=split(':', $_);
-# if($cache->{'ProblemStatisticsMaps'} ne 'All Maps' &&
-# $cache->{'ProblemStatisticsMaps'} ne $cache->{$sequence.':title'}) {
-# next;
-# }
-
-
- my $ref = ''.$cache->{$problem.':title'}.'';
-# my $ref = $cache->{$problem.':title'};
- my $title = $cache->{$problem.':title'};
- my $source = 'source';
- my $tableData = join('&', $ref, $title, $source,
- $cache->{$_.':studentCount'},
- $cache->{$_.':totalTries'},
- $cache->{$_.':maxTries'},
- sprintf("%.2f", $cache->{$_.':mean'}),
- $cache->{$_.':correct'},
- $cache->{$_.':correctByOverride'},
- sprintf("%.1f", $cache->{$_.':percentWrong'}),
- sprintf("%.2f", $cache->{$_.':degreeOfDifficulty'}),
- sprintf("%.1f", $cache->{$_.':standardDeviation'}),
- sprintf("%.1f", $cache->{$_.':skewness'}),
- sprintf("%.2f", $cache->{$_.':discriminationFactor1'}),
- sprintf("%.2f", $cache->{$_.':discriminationFactor2'}),
- 0); # 0 is for discussion, need to figure out
-
-#6666666
-# $r->print(' '.$out.'&'.$DoD);
-# print (OUT $out.'@'.$DoD.'&');
-#6666666
-
-#check with Gerd
-# $urlres=~/^(\w+)\/(\w+)/;
-# if ($StdNo) {
-# &Apache::lonnet::put('nohist_resevaldata',\%storestats,
-# $1,$2);
-# }
-#-------------------------------- Row of statistical table
- &TableRow($displayFormat,$tableData,$count,$r,$color);
- $count++;
- }
- if($cache->{'DisplayFormat'} ne 'Display CSV Format') {
- $r->print('
'."\n");
- }
- $r->print('
');
-#6666666
-# close( OUT );
-#666666
+ $excel_sheet->write($rows_output,$cols_output++,$sectionstring);
+ $cols_output += scalar(@Sections);
+ #
+ # Time restrictions
+ my $time_string;
+ if (defined($starttime)) {
+ # call localtime but not lonlocal:locallocaltime because excel probably
+ # cannot handle localized text. Probably.
+ $time_string .= 'Data collected from '.localtime($time_string);
+ if (defined($endtime)) {
+ $time_string .= ' to '.localtime($endtime);
+ }
+ $time_string .= '.';
+ } elsif (defined($endtime)) {
+ # See note above about lonlocal:locallocaltime
+ $time_string .= 'Data collected before '.localtime($endtime).'.';
+ }
+
+ #
+ # Put the date in there too
+ $excel_sheet->write($rows_output,$cols_output++,
+ 'Compiled on '.localtime(time));
+ #
+ $rows_output++;
+ $cols_output=0;
+ #
+ # Long Headersheaders
+ foreach my $field (@Fields) {
+ next if ($field->{'name'} eq 'problem_num');
+ if (exists($field->{'long_title'})) {
+ $excel_sheet->write($rows_output,$cols_output++,
+ $field->{'long_title'});
+ } else {
+ $excel_sheet->write($rows_output,$cols_output++,'');
+ }
+ }
+ $rows_output++;
+ $cols_output=0;
+ # Brief headers
+ foreach my $field (@Fields) {
+ next if ($field->{'name'} eq 'problem_num');
+ # Use english for excel as I am not sure how well excel handles
+ # other character sets....
+ $excel_sheet->write($rows_output,$cols_output++,$field->{'title'});
+ }
+ $rows_output++;
+ #
+ # Write the data
+ my $problem_num=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'}}) {
+ $cols_output=0;
+ $problem_num++;
+ my $data = &get_statistics($sequence,$resource,$part,
+ $problem_num);
+ #
+ if (!defined($part) || $part eq '') {
+ $part = ' ';
+ }
+ foreach my $field (@Fields) {
+ next if ($field->{'name'} eq 'problem_num');
+ $excel_sheet->write($rows_output,$cols_output++,
+ $data->{$field->{'name'}});
+ }
+ $rows_output++;
+ }
+ }
+ }
+ #
+ # Write the excel file
+ $excel_workbook->close();
+ # Tell the user where to get their excel file
+ $r->print(' '.
+ ''.
+ &mt('Your Excel Spreadsheet').''."\n");
+ $r->rflush();
return;
}
-sub TableRow {
- my ($displayFormat,$Str,$RealIdx,$r,$color)=@_;
- my($ref,$title,$source,$StdNo,$TotalTries,$MxTries,$Avg,$YES,$Override,
- $Wrng,$DoD,$SD,$Sk,$_D1,$_D2,$DiscNo,$Prob)=split(/\&/,$Str);
- my $Ptr;
- if($displayFormat eq 'Display CSV Format') {
- $Ptr="\n".' '.
- "\n".'"'.$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".'"'.$DiscNo.'"';
+###############################################
+###############################################
- $r->print("\n".$Ptr);
- } else {
- $Ptr="\n".'
'.
- "\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".'
'.$DiscNo.'
';
- $r->print("\n".$Ptr.'
' );
+=pod
+
+=item &statistics_html_table_data()
+
+Help function used to format the rows for HTML table output.
+
+=cut
+
+###############################################
+###############################################
+sub statistics_html_table_data {
+ my ($data,$options) = @_;
+ my $row = '';
+ foreach my $field (@Fields) {
+ next if ($options =~ /no $field->{'name'}/);
+ $row .= '
Discrimination Factor: A Standard for evaluating the ';
$Ptr .= 'problem according to a Criterion ';
- $Ptr .= '[Applied Criterion in %27 Upper Students - ';
- $Ptr .= 'Applied the same Criterion in %27 Lower Students] ';
+ $Ptr .= '[Criterion to group students into %27 Upper Students - ';
+ $Ptr .= 'and %27 Lower Students] ';
$Ptr .= '1st Criterion for Sorting the Students: ';
$Ptr .= 'Sum of Partial Credit Awarded / Total Number of Tries ';
$Ptr .= '2nd Criterion for Sorting the Students: ';
@@ -378,301 +985,10 @@ sub ProblemStatisticsLegend {
$Ptr .= '
Disc.
';
$Ptr .= '
Number of Students had at least one discussion.';
$Ptr .= '