[LON-CAPA-cvs] cvs: loncom /interface/spreadsheet Spreadsheet.pm
albertel
lon-capa-cvs@mail.lon-capa.org
Fri, 13 May 2005 15:59:07 -0000
albertel Fri May 13 11:59:07 2005 EDT
Modified files:
/loncom/interface/spreadsheet Spreadsheet.pm
Log:
- elminates the use of
grep eval(/$re/) keys(%sheet_values)
which was a very slow operation
Index: loncom/interface/spreadsheet/Spreadsheet.pm
diff -u loncom/interface/spreadsheet/Spreadsheet.pm:1.44 loncom/interface/spreadsheet/Spreadsheet.pm:1.45
--- loncom/interface/spreadsheet/Spreadsheet.pm:1.44 Thu May 12 18:42:57 2005
+++ loncom/interface/spreadsheet/Spreadsheet.pm Fri May 13 11:59:07 2005
@@ -1,5 +1,5 @@
#
-# $Id: Spreadsheet.pm,v 1.44 2005/05/12 22:42:57 albertel Exp $
+# $Id: Spreadsheet.pm,v 1.45 2005/05/13 15:59:07 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -670,30 +670,62 @@
return $max;
}
+#-------------------------------------------------------
+
+=pod
+
+=item &get_values($lower,$upper)
+
+Inputs: $lower and $upper, cell names ("X12" or "a150") or globs ("X*").
+
+Returns: an array ref of the values of the cells that exist in the
+ speced range
+
+=cut
+
+#-------------------------------------------------------
sub get_values {
my ($lower,$upper)=@_;
- my $mask=&mask(@_);
+ $upper = $lower if (! defined($upper));
my @values;
- foreach (grep eval("/$mask/"),keys(%sheet_values)) {
- push(@values,$sheet_values{$_});
- }
- return \@values;
- if (0) {
- # perhaps creating a list of possible cells and looking if they exist
- # would be faster somtimes?
- &logthis("mask is ".$mask);
+ my ($la,$ld) = ($lower=~/([A-z]|\*)(\d+|\*)/);
+ my ($ua,$ud) = ($upper=~/([A-z]|\*)(\d+|\*)/);
+ my ($alpha,$num);
+ if ($ld ne '*' && $ud ne '*') {
my @alpha;
if (($la eq '*') || ($ua eq '*')) {
@alpha=('A'..'z');
} else {
- if ($la gt $ua) {
- my $tmp = $ua;
- $ua = $la;
- $la = $ua;
+ if ($la gt $ua) { ($la,$ua)=($ua,$la); }
+ if ((lc($la) ne $la) && (lc($ua) eq $ua)) {
+ @alpha=($la..'Z','a'..$ua);
+ } else {
+ @alpha=($la..$ua);
+ }
+ }
+ my @num=($ld..$ud);
+ foreach my $a (@alpha) {
+ foreach my $n (@num) {
+ if (exists($sheet_values{$a.$n})) {
+ push(@values,$sheet_values{$a.$n});
+ }
}
- $alpha=($la..$ua);
}
+ return \@values;
+ } else {
+ $num = '(\d+)';
+ }
+ if (($la eq '*') || ($ua eq '*')) {
+ $alpha='[A-z]';
+ } else {
+ if ($la gt $ua) { ($la,$ua)=($ua,$la); }
+ $alpha=qq/[$la-$ua]/;
+ }
+ my $expression = '^'.$alpha.$num.'$';
+ foreach (grep /$expression/,keys(%sheet_values)) {
+ push(@values,$sheet_values{$_});
}
+ return \@values;
}
sub calc {
@@ -758,92 +790,6 @@
######################################################
-
-######################################################
-
-=pod
-
-=item &mask($lower,$upper)
-
-Inputs: $lower and $upper, cell names ("X12" or "a150") or globs ("X*").
-
-Returns: Regular expression matching spreadsheet cells that are within
-the rectangle defined by $lower and $upper. Due to the nature of the
-regular expression this result must be used inside an eval().
-
-=cut
-
-######################################################
-{
-
-my %memoizer;
-
-sub mask {
- my ($lower,$upper)=@_;
- my $key = $lower.'_'.$upper;
- if (exists($memoizer{$key})) {
- return $memoizer{$key};
- }
- $upper = $lower if (! defined($upper));
- #
- my ($la,$ld) = ($lower=~/([A-z]|\*)(\d+|\*)/);
- my ($ua,$ud) = ($upper=~/([A-z]|\*)(\d+|\*)/);
- #
- my $alpha='';
- my $num='';
- #
- # Do not put parenthases around $alpha.
- # $num depends on the value in $1.
- if (($la eq '*') || ($ua eq '*')) {
- $alpha='[A-z]';
- } else {
- if ($la gt $ua) {
- my $tmp = $ua;
- $ua = $la;
- $la = $ua;
- }
- $alpha=qq/[$la-$ua]/;
- }
- if ($ld ne '*' && $ud ne '*') {
- # Make sure $ld <= $ud
- if ($ld > $ud) {
- my $tmp = $ud;
- $ud = $ld;
- $ld = $tmp;
- }
- # Here we make a regular expression using some advanced regexp
- # abilities.
- # (\d+) will match the digits of the cell name and dump them in
- # to $1
- # (?(?{ ... code ...} pattern_if_true | pattern_if_false)) will
- # choose pattern_if_true if { ... code ... } is true and
- # pattern_if_false if { ... code ... } is false.
- # In this case, pattern_if_true is empty. pattern_if_false is
- # 'donotmatch' and will not match our cells because none of
- # them end with donotmatch.
- # Unfortunately, the use of this type of regular expression
- # requires that each match be wrapped in an eval(). Search for
- # $mask in this module for examples
- $num = '(\d+)(?(?{$1>= '.$ld.' && $1<='.$ud.'})|donotmatch)';
- } else {
- $num = '(\d+)';
- }
- my $expression = '^'.$alpha.$num.'$';
- $memoizer{$key} = $expression;
- return $expression;
-}
-
-#
-# Debugging routine
-sub dump_memoized_values {
- while (my ($key,$value) = each(%memoizer)) {
- &Apache::lonnet::logthis('memoizer: '.$key.' = '.$value);
- }
- return;
-}
-
-}
-
##
## sub add_hash_to_safe {} # spreadsheet, would like to destroy
##