[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
 ##