CIT 042 Index > Program - Modules

Programming Assignment—Modules

Read everything before doing anything! Really, I mean it. The hints at the end are well worth reading.

Part One

Complete the following module, which has utilities for handling civilian and military time. You may name the module whatever you wish.

#!/usr/bin/perl

#   Written by YOUR NAME HERE

=begin comment

    This file contains utilities for handling
    military and civilian times.

    TIME INPUT
    ==========
    Military time strings are always in the form
    of four digits without a colon.

        0725
        1509

    Civilian time strings always contain a colon. The
    "hours" part does not need a leading zero, though
    it may have one.  They are always followed by an
    abbreviation for morning or afternon.  Acceptable
    abbreviations for morning and afternoon are:

        a.m.   am   a
        p.m.   pm   p

    You may mix upper and lower case as much as you like,
    and you may have whitespace before the abbreviation.

    Thus, the following are all valid:

        7:25 a.m.     7:25 AM    07:25a
        11:05 p.m.   11:05 pM   11:05P.M.

    You may presume that time strings will NOT have leading
    or trailing blanks.

    TIME OUTPUT
    ===========
    Military time is always presented as four digits without
    a colon.

    Civilian time is always presented as hours (without a
    leading zero), a colon, two digits for the minute,
    one blank, and either "a.m." for morning or "p.m." for afternoon.

=end comment

=cut

#
#   Name the package appropriately,
#   and export these subroutines by default:
#
#       civilian_to_military
#       military_to_civilian
#
#   Do not export subroutine duration.
#   Do not make it "OK" to export subroutine duration.


=begin comment

The "military_to_civilian" subroutine takes a military time
string as its input and returns a string giving
the corresponding civilian time.

Example: input of "0825" produces "8:25 a.m."
If an invalid time is entered, returns the
null string.

=end comment

=cut

sub military_to_civilian
{
    # your code goes here
}

=begin comment

The "civilian_to_military" subroutine takes a civilian time
string as its input and returns a string giving
the corresponding military time.

Example: input of "8:25PM" produces "2025"
If an invalid time is entered, returns the
null string.

=end comment

=cut

sub civilian_to_military
{
    # your code goes here
}


=begin comment

Returns a list giving the total number of hours and minutes
between two times. The times may be in either military or
civilian format. If improper data is entered, returns -1
for hours and minutes.  The times may be in any order;
the subroutine will put the earlier time first.

Examples:
   duration( "1015", "12:45p.m." )

returns the list (2, 30) because it is two and a half
hours from 10:15 a.m. to 12:45 p.m.

   duration( "2:40 PM", "1:00 p.m." )

returns the list (1, 40).

=end comment

=cut

sub duration
{
    # your code goes here
}


#
#   Add any extra code that you need below this line

Part Two

Modify the following program to work with the module you wrote in part one. You will need to qualify certain names so that the program works properly. Save the program in a file named lastname_firstname_moduletest.pl

#!/usr/bin/perl

#
#   Written by YOUR NAME HERE
#
#   Test program for module.
#   This program uses arrays of input to each of
#   the module subroutines to check that it works
#   as it is supposed to.
#
my $mil_time;
my $civ_time;

my @mil_test = (
    "0000", "1200", "2359", "0715", # valid data
    "2400", "2360", "abcd", "315"   # should return null string
);

my @civ_test = (
    "3:00 p.m.", "12:00 a.m.", "12:00PM", # valid data
    "7:15p",  "7:15A", "08:35pM.",        # valid data
    "15:13p", "11:62 a.m.", "9:25"        # should return null string
);

my @duration_test = (
    "0200", "4:00A",        # should return (2, 0)
    "1315", "0900",         # should return (4, 15)
    "12:45p.m.", "1620",    # should return (3, 35)
    "2460", "15:00"         # should return (-1, -1)
);

my $i;
my ($start_time, $end_time, $n_hrs, $n_min);

print "Test conversion to civilian time\n";
foreach $mil_time (@mil_test)
{
    $civ_time = military_to_civilian($mil_time);
    print "$mil_time is the equivalent of |$civ_time|\n";
}

print "\nTest conversion to military time\n";

foreach $civ_time (@civ_test)
{
    $mil_time = civilian_to_military($civ_time);
    print "$civ_time is the equivalent of |$mil_time|\n";
}

print "\nTest duration\n";

for ($i=0; $i < scalar @duration_test; $i+=2)
{
    $start_time = $duration_test[$i];
    $end_time = $duration_test[$i+1];

    ($n_hrs, $n_min) = duration( $start_time, $end_time );
    print "From $start_time to $end_time is $n_hrs h $n_min m\n";
}

Hints

Use regular expressions to parse the civilian time. You may want to treat the military time as an integer for purposes of calculation, but you can use a regular expression to check that it has four digits.

To format a number as two digits with a leading zero:

$n = 5;
$str = sprintf("%02d", $n); # $str now contains "05"

You may want to write two more subroutines to make your life easier:

sub military_to_minutes

Accepts a military time string and returns the number of minutes after midnight. Thus,

   $minutes = military_to_minutes("1015");

will put 615 (10 * 60 + 15) into $minutes. Invalid times will return -1 for the number of minutes.

sub civilian_to_minutes

Accepts a civilian time string and returns the number of minutes after midnight. Thus,

   $minutes = civilian_to_minutes("1:45 PM");

will put 825 (13 * 60  + 45) into $minutes. Invalid times will return -1 for the number of minutes.

I have already written these functions; if you can’t figure out how to do it and need the code, here it is.

When You Finish

Upload the module and test program.