--- loncom/interface/statistics/lonproblemanalysis.pm 2004/01/30 16:31:36 1.63 +++ loncom/interface/statistics/lonproblemanalysis.pm 2008/12/12 07:26:28 1.134 @@ -1,6 +1,6 @@ # The LearningOnline Network with CAPA # -# $Id: lonproblemanalysis.pm,v 1.63 2004/01/30 16:31:36 matthew Exp $ +# $Id: lonproblemanalysis.pm,v 1.134 2008/12/12 07:26:28 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -27,16 +27,20 @@ package Apache::lonproblemanalysis; use strict; -use Apache::lonnet(); +use Apache::lonnet; use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::loncoursedata(); use Apache::lonstatistics; use Apache::lonlocal; -use Apache::lonstathelpers; +use Apache::lonstathelpers(); +use Apache::lonstudentsubmissions(); use HTML::Entities(); use Time::Local(); -use Spreadsheet::WriteExcel(); +use capa; +use lib '/home/httpd/lib/perl/'; +use LONCAPA; + my $plotcolors = ['#33ff00', '#0033cc', '#990000', '#aaaa66', '#663399', '#ff9933', @@ -50,23 +54,16 @@ my @SubmitButtons = ({ name => 'PrevProb { name => 'NextProblemAnalysis', text => 'Next Problem' }, { name => 'break'}, - { name => 'ClearCache', - text => 'Clear Caches' }, - { name => 'updatecaches', - text => 'Update Student Data' }, { name => 'SelectAnother', - text => 'Choose a different Problem' }, - { name => 'ExcelOutput', - text => 'Produce Excel Output' }); - + text => 'Choose a different Problem' }); sub BuildProblemAnalysisPage { my ($r,$c)=@_; # my %Saveable_Parameters = ('Status' => 'scalar', 'Section' => 'array', + 'Groups' => 'array', 'NumPlots' => 'scalar', - 'AnalyzeAs' => 'scalar', 'AnalyzeOver' => 'scalar', ); &Apache::loncommon::store_course_settings('problem_analysis', @@ -76,31 +73,24 @@ sub BuildProblemAnalysisPage { # &Apache::lonstatistics::PrepareClasslist(); # - $r->print('
'.
+ &mt($no_data_message,$plot_num,@extra_data).
+ ' | |
'. + &mt($header_message,$plot_num,@extra_data). + ' | |
'. + &mt($stats_message, + $stats->{'submission_count'}, + $stats->{'correct_count'}, + $stats->{'incorrect_count'}, + $stats->{'students'}, + @extra_data). + ' | |
'. + &numerical_plot_percent($r,$responses,$stats).' | '. + ''. + &numerical_plot_differences($r,$responses,$stats).' | '. + '
'.$post_message.' |
'.&mt('Bar').' | '. + ''.&mt('Range').' | '. + ''.&mt('Incorrect').' | '. + ''.&mt('Correct').' | '. + ''.&mt('Count').' | '. + '||
---|---|---|---|---|---|---|
'.$labels->[$i].' | '. + ''.$lownum.' | '. + '- | '. + ''.$highnum.' | '. + ''.$incorrect->[$i].' | '. + ''.$correct->[$i].' | '. + ''.$count->[$i].' | '. + '
'.
+ ''.&mt('Distribution of correct answers').''.
+ ' '.&mt('[_1] students, [_2] distinct correct answers', + $n,scalar(keys(%$data))). + ' '.&mt('Maximum number of coinciding values: [_1]',$max_y). + ' | ||
'.$min_x.' | '. + ''.$plotresult.' | '. + ''.$max_x.' | '. + '
'. + ''. + &mt($pre_graph_text, + $plot_num,$foil_choice_data->{'_count'}, + $correct, + $incorrect, + $foil_choice_data->{'_students'}, + @extra_data). + ' | ||||
'.$concept_plot.' | '. + ''.$choice_plot.' | '; + if ($stacked_plot ne '') { + $analysis_html .= + ''.$stacked_plot.' | '. + ''.&build_foil_key($foils,$count_by_foil).' | '; } else { - if ($ProblemData->{'_Foils'}->{$foilid}->{'value'} eq 'true') { - push (@PlotData_Correct, - int(100*$DataSet{$foilid}/$total)); - push (@PlotData_Incorrect,0); + $analysis_html .= (''x2); + } + $analysis_html.=' |
'. + $post_graph_text.' | ||||
'.
+ ' '.
+ &mt($no_data_text,
+ $plot_num,$foil_choice_data->{'_count'},
+ $correct,
+ $foil_choice_data->{'_count'}-$correct,
+ @extra_data).
+ ' ';
+ if (defined($post_graph_text)) {
+ $analysis_html.=''.$post_graph_text; + } + $analysis_html.=' |
'
+ .' '
+ .&mt('None of the selected students attempted the problem more than [_1] times.'
+ ,$try-1)
+ .' '
+ .' | |||
'
+ .' '
+ .&mt('None of the selected students have attempted the problem.')
+ .' '
+ .' | |||
'.$correctgraph.' | '; - ## - ## - next if (! defined($Datasets[0])); - for (my $i=0; $i< scalar(@{$Datasets[0]});$i++) { - $Datasets[0]->[$i]=0; - } - $count = $ResponseData{'_total'}->[$i]-$ResponseData{'_correct'}->[$i]; - if ($count == 0) { - $count = 'no submissions'; - } elsif ($count == 1) { - $count = '1 submission'; - } else { - $count = $count.' submissions'; + # + # Put a blank in the data set between concepts + for (my $set =0;$set<=$#Datasets;$set++) { + my @Data = @{$Datasets[$set]}; + my $idx = 0; + foreach my $concept (@{$Concepts}) { + foreach my $foilid (@{$concept->{'foils'}}) { + $Datasets[$set]->[$idx++]=shift(@Data); + } + if ($concept->{'name'} ne $Concepts->[-1]->{'name'}) { + $Datasets[$set]->[$idx++] = 0; + } + } } - $title = 'Attempt '.$i.', '.$count; - my $incorrectgraph = &Apache::loncommon::DrawBarGraph - ($title,'Foil Number','% Option Chosen Incorrectly', - 100,$plotcolors,@Datasets); - $analysis_html.= ''.$incorrectgraph.' | '; - $analysis_html.= ''.$foilkey." |
'.$graphlink." | ||||
'. + ''. + &mt('Attempt [_1], [_2] submissions, [_3] correct, [_4] incorrect', + $try,$data_count,$correct,$data_count-$correct). + ''.' | ||||
'.$concept_graph.' | '. + ''.$correct_graph.' | '. + ''.$incorrect_graph.' | '. + ''.$optionkey.' | '. + ' |
'. + &mt('Data from [_1] to [_2]', + &Apache::lonlocal::locallocaltime($starttime), + &Apache::lonlocal::locallocaltime($endtime)). + ' | |||
'. + &mt('[_1] submissions from [_2] students, [_3] correct, [_4] incorrect', + $data_count,$student_count,$correct,$data_count-$correct). + ' | |||
'.$concept_correct_plot.' | '. + ''.$foil_correct_plot.' | '. + ''.$foil_incorrect_plot.' | '. + ''.$foilkey.' |
'.
+ &mt('Start time: [_1]',$startdateform).' '. + &mt('End time: [_1]',$enddateform).' | |||
  |
