#-------------------------------------------------------------------------- #-- Author: Adam McManus #-- Date: 2/10/03 #-- File: program2.pl #-- Description: #-- #-------------------------------------------------------------------------- use strict; #-- Check usage die "Usage: $0 input_file\n" if( scalar(@ARGV) != 1 ); #-- Get cmd line arguments my $input_file = $ARGV[0]; #-- file containing student info #-- Declare variables #-------------------------------------------------------------- #-- %students is a hash of student information, indexed by name #-- $students{last,first}{grades} is the array of grades #-- $students{last,first}{avg_grade} is the student's average #-------------------------------------------------------------- my %students; my @averages; #-- sorted array of student averages my @buffer; #-- buffer to read line from file into my $name_index; #-- index for %students "lastname,firstname" my $median_class_avg; #-- median class average #-- Open the input file open(INPUT, '<', $input_file) or die "Couldn't open $input_file: $!\n"; #-- Read the input file one line at a time while( ) { next if( /^$/ ); #-- skip blank lines @buffer = split; #-- split on whitespace $name_index = "$buffer[1],$buffer[0]"; #-- create the name index #-- Load the student's grades and begin computing the average #-- by summing up the student's grades foreach my $i ( 2 .. $#buffer ) { push @{ $students{$name_index}{grades} }, $buffer[$i]; $students{$name_index}{avg_grade} += $buffer[$i]; } #-- Finish computing the student's average by dividing by number of grades $students{$name_index}{avg_grade} /= scalar(@{ $students{$name_index}{grades} }); #-- Store the average into the class averages push @averages, sprintf("%.1f", $students{$name_index}{avg_grade}); } #-- Close the input file close(INPUT) or warn "Warning! $input_file was not closed properly: $!\n"; #-- Sort the array of averages numerically for median purposes @averages = sort { $a <=> $b } @averages; #------------------------------------------------------- #-- Find the class median #-- If even number of grades, take the average of the #-- middle two grades #-- Else, take the middle grade #------------------------------------------------------- if( scalar(@averages) % 2 == 0 ) { my $i = scalar(@averages) / 2; $median_class_avg = ( $averages[$i] + $averages[$i - 1] ) / 2; } else { my $i = sprintf("%d", scalar(@averages) / 2 ); $median_class_avg = $averages[$i]; } #-- Print the header for final report printf "\n%21s%16s%11s\n", 'Name', 'Average', 'Grades'; print '-' x 79 . "\n"; #-- Print the student info foreach my $name ( sort keys %students ) { #-- split out the first and last name of students my ($last, $first) = split(',', $name); #---------------------------------------- #-- Check if the student's avg is lower #-- than median class average and flag #-- if it is #---------------------------------------- if( $students{$name}{avg_grade} < ($median_class_avg * 0.8) ) { printf "**<.8med** %8s, %-10s", $last, $first; } else { printf "%10s %8s, %-10s", ' ', $last, $first; } #-- Print student's average printf "%5.1f%2s", $students{$name}{avg_grade}; #-- Print student's grades foreach ( 0 .. $#{ $students{$name}{grades} } ) { printf "%4d", $students{$name}{grades}[$_]; } print "\n"; } #-- Print the number of students and class median average printf "\nNumber of students processed: %d\n", scalar(@averages); printf "Median Average: %4.1f\n", $median_class_avg; print '-' x 79 . "\n"; #-- Program End