# Session J5: Control Structures for Repetition

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.

### Repetition

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.
*/
public int dayOfYear() {
int to_start_of_month;
switch (this.month) {
case 1:  // January
to_start_of_month = 0;
break;
case 2:  // February
to_start_of_month = 31;
break;
case 3:  // March
to_start_of_month = 59; // We'll deal with leap years later in this function.
break;
...
} // switch(this.month)
// Handle leap years
if (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 month
} // 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
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.
*/
public int daysUntilStartOfMonth(int m) {
int prev = 1; // A previous month
int days = 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)
```

### While loops

In fact, this is legal Java. Java provides a `while` statement with the following form.

```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(int)` method, and you may recall that we designed `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.
*/
public int daysInMonth() {
return this.daysInMonth(this.month);
} daysInMonth()

/**
* Compute the number of days in month m.
*/
public int daysInMonth(int m) {
switch (m) {
case 1:
case 3:
...
return 31;
break;
case 2:
if (this.isLeapYear()) {
return 29;
} // February in a leap year
else {
return 28;
} // February, but not a leap year
break;
...
} // switch
} // daysInMonth(int)
```

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

### `for` loops

Is the `while` loop the only looping mechanism that Java provides? No. Because so many algorithms naturally include a section that reads 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 `for` loop has the following form

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

In effect, this is a shorthand for the following `while` loop.

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

That is, a `for` 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 example, we might rewrite our `daysUntilStartOfMonth` method as

```  //**
* Compute the number of days until the start of the month.
*/
public int daysUntilStartOfMonth(int m) {
int prev = 1; // A previous month
int days = 0; // Total number of days

// Sum the days in the previous months
for (prev = 1; prev < m; prev = prev + 1) {
days = days + this.daysInMonth(prev);
} // for

// Deal with leap years
if (this.isLeapYear() && m > 2) {
days = days + 1;
} // After February in a leap year

// And that's it.
return days;
} // daysUntilStartOfMonth(int)
```

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

### Detour: Arithmetic shorthand

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 `for` loops that look like

```    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.

### Loops and applets

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 `for` 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.

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 `this.getSize()` to obtain a `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.

```    int right;  // The right edge of the area allocated to the applet.
int bottom; // 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.