Introduction to Programming (CPSC 124)
—Hobart & William Smith Colleges, Fall 2014
Thursday Lab #3
Home | Syllabus | Calendar | Class Notes | Labs and Projects | General Notes

Due by 2:59 pm on Friday, 09/19/2014)

Overview

There are two goals for this lab. One is to learn the behavior of while, Java's principal construct for expressing iteration, i.e. "loops". The other is to make you conversant with two new techniques: scaffolding and learning by experimentation

Study

The while construct

The basic form of a while loop is very similar to an if statement. In fact, it's identical, except that you replace the keyword if with the keyword while:

while (  < test > ) {
    < body >
}

Like conditional blocks, the < test > is any expression that evaluates to a boolean value. The < body > inside the curly braces is any legal block of statements (including assignments, if statements, and even other while loops).

A loop behaves as follows

  1. The expression in < test > is evaluated.
  2. If the < test > evaluates to true, the block of statements making up the < body > run. Then we go back to step 1, and test again.
  3. If the < test > evaluates to false, the < body > is skipped, and the first statement after the closing } is run.

Example, with scaffolding

The following program gives a working example of a loop. It has a number of print and println statements in it. Of these, only the last one in the program truly belongs. The ones whose output begins with "[DEBUG]" are there to show the behavior of the program as it runs. This technique of instrumenting code with statements that print out important values as the program runs is known as scaffolding. It is a common technique to aid in comprehension of a program.


public class Compound {
   public static void main(String[] args) {
  
      double principal = Double.parseDouble(args[0]);  
      // The value of the investment.
      double rate = Double.parseDouble(args[1]);       
      // The annual interest rate.      
      int years = 5; 
      // Number of years to maturity of the investment

      System.out.println("[DEBUG] Initial principal: " + principal);
  
      int i = 0;
      while (i < years) {
         double interest = principal * rate;
         principal = principal + interest;   
         i = i + 1;   
         System.out.println("[DEBUG] After year " + i + ": " + principal);
      } 
       
      System.out.println("Value after " + years + " years is $" + principal);
   } // end of main()      
} // end of class Compound

Your Job

  1. On a blank sheet of paper, write down the sequence of statements that you think the Compound program will print when it is run with the arguments 1000 and 0.05:

    John-Lasseter:~ jlasseter$ java Compound 1000 0.05
    
    

    It is important that you do this before you actually run the program! The whole point of this step is that you are making an initial analysis of the program by hand, and you'll need to have a record of that to check against the observed behavior.

  2. Run the program, and write down the observed results alongside your earlier analysis. Do they agree? If not, what part of your understanding of the behavior of while needed adjustment? Discuss this in a sentence or two.

    Again, the point is not to "get the right answer" here. That's boring and not very useful. It's far more important to use the comparison of predicted and observed results to solidify your understanding of this new construct.

  3. Now try a version of the program without the statement "i = i + 1" (you can just put a "//" at the beginning of that line). Write down what you think the program will print now, when run with the same arguments as in Problem 1. Then run it with these arguments (ADVICE: hitting the CTRL and c keys together (written "^c") will kill a program's execution).

    How does the observed result compare with what you expected? What do you conclude about the behavior of while from this?

  4. Put the "i = i + 1" statement back in, but change it to "i = i + 2". As before, write down what you predict will happen when the program is run (same arguments). Then run it, and write that down, too. Again, what do you conclude about while from this?

  5. Suppose we also want to know the amount of interest that was added in the final year. We can try to do this by adding the following line, immediately after the while loop's closing }:

  6. System.out.println(interest);

    Make this change. What happens when you try to compile the program? The underlying issue here is a rule concerning a variable's scope, i.e. the rules determining where a variable is visible in the program. What do you conclude the rules for scope?

  7. Here's yet another program with a loop:

  8. public class Collatz {
        public static void main(String[] args) {
            int n = Integer.parseInt(args[0]);
            
            while (n != 1) {
              if (n % 2 == 0) {  // i.e. if n is even
                n = n / 2;      
                // remember that int division truncates the fractional component
              } else {
                n = 3 * n + 1;
              }
            }
            
            System.out.println("Done.");
        }
    }

    This program implements a famous open problem in mathematics, known as the Collatz Conjecture. That conjecture states that the program above will reach the last "Done" print statement for all possible integers greater than 0. It is not known whether this is true.

    Your job is to consider the behavior of this program when it is run with each of the following values: 1, 3, 5, 6, and 17. As written, the program will only print "Done" on each of these values.

    The question for this problem is in two parts. First, for each of these values, how many times will the loop run? Second, for each of these input values, what are the values of n on each iteration of the loop? You will need to add appropriate scaffolding code to observe this.

Turn In


John H. E. Lasseter