'.&mt("Unable to create new Excel file. ". - "This error has been logged. ". - "Please alert your LON-CAPA administrator"). - '
'); + return &Apache::loncommon::DrawBarGraph('Correct Concepts', + 'Concept Number', + 'Percent Correct', + 100, + $plotcolors, + undef, + \@plotdata,{xskip=>1}); +} + +sub OR_time_process_data { + my ($performance_data,$begin_index,$end_index)=@_; + my %processed_time_data; + my %distinct_students; + my ($correct,$data_count); + if (($begin_index == $end_index) && + ($end_index != scalar(@$performance_data)-1)) { return undef; } - # - $workbook->set_tempdir('/home/httpd/perl/tmp'); - # - # Define some potentially useful formats - my $format; - $format->{'header'} = $workbook->add_format(bold => 1, - bottom => 1, - align => 'center'); - $format->{'bold'} = $workbook->add_format(bold=>1); - $format->{'h1'} = $workbook->add_format(bold=>1, size=>18); - $format->{'h2'} = $workbook->add_format(bold=>1, size=>16); - $format->{'h3'} = $workbook->add_format(bold=>1, size=>14); - $format->{'date'} = $workbook->add_format(num_format=> - 'mmm d yyyy hh:mm AM/PM'); - # - # Create and populate main worksheets - my $problem_data_sheet = $workbook->addworksheet('Problem Data'); - my $student_data_sheet = $workbook->addworksheet('Student Data'); - my $response_data_sheet = $workbook->addworksheet('Response Data'); - foreach my $sheet ($problem_data_sheet,$student_data_sheet, - $response_data_sheet) { - $sheet->write(0,0,$resource->{'title'},$format->{'h2'}); - $sheet->write(1,0,$resource->{'src'},$format->{'h3'}); - } - # - my $result; - $result = &OR_build_problem_data_worksheet($problem_data_sheet,$format, - $Concepts,$ORdata); - if ($result ne 'okay') { - # Do something useful - } - $result = &OR_build_student_data_worksheet($student_data_sheet,$format); - if ($result ne 'okay') { - # Do something useful - } - $result = &OR_build_response_data_worksheet($response_data_sheet,$format, - $PerformanceData,$Foils, - $ORdata); - if ($result ne 'okay') { - # Do something useful - } - $response_data_sheet->activate(); - # - # Close the excel file - $workbook->close(); - # - # Write a link to allow them to download it - $result .= ''. - &mt('Your Excel spreadsheet.'). - '
'."\n"; - return $result; -} - -sub OR_build_problem_data_worksheet { - my ($worksheet,$format,$Concepts,$ORdata) = @_; - my $rows_output = 3; - my $cols_output = 0; - $worksheet->write($rows_output++,0,'Problem Structure',$format->{'h3'}); - ## - ## - my @Headers; - if (@$Concepts > 1) { - @Headers = ("Concept\nNumber",'Concept',"Foil\nNumber", - 'Foil Name','Foil Text','Correct value'); - } else { - @Headers = ('Foil Number','FoilName','Foil Text','Correct value'); - } - $worksheet->write_row($rows_output++,0,\@Headers,$format->{'header'}); - my %Foildata = %{$ORdata->{'_Foils'}}; - my $conceptindex = 1; - my $foilindex = 1; - foreach my $concept (@$Concepts) { - my @FoilsInConcept = @{$concept->{'foils'}}; - my $firstfoil = shift(@FoilsInConcept); - if (@$Concepts > 1) { - $worksheet->write_row($rows_output++,0, - [$conceptindex, - $concept->{'name'}, - $foilindex++, - $Foildata{$firstfoil}->{'name'}, - $Foildata{$firstfoil}->{'text'}, - $Foildata{$firstfoil}->{'value'},]); - } else { - $worksheet->write_row($rows_output++,0, - [ $foilindex++, - $Foildata{$firstfoil}->{'name'}, - $Foildata{$firstfoil}->{'text'}, - $Foildata{$firstfoil}->{'value'},]); - } - foreach my $foilid (@FoilsInConcept) { - if (@$Concepts > 1) { - $worksheet->write_row($rows_output++,0, - ['', - '', - $foilindex, - $Foildata{$foilid}->{'name'}, - $Foildata{$foilid}->{'text'}, - $Foildata{$foilid}->{'value'},]); - } else { - $worksheet->write_row($rows_output++,0, - [$foilindex, - $Foildata{$foilid}->{'name'}, - $Foildata{$foilid}->{'text'}, - $Foildata{$foilid}->{'value'},]); - } - } continue { - $foilindex++; - } - } continue { - $conceptindex++; - } - $rows_output++; - $rows_output++; - ## - ## Option data output - $worksheet->write($rows_output++,0,'Options',$format->{'header'}); - foreach my $string (@{$ORdata->{'_Options'}}) { - $worksheet->write($rows_output++,0,$string); - } - return 'okay'; -} - -sub OR_build_student_data_worksheet { - my ($worksheet,$format) = @_; - my $rows_output = 3; - my $cols_output = 0; - $worksheet->write($rows_output++,0,'Student Data',$format->{'h3'}); - my @Headers = ('full name','username','domain','section', - "student\nnumber",'identifier'); - $worksheet->write_row($rows_output++,0,\@Headers,$format->{'header'}); - my @Students = @Apache::lonstatistics::Students; - my $studentrows = &Apache::loncoursedata::get_student_data(\@Students); - my %ids; - foreach my $row (@$studentrows) { - my ($mysqlid,$student) = @$row; - $ids{$student}=$mysqlid; - } - foreach my $student (@Students) { - my $name_domain = $student->{'username'}.':'.$student->{'domain'}; - $worksheet->write_row($rows_output++,0, - [$student->{'fullname'}, - $student->{'username'},$student->{'domain'}, - $student->{'section'},$student->{'id'}, - $ids{$name_domain}]); - } - return; -} - -sub OR_build_response_data_worksheet { - my ($worksheet,$format,$PerformanceData,$Foils,$ORdata)=@_; - my $rows_output = 3; - my $cols_output = 0; - $worksheet->write($rows_output++,0,'Response Data',$format->{'h3'}); - $worksheet->set_column(1,1,20); - $worksheet->set_column(2,2,13); - my @Headers = ('identifier','time','award detail','attempt'); - foreach my $foil (@$Foils) { - push (@Headers,$foil.' submission'); - push (@Headers,$foil.' grading'); - } - $worksheet->write_row($rows_output++,0,\@Headers,$format->{'header'}); - # - foreach my $row (@$PerformanceData) { - next if (! defined($row)); - my ($student,$award,$grading,$submission,$time,$tries) = @$row; - my @Foilgrades = split('&',$grading); - my @Foilsubs = split('&',$submission); - my %ResponseData; - for (my $j=0;$j<=$#Foilgrades;$j++) { - my ($foilid,$correct) = split('=',$Foilgrades[$j]); - my (undef,$submission) = split('=',$Foilsubs[$j]); - $submission = &Apache::lonnet::unescape($submission); - $ResponseData{$foilid.' submission'}=$submission; - $ResponseData{$foilid.' award'}=$correct; - } - $worksheet->write($rows_output,$cols_output++,$student); - $worksheet->write($rows_output,$cols_output++, - &calc_serial($time),$format->{'date'}); - $worksheet->write($rows_output,$cols_output++,$award); - $worksheet->write($rows_output,$cols_output++,$tries); - foreach my $foilid (@$Foils) { - $worksheet->write($rows_output,$cols_output++, - $ResponseData{$foilid.' submission'}); - $worksheet->write($rows_output,$cols_output++, - $ResponseData{$foilid.' award'}); + # Be sure we include the last one if we are asked for it. + # That we have to correct here (and not when $end_index is + # given a value) should probably be considered a bug. + if ($end_index == scalar(@$performance_data)-1) { + $end_index++; + } + my $count; + for (my $i=$begin_index;$i<$end_index;$i++) { + my $attempt = $performance_data->[$i]; + $count++; + next if (! defined($attempt)); + my %attempt = &Process_OR_Row($attempt); + $data_count++; + $correct += $attempt{'_correct'}; + $distinct_students{$attempt->[&Apache::loncoursedata::RD_student_id()]}++; + while (my ($foilid,$href) = each(%attempt)) { + if (! ref($href)) { + $processed_time_data{$foilid} += $href; + next; + } + while (my ($option,$value) = each(%$href)) { + $processed_time_data{$foilid}->{$option}+=$value; + } } - $rows_output++; - $cols_output = 0; } - return; -} - - -## -## The following is copied from datecalc1.pl, part of the -## Spreadsheet::WriteExcel CPAN module. -## -## -###################################################################### -# -# Demonstration of writing date/time cells to Excel spreadsheets, -# using UNIX/Perl time as source of date/time. -# -# Copyright 2000, Andrew Benham, adsb@bigfoot.com -# -###################################################################### -# -# UNIX/Perl time is the time since the Epoch (00:00:00 GMT, 1 Jan 1970) -# measured in seconds. -# -# An Excel file can use exactly one of two different date/time systems. -# In these systems, a floating point number represents the number of days -# (and fractional parts of the day) since a start point. The floating point -# number is referred to as a 'serial'. -# The two systems ('1900' and '1904') use different starting points: -# '1900'; '1.00' is 1 Jan 1900 BUT 1900 is erroneously regarded as -# a leap year - see: -# http://support.microsoft.com/support/kb/articles/Q181/3/70.asp -# for the excuse^H^H^H^H^H^Hreason. -# '1904'; '1.00' is 2 Jan 1904. -# -# The '1904' system is the default for Apple Macs. Windows versions of -# Excel have the option to use the '1904' system. -# -# Note that Visual Basic's "DateSerial" function does NOT erroneously -# regard 1900 as a leap year, and thus its serials do not agree with -# the 1900 serials of Excel for dates before 1 Mar 1900. -# -# Note that StarOffice (at least at version 5.2) does NOT erroneously -# regard 1900 as a leap year, and thus its serials do not agree with -# the 1900 serials of Excel for dates before 1 Mar 1900. -# -###################################################################### -# -# Calculation description -# ======================= -# -# 1900 system -# ----------- -# Unix time is '0' at 00:00:00 GMT 1 Jan 1970, i.e. 70 years after 1 Jan 1900. -# Of those 70 years, 17 (1904,08,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68) -# were leap years with an extra day. -# Thus there were 17 + 70*365 days = 25567 days between 1 Jan 1900 and -# 1 Jan 1970. -# In the 1900 system, '1' is 1 Jan 1900, but as 1900 was not a leap year -# 1 Jan 1900 should really be '2', so 1 Jan 1970 is '25569'. -# -# 1904 system -# ----------- -# Unix time is '0' at 00:00:00 GMT 1 Jan 1970, i.e. 66 years after 1 Jan 1904. -# Of those 66 years, 17 (1904,08,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68) -# were leap years with an extra day. -# Thus there were 17 + 66*365 days = 24107 days between 1 Jan 1904 and -# 1 Jan 1970. -# In the 1904 system, 2 Jan 1904 being '1', 1 Jan 1970 is '24107'. -# -###################################################################### -# -# Copyright (c) 2000, Andrew Benham. -# This program is free software. It may be used, redistributed and/or -# modified under the same terms as Perl itself. -# -# Andrew Benham, adsb@bigfoot.com -# London, United Kingdom -# 11 Nov 2000 -# -###################################################################### - -# Use 1900 date system on all platforms other than Apple Mac (for which -# use 1904 date system). -my $DATE_SYSTEM = ($^O eq 'MacOS') ? 1 : 0; - -#----------------------------------------------------------- -# calc_serial() -# -# Called with (up to) 2 parameters. -# 1. Unix timestamp. If omitted, uses current time. -# 2. GMT flag. Set to '1' to return serial in GMT. -# If omitted, returns serial in appropriate timezone. -# -# Returns date/time serial according to $DATE_SYSTEM selected -#----------------------------------------------------------- -sub calc_serial { - my $time = (defined $_[0]) ? $_[0] : time(); - my $gmtflag = (defined $_[1]) ? $_[1] : 0; - - # Divide timestamp by number of seconds in a day. - # This gives a date serial with '0' on 1 Jan 1970. - my $serial = $time / 86400; - - # Adjust the date serial by the offset appropriate to the - # currently selected system (1900/1904). - if ($DATE_SYSTEM == 0) { # use 1900 system - $serial += 25569; - } else { # use 1904 system - $serial += 24107; - } - - unless ($gmtflag) { - # Now have a 'raw' serial with the right offset. But this - # gives a serial in GMT, which is false unless the timezone - # is GMT. We need to adjust the serial by the appropriate - # timezone offset. - # Calculate the appropriate timezone offset by seeing what - # the differences between localtime and gmtime for the given - # time are. - - my @gmtime = gmtime($time); - my @ltime = localtime($time); - - # For the first 7 elements of the two arrays, adjust the - # date serial where the elements differ. - for (0 .. 6) { - my $diff = $ltime[$_] - $gmtime[$_]; - if ($diff) { - $serial += _adjustment($diff,$_); - } - } - } - - # Perpetuate the error that 1900 was a leap year by decrementing - # the serial if we're using the 1900 system and the date is prior to - # 1 Mar 1900. This has the effect of making serial value '60' - # 29 Feb 1900. - - # This fix only has any effect if UNIX/Perl time on the platform - # can represent 1900. Many can't. - - unless ($DATE_SYSTEM) { - $serial-- if ($serial < 61); # '61' is 1 Mar 1900 - } - return $serial; -} - -sub _adjustment { - # Based on the difference in the localtime/gmtime array elements - # number, return the adjustment required to the serial. - - # We only look at some elements of the localtime/gmtime arrays: - # seconds unlikely to be different as all known timezones - # have an offset of integral multiples of 15 minutes, - # but it's easy to do. - # minutes will be different for timezone offsets which are - # not an exact number of hours. - # hours very likely to be different. - # weekday will differ when localtime/gmtime difference - # straddles midnight. - # - # Assume that difference between localtime and gmtime is less than - # 5 days, then don't have to do maths for day of month, month number, - # year number, etc... - - my ($delta,$element) = @_; - my $adjust = 0; - - if ($element == 0) { # Seconds - $adjust = $delta/86400; # 60 * 60 * 24 - } elsif ($element == 1) { # Minutes - $adjust = $delta/1440; # 60 * 24 - } elsif ($element == 2) { # Hours - $adjust = $delta/24; # 24 - } elsif ($element == 6) { # Day of week number - # Catch difference straddling Sat/Sun in either direction - $delta += 7 if ($delta < -4); - $delta -= 7 if ($delta > 4); - - $adjust = $delta; - } - return $adjust; + return (\%processed_time_data,$correct,$data_count, + scalar(keys(%distinct_students))); } sub build_foil_index { @@ -1264,15 +1726,15 @@ sub build_foil_index { my $a1 = lc($a); my $b1 = lc($b); if (exists($Numbers{$a1})) { - $a = $Numbers{$a1}; + $a1 = $Numbers{$a1}; } if (exists($Numbers{$b1})) { - $b = $Numbers{$b1}; + $b1 = $Numbers{$b1}; } - if (($a =~/^\d+$/) && ($b =~/^\d+$/)) { - return $a <=> $b; + if (($a1 =~/^\d+$/) && ($b1 =~/^\d+$/)) { + return $a1 <=> $b1; } else { - return $a cmp $b; + return $a1 cmp $b1; } }; my @Concepts; @@ -1287,23 +1749,23 @@ sub build_foil_index { } # # Build up the table of row labels. - my $table = ''.&mt('Concept Number').' | '. ''.&mt('Concept').' | '. ''.&mt('Foil Number').' | '. ''.&mt('Foil Name').' | '. ''.&mt('Foil Text').' | '. ''.&mt('Correct Value').' | '. - "|
---|---|---|---|---|---|---|
'.&mt('Foil Number').' | '. ''.&mt('Foil Name').' | '. ''.&mt('Foil Text').' | '. ''.&mt('Correct Value').' | '. - "|||
'.$conceptindex.' | '. - ''.&HTML::Entities::encode($concept->{'name'}).' | '. + ''.&HTML::Entities::encode($concept->{'name'},'<>&"').' | '. ''.$foilindex++.' | '. - ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'name'}).' | '. - ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'text'}).' | '. - ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'value'}).' | '. - "'.&HTML::Entities::encode($Foildata{$firstfoil}->{'name'},'<>&"').' | '. + ''.$Foildata{$firstfoil}->{'text'}.' | '. + ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'value'},'<>&"').' | '. + &Apache::loncommon::end_data_table_row(); } else { - $table .= '
'.$foilindex++.' | '. - ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'name'}).' | '. - ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'text'}).' | '. - ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'value'}).' | '. - "'.&HTML::Entities::encode($Foildata{$firstfoil}->{'name'},'<>&"').' | '. + ''.$Foildata{$firstfoil}->{'text'}.' | '. + ''.&HTML::Entities::encode($Foildata{$firstfoil}->{'value'},'<>&"').' | '. + &Apache::loncommon::end_data_table_row(); } foreach my $foilid (@FoilsInConcept) { if (@Concepts > 1) { - $table .= '
'. ' | '. ' | '.$foilindex.' | '. - ''.&HTML::Entities::encode($Foildata{$foilid}->{'name'}).' | '. - ''.&HTML::Entities::encode($Foildata{$foilid}->{'text'}).' | '. - ''.&HTML::Entities::encode($Foildata{$foilid}->{'value'}).' | '. - "'.&HTML::Entities::encode($Foildata{$foilid}->{'name'},'<>&"').' | '. + ''.$Foildata{$foilid}->{'text'}.' | '. + ''.&HTML::Entities::encode($Foildata{$foilid}->{'value'},'<>&"').' | '. + &Apache::loncommon::end_data_table_row(); } else { - $table .= '
'.$foilindex.' | '. - ''.&HTML::Entities::encode($Foildata{$foilid}->{'name'}).' | '. - ''.&HTML::Entities::encode($Foildata{$foilid}->{'text'}).' | '. - ''.&HTML::Entities::encode($Foildata{$foilid}->{'value'}).' | '. - "'.&HTML::Entities::encode($Foildata{$foilid}->{'name'},'<>&"').' | '. + ''.$Foildata{$foilid}->{'text'}.' | '. + ''.&HTML::Entities::encode($Foildata{$foilid}->{'value'},'<>&"').' | '. + &Apache::loncommon::end_data_table_row(); } } continue { $foilindex++; @@ -1351,7 +1813,7 @@ sub build_foil_index { } continue { $conceptindex++; } - $table .= "
'. + ''.('*'x4).' | '. + ''.&HTML::Entities::encode($foil,'<>&"'). + (' 'x2).$extra_data->{$foil}.' | '. + "
'.&mt('Sections').' | '; - $Str .= ''.&mt('Enrollment Status').' | '; -# $Str .= ''.&mt('Sequences and Folders').' | '; - $Str .= ''; - $Str .= ' | '.&mt('Sections').' | '; + $Str .= ''.&mt('Groups').' | '; + $Str .= ''.&mt('Access Status').' | '; + $Str .= ''.&mt('Options').' | '; + $Str .= &Apache::loncommon::end_data_table_header_row(); ## ## - $Str .= '
---|---|---|---|---|---|---|
'."\n"; + $Str .= &Apache::loncommon::start_data_table_row(); + $Str .= ' | '."\n"; $Str .= &Apache::lonstatistics::SectionSelect('Section','multiple',5); $Str .= ' | '; # + $Str .= ''."\n"; + $Str .= &Apache::lonstatistics::GroupSelect('Group','multiple',5); + $Str .= ' | '; + # $Str .= ''; $Str .= &Apache::lonhtmlcommon::StatusOptions(undef,undef,5); $Str .= ' | '; # -# $Str .= ''; - my $only_seq_with_assessments = sub { - my $s=shift; - if ($s->{'num_assess'} < 1) { - return 0; - } else { - return 1; - } - }; - &Apache::lonstatistics::MapSelect('Maps','multiple,all',5, - $only_seq_with_assessments); ## ## - $Str .= ' | ';
- { # These braces are here to organize the code, not scope it.
- {
- $Str .= ' '; - } - { - $Str .= ' '; - } - { - $Str .= ' | ';
+ ##
+ my $showprob_checkbox =
+ '';
+ $Str.= ' '; + ## + my $analyze_selector = ''; + $Str .= ' '.$/; + ## + my $numplots_selector = ''; + $Str .= ' '; + ## $Str .= ' | ';
##
##
- $Str .= '