Print a Calendar

From CompSciWiki
Revision as of 10:42, 8 April 2010 by EdwinA (Talk | contribs)

Jump to: navigation, search

{{1010PrAD|ProblemName=Text Based Calendar

|Problem=How do we use two loops to print out a calendar month?

|SideSectionTitle=By Students |SideSection= I don't like Calendars. But I really like writing code! This question was a happy medium.

That said, nested loops are ideal for going over multiple groups of items. If your dealing with items in a grid, individual servers in multiple cities, or how many blueberries there are in everyone's ice cream cone, you'll need nested loops.

|Solution=We'll start this one easy. Make a function that takes two parameters: One that says what day of the week the first day of the month is, the other how many days are in the particular month. Your start code should look like:

class CalendarPrinter
{
	public static void main(String args[])
	{
		System.out.print("January 2010:\n\n");
		printMonth(6, 31);
	}

	function printMonth(int firstDay, int numDays)
	{

	}
}

Next your goal is to print a 7 column by 6 row grid to System.out with two loops. your output should look something like the following:

0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

That's the meat of this application. I used to have huge problems printing boxes in the correct dimensions. Just remember that the inner loop does its thing before the outer loop does, so if we were drawing a picture from left to right, the outer loop would control what row we were drawing, and the inner loop would deal with actually drawing the row.

Now, the next step is to have a counter so our zeros are actually incrementing numbers. Just declare a counter and increment that puppy in the right spot. You'll figure out where to do the incrementing yourself I imagine.

Now the tricky part is when do you start printing numbers? That's where our firstDay variable in our function prototype comes in. Just print a blank space if your current number is less than firstDay. Your output now should look like this:

0 0 0 0 0 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

Now, January 2010 didn't start at day six, but we need to keep track of what cell we're on. We could have a second counter, but I'm more of an offset man myself, so I would just subtract firstDay + 1.

So what's left? If you run your code, you'll see we keep counting far past the 31st. You deal with that problem by introducing new tests into one of your loops. You might know that the inner part of your 'for' statement is a Boolean logic test.

// Run while loop is less than 10
for (int loop = 0; loop < 10; loop++)

// Run while loop is less than 10 and more than b
for (int loop = 0; loop < 10 && loop > b; a++)

So you really just have to know when to stop printing days. I'll let you figure that out. After that jazz is done, so are you! You just printed the calendar month for January 2010.

Now, you're probably going to hate my solution code to this. There's tonnes in there for output formatting that makes it convoluted and confusing. Those extras were not the point of this question. What I wanted from you is to have seven numbers drawn per line except the first and last weeks which might have less.

|SolutionCode=
// Print a month starting on a friday with 31 days.
// Put this in a file called CalendarPrinter.java
import javax.swing.JOptionPane;

class CalendarPrinter
{
	public static void main(String args[])
	{
		String strOutput = printMonth(6, 31);

		System.out.println("January 2010:\n");
		System.out.println(strOutput);

		JOptionPane.showMessageDialog(null, strOutput);
	}

	static String printMonth(int firstDay, int numDays)
	{
		int currentCell = 0;    // What cell number are we in.
		int weekNum;            // What week number of the month
		int dayNum;             // What day of the week are we in

		int dayOutput = 0;      // What number to print in the cell

		String strOutput = "";	// Holds our final message

		for (weekNum = 0; weekNum < 6; weekNum++)
		{
			// Loop until we're at sunday OR we don't need to print more days
			for (dayNum = 0; dayNum < 7 && dayOutput + 1 <= numDays; dayNum++)
			{
				currentCell++;                                  // We're working on a new cell
				if (currentCell >= firstDay)                    // Can we start showing days yet?
				{
					dayOutput = currentCell - firstDay + 1; // What day of the month to show
					if (dayOutput < 10)			// If the number is under ten, we need
					{					// to pad our number with a space
						strOutput += " ";
					}

					strOutput += " " + dayOutput;		// Space between numbers
				}
				else
				{
					strOutput += "   ";           	        // Output a blank cell
				}
			}

			strOutput += "\n";					// Done drawing a week, start a new line
		}

		return strOutput;
	}
}