The George Washington University
School of Engineering and Applied Science
Department of Electrical Engineering and Computer Science
CSci 51 -- Spring 2000
Project #5
Due Date: start of class, April 4, 2000

This project depends upon Chapters 1-7, and provides experience with writing procedures, writing and modifying packages, exception handling, and robust input.

Part I

The function DayWeek.DayOfWeek computes a meaningless result if its three inputs do not form a valid date. Even if the month, day, and year are all in the proper ranges, the combination could result in February 29, 1999 (a non-leap year) or November 31, 2000 (November has only 30 days), etc. In this part of the project, you will add an exception to the DayWeek specification, and raise it in the body of DayWeek.DayOfWeek. In the spec, declare

Date_Error: EXCEPTION;

and in the function body, before you proceed to compute the day of the week, add some tests to determine whether the date is valid. For example, you could write

CASE Month IS
  WHEN 4 | 6 | 9 | 11 =>
    IF Day = 31 THEN
      RAISE Date_Error;
    END IF;
  WHEN 2 =>
    -- check for leap year, etc.
    ...
END CASE;

Test this modified function, perhaps using your Project 3 program as a starting point.

Part II

Now add a child package DayWeek.IO to the package DayWeek. (See Section 7.10 for an example of writing a child package.) This package will have the following specification:
WITH Ada.Calendar;
PACKAGE DayWeek.IO IS
 
  TYPE Months IS (Jan, Feb, Mar, Apr, May, Jun,
                  Jul, Aug, Sep, Oct, Nov, Dec);
 
  PROCEDURE Get (MonthName: OUT Months; 
                 Day: OUT Ada.Calendar.Day_Number; 
                 Year: OUT Ada.Calendar.Year_Number);
  -- Pre:  None
  -- Post: The 3 values MonthName, Day, Year represent a valid date
 
END DayWeek.IO;
In the body of this package, the procedure Get will read a date robustly,that is, The procedure will read the components robustly as follows: To check the validity of the overall date, you can use the work from Part I. Declare a variable in your new Get procedure:

DayCode: DaysOfWeek;

then call DayWeek.DayOfWeek with the 3 parameters received by Get from the user.

DayCode :=
  DayWeek.DayOfWeek(Month => Month, Day => Day, Year => Year);
The function call will either return a value to DayCode, or raise the exception Date_Error. So now you can put an exception loop in the body of Get whose handler looks like
EXCEPTION
  WHEN DayWeek.Date_Error =>
    -- write message to user
You can use a modification of your program from Project 3 to test this child package. Since the month abbreviations are now declared in the package, you will need to remove the declaration from your Project 3 program. Also, instead of reading the month, day, and year directly in this program, just call DayWeek.IO.Get.