teaching machines

CS 145 Lecture 17 – Diversions and Bifurcations

October 19, 2016 by . Filed under cs145, fall 2016, lectures.

Dear students,

We’ve seen the computer as a calculator, crunching numbers. We’ve seen the computer as a chef, calling upon recipes of code. We’ve seen the computer as a philosopher, considering truths about our data. Now it’s time to let those truths drive our computer’s actions. We will see the computer as a pilot, navigating wild routes through our code based on conditions.

Normally, the flow of control in a program goes from the top of a method to its bottom, one statement after another. The ball gets rolling in main, and it may temporarily pause its execution to let another method do some work. But in general, it’s one statement after another. But sometimes we want to do some extra work under certain conditions. I call this pattern a diversion, and we structure it like so:

// pre work
if (booleanCondition) {
  // diversion work
}
// post work

The key observation here is that the diversion doesn’t always get executed. Only when booleanCondition is true. Let’s see this pattern in some real contexts:

In other situations, we actually want to choose between two competing choices. I call this pattern a bifurcation, and it has this structure:

// pre work
if (booleanCondition) {
  // then work
} else {
  // else work
}
// post work

Only of the two blocks will get executed. Let’s also see this pattern in some real contexts:

We’re now on our third structure that uses curly braces. The first two are classes and methods. We will meet more. It is very important that you consistently indent your code within every set of curly braces. Java does not require this, but humans do.

Also, you’re going to see folks write conditionals without curly braces. Like this:

if (i < 0)
  System.err.println("That's not enough.");

When a then- or else-block is only one statement long, the braces can be omitted. But I don’t recommend it. Consider this bit of code:

if (6 == 7)
  System.out.println("a");
  System.out.println("b");

Many corporate style guides mandate braces all the time, even when the block consists of only one statement. Google does.

Also, software developers are greatly tempted to overuse conditional statements. But they are not always the best choice. For one, they take up multiple lines, and when you get to a language where you start passing code around as parameters to methods, your code will become unreadable. For two, conditionals are statements, not expressions. They do not produce a usable value; they do something. Just like println. Sure, their blocks can assign a value to a variable, but that is not always going to work. If statements do not exist in every language. For three, if statements actually 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. For four, most 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. Anything is simple once you’re familiar with it.

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 hasRepeatedLetter(String s) {
  if (s.length() < 2) {
    return false;
  } else {
    return s.charAt(0) == s.charAt(1);
  }
}

This would be better written as:

public static boolean hasRepeatedLetter(String s) {
  return s.length() >= 2 && s.charAt(0) == s.charAt(1);
}

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

See you next class!

Sincerely,

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

Diversions.java

package lecture1019;

public class Diversions {
  public static void main(String[] args) {
    System.out.println(abs(5));
    
    System.out.println(pluralize(-1));
  }

  public static int abs(int xnx) {

    if (xnx < 0) {
      xnx = -xnx;
    }

    return xnx;
  }

  public static String appendDomain(String username) {
    // username might be johnch, return johnch@uwec.edu
    // username might be johnch@uwec.edu, return as is

    if (!username.endsWith("@uwec.edu")) {
      // username = username + "@uwec.edu";
      username += "@uwec.edu";
    }

    return username;
  }
  
  public static String pluralize(int n) {
    String text = "You have " + n + " new message";
    
    if (n != 1) {
      text += "s";
    }
    
    return text;
  }
}

Sometimes.java

package lecture1019;

import java.util.Random;

public class Sometimes {
  public static void main(String[] args) {
    Random generator = new Random();
    boolean isRed = generator.nextBoolean();
    
    String color;
    
    if (isRed) {
      color = "red";
    } else {
      color = "blue";
    }
    
    String html = "<html><body style=\"background-color: " + color + "\"></body></html>";
    System.out.println(html);
  }
}