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
%scoresmaps each student to an arrayref of scores;averagesums@_.mapderefs each list into the helper to build%avgin one pass.printfcolumn widths line the table up; a chained ternary picks the grade.map { @$_ } values %scoresflattens everything for the class average.
Keywords and builtins used here
averageforjoinkeysmapmyprintprintfreturnsortsubusevalues
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.
Step 2 of 3 in Encore, step 26 of 27 in Language basics.