teaching machines

CS 145 Lecture 18 – If Ladders

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

Dear students,

Let’s start today by writing a little game modeled after an exercise that my kids do at school. It’s called Math Mountain. A number appears at the peak, and another small number appears at mountain’s left foot. The left and right foot are to sum up to the peak. The student must supply the right foot.

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 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;
  }
}

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);
}

For our next example, let’s write an application that we all need from time a time: a restaurant chooser. We think we like choice, but when it comes time to make a decision, most of us would like to not have that responsibility. So, we will give that responsibility over to our phone. However, we will some influence. We’ll decide how likely it is a certain restaurant will be picked. To make this happen, we will create what I called an if ladder, which looks like a series of choices. This is really just an extension of the if/else structure, which presents only two choices. But with some clever nesting and syntax tweaks, we get an n-way choice.

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

See you next class!

Sincerely,

P.S. It’s Haiku Friday!

I’ll accept the vote
If I win, else it is rigged
Donald’s if statement

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

MathMountain.java

package lecture1021;

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

public class MathMountain {
  public static void main(String[] args) {

    System.out.println("Complete the following pyramid...");
    System.out.println();

    Random generator = new Random();

    int top = generator.nextInt(20) + 1;
    int bottomLeft = generator.nextInt(top);

    System.out.printf("%5d%n", top);
    System.out.printf("%2d + ", bottomLeft);

    Scanner in = new Scanner(System.in);
    int bottomRight = in.nextInt();

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

// String s = null;
// System.out.println(s.length());

    if (top == bottomLeft + bottomRight) {
      System.err.println("You didn't fail.");
    } else {
      System.err.println("You didn't win.");
    }
  }
}

Randaurant.java

package lecture1021;

import java.util.Random;

public class Randaurant {
  public static void main(String[] args) {
    System.out.println(getRestaurant());
  }

  public static String getRestaurant() {
    Random generator = new Random();
    int i = generator.nextInt(100);

    if (i < 50) {
      return "Jeff's Pizza";
    } else if (i < 60) {
      return "Davies";
    } else if (i < 75) {
      return "Nucleus Cafe";
    } else if (i < 90) {
      return "Milwaukee Burger";
    } else if (i < 98) {
      return "Golden Arches Supper Club";
    } else {
      return "Taco Bell";
    }

  }
}

NoIfs.java

package lecture1021;

public class NoIfs {
  public static boolean isEven(int x) {
//    if (x % 2 == 0) {
//      return true;
//    } else {
//      return false;
//    }
    return x % 2 == 0;
  }
  
  public static boolean isDayOfWeek(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;
    }
  }
}