slanted W3C logo

Day 16 — More Loops

In today's lecture we look at more loop examples.

Sentinel-Based Input Review

A common 1020 problem involves repeatedly reading in values from the user until the user types in a special value (called the sentinel). Usually you will have to do something with the values the user types in. For example, suppose you need to write a program that sums all of the values a user types in until the user types in -1.

      output.println("Enter an integer pressing Enter after each: ");
      final int SENTINEL = -1;
      int sum = 0;
      for (int val = input.nextInt(); val != SENTINEL; val = input.nextInt())
      {
         sum = sum + val;
      }

What do you do if the sentinel is an object?

Sentinel-Based Input with an Object

Suppose that you want to buy Stock objects until a certain Stock is entered.

      final Stock SENTINEL = new Stock("HR.Z");
      double cashInvested = 0.0;
      for (???; ???; ???)
      {

      }

Sentinel-Based Input with an Object

The logical-expression should be true whenever we want the loop to run; the sentinel is a Stock object so we want something like:

      final Stock SENTINEL = new Stock("HR.Z");
      double cashInvested = 0.0;
      for (???; !aStock.equals(SENTINEL); ???)
      {

      }

aStock is the name of a Stock object that we want to use inside the loop.

Note the use of equals and not ==. Also note the use of the NOT operator !.

Sentinel-Based Input with an Object

It is easy to initialize a loop with a primitive type, but it is harder with objects because the object might have multiple constructor arguments. It is usually easier to initialize the object before the loop and discard the initial-expression:

      final Stock SENTINEL = new Stock("HR.Z");
      double cashInvested = 0.0;
      
      output.println("Enter the symbols of the
                      stocks you wish to purchase");
      Stock aStock = new Stock(input.next());
      
      for ( ; !aStock.equals(SENTINEL); ???)
      {

      }

Sentinel-Based Input with an Object

Inside the loop we find the price and add it to the cash invested:

      final Stock SENTINEL = new Stock("HR.Z");
      double cashInvested = 0.0;
      
      output.println("Enter the symbols of the
                      stocks you wish to purchase");
      Stock aStock = new Stock(input.next());
      
      for ( ; !aStock.equals(SENTINEL); ???)
      {
         cashInvested += aStock.getPrice();
      }

Sentinel-Based Input with an Object

There is nothing to do at the end of the loop so we can eliminate the update expression.

      final Stock SENTINEL = new Stock("HR.Z");
      double cashInvested = 0.0;
      
      output.println("Enter the symbols of the
                      stocks you wish to purchase");
      Stock aStock = new Stock(input.next());
      
      for ( ; !aStock.equals(SENTINEL); )
      {
         cashInvested += aStock.getPrice();
         aStock = new Stock(input.next());
      }

Friendly Input Validation

The sentinel idea is useful for friendly input validation. Suppose you want the user to enter only even whole numbers.

      output.print("Enter an even whole number... ");
      int num;
      for (num = input.nextInt();
           num % 2 != 0;
           num = input.nextInt())
      {
         output.println("Not even... please try again");
      }

Friendly Input Validation

Suppose you want the user to enter real numbers between 500.00 and 1000.00 (if you are searching for an apartment with a certain rent for example)

      output.print("Enter a price between 500 and 1000... ");
      double price;
      for (price = input.nextDouble();
           price < 500.0 || price > 1000.0;
           price = input.nextDouble())
      {
         output.println("Price out of range... please try again");
      }

What if you wanted to avoid the range from 500 to 1000?

Counting by 2s

Suppose you wanted to sum all of the numbers 0, 2, 4, 6, 8, ..., up to some user specified value number.

      output.print("Enter an even whole number... ");
      int num;
      for (num = input.nextInt();
           num % 2 != 0;
           num = input.nextInt())
      {
         output.println("Not even... please try again");
      }
      int sum = 0;
      for (int i = 0; i <= num; i += 2)
      {
         sum += i;
      }

Nested Loops

You can put one loop inside another loop. For example, supposed you wanted to print this:

****
****
****
****
1. for each row
   a. print 4 stars
   b. print a newline
      final int N = 4;
      for (int row = 1; row <= N; row++)
      {
         for (int col = 1; col <= N; col++)
         {
            output.print("*");
         }
         output.println();
      }

Nested Loops

Supposed you wanted to print this:

    *
   **
  ***
 ****
*****
1. for each row
   a. print some spaces
   b. print some stars
   c. print a new line
      final int N = 5;
      for (int row = 1; row <= N; row++)
      {
         // how many spaces?
         int spaces = N - row;
         for (int col = 1; col <= spaces; col++)
         {
            output.print(" ");
         }
         // how many stars?
         int stars = row;
         for (int col = 1; col <= stars; col++)
         {
            output.print("*");
         }
         output.println();
      }

Nested Loops

Supposed you wanted to print this:

    *
   ***
  *****
 *******
*********
1. for each row
   a. print some spaces
   b. print some stars
   c. print a new line
      final int N = 5;
      for (int row = 1; row <= N; row++)
      {
         // how many spaces?
         int spaces = N - row;
         for (int col = 1; col <= spaces; col++)
         {
            output.print(" ");
         }
         // how many stars?
         int stars = 2 * row - 1;
         for (int col = 1; col <= stars; col++)
         {
            output.print("*");
         }
         output.println();
      }

To Do For Next Lecture

Start reading Chapter 6.

Check your CSE email for miscellaneous midterm information (2—4PM on Sunday in CSE B and C).