On Thu, 17 Feb 2005 00:52:48 +1000, Alfred Vahau <[EMAIL PROTECTED]> wrote: > Hi, > I've been struggling with what should be a trivial problem. Perl is such > a rich language that in formulating the logic, I've actually > became confused. Partly because I took a C approach when I know that a > veteran Perl programmer would write only a few lines to achive the same > result. (The challenge coming from 'The Camel' 3rd ed. pp.119, 120). >
Alfred, I'm a little confused by your weighting here...it seems to me that GPA = SUM(G * CC)/SUM(CC), where G = Cource Grade CC = Course Credit. In the US, we often call (G*CC) Honor Points. So let's take student 386. Assuming a 4-point scale: Grade Credits Points F 3.00 0 C 3.00 6 C 3.00 6 D 2.00 4 D 3.00 3 D 3.00 3 B 3.00 9 C 3.00 6 F 2.00 0 ----------------------- 36.00 37 37/36 = 1.027.. In other words, our formula is good, so we don't need the elaborate lookup table. Other places to simplfy: the idea behind the match operator is that it will match what you're looking for; you don't need to match all cases and then discard the ones you don't want. Just look for the ones you want, and get rid of the rest. "unless" is your friend here, as are character classes. Also, if the string you're matching against doesn't have embedded \s, \b is redundant--as are ^ and $. Where else could you possibly match? Given that, here's one quick way to do it. It's easier for me to type, using <>; you can go back and hard code the data file later if you want: __CODE__ #!/usr/bin/perl use warnings ; use strict ; my %grades = ( A => 4, B => 3, C=> 2, D=> 1, F => 0 ) ; # lookup hash for the grades my %studcredit ; # we'll store the credits attempted here my %studpoints ; # we'll store the honor points here while (<>) { chomp; my ($id, $grade, $cred) = split /\s/, $_ ; # or just split next unless $grade =~ /[ABCDF]/; my $numgrade = $grades{$grade}; $studcredit{$id} += $cred; $studpoints{$id} += ($numgrade * $cred); } # using the hashes let us save the division to the end. # I did it because it's easier than nesting loops, but it # has the side benefit of handling improperly sorted data. # so now we'll get the results: foreach my $sid (keys %studcredit) { my $gpa = ($studpoints{$sid} / $studcredit{$sid}); # do something useful with $gpa here, # like apply rules for turning it into a letter grade. # for now, we'll just print it print "$sid\t$gpa\n"; } __END__ HTH, --jay -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>