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

Due by 2:59 pm on Friday the 13th, 2015

Overview

There are two goals for this lab. One is to learn the behavior of the if and while constructs, which represent the most important forms of control: conditional execution ("branches") and iteration ("loops"). The other is to make you conversant with two new techniques: scaffolding and learning by experimentation

Study

The if and if/else constructs

The if and if/else constructs allows us to specify actions that only happen if a certain condition is met. The basic form is

if (  < test > ) {
    < body >
}

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). If the < test > evaluates to true, then the code in the < body > executes. Otherwise, it is skipped.

A more powerful and useful variant is the if/else statement:

if (  < test > ) {
    < body1 >
} else {
    < body2 >
}
< rest of the program >

Again, the first thing that happens here is evaluation of the < test >. If the < test > evaluates to true, then the code in the < body1 > executes, followed by the < rest of the program > (< body2 > is skipped). Otherwise, we execute the < body2 > code, followed by the < rest of the program >.

Example

The following variation on our windchill calculator performs an initial check on the arguments to make sure that they are within the range of acceptable values for calculating a valid windchill. If they are not, an error message is displayed:

public class Windchill2 {
    public static void main(String[] args) {
        double temp = Double.parseDouble(args[0]);
        double wind = Double.parseDouble(args[1]);
        
        boolean validTemp = temp < 50;
        boolean validWindspeed = wind > 3.0;
        
        if (validTemp && validWindspeed) {
            double v2 = Math.pow(wind,0.16);
            double windchill = 35.74 + 0.6215*temp 
                + (0.4275 * temp  - 35.75) * v2;
            
            System.out.println("Windchill: "  + windchill);
        } else {
            System.out.println("Windchill is not defined for this input:");
            if (!validTemp) {
                System.out.println("The temperature is too high.");
            }
            
            if (!validWindspeed) {
                System.out.println("The wind speed is too low.");
            }
            System.out.println("Sorry.");
        } // else
        
        System.out.println("Goodbye.");
    } //main
}

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. Modify your Weekday.java program from Lab#2, so that it prints the name of a date's weekday, rather than just a number between 0 and 6.

    John-Lasseter:~ jlasseter$ java Weekday 2015 2 12
    Thursday
    John-Lasseter:~ jlasseter$ java Weekday 2012 2 29
    Wednesday
  2. Write a program, Max.java, which take three numbers as command line arguments. The program should print the largest of the three values.

    John-Lasseter:~ jlasseter$ java Max 34 1.7 56.9
    56.9
    John-Lasseter:~ jlasseter$ java Max 3.4 17 5.69
    17.0
  3. Study this program, but don't build/run it just yet:

    
    public class F {
       public static void main(String[] args) {
          int n = Integer.parseInt(args[0]);  
          int nF = 1;     
          int i = 0;
          
          System.out.printf("[INIT] Initial values: n == %d and nF == %d\n",n,nF);
    
          while (i < n) {
             nF = (n-i) * nF;  
             i = i + 1;   
             System.out.printf("[LOOP] i == %d, n == %d, nF == %d\n", i, n, nF);
          } 
           
          System.out.printf("[FINISH]  i == %d, n == %d, nF == %d\n", i, n, nF);
       } // end of main()      
    } 
    
    

    On a blank sheet of paper, write down the sequence of statements that you think the program will print when it is run with the arguments 4 and 6

    John-Lasseter:~ jlasseter$ java F 4
    John-Lasseter:~ jlasseter$ java F 6
    

    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.

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

  5. 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?

  6. 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?

  7. Now consider this program:

    
    public class Drawing {
        public static void main(String[] args) {
            int width = Integer.parseInt(args[0]);
            
            int i = 0;
            while (i < width) {
                int j = 0;
                while (j < (i + 1)) {
                    System.out.print(" *");  // no line break
                    j = j + 1;
                } // while
                System.out.println();  // includes line break
                i = i + 1;
            } // while
        } // main
    } // class Drawing
    
    
  8. Again, write down what you think will be printed (without running the program) on arguments of 4, 5, and 6. Then run it. Was there a difference between predicted and observed results? If so, why?

  9. Modify Drawing.java so that it prints its result "upside down".

Expectations

For the written hypothesis/observation problems, it's pretty easy to "cheat" on them by just running the programs, writing down what you see, and pretending that this is what you predicted. I have no way to enforce against this, but know if you take this route, the exercise is totally pointless. You'll get out of it what you put in.

As with all programming problems, the source code for Weekday.java, Max.java, and Drawing.java must be free of compile-time errors. If not, there is no credit for that part of the assignment. On the other hand, partial credit is alway awarded for partially-correct solutions (so long as they are legal programs).

Turn In


John H. E. Lasseter