Milestone 1 - Due Wednesday, March 27th

Milestone 2 - Due Tuesday, April 9th

Getting Started

Start by downloading CS101_Assign04.zip, saving it in the directory H:\CS101.

Start a Cygwin Bash Shell and run the following commands:

cd h:
cd CS101
unzip CS101_Assign04.zip
cd CS101_Assign04

Using Notepad++, open the file

H:\CS101\CS101_Assign04\Calendar.cpp

You will add your code to this file.

When you are ready to compile the program, in the Cygwin window type the command

make

To run the program, type the command

./Calendar.exe

Milestone 1

The program should prompt the user to enter the month and year as integers. It should then print out

  1. How many days the specified month has, and
  2. What day of the week the first day of the specified month falls on

Example run (user input in bold):

Enter month and year: 3 2012
That month has 31 days
The first day of that month is Thursday

Note that your program must ensure that the user enters a month that is valid (in the range 1..12). If an invalid month is entered, the program should prompt the user to re-enter the month and year:

Enter month and year: 13 2012
Invalid month: please enter a month value in the range 1-12
Enter month and year: 2 2012
That month has 29 days
The first day of that month is Wednesday

Required functions

Your program must contain the following functions:

bool is_leap_year(int year);
int num_days_in_month(int month, int year);
int get_julian_day(int day, int month, int year);

The is_leap_year function takes an integer year as a parameter and returns true if that year is a leap year, false if it is not a leap year.

The num_days_in_month function returns the number of days in the month given as a parameter, where 1 indicates January, 2 indicates February, etc. The year parameter specifies the year, because calculating the correct number of days for February requires knowledge of whether or not the year is a leap year.

The get_julian_day function takes integer day (1 for first day of month), month (1 for January), and year parameters, and returns the Julian Day Number of that day.

Your program must use these functions in computing the output values shown to the user.

Approach/Hints

Leap Years

A year is a leap year if either:

  • It is evenly divisble by 4 and not evenly divisible by 100, or
  • It is evenly divisible by 400

For example, 1996 and 2000 were leap years, but 1900 and 2003 were not leap years.

Number of days in month

To determine the number of days in the month:

  • January, March, May, July, August, October, and December each have 31 days
  • April, June, September, and November each have 30 days
  • February has 28 days, except in leap years, when it has 29 days

Because the number of days in February depends on whether or not the year is a leap year, your num_days_in_month function should call your is_leap_year function.

Julian Day Computation

A Julian Day Number is an integer representation of dates since January 1, 4713 BC.

Assuming that M is a month (1 for January), D is a day of the month (1 for the first day of the month), and Y is a year, then the Julian Day Number (JDN) can be computed as follows:

JDN = (1461 × (Y + 4800 + (M - 14)/12))/4 +(367 × (M - 2 - 12 × ((M - 14)/12)))/12 - (3 × ((Y + 4900 + (M - 14)/12)/100))/4 + D - 32075

[source: Wikipedia]

Note that all divisions in the formula above are integer divisions, meaning that any fraction in the quotient is discarded.

Any Julian Day Number can be taken modulo 7 in order to determine which day of the week the day falls on:

JDN % 7 == 0 Monday
JDN % 7 == 1 Tuesday
JDN % 7 == 2 Wednesday
JDN % 7 == 3 Thursday
JDN % 7 == 4 Friday
JDN % 7 == 5 Saturday
JDN % 7 == 6 Sunday

Milestone 2

Your task is to modify the program you wrote for Milestone 1 so that it uses the terminal graphics functions to display the calendar for the month.

For example, here is what the screen should look like if the user enters 10 as the month and 2011 as the year (click for full size):

Here is what the screen should look like if the user enters 2 as the month and 2000 as the year (click for full size):

Note that the small green rectangle at the lower right of these screenshots is the cursor, not part of the output.

Modifying the program

Add the following directive at the top of your program, just underneath #include <stdio.h>:

#include "Console.h"

Add the following statements at the end of your main function, just before the line return 0;:

cons_clear_screen();
draw_calendar(month, year);
cons_update();
cons_wait_for_keypress();

You will need to add a draw_calendar function (prototype and definition). This function should draw the calendar for the month entered by the user.

As in Lab 14, you can use the cons_change_color function to choose the text color, cons_move_cursor to move the cursor, and cons_printw to print text to the screen.

Requirements

Your calendar should have the following features:

  • At top, centered: name of month, year
  • Above each column, a header with the abbreviated day name (Sun, Mon, Tues, Wed, etc.)
  • The days of the month should be draw within a grid of solid horizontal and vertical lines which has exactly the right number of rows for the month being displayed
  • The grid line must be drawn using functions (that you write) that draw solid horizontal and vertical lines: see Hints below

Your output should look like the screenshots above, but does not have to match exactly.

Hints

You could use the following function prototypes for the functions which draw the solid horizontal and vertical lines of the grid:

void hline(int row, int start_col, int end_col);
void vline(int col, int start_row, int end_row);

Then you would need to make calls to these functions from your draw_calendar function.

Grading

Your grade will be determined as follows:

Milestone 1:

  • Function prototypes: 5
  • Input month/year: 5
  • Validate month input, re-prompt if invalid value is entered: 5
  • is_leap_year function: 10
  • num_days_in_month function: 15
  • get_julian_day function: 15
  • Output of number of days in chosen month: 10
  • Output of day of week of first day of chosen month: 10

Milestone 2:

  • Compute day of week of first of month (previous milestone): 5
  • Compute number of days in month (previous milestone): 5
  • Draw title (name of month, year): 10
  • Column headers with abbreviations for days of week: 15
  • Days of months regularly spaced in rows and columns: 30
    • Days are right-aligned in their columns: 5
  • Grid of horizontal and vertical lines
    • Is drawn: 5
    • Drawn with functions: 10
    • Correctly aligned with days of month: 10
    • Correct number of rows: 5

Both milestones:

Points will be deducted for programs which do not follow good coding style practices. Make sure your program is indented consistently, uses meaningful variable names, and has appropriate comments.

Submitting

To submit your work, make sure your Calendar.cpp file is saved, and in the Cygwin window type the command

make submit_ms1

or

make submit_ms2

depending on which milestone you are submitting.

Enter your Marmoset username and password (which you should have received by email.) Note that your password will not be echoed to the screen. Make sure that after you enter your username and password, you see a message indicating that the submission was successful.

Important: Make sure that you check the file(s) you submitted to ensure that they are correct. Log into the server using the following URL (also linked off the course homepage):

https://cs.ycp.edu/marmoset/

You should see a list of labs and assignments. In the row for assign04_ms1 (Milestone 1) or assign04_ms2 (Milestone 2), click the link labeled view. You will see a list of your submissions. Download the most recent one (which should be listed first). Verify that it contains the correct files.

You are responsible for making sure that your submission contains the correct file(s).