#!/usr/athena/bin/perl

#this script takes an input file as an argument and computes the GPA based 
#on that. 
#
#It is intended to allow a user to keep a GPA file which can be modified
#easily, without having to enter in every subject every time they get a new
#grade.  It can also be used to easily play with what future grades might
#do to your GPA.
#
#Supported grades are A,B,C,D,F,P,and S, and any number. J is not supported.
#(well, a number like 4e3 is disallowed, by .004 should work)
#Modifiers, e.g., A+, are allowed and ignored
#
#The script works in three modes, taking input from a file as an argument,
#taking input from a file as STDIN, using "<", and taking input from the
#keyboard.  The user should see no difference between the first two modes,
#computegpa filename, and computegpa < filename
#The third mode will supply prompts, and expect a return after every input.
#
#A valid input file will have three fields per line, separated by commas
#or semicolons.  Lines with less than three fields are taken as comments.
#tabs and spaces are ignored, but returns are not.
#The first field is ignored, and can be anything (w/o ","s or ";"s),
#however, it should probably describe what the next fields refer to.
#The second field is the number of units.
#The third field is the grade.
#
#The file samplegpafile contains a sample input file.

if ($#ARGV > -1) {
    $infile = 1;
    printf ("%s\n",$ARGV[0]);
    open (f,"$ARGV[0]");
}
elsif (-t STDIN) {
    $infile = 0;
}
else {
    $infile = -1;
}


$totalgrade = 0;
$totalunits = 0;
$gradedunits = 0;

if ($infile) {
    if ($infile > 0) {
	$str = <f>;
    }
    else {
	$str = <STDIN>;
    }
    while ($str) {
	chop $str;
	($classd,$units,$grade) = split(/[,;]/, $str);
	if ($grade) {&body;}
	if ($infile > 0) {
	    $str = <f>;
	}
	else {
	    $str = <STDIN>;
	}

    }
}
else {
    printf("enter class descriptor:");
    $classd = <STDIN>;
    chop $classd;

    while ($classd ne "") {
	printf("enter units:");
	$units = <STDIN>;
	printf("enter grade:");
	$grade = <STDIN>;
	chop $grade;
	&body;
	printf ("enter class descriptor (RET to exit)");
	$classd = <STDIN>;
	chop $classd;
    }
}

if ($gradedunits > 0) {
    printf ("your GPA is %f with %d units and %d graded units\n",$totalgrade/$gradedunits,$totalunits,$gradedunits);
}
else {
    printf ("you have no graded units, and %d total units\n",$totalunits);
}

sub body{
	if ($grade =~ "A") {$grade = 5;}
	elsif ($grade =~ "B") {$grade = 4;}
	elsif ($grade =~ "C") {$grade = 3;}
	elsif ($grade =~ "D") {$grade = 2;}
	elsif ($grade =~ "P") {$gradedunits=$gradedunits-$units;}
	elsif ($grade =~ "S") {$gradedunits=$gradedunits-$units;}
	elsif ($grade =~ "F") {}
	elsif ($grade =~ /[a-zA-Z]/) {
	    printf ("$grade is an unsupported grade, not counted toward graded units.\n");
	    $gradedunits=$gradedunits-$units;
	}
	

	$totalunits = $totalunits + $units;
	$gradedunits = $gradedunits + $units;
	$totalgrade = $totalgrade + $grade * $units;
}    
