typestar

grade_report.pl in Perl

Averages per-student scores from a hash of arrays into a graded table.

use strict;
use warnings;

# grade_report: average per-student scores and print a table

my %scores = (
    Alice => [92, 88, 95],
    Bob   => [75, 82, 79],
    Cara  => [88, 91, 84],
    Dev   => [60, 71, 68],
);

sub average {
    my $sum = 0;
    $sum += $_ for @_;
    return $sum / @_;
}

my %avg = map { $_ => average(@{ $scores{$_} }) } keys %scores;

printf "%-8s %-12s %6s  %s\n", "student", "scores", "avg", "grade";
print "-" x 34, "\n";

for my $name (sort { $avg{$b} <=> $avg{$a} } keys %scores) {
    my $mean  = $avg{$name};
    my $grade = $mean >= 90 ? "A"
              : $mean >= 80 ? "B"
              : $mean >= 70 ? "C" : "D";
    printf "%-8s %-12s %6.1f  %s\n",
        $name, join(" ", @{ $scores{$name} }), $mean, $grade;
}

my $class = average(map { @$_ } values %scores);
printf "class average: %.1f\n", $class;

How it works

  1. %scores maps each student to an arrayref of scores; average sums @_.
  2. map derefs each list into the helper to build %avg in one pass.
  3. printf column widths line the table up; a chained ternary picks the grade.
  4. map { @$_ } values %scores flattens everything for the class average.

Keywords and builtins used here

The run, in numbers

Lines
34
Characters to type
764
Tokens
243
Three-star pace
80 tpm

At the three-star pace of 80 tokens a minute, this run takes about 182 seconds.

Type this snippet

Step 2 of 3 in Encore, step 26 of 27 in Language basics.

← Previous Next →