teaching machines

CS1: Lecture 22 – While Loops

October 23, 2019 by . Filed under cs1, fall 2019, lectures.

Dear students,

Today we extend the notion of a Computer as Pilot to not just yaw left or right as it navigates through our code, but to also swoop back around to code that it has run previously. But first we examine some situations where developers write conditional statements that they shouldn’t have written.

If Gotchas

Software developers are greatly tempted to overuse conditional statements. But there are several reasons why they are not always the best choice:

  1. They are syntactically “noisier,” and when you get to a language where you start passing code around as parameters to methods, your code will become less readable if you use conditional statements.
  2. Conditionals in Java are statements, not expressions. They do not produce a usable value; they do something. Just like println. Not all languages have statements, and you should be prepared for situations in which you can’t write them.
  3. Conditional statements cause a bump in your program’s execution. Normally the processor is working on several instructions at once, getting the next ones ready while the current one is executing. In the case of an if, the computer can’t predict what the next instruction is. This is called a pipeline stall.
  4. Many excuses for writing ifs when they aren’t needed are pretty weasely: “This is the way I’ve always done it,” “This is how I think about it,” or “This is simpler.” Simple is a proxy for familiar. Many things are simple once you’re familiar with them.

Let’s see some examples of ifs that should not have been written:

public static boolean isEven(int x) {
  if (x % 2 == 0) {
    return true;
  } else {
    return false;
  }
}

This would be better written as:

public static boolean isEven(int x) {
  return x % 2 == 0;
}

How about this one?

public static boolean isDay(String s) {
  if (s.equals("Sunday")) {
    return true;
  } else if (s.equals("Monday")) {
    return true;
  } else if (s.equals("Tuesday")) {
    return true;
  } else if (s.equals("Wednesday")) {
    return true;
  } else if (s.equals("Thursday")) {
    return true;
  } else if (s.equals("Friday")) {
    return true;
  } else if (s.equals("Saturday")) {
    return true;
  } else {
    return false;
  }
}

Better to use ||! How about this one?

public static boolean isEdible(boolean isHealthy, int costInCents) {
  if (!isHealthy) {
    if (costInCents == 0) {
      return true;
    } else {
      return false;
    }
  } else {
    return true;
  }
}

How about this one?

public static boolean isIsosceles(double sideA, double sideB, double sideC) {
  if (Math.abs(a - b) < 0.0001) {
    if (Math.abs(b - c) < 0.0001) {
      return true;
    } else {
      return false;
    }
  } else {
    return false;
  }
}

While Loops

Conditional statements put suspense in our code. We just don’t know what’s going to happen next. Consider this case of an if without an else. What will happen?

Random generator = new Random();
if (generator.nextBoolean()) {
  System.out.println("H");
}

We don’t know what will happen without running it. Developing software requires a great deal of hypothetical reasoning because of these conditional statements. However, we can put some bounds on how many times the block will execute. It will execute 0 times or 1 time.

There is another structure that can make this number go higher. It can make the block execute 2 times, 3 times, 100 times, or forever. That structure is the while loop. Its syntax is nearly indentical to if.

How many times will the block execute now?

Random generator = new Random();
while (generator.nextBoolean()) {
  System.out.println("H");
}

We still don’t know, but it’s very unlikely that it will go on forever. To get more control over the number of repetitions or iterations of the loop, we can follow this general pattern:

initialize
while (keep-going?) {
  action
  update
}

To count to 10, first instance, we’d write this:

int i = 1;
while (i <= 10) {
  System.out.println(i);
  i += 1;
}

Very frequently we will start our counting at 0 because we will be marching through collections of data that use indices—like strings do. So, we’ll write this code instead:

int i = 0;
while (i < 10) {
  System.out.println(i);
  i += 1;
}

Let’s see while loops at work as solve the following problems together:

TODO

Here’s your TODO list to complete before we meet again:

See you next class!

Sincerely,

P.S. It’s time for a haiku!

They’ll write about you
How you looped around the sun
Orbituary

P.P.S. Here’s the code we wrote together in class…

Acrostic.java

package lecture1023.cs145;

import java.util.Scanner;

public class Acrostic {
  public static void main(String[] args) {
    Scanner in = new Scanner(System.in);

    System.out.print("Theme: ");
    String theme = in.nextLine();

    int i = 0;
    while (i < theme.length()) {
      System.out.print(theme.charAt(i));
      in.nextLine();
      i += 1;
    }
  }
}

Multiplication.java

package lecture1023.cs145;

import java.util.Random;
import java.util.Scanner;

public class Multiplication {
  public static void main(String[] args) {
    Random generator = new Random();
    Scanner in = new Scanner(System.in);

    int i = 0;
    while (i < 10) {
      int a = generator.nextInt(12);
      int b = generator.nextInt(12);
      System.out.printf("%d * %d = ", a, b);
      int guess = in.nextInt();

      if (guess == a * b) {
        System.out.println(":)");
      } else {
        System.out.println("...");
      }

      i += 1; // i = i + 1  || i++  || ++i
    }
  }
}

While.java

package lecture1023.cs145;

import java.util.Random;

public class While {
  public static void main(String[] args) {
    Random generator = new Random();
    while (generator.nextBoolean()) {
      System.out.println("H");
    }
  }
}

Acrostic.java

package lecture1023.cs148;

import java.util.Scanner;

public class Acrostic {
  public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    String theme = in.nextLine();

    int i = 0;
    while (i < theme.length()) {
      System.out.print(theme.charAt(i));
      in.nextLine();
      i++;
    }
  }
}

Modcards.java

package lecture1023.cs148;

import java.util.Random;
import java.util.Scanner;

public class Modcards {
  public static void main(String[] args) {
    Random generator = new Random();
    Scanner in = new Scanner(System.in);

    int count = 0;
    while (count < 7) {
      int a = generator.nextInt(101);
      int b = generator.nextInt(20) + 1;
      System.out.printf("%d %% %d = ", a, b);
      int guess = in.nextInt();
      if (guess == a % b) {
        System.out.println(":D");
      } else {
        System.out.println(">:<");
      }
      count++;
    }

//    int i = 0;
//    i-=-1;
//    i++;
  }
}

Something.java

package lecture1023.cs148;

import java.util.Random;

public class Something {
  public static void main(String[] args) {
    Random generator = new Random();

    while (generator.nextBoolean()) {
      System.out.println("H");
    }

    // init
    // while (keep-going?) {
    //   action
    //   update
    // }
  }
}