Diff for /loncom/interface/spreadsheet/assesscalc.pm between versions 1.35 and 1.49

version 1.35, 2004/12/08 00:15:18 version 1.49, 2005/05/17 18:04:40
Line 104  my %nice_parameter_name; Line 104  my %nice_parameter_name;
 my %useropt;  my %useropt;
 my %userdata;  my %userdata;
 my %courseopt;  my %courseopt;
   my $navmap;
   
 ########################################################  ########################################################
 ########################################################  ########################################################
Line 124  sub clear_package { Line 125  sub clear_package {
     if (defined($current_name) &&      if (defined($current_name) &&
         defined($current_domain) &&          defined($current_domain) &&
         defined($current_course) &&          defined($current_course) &&
         $current_course eq $ENV{'request.course.id'} &&          $current_course eq $env{'request.course.id'} &&
         %newExportrows) {          %newExportrows) {
         &save_cached_export_rows($current_name,$current_domain);          &save_cached_export_rows($current_name,$current_domain);
     }      }
Line 136  sub clear_package { Line 137  sub clear_package {
     undef(%useropt);      undef(%useropt);
     undef(%userdata);      undef(%userdata);
     undef(%courseopt);      undef(%courseopt);
       undef($navmap);
 }  }
   
 sub save_cached_export_rows {  sub save_cached_export_rows {
     my ($sname,$sdomain) = @_;      my ($sname,$sdomain) = @_;
     my $start = Time::HiRes::time;  
     my $result = &Apache::lonnet::put      my $result = &Apache::lonnet::put
         ('nohist_calculatedsheets_'.$ENV{'request.course.id'},          ('nohist_calculatedsheets_'.$env{'request.course.id'},
          $newExportrows{$sname.':'.$sdomain},           $newExportrows{$sname.':'.$sdomain},
          $sdomain,$sname);           $sdomain,$sname);
     delete($newExportrows{$sname.':'.$sdomain});      delete($newExportrows{$sname.':'.$sdomain});
 }  }
   
 sub initialize {  sub initialize {
       my ($in_navmap) = @_;
     &clear_package();      &clear_package();
       $navmap = $in_navmap;
       if (! defined($navmap)) {
           $navmap = Apache::lonnavmaps::navmap->new();
       }
       if (!defined($navmap)) {
           &Apache::lonnet::logthis('assesscalc:Can not open Coursemap');
       }
     &Apache::loncoursedata::clear_internal_caches();      &Apache::loncoursedata::clear_internal_caches();
 }  }
   
Line 165  sub initialize { Line 174  sub initialize {
 ########################################################  ########################################################
 ########################################################  ########################################################
 sub initialize_package {  sub initialize_package {
     my ($sname,$sdomain) = @_;      my ($sname,$sdomain,$in_navmap) = @_;
     $current_name   = $sname;      $current_name   = $sname;
     $current_domain = $sdomain;      $current_domain = $sdomain;
       $navmap = $in_navmap;
     undef(%useropt);      undef(%useropt);
     undef(%userdata);      undef(%userdata);
     if ($current_course ne $ENV{'request.course.id'}) {      if ($current_course ne $env{'request.course.id'}) {
         $current_course = $ENV{'request.course.id'};          $current_course = $env{'request.course.id'};
         undef(%courseopt);          undef(%courseopt);
     }      }
     &load_cached_export_rows();      &load_cached_export_rows();
Line 197  sub load_parameter_caches { Line 207  sub load_parameter_caches {
     #      #
     # Course Parameters Cache      # Course Parameters Cache
     if (! %courseopt) {      if (! %courseopt) {
         $current_course = $ENV{'request.course.id'};          $current_course = $env{'request.course.id'};
         undef(%courseopt);          undef(%courseopt);
         if (! defined($current_name) || ! defined($current_domain)) {          if (! defined($current_name) || ! defined($current_domain)) {
             return;              return;
         }          }
         my $dom = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'};          my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
         my $id  = $ENV{'course.'.$ENV{'request.course.id'}.'.num'};          my $id  = $env{'course.'.$env{'request.course.id'}.'.num'};
         my %Tmp = &Apache::lonnet::dump('resourcedata',$dom,$id);          my %Tmp = &Apache::lonnet::dump('resourcedata',$dom,$id);
         while (my ($name,$value) = each(%Tmp)) {          while (my ($name,$value) = each(%Tmp)) {
             $courseopt{$name}=$value;              $courseopt{$name}=$value;
Line 246  sub ensure_current_caches { Line 256  sub ensure_current_caches {
     ## Check for a modified parameters      ## Check for a modified parameters
     ##      ##
     if (! defined($current_course) ||       if (! defined($current_course) || 
         $current_course ne $ENV{'request.course.id'} ) {          $current_course ne $env{'request.course.id'} ) {
         $current_course = $ENV{'request.course.id'};          $current_course = $env{'request.course.id'};
         undef(%courseopt);           undef(%courseopt); 
         undef(%useropt);          undef(%useropt);
         undef(%userdata);          undef(%userdata);
Line 291  this user and course. Line 301  this user and course.
 ##################################################  ##################################################
 sub parmval {  sub parmval {
     my $self = shift;      my $self = shift;
     my ($what,$symb,$uname,$udom,$csec,$recurse)=@_;      my ($what,$symb,$uname,$udom,$csec,$recurse,$mapname,$id,$fn)=@_;
     $uname = $self->{'name'}    if (! defined($uname));      $uname = $self->{'name'}    if (! defined($uname));
     $udom  = $self->{'domain'}  if (! defined($udom));      $udom  = $self->{'domain'}  if (! defined($udom));
     $csec  = $self->{'section'} if (! defined($csec));      $csec  = $self->{'section'} if (! defined($csec));
Line 300  sub parmval { Line 310  sub parmval {
     my $result='';      my $result='';
     #      #
     # This should be a       # This should be a 
     my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb);      if (!defined($mapname) || !defined($id) || !defined($fn)) {
    ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb);
       }
     # Cascading lookup scheme      # Cascading lookup scheme
     my $rwhat=$what;      my $rwhat=$what;
     $what =~ s/^parameter\_//;      $what =~ s/^parameter\_//;
Line 337  sub parmval { Line 349  sub parmval {
     #      #
     # check course      # check course
     return $courseopt{$courselevelr} if (defined($courseopt{$courselevelr}));      return $courseopt{$courselevelr} if (defined($courseopt{$courselevelr}));
     return $courseopt{$courselevelm} if (defined($courseopt{$courselevelm}));  
     return $courseopt{$courselevel}  if (defined($courseopt{$courselevel}));  
     # check map parms      # check map parms
     my $thisparm = $parmhash{$symbparm};      my $thisparm = $parmhash{$symbparm};
     return $thisparm if (defined($thisparm));      return $thisparm if (defined($thisparm));
     # check default      # check default
     $thisparm = &Apache::lonnet::metadata($fn,$rwhat.'.default');      $thisparm = &Apache::lonnet::metadata($fn,$rwhat.'.default');
     return $thisparm if (defined($thisparm));      return $thisparm if (defined($thisparm));
     #      # check more course
       return $courseopt{$courselevelm} if (defined($courseopt{$courselevelm}));
       return $courseopt{$courselevel}  if (defined($courseopt{$courselevel}));
   
     # Cascade Up      # Cascade Up
     my $space=$what;      my $space=$what;
     $space=~s/\.[^._]+$//;      $space=~s/\.[^._]+$//;
Line 356  sub parmval { Line 369  sub parmval {
  if ($part eq '') { $part='0'; }   if ($part eq '') { $part='0'; }
  my $newwhat=$rwhat;   my $newwhat=$rwhat;
  $newwhat=~s/\Q$space\E/$part/;   $newwhat=~s/\Q$space\E/$part/;
  my $partgeneral=$self->parmval($newwhat,$symb,$uname,$udom,$csec,1);   my $partgeneral=$self->parmval($newwhat,$symb,$uname,$udom,$csec,1,
          $mapname,$id,$fn);
  if (defined($partgeneral)) { return $partgeneral; }   if (defined($partgeneral)) { return $partgeneral; }
     }      }
     if ($recurse) { return undef; }      if ($recurse) { return undef; }
Line 501  sub assess_html_row { Line 515  sub assess_html_row {
     my @rowdata = $self->get_row($row);      my @rowdata = $self->get_row($row);
     my $num_cols_output = 0;      my $num_cols_output = 0;
     my $row_html;      my $row_html;
     if (exists($nice_parameter_name{$parameter_name})) {      my $name=$self->get_parm_name($parameter_name);
         my $name = $nice_parameter_name{$parameter_name};      if ($name ne '') {
         $name =~ s/ /\ /g;          $name =~ s/ /\ /g;
         $row_html .= '<td>'.$name.'<br />'.$parameter_name.'</td>';          $row_html .= '<td>'.$name.'<br />'.$parameter_name.'</td>';
     } else {      } else {
Line 537  sub csv_rows { Line 551  sub csv_rows {
     # Write each row      # Write each row
     foreach my $rownum (sort {$a <=> $b} ($self->rows())) {      foreach my $rownum (sort {$a <=> $b} ($self->rows())) {
         my $parameter_name = $self->{'formulas'}->{'A'.$rownum};          my $parameter_name = $self->{'formulas'}->{'A'.$rownum};
         my $description = '';          my $description = $self->get_parm_name($parameter_name);
         if (exists($nice_parameter_name{$parameter_name})) {  
             $description = $nice_parameter_name{$parameter_name};  
         }  
         $self->csv_output_row($filehandle,$rownum,          $self->csv_output_row($filehandle,$rownum,
                               $parameter_name,$description);                                $parameter_name,$description);
     }      }
Line 551  sub excel_rows { Line 562  sub excel_rows {
     # writes the meat of the spreadsheet to an excel worksheet.  Called      # writes the meat of the spreadsheet to an excel worksheet.  Called
     # by Spreadsheet::outsheet_excel;      # by Spreadsheet::outsheet_excel;
     my $self = shift;      my $self = shift;
     my ($connection,$worksheet,$cols_output,$rows_output) = @_;      my ($connection,$worksheet,$cols_output,$rows_output,$format) = @_;
     return if (! ref($worksheet));      return if (! ref($worksheet));
     #      #
     # Write a header row      # Write a header row
     $cols_output = 0;      $cols_output = 0;
     foreach my $value ('Parameter','Description','Value') {      foreach my $value ('Parameter','Description','Value') {
         $worksheet->write($rows_output,$cols_output++,$value);          $worksheet->write($rows_output,$cols_output++,$value,$format->{'h4'});
     }      }
     $rows_output++;          $rows_output++;
     #      #
     # Write each row      # Write each row
     foreach my $rownum (sort {$a <=> $b} ($self->rows())) {      foreach my $rownum (sort {$a <=> $b} ($self->rows())) {
         my $parameter_name = $self->{'formulas'}->{'A'.$rownum};          my $parameter_name = $self->{'formulas'}->{'A'.$rownum};
         my $description = '';          my $description = $self->get_parm_name($parameter_name);
         if (exists($nice_parameter_name{$parameter_name})) {  
             $description = $nice_parameter_name{$parameter_name};  
         }  
         $self->excel_output_row($worksheet,$rownum,$rows_output++,          $self->excel_output_row($worksheet,$rownum,$rows_output++,
                                 $parameter_name,$description);                                  $parameter_name,$description);
     }      }
Line 577  sub excel_rows { Line 585  sub excel_rows {
 ##  ##
 ## Routines to support assesscalc::compute  ## Routines to support assesscalc::compute
 ##  ##
 sub get_parm_names {  sub get_parm {
     my $self = shift;      my $self = shift;
     my @Mandatory_parameters = @_;      my @Mandatory_parameters = @_;
     my %parameters_and_names;      my %parameters;
     #      #
     my ($symap,$syid,$srcf) = &Apache::lonnet::decode_symb($self->{'symb'});      my ($symap,$syid,$srcf) = &Apache::lonnet::decode_symb($self->{'symb'});
     my @Metadata = split(/\,/,&Apache::lonnet::metadata($srcf,'keys'));      my @Metadata = split(/\,/,&Apache::lonnet::metadata($srcf,'keys'));
Line 589  sub get_parm_names { Line 597  sub get_parm_names {
         my $cleaned_name = $parm;          my $cleaned_name = $parm;
         $cleaned_name =~ s/^resource\./stores_/;          $cleaned_name =~ s/^resource\./stores_/;
         $cleaned_name =~ s/\./_/g;          $cleaned_name =~ s/\./_/g;
         my $display = &Apache::lonnet::metadata($srcf,          $parameters{$cleaned_name}=1;
                                                 $cleaned_name.'.display');  
         if (! $display) {  
             $display .= &Apache::lonnet::metadata($srcf,$cleaned_name.'.name');  
         }  
         $parameters_and_names{$cleaned_name}=$display;  
     }      }
     return (%parameters_and_names);      return (keys(%parameters));
   }
   
   sub get_parm_name {
       my $self = shift;
       my $parm = shift;
       my ($symap,$syid,$srcf) = &Apache::lonnet::decode_symb($self->{'symb'});
       my $display = &Apache::lonnet::metadata($srcf,$parm.'.display');
       if (! $display) {
    $display .= &Apache::lonnet::metadata($srcf,$parm.'.name');
       }
       return $display;
 }  }
   
 sub get_parameter_values {  sub get_parameter_values {
Line 616  sub get_parameter_values { Line 630  sub get_parameter_values {
     my $filename = $self->{'coursefilename'}.'_parms.db';      my $filename = $self->{'coursefilename'}.'_parms.db';
     if (tie(%parmhash,'GDBM_File',      if (tie(%parmhash,'GDBM_File',
             $self->{'coursefilename'}.'_parms.db',&GDBM_READER(),0640)) {              $self->{'coursefilename'}.'_parms.db',&GDBM_READER(),0640)) {
    my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($self->{'symb'});
         foreach my $parmname (@Parameters) {          foreach my $parmname (@Parameters) {
             my $value = $self->parmval($parmname);              my $value = $self->parmval($parmname,$self->{'symb'},
          $self->{'name'},$self->{'domain'},
          $self->{'section'},undef,
          $mapname,$id,$fn);
             $parameters{$parmname} =$value;              $parameters{$parmname} =$value;
         }          }
         untie(%parmhash);          untie(%parmhash);
Line 650  sub get_problem_state { Line 668  sub get_problem_state {
   
 sub determine_parts {  sub determine_parts {
     my $self = shift;      my $self = shift;
       my $check_hidden = shift;
     if (exists($self->{'Parts'}) && ref($self->{'Parts'}) eq 'HASH') {      if (exists($self->{'Parts'}) && ref($self->{'Parts'}) eq 'HASH') {
         return;          return;
     }      }
Line 660  sub determine_parts { Line 679  sub determine_parts {
     my $metadata = &Apache::lonnet::metadata($src,'packages');      my $metadata = &Apache::lonnet::metadata($src,'packages');
     foreach (split(',',$metadata)) {      foreach (split(',',$metadata)) {
         my ($part) = (/^part_(.*)$/);          my ($part) = (/^part_(.*)$/);
         if (defined($part) &&           if (!defined($part)) { next; }
             ! &Apache::loncommon::check_if_partid_hidden          if (!$check_hidden) { $Parts{$part}++; next; }
                 ($part,$self->{'symb'},$self->{'name'},$self->{'domain'})          if (!&Apache::loncommon::check_if_partid_hidden
       ($part,$self->{'symb'},$self->{'name'},$self->{'domain'})
             ) {              ) {
             $Parts{$part}++;              $Parts{$part}++;
         }          }
Line 697  sub parameter_part_is_valid { Line 717  sub parameter_part_is_valid {
 sub compute {  sub compute {
     my $self = shift;      my $self = shift;
     my ($r) = @_;      my ($r) = @_;
     my $connection = $r->connection();  
     if ($connection->aborted()) { $self->cleanup(); return; }  
     $self->initialize_safe_space();      $self->initialize_safe_space();
     #########################################      #########################################
     #########################################      #########################################
Line 719  sub compute { Line 737  sub compute {
     my %parameters;   # holds underscored parameters by name      my %parameters;   # holds underscored parameters by name
     #      #
     # Get the metadata fields and determine their proper names      # Get the metadata fields and determine their proper names
     my %nice_parm_names = $self->get_parm_names(@Mandatory_parameters);      my @parameters=$self->get_parm(@Mandatory_parameters);
     while (my($cleaned_name,$display) = each(%nice_parm_names)) {  
         $parameters{$cleaned_name}++;  
         $nice_parameter_name{$cleaned_name} = $display;  
     }  
     #      #
     # Get the values of the metadata fields      # Get the values of the metadata fields
     if ($connection->aborted()) { $self->cleanup(); return; }  
     $self->ensure_current_caches();      $self->ensure_current_caches();
     if ($connection->aborted()) { $self->cleanup(); return; }      %parameters = $self->get_parameter_values(@parameters);
     %parameters = $self->get_parameter_values(keys(%parameters));  
     if ($connection->aborted()) { $self->cleanup(); return; }  
     #      #
     # Clean out unnecessary parameters      # Clean out unnecessary parameters
     foreach (keys(%parameters)) {      foreach (keys(%parameters)) {
Line 738  sub compute { Line 749  sub compute {
     }      }
     #      #
     # Get the students performance data      # Get the students performance data
       $self->determine_parts(($parameters{'parameter_0_hiddenparts'} ne ''));
     my %student_parameters = $self->get_problem_state();      my %student_parameters = $self->get_problem_state();
     while (my ($parm,$value) = each(%student_parameters)) {      while (my ($parm,$value) = each(%student_parameters)) {
         $parm =~ s/^resource\./stores_/;          $parm =~ s/^resource\./stores_/;
         $parm =~ s/\./_/g;          $parm =~ s/\./_/g;
         $parameters{$parm} = $value;   # Clean out any bad parameters
     }   next if (! $self->parameter_part_is_valid($parm));
     #   $parameters{$parm} = $value;
     # Clean out any bad parameters  
     $self->determine_parts();  
     foreach my $param (keys(%parameters)) {  
         if (! $self->parameter_part_is_valid($param)) {  
             delete ($parameters{$param});  
         }  
     }      }
     #      #
     # Set up the formulas and parameter values      # Set up the formulas and parameter values
Line 758  sub compute { Line 764  sub compute {
     my %c;      my %c;
     #      #
     # Check for blackout requirements      # Check for blackout requirements
     if ((!exists($ENV{'request.role.adv'}) || !$ENV{'request.role.adv'})) {      if ((!exists($env{'request.role.adv'}) || !$env{'request.role.adv'})) {
         while (my ($parm,$value) = each(%parameters)) {          while (my ($parm,$value) = each(%parameters)) {
             last if ($self->blackout());              last if ($self->blackout());
             next if ($parm !~ /^(parameter_.*)_problemstatus$/);              next if ($parm !~ /^(parameter_.*)_problemstatus$/);
Line 772  sub compute { Line 778  sub compute {
             }              }
         }          }
     }      }
     if ($connection->aborted()) { $self->cleanup(); return; }  
     #      #
     # Move the parameters into the spreadsheet      # Move the parameters into the spreadsheet
     while (my ($parm,$value) = each(%parameters)) {      while (my ($parm,$value) = each(%parameters)) {
Line 786  sub compute { Line 791  sub compute {
     }      }
     $self->formulas(\%f);      $self->formulas(\%f);
     $self->constants(\%c);      $self->constants(\%c);
     if ($connection->aborted()) { $self->cleanup(); return; }  
     $self->calcsheet();      $self->calcsheet();
     #      #
     # Store export row in cache      # Store export row in cache
     my @exportarray = $self->exportrow();      my @exportarray = $self->exportrow();
     $self->deal_with_export_row(@exportarray);      $self->deal_with_export_row(@exportarray);
     $self->save() if ($self->need_to_save());      $self->save() if ($self->need_to_save());
     if ($connection->aborted()) { $self->cleanup(); return; }  
     return;      return;
 }  }
   
Line 803  sub compute { Line 806  sub compute {
 sub sett {  sub sett {
     my $self = shift;      my $self = shift;
     my %t=();      my %t=();
       undef(%Apache::Spreadsheet::sheet_values);
     #      #
     # Deal with the template row by copying the template formulas into each      # Deal with the template row by copying the template formulas into each
     # row.      # row.
Line 828  sub sett { Line 832  sub sett {
     while (my ($cell,$formula) = each(%{$self->{'formulas'}})) {      while (my ($cell,$formula) = each(%{$self->{'formulas'}})) {
  next if ($cell =~ /template_/);   next if ($cell =~ /template_/);
         if ($cell =~ /^A/ && $cell ne 'A0') {          if ($cell =~ /^A/ && $cell ne 'A0') {
             if ($formula !~ /^\!/) {      if ($formula !~ /^\!/ 
                 $t{$cell}=$self->{'constants'}->{$formula};   && exists($self->{'constants'}->{$formula}) 
    && $self->{'constants'}->{$formula} ne ''
    ) {
    $Apache::Spreadsheet::sheet_values{$cell}=
       eval($self->{'constants'}->{$formula});
             }              }
         } else {          } else {
             $t{$cell}=$formula;              $t{$cell}=$formula;
Line 864  These rows are saved in the students dir Line 872  These rows are saved in the students dir
 sub load_cached_export_rows {  sub load_cached_export_rows {
     undef(%Exportrows);      undef(%Exportrows);
     my @tmp = &Apache::lonnet::dump('nohist_calculatedsheets_'.      my @tmp = &Apache::lonnet::dump('nohist_calculatedsheets_'.
                                     $ENV{'request.course.id'},                                      $env{'request.course.id'},
                                     $current_domain,$current_name,undef);                                      $current_domain,$current_name,undef);
     if ($tmp[0]!~/^error/) {      if ($tmp[0]!~/^error/) {
         my %tmp = @tmp;          my %tmp = @tmp;
         my $default_filename =  $ENV{'course.'.$ENV{'request.course.id'}.          my $default_filename =  $env{'course.'.$env{'request.course.id'}.
                                          '.spreadsheet_default_assesscalc'};                                           '.spreadsheet_default_assesscalc'};
         # We only got one key, so we will access it directly.          # We only got one key, so we will access it directly.
         while (my ($key,$sheetdata) = each(%tmp)) {          while (my ($key,$sheetdata) = each(%tmp)) {
Line 908  spreadsheet only if necessary. Line 916  spreadsheet only if necessary.
 sub export_data {  sub export_data {
     my $self = shift;      my $self = shift;
     my ($r) = @_;      my ($r) = @_;
     my $connection = $r->connection();  
     my $symb = $self->{'symb'};      my $symb = $self->{'symb'};
     if (! exists($ENV{'request.role.adv'}) || ! $ENV{'request.role.adv'} ||      if (! exists($env{'request.role.adv'}) || ! $env{'request.role.adv'} ||
         ! exists($Exportrows{$symb}) || ! defined($Exportrows{$symb})  ||          ! exists($Exportrows{$symb}) || ! defined($Exportrows{$symb})  ||
         ! $self->check_expiration_time($Exportrows{$symb}->{'time'}) ||          ! $self->check_expiration_time($Exportrows{$symb}->{'time'}) ||
         ! exists($Exportrows{$symb}->{$self->{'filename'}}) ||          ! exists($Exportrows{$symb}->{$self->{'filename'}}) ||
Line 919  sub export_data { Line 926  sub export_data {
         ) {          ) {
         $self->compute($r);          $self->compute($r);
     }      }
     if ($connection->aborted()) { $self->cleanup(); return; }  
     my @Data;      my @Data;
     if ($self->badcalc()) {      if ($self->badcalc()) {
         @Data = ();          @Data = ();

Removed from v.1.35  
changed lines
  Added in v.1.49


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