Diff for /loncom/interface/spreadsheet/studentcalc.pm between versions 1.15 and 1.22

version 1.15, 2003/07/16 20:30:36 version 1.22, 2003/09/18 20:12:40
Line 45  studentcalc Line 45  studentcalc
 ###################################################  ###################################################
 package Apache::studentcalc;  package Apache::studentcalc;
   
   use warnings FATAL=>'all';
   no warnings 'uninitialized';
   
 use strict;  use strict;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
 use Apache::lonnet;  use Apache::lonnet;
Line 54  use Apache::lonnavmaps; Line 57  use Apache::lonnavmaps;
 use Apache::Spreadsheet();  use Apache::Spreadsheet();
 use Apache::assesscalc();  use Apache::assesscalc();
 use HTML::Entities();  use HTML::Entities();
 use Spreadsheet::WriteExcel;  
 use Time::HiRes;  use Time::HiRes;
   
 @Apache::studentcalc::ISA = ('Apache::Spreadsheet');  @Apache::studentcalc::ISA = ('Apache::Spreadsheet');
Line 86  sub ensure_correct_sequence_data { Line 88  sub ensure_correct_sequence_data {
 sub initialize_sequence_cache {  sub initialize_sequence_cache {
     #      #
     # Set up the sequences and assessments      # Set up the sequences and assessments
     @Sequences = ();      undef(@Sequences);
     my ($top,$sequences,$assessments) =       my ($top,$sequences,$assessments) = 
         &Apache::loncoursedata::get_sequence_assessment_data();          &Apache::loncoursedata::get_sequence_assessment_data();
     if (! defined($top) || ! ref($top)) {      if (! defined($top) || ! ref($top)) {
Line 98  sub initialize_sequence_cache { Line 100  sub initialize_sequence_cache {
 }  }
   
 sub clear_package {  sub clear_package {
     @Sequences = undef;      undef(@Sequences);
     %Exportrows = undef;      undef(%Exportrows);
       &Apache::assesscalc::clear_package();
 }  }
   
 sub get_title {  sub get_title {
Line 125  sub get_html_title { Line 128  sub get_html_title {
     my $title = '<h1>'.$name;      my $title = '<h1>'.$name;
     if ($ENV{'user.name'} ne $self->{'name'} &&       if ($ENV{'user.name'} ne $self->{'name'} && 
         $ENV{'user.domain'} ne $self->{'domain'}) {          $ENV{'user.domain'} ne $self->{'domain'}) {
         $title .= &Apache::loncommon::aboutmewrapper          $title .= ' '.&Apache::loncommon::aboutmewrapper
                                     ($self->{'name'}.'@'.$self->{'domain'},                                      ($self->{'name'}.'@'.$self->{'domain'},
                                      $self->{'name'},$self->{'domain'});                                       $self->{'name'},$self->{'domain'});
     }      }
Line 137  sub get_html_title { Line 140  sub get_html_title {
   
 sub parent_link {  sub parent_link {
     my $self = shift;      my $self = shift;
     my $link .= '<p><a href="/adm/classcalc?'.      return '<p><a href="/adm/classcalc">Course level sheet</a></p>'."\n";
         'sname='.$self->{'name'}.  
             '&sdomain='.$self->{'domain'}.'">'.  
                 'Course level sheet</a></p>'."\n";  
     return $link;  
 }  }
   
 sub convenience_links {  sub convenience_links {
Line 409  sub outsheet_recursive_excel { Line 408  sub outsheet_recursive_excel {
     my ($r) = @_;      my ($r) = @_;
 }   } 
   
   ##
   ## Routines to deal with sequences in the safe space
   ##
   sub get_rows_in_sequence {
       my $self = shift();
       my ($sequence) = @_;
       my @Rows;
       foreach my $resource (@{$sequence->{'contents'}}) {
           if ($resource->{'type'} eq 'assessment') {
               my $rownum = $self->get_row_number_from_key($resource->{'symb'});
               push (@Rows,$rownum);
           }
       }
       return @Rows;
   }
   
   sub remove_sequence_data_from_safe_space {
       my $self = shift();
       my $command = 'undef(%Sequence_Rows);';
       $self->{'safe'}->reval($command);
   }
   
   sub put_sequence_data_in_safe_space {
       my $self = shift();
       my $data = 'undef(%Sequence_Rows);';
       # Build up the %Sequence_Rows hash - each sequence title is associated with
       # an array pointer, which holds the rows in the sequence.
       foreach my $seq (@Sequences) {
           my @Rows = $self->get_rows_in_sequence($seq);
           # 
           # Potential problems with sequence titles:
           # 1. duplicate titles - they get the total for the titles
           # 2. control characters in titles - use q{} around the string to
           #    deal with it.  
           my $title = &HTML::Entities::decode($seq->{'title'});
           $title =~ s/&\#058;/:/g;
           if (@Rows) {
               $data .= 'push(@{$Sequence_Rows{"'.quotemeta($title).'"}},'.
                   '('.join(',',@Rows).'));'."\n";;
           }
       }
       my $new_code = $data.<<'END';
   sub SUMSEQ {
       my ($col,@titles) = @_;
       return 'bad column: '.$col if ($col !~ /^[A-z]$/);
       my $sum = 0;
       foreach my $title (@titles) {
           while (my ($seq_title,$rows) = each(%Sequence_Rows)) {
               my $regexp;
               if ($title =~ /^regexp:(.*)$/) {
                   $regexp = $1;
               } elsif (lc($title) eq 'all') {
                   $regexp = '.';
               }
               if (defined($regexp)) {
                   next if ($seq_title !~ /$regexp/);
               } else {
                   next if ($seq_title ne $title);
               }
               foreach my $rownum (@{$rows}) {
                   my $cell = $col.$rownum;
                   if (exists($sheet_values{$cell})) {
                       $sum += $sheet_values{$cell};
                   }
               }
           }
       }
       return $sum;
   }
   END
       $self->{'safe'}->reval($new_code);
       return;
   }
   
   ##
   ## Main computation method
   ##
 sub compute {  sub compute {
     my $self = shift;      my $self = shift;
     $self->logthis('computing');      my ($r) = @_;
       my $connection = $r->connection();
       if ($connection->aborted()) { $self->cleanup; return; }
     if (! defined($current_course) ||      if (! defined($current_course) ||
         $current_course ne $ENV{'request.course.id'}) {          $current_course ne $ENV{'request.course.id'} ||
           ! @Sequences ) {
         $current_course = $ENV{'request.course.id'};          $current_course = $ENV{'request.course.id'};
         &clear_package();          &clear_package();
         &initialize_sequence_cache();          &initialize_sequence_cache();
     }      }
     $self->initialize_safe_space();      $self->initialize_safe_space();
     my @sequences = @Sequences;  
     if (@sequences < 1) {  
         my ($top,$sequences,$assessments) =   
             &Apache::loncoursedata::get_sequence_assessment_data();  
         if (! defined($top) || ! ref($top)) {  
             &Apache::lonnet::logthis('top is undefined');  
             return;  
         }  
         @sequences = @{$sequences} if (ref($sequences) eq 'ARRAY');  
     }  
     &Apache::assesscalc::initialize_package($self->{'name'},$self->{'domain'});      &Apache::assesscalc::initialize_package($self->{'name'},$self->{'domain'});
     my %f = $self->formulas();      my %f = $self->formulas();
     #      #
     # Process the formulas list -       # Process the formulas list - 
     #   the formula for the A column of a row is symb__&&__filename      #   the formula for the A column of a row is symb__&&__filename
     my %c = $self->constants();      my %c = $self->constants();
     foreach my $seq (@sequences) {      foreach my $seq (@Sequences) {
         next if ($seq->{'num_assess'}<1);          next if ($seq->{'num_assess'}<1);
         foreach my $resource (@{$seq->{'contents'}}) {          foreach my $resource (@{$seq->{'contents'}}) {
               if ($connection->aborted()) { $self->cleanup(); return; }
             next if ($resource->{'type'} ne 'assessment');              next if ($resource->{'type'} ne 'assessment');
             my $rownum = $self->get_row_number_from_key($resource->{'symb'});              my $rownum = $self->get_row_number_from_key($resource->{'symb'});
             my $cell = 'A'.$rownum;              my $cell = 'A'.$rownum;
Line 448  sub compute { Line 518  sub compute {
                 $self->{'row_source'}->{$rownum} = $assess_filename;                  $self->{'row_source'}->{$rownum} = $assess_filename;
             }              }
             $f{$cell} = $resource->{'symb'}.'__&&&__'.$assess_filename;              $f{$cell} = $resource->{'symb'}.'__&&&__'.$assess_filename;
               if ($connection->aborted()) { $self->cleanup(); return; }
             my $assessSheet = Apache::assesscalc->new($self->{'name'},              my $assessSheet = Apache::assesscalc->new($self->{'name'},
                                                       $self->{'domain'},                                                        $self->{'domain'},
                                                       $assess_filename,                                                        $assess_filename,
                                                       $resource->{'symb'});                                                        $resource->{'symb'});
             my @exportdata = $assessSheet->export_data();              my @exportdata = $assessSheet->export_data($r);
               if ($connection->aborted()) { $self->cleanup(); return; }
             if ($assessSheet->blackout()) {              if ($assessSheet->blackout()) {
                 $self->blackout(1);                  $self->blackout(1);
                 $self->{'blackout_rows'}->{$rownum} = 1;                  $self->{'blackout_rows'}->{$rownum} = 1;
Line 477  sub compute { Line 549  sub compute {
     }      }
     $self->constants(\%c);      $self->constants(\%c);
     $self->formulas(\%f);      $self->formulas(\%f);
       $self->put_sequence_data_in_safe_space();
     $self->calcsheet();      $self->calcsheet();
       $self->remove_sequence_data_from_safe_space();
     #      #
     # Store export row in cache      # Store export row in cache
     my @exportarray=$self->exportrow();      my @exportarray=$self->exportrow();
Line 494  sub compute { Line 568  sub compute {
 sub set_row_sources {  sub set_row_sources {
     my $self = shift;      my $self = shift;
     while (my ($cell,$value) = each(%{$self->{'formulas'}})) {      while (my ($cell,$value) = each(%{$self->{'formulas'}})) {
         next if ($cell !~ /^A(\d+)/ && $1 > 0);          next if ($cell !~ /^A(\d+)$/ || $1 < 1);
         my $row = $1;          my $row = $1;
         (undef,$value) = split('__&&&__',$value);          (undef,$value) = split('__&&&__',$value);
         $value = 'Default' if (! defined($value));          $value = 'Default' if (! defined($value));
Line 511  sub set_row_numbers { Line 585  sub set_row_numbers {
         next if ($row == 0);          next if ($row == 0);
         my ($symb,undef) = split('__&&&__',$formula);          my ($symb,undef) = split('__&&&__',$formula);
         $self->{'row_numbers'}->{$symb} = $row;          $self->{'row_numbers'}->{$symb} = $row;
         $self->{'maxrow'} = $1 if ($1 > $self->{'maxrow'});          $self->{'maxrow'} = $row if ($row > $self->{'maxrow'});
     }      }
 }  }
   
Line 541  These rows are saved in the courses dire Line 615  These rows are saved in the courses dire
 #############################################  #############################################
 #############################################  #############################################
 sub load_cached_export_rows {  sub load_cached_export_rows {
     %Exportrows = undef;      undef(%Exportrows);
     my @tmp = &Apache::lonnet::dump('nohist_calculatedsheets',      my @tmp = &Apache::lonnet::dump('nohist_calculatedsheets',
      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},       $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
      $ENV{'course.'.$ENV{'request.course.id'}.'.num'},undef);       $ENV{'course.'.$ENV{'request.course.id'}.'.num'},undef);
Line 580  Writes the export data for this student Line 654  Writes the export data for this student
 #############################################  #############################################
 sub save_export_data {  sub save_export_data {
     my $self = shift;      my $self = shift;
       &Apache::assesscalc::save_cached_export_rows($self->{'name'},
                                                    $self->{'domain'});
     return if ($self->temporary());      return if ($self->temporary());
     my $student = $self->{'name'}.':'.$self->{'domain'};      my $student = $self->{'name'}.':'.$self->{'domain'};
     return if (! exists($Exportrows{$student}));      return if (! exists($Exportrows{$student}));
Line 589  sub save_export_data { Line 665  sub save_export_data {
     my $newstore = join('___;___',      my $newstore = join('___;___',
                         @{$Exportrows{$student}->{'data'}});                          @{$Exportrows{$student}->{'data'}});
     $newstore = '___=___'.$newstore;      $newstore = '___=___'.$newstore;
     &Apache::lonnet::put('nohist_calculatedsheets',      my $result= &Apache::lonnet::put('nohist_calculatedsheets',
                          { $key     => $newstore,                           { $key     => $newstore,
                            $timekey => $Exportrows{$student}->{'time'} },                             $timekey => $Exportrows{$student}->{'time'} },
                          $self->{'cdom'},                           $self->{'cdom'},
Line 613  spreadsheet only if necessary. Line 689  spreadsheet only if necessary.
 #############################################  #############################################
 sub export_data {  sub export_data {
     my $self = shift;      my $self = shift;
       my ($r) = @_;
       my $connection = $r->connection();
     my $student = $self->{'name'}.':'.$self->{'domain'};      my $student = $self->{'name'}.':'.$self->{'domain'};
     if (! exists($Exportrows{$student}) ||      if (! exists($Exportrows{$student}) ||
         ! defined($Exportrows{$student}) ||          ! defined($Exportrows{$student}) ||
           ! exists($Exportrows{$student}->{'data'}) ||
         ! defined($Exportrows{$student}->{'data'}) ||          ! defined($Exportrows{$student}->{'data'}) ||
           ! exists($Exportrows{$student}->{'time'}) ||
           ! defined($Exportrows{$student}->{'time'}) ||
         ! $self->check_expiration_time($Exportrows{$student}->{'time'})) {          ! $self->check_expiration_time($Exportrows{$student}->{'time'})) {
         $self->compute();          $self->compute($r);
     }      }
       if ($connection->aborted()) { $self->cleanup(); return; }
     my @Data = @{$Exportrows{$student}->{'data'}};      my @Data = @{$Exportrows{$student}->{'data'}};
     for (my $i=0; $i<=$#Data;$i++) {      for (my $i=0; $i<=$#Data;$i++) {
         $Data[$i]="'".$Data[$i]."'" if ($Data[$i]=~/\D/ && defined($Data[$i]));          $Data[$i]="'".$Data[$i]."'" if ($Data[$i]=~/\D/ && defined($Data[$i]));

Removed from v.1.15  
changed lines
  Added in v.1.22


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>