Jay wrote:
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.
The observation is correct. The sums are involved here.
In the US, we often call (G*CC) Honor Points.Thanks. I couldn't recall the term for the numerator. Been a while since my days at Blacksburg, VA.
When I turn warnings and strict off, the program executes smoothly. When they are on, the following compilationSo 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 ;
error results:
*****
Global symbol "$inputfile" requires explicit package name at gpa3.pl line 15.
Global symbol "$inputfile" requires explicit package name at gpa3.pl line 17.
Global symbol "$inputfile" requires explicit package name at gpa3.pl line 17.
Execution of gpa3.pl aborted due to compilation errors.
******
This is a result of declaring the file name prior to opening.
$inputfile = 'gpa.dat'; open (INF, "<$inputfile") || die "can't open file $inputfile $!:\n";
But this is another problem that I can address later. *********
my %grades = ( A => 4, B => 3, C=> 2, D=> 1, F => 0 ) ;
# lookup hash for the grades
Thank you. Keeps tracking easier.
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
I'll use /\s+/ just in case of additional white spaces in the real data
next unless $grade =~ /[ABCDF]/;The use of character classes clearly skipped my mind. Just to be sure of cases, I'll use /[a-fA-F]/
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
Yes. There's a bit of repetive processing involved.
print "$sid\t$gpa\n";
Id 316 gpa = 1.40 is confirmed. Id 216 = 1.64 is different from one I quoted (1.73).
Ankur Gupta in an earlier posting quoted 1.98 for id 216 so I will have to check the calculations again
for non-allowed grades.
} __END__
HTH,
Thank you. It sure is a big help.
--jay
Alfred,
--
Perl - "... making the easy jobs easy,
without making the hard jobs impossible."
'The Camel', 3ed
-- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>