#!/usr/bin/perl use strict; use warnings; use Carp; # Table containing numerical grade thresholds my %grade_for = ( '90' => 'A', '80' => 'B', '70' => 'C', '60' => 'D', '50' => 'F', ); # Determine whether you want to round up or 'chop off' grades sub _round_grade { my $grade = shift; # We deal with thresholds in multiples of ten return 10 * sprintf( "%02.0f", $grade / 10 ); } sub _chop_grade { my $grade = shift; # We deal with thresholds in multiples of ten return 10 * int ( $grade / 10 ); } sub _convert_grade { my $grade = shift; # Check whether the grade entered is listed in our table if ( defined( $grade_for{$grade} ) ) { return $grade_for{$grade}; } else { # No character representation available; warn the user carp "Character grade for $grade not listed in our table."; return q{}; } } LINE: while ( my $line = ) { # Strip the newlines from our input chomp $line; # Prepare a RE to match the line against my $grade_re = qr{ \A # Start of the string \s* # Allow for leading spacing (\d{1,2}) # Match at least 1 digit and at most 2 digits \s* # Allow for trailing spacing \z # End of the string }xms; # Skip lines that are not a number next LINE if $line !~ m{$grade_re}xms; # Be strict when dealing out grades; round down our numerical input # $1 is valid, given the previous RE match my $grade_numeric = _chop_grade($line); # Convert our numeric input to a character my $grade = _convert_grade($grade_numeric); print "$line - $grade\n"; }