CMSC 201
Programming Project One
Manipulating Dates
v2.0
Out: Wednesday 23 February
2005
Due: Before Midnight, Tuesday 8 March 2005
Engineering Change Notices
An engineering change notice (ECN) describes changes to the
design of an engineeringed object made after the original design is
released.
- ECN1 - The PrintInterval function now takes
two dates.
The Objective
The objective of this assignment is to get you started writing programs
in C in the UNIX environment. Its main emphasis is design, so we will
be designing the project together in class. This project will also give
you practice writing functions, loops, switch statements and using separate
compilation.
The Background
You are just beginning to learn to program in C and you want to challenge
yourself by writing a large enough program to test your design skills
and to give you practice with separate compilation. You decide to write
a program that you can release as public domain software (give away
to others). It should be something that is a little bit useful and maybe
even a little bit fun ... something to do with dates and calendars.
It would be useful to have a kind of perpetual calendar -- one that
you can use to do things like the following:
- find out the day of week for any particular date in the past or
the future (so you can find out what kind
of person you are based on the day of the week on which you were
born);
- Print a calendar for any given month or year, past or future;
- Compute the number of days between any two dates (e.g., how long
till the singularity?)
We are all familiar with the basic concepts involved -- days, months,
years -- but some of the details are messy and can be blamed on the
orbits of the Sun and the Moon and how our ancient ancestors tried to
make sense of it all. The months differ in their lengths and so do the
years (leap years having 366 and regular years 365 days). A date's "day
of the week" name depends on a seven day cycle rooted in ancient
religions. But, it turns out that the details are not too complex and
it's pretty easy to support the simple functions above, with some limitations.
Calendars have
gone through many reforms. The one used in the "West" and
for most of the world, at least for business, was last
reformed in 1752 So, if we restrict ourselves to dates after Sunday,
December 31, 1752, we will only have one set of rules to work with.
If you are interested in the techniques for representing dates going
back to Monday, January 1, 4713 BC, check out the Julian
day concept.
The Task
Design (to be done in class) and code a project that after printing
a greeting to the user, presents the user with a menu and allows her
to choose any of six different options, including quit. After
performing the option, the user should be presented with the menu again,
so that she can continue to make choices.
The Design
Since you are distributing this software to others, you must use separate
compilation and provide the interface for the user. This is in the form
of a well commented header (.h) file. You must have three files. The
file that contains main( ) MUST be called proj1.c;
the file containing the function definitions MUST be called dates.c
and the header file MUST be called dates.h.
You are required to use a switch statement to handle the menu
requests. There are also other places where the switch statement is
the appropriate choice too.
You must adhere to the design given in class. The function prototypes
given in the design document must be used and may NOT be altered in
anyway
Here is the design document you must follow.
It defines the functions you should implement and gives their prototypes.
It also shows the constants your program should use. In future projects,
we will ask you to develop you own design and submit that as the first
part of your project. After that you will implement the design, debug
the result and submit that. But, for this first assignment, you must
use the design we provide. That means you have to implement the functions
as we have specified and use the defined constants we have given you.
Notes and suggestions
Here are some notes on some of the functions that will be in your program.
The Anchor date. Your program will only work for dates after
December 31, 1752, which we will call the anchor date. This
date is specified using the constants ANCHOR_DAY, ANCHOR_MONTH and ANCHOR_YEAR.
In addition, we know that this date was a Sunday, so define the constant
ANCHOR_DAY_OF_WEEK as 0. A key property of any date is the number of
days since the anchor. Knowing this, we can easily compute the day of
week of a date or the interval between any two dates.
DaysSinceAnchor(day,month,year) returns the number
of days since the anchor. This can be computed as the number of days
in each year between the anchor year and year (exclusive) plus the"day
number" of the given date, as computed by DayNumber(day, month,
year).
DayNumber(day,month,year) returns the number of the
given day in the year. e.g., 1/1/2005 is 1 and 12/31/2005 is 365. It's
pretty easy to compute.
DaysInYear(year) returns the number of days in the
given year and is even easier to compute if you know whether or not
the year is a leap year.
IsLeapYear(year) returns true (1) if the year is a
leap year and false (0) otherwise. You must handle leap years properly
and according to the usual rule: "A year is a leap year if it is evenly
divisible by 4 but not also evenly divisible by 100, however a year
is also a leap year if it is evenly divisible by 400." Thus 2000 is
was a leap year as is 2004. 2005 is not a leap year, nor will 2100 be
one.
DaysInMonth(month,year) returns the number of days
in the given month and year. A piece of cake.
DaysBetween(d1,m1,y1,d2,m2,y2) returns the number
of days between the two dates as a positive number. You can do this
easily with two calls to DaysSinceAnchor and some math. You will find
the abs function in the stdlib library useful -- see
man abs.
DayOfWeek(day,month,year) returns an integer representing
the date's day of week (e.g., 0 for Sunday, 6 for Saturday). Since we
know the day of the week of the anchor, we can easily compute this by
finding the days since the anchor and taking this modulo seven and adding
the anchor's day of week.
PrintMonth(month, year) takes a month and year and
prints a minimal calendar for that month. For example, PrintMonth(2,2005)
should print something like this:
February 2005
SU MO TU WE TH FR SA
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28
Here are some suggestions: The first two lines should be easy to figure
out. The calendar block has seven "logical" columns, each of which is
three spaces wide. Print each day's number using "%3d" so it's printed
using three "spaces". Before you begin printing the dates, you will have
to figure out how many of the "logical" columns to "skip". That is, if
we know we want to start printing on a Tuesday (day=2 corresponding to
the third logical column), we'll have to print two set of three spaces
to skip over the first two logical columns. Now we're ready to start printing
the numbers for the days in the month. How many are there? Use the DaysInMonth
function to find out. To print them all, just loop from 1 to the number
of days and print them using %3d. Each time you print a number, increment
a separate counter to keep track of which logical column you have printed.
When you've printed the day in the seventh logical column, then print
a newline. That's it.
PrintYear(year) is easy once you have PrintMonth.
Can you spell f-o-r?
PrintInterval(d1,m1,y1,d2,m2,y2) computes the number
of days between the two dates and prints its absolute value.
Managing complexity
Computer programs, even relatively simple ones like Project One, are
complicated artifacts and managing the complexity of designing, implementing
and debugging them is probably the biggest reason why programming is
hard. Our field has developed many techniques and tools to help you
manage the complexity. One of the simplest techniques, and one you can
use now, is the use of stubs. A stub is a "dummy definition"
for a function that allows you to write, test and debug the rest of
the program before you get to the task of developing the stubbed function.
For example, for Project One, you might put off the subtask of writing
DaysSinceAnchor by using the following stub definition:
/* STUB! RETURNS 3 */
int DaysSinceAnchor (int day, int month, int year) {
return 3;
}
A slightly better stub might be one that returns a random integer between
one and 10,000, which will better 'exercise' your code in other functions
that need to know the day of week (e.g., PrintDate, PrintMonth). To use
this version, you would have to add #include <stdlib.h>
to your dates.c file, of course.
/* STUB STILL, BUT BETTER: RETURNS RANDOM NUMBER BETWEEN 1 AND 10K */
int DaysSinceAnchor (int day, int month, int year) {
return (rand() % 10000) + 1;
}
Coding standards
You must follow the CMSC201 coding standards, see the 201
projects page for details and a description of how we will evaluate
and grade your work.
Sample Run
We've provided you with a sample run
demonstrating how our model solution
works. Although your output need not be identical to the above, all
information (including the greeting) must be present. This is definitely
NOT a complete test of the program. Your testing should be much
more extensive. You may run the sample executable found at
/afs/umbc.edu/users/s/b/sbogar1/pub/
It's called p1a.out
We'll give your program a good workout to see if it is appropriately
robust and works for all reasonable inputs.
Submitting the Program
- You are to use separate compilation for this project, so you will
be submitting three files, proj1.c, dates.c and dates.h
- Your C source code file that contains main( ) MUST be called
proj1.c.
- The file which contains the function definitions MUST be
called dates.c and the header file MUST be called dates.h
- To submit your project, type the following at the Unix prompt.
Note that the project name starts with uppercase 'P'.
submit cs201 Proj1 proj1.c dates.c
dates.h
- To verify that your project was submitted, you can execute the following
command at the Unix prompt. It will show all files that you submitted
in a format similar to the Unix 'ls' command.
submitls cs201 Proj1
- The files must be submitted before Midnight at
the end of Tuesday 8 March 2005.
|