Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Re: Passing input through a hash then displaying results

by rkrieger (Friar)
on Jan 23, 2007 at 14:13 UTC ( #596097=note: print w/replies, xml ) Need Help??

in reply to Passing input through a hash then displaying results

You'd probably make things easier for yourself if you determine how you want to deal with grades between the multiples you defined. From that point on, you can just look up the grade in a table.

  • You do not deal out grades below 50 or above 90 or are willing to accept warnings about such grades.
  • You do not deal out a 'default' grade (e.g. F)
  • You only deal with thresholds in multiples of 10.
  • 85 etc. get rounded down to 80, even in _round_grade(). Perhaps the POSIX:: functions are more to your liking. See the Perl documentation for sprintf for more info.
  • For non-existent grades, you get a warning and _convert_grade() returns an empty string.
Code suggestion:
#!/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 = <STDIN> ) { # 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 inpu +t # $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"; }
foreach my $grade ( 4, 8, 45, 48, 50, 51, 57, 60, 64, 66 , 90, 91, 99, + 100) { my $chopped = _chop_grade($grade); my $rounded = _round_grade($grade); my $grade_chopped = _convert_grade($chopped); my $grade_rounded = _convert_grade($rounded); print "${grade}: ${rounded}/${grade_rounded} (Rounded) " . "- ${chopped}/${grade_chopped} (Chopped)\n"; }
If you don't know where you're going, any road will get you there.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://596097]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2018-06-24 10:07 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (126 votes). Check out past polls.