In the previous laboratory session, we
developed a number of methods for the `SimpleDate`

class,
progressing from simple methods to more advanced methods. In this
laboratory, we will continue with our exploration of the
`SimpleDate`

class. We will begin by looking at a
`dayOfYear`

method which determines which day of the year it
is. From that method, we will develop a `daysUntil`

method
that determines the number of days until a particular date. Using that
method, in the experiments you will develop a `dayOfWeek`

method that determines the day of the week a date falls on.

How do we determine what day of the year a particular date is? We can determine the number of days between the first day of the year and the first day of the month, and then add which day of the month it is. For example, consider February 3. The zeroth day of February is 31 days from the beginning of the year. February 3 comes three days later, so February 3 is 34 days from the beginning of the year.

Unfortunately, the computation for later months is not so easy. For example, how many days is August 1 from the beginning of the year? It may be possible to precompute all of those numbers, as in

/** * Compute the position of this day within the current year. */publicintdayOfYear() {intto_start_of_month;switch(this.month) {case1:to_start_of_month = 0;// Januarybreak;case2:to_start_of_month = 31;// Februarybreak;case3:to_start_of_month = 59;// March// We'll deal with leap years later in this function.break; ... } // switch(this.month)// Handle leap yearsif(this.isLeapYear() &&this.month > 2) { to_start_of_month = to_start_of_month + 1; } // After February in a leap year// Add the days in this monthreturnto_start_of_month +this.day; } // dayOfYear()

However, the work precomputing the position of the beginning of each
month from the beginning of the year is painful and prone to simple
errors in calculation if done by hand. Hence, we'd prefer to have the
computer do such computation. How do we compute the number of days
until the first of month `m`

? We sum the number of days in
each of the previous months. Algorithmically, we might write

// Compute the number of days until the start of month m daysUntilStartOfMonth(m) sum the number of days in each month, p, that precedes m if it's a leap year and after February, add 1 return the result

The `sum`

command in that algorithm is vague and is not
included in most programming languages. Hence, we must expand it to
work out the details. How do we compute the sum? By explicitly adding
the days in each prior month.

// Compute the number of days until the start of month m daysUntilStartOfMonth(m) days = 0 for each month, p, that precedes m add the number of days in month p to days end for if it's a leap year and after February, add 1 to days return days

The ``for each month'' is also vague. It may be better to make it explicit by using a counter.

// Compute the number of days until the start of month m daysUntilStartOfMonth(m) days = 0 p = 1 while p < m add the number of days in month p to days add 1 to p end for if it's a leap year and after February, add 1 to days return days

Rewriting this in Java-like syntax, we get

//*** Compute the number of days until the start of the month. */publicintdaysUntilStartOfMonth(intm) {intprev = 1;// A previous monthintdays = 0;// Total number of days// Sum the days in the previous months. We assume that the//`daysInMonth`

method handles leap years // correctly. while (prev < m) { days = days + this.daysInMonth(prev); prev = prev + 1; } // while // And that's it. return days; } // daysUntilStartOfMonth(int)

In fact, this is legal Java. Java provides a

statement with the following
form.
__while__

while(test) {body} // while

The test is executed. If it fails, the while loop terminates and control passes to the subsequent statement. If the test holds, then the statements in the body are executed. After the body is executed, the test is done again. The test and body are repeatedly executed until the test no longer holds.

Note that the test is done once per repetition, which means that the test need hold only at the beginning of the body. If, during the body, the test would no longer hold, execution of the body still continues until the end.

In Experiment J5.1 you will experiment with some basic looping examples.

Wait! Something seems wrong with the code above. It
uses a `daysInMonth(`

method, and you
may recall that we designed __int__)`daysInMonth`

to take no
parameters. What do we do? Once again, this is an instance of
*overloading* method names: providing multiple methods with
the same name, but different types of parameters.

Using overloading, we might extend our old `SimpleDate`

class with the new, parameterized `daysInMonth`

. We can
also have the old `daysInMonth`

use the new one, as in

/** * Compute the number of days in the current month. */publicintdaysInMonth() {returnthis.daysInMonth(this.month); } daysInMonth()/** * Compute the number of days in month m. */publicintdaysInMonth(intm) {switch(m) {case1:case3: ...return31;break;case2:if(this.isLeapYear()) {return29; } // February in a leap yearelse{return28; } // February, but not a leap yearbreak; ... } // switch } // daysInMonth(int)

In Experiment J5.2 you will consider how to use loops to count days in the year.

__for__

loops
Is the

loop the only looping
mechanism that Java provides? No. Because so many algorithms naturally
include a section that reads __while__*for every value of n between
a and b do ...* that Java includes a

__for__

control structure to make it more convenient to
express such algorithms.
The

loop has the following form
__for__

for(initialization;test;increment) {body} // for

In effect, this is a shorthand for the following

loop.
__while__

initialization;while(test) {body;increment; } // while

That is, a

loop begins by executing
the initialization portion. Traditionally, this sets the initial
value for a counter variable. Next, it executes the test. If
the test fails, the loop terminates and control moves on to the next
statement. If the test succeeds, the body is executed. After
the body is done, the increment is executed. The test
is done again, and the cyclic process continues.
__for__

For example, we might rewrite our `daysUntilStartOfMonth`

method as

//*** Compute the number of days until the start of the month. */publicintdaysUntilStartOfMonth(intm) {intprev = 1;// A previous monthintdays = 0;// Total number of days// Sum the days in the previous monthsfor(prev = 1; prev < m; prev = prev + 1) { days = days +this.daysInMonth(prev); } // for// Deal with leap yearsif(this.isLeapYear() && m > 2) { days = days + 1; } // After February in a leap year// And that's it.returndays; } // daysUntilStartOfMonth(int)

In Experiment J5.3
you will consider some simple examples of

loops.
__for__

As you read other people's Java code (or C code or C++ code or ...),
you will find many *shorthand* expressions for common
arithmetic expressions. For example, it is so typical to add one to
a variable that Java includes a `++`

operator that does
just that. In particular,

++i;

is the same as

i = i + 1;

Hence, you will often see

loops
that look like
__for__

for(i = 0; i < n; ++i)

The prefix `++`

(also called *preincrement*) differs
from the longer form in that it can be more easily used as part of
larger expressions. For example,

j = ++i + 3;

represents ``Add 1 to `i`

. Add 3 to the
updated `i`

, and store the result in `j`

.''

There is also a postfix `++`

(also called *postincrement*)
that adds 1 to the argument, but returns the old value. For example,

j = i++ + 3;

represents ``Add 1 to `i`

; add 3 to the
old value of `i`

; store the result in `j`

''.

As you might guess, there are also prefix and postfix `--`

operators (predecrement and postdecrement), with the intended meaning of
decrementing the corresponding variable.

Finally, Java also provides a `+=`

assignment which
has the affect of adding the right-hand-side to the left-hand-side.
For example,

k += 5;

represents ``Add 5 to `k`

''.

In Experiment J5.4 you will consider Java's various arithmetic shorthands.

*This section is optional and is intended for classes emphasizing
applets or pursuing a simultaneous discussion of applications and
applets.*

Loops have many applications for applets, particularly with regards to
drawing regular and repetitious figures, such as sequences of images.
In Experiment J5.5, you will use

loops to create a rainbow text effect.
In Experiment J5.6, you will track down
errors in an applet designed to draw a regular grid using a
__for__

loop.
__for__

In Experiment J5.7, you will attempt a more complicated task: showing the positions of a bouncing ball. In order to make the ball bounce, you need to be able to determine the area available to the applet.

You may have noted that the dimensions (width and height) of the area reserved for an applet are set within the HTML files that loads the applet and not within the applet itself. Clearly, it is possible to load the same applet with different dimensions and different pages may therefore choose different dimensions for the same applet. For many applets, it becomes important for the applet designer to be able to determine these dimensions. This is particularly true of our bouncing ball applet, in which the ball must change direction

Fortunately, Java provides a mechanism for the applet author to determine
the dimensions given for the applet. You can call

to obtain a __this__.getSize()`java.awt.Dimension`

object.
You can then get the width of that object by referring to its
`width`

and `height`

fields.

For example, you might write the following to set the right and bottom edges of the area allocated to the applet. Note that since the area begins at (0,0), the width of the applet gives the horizontal offset of the right edge, and the height of the applet gives the vertical offset of the bottom edge.

intright;// The right edge of the area allocated to the applet.intbottom;// The bottom edge of the area allocated to the applet.Dimension dim =this.getSize(); right = dim.width; bottom = dim.height;

Now, how do you make the ball bounce? We'll explore that issue in Experiment J5.7.

[Front Door] [Introduction] [Code]

Copyright (c) 1998 Samuel A. Rebelsky. All rights reserved.

Source text last modified Mon Oct 25 16:21:05 1999.

This page generated on Tue Oct 26 15:38:16 1999 by Siteweaver.

Contact our webmaster at rebelsky@math.grin.edu