This is an assignment turned in for a programming languages class. It was meant to be a simple introduction to Perl and I wrote it fairly simply. However, I am curious if anyone has thoughts on the code and/or any ideas for more "creative" :) ways to accomplish the problem. Again, I am not asking for help to solve the assignment since it has already been completed, just seeking constructive criticism. :)

Here's the assignment:

Given an input file of the following format

Firstname Lastname list_of_grades(any number of grades)

You should output

Lastname, Firstname Average list_of_grades

The output should be sorted on lastname, followed by first name to break ties on lastnames. Also, the report should mark any students whose average is at least 20% less than the median class average.

Sample Input File

David Allen 50 60 70
Jane Aardmore 100 100 100
John Smith 75 74 72 73 89
Carl Allen 25 100 100 20
Mike Jones 80 85 82 89 88 86 80


Here's my code.

#--------------------------------------------------------------------- +----- #-- 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( <INPUT> ) { 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_inde +x}{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


Thanks,
Inelukii

In reply to Style and Coding criticism requested by inelukii

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.