teaching machines

CS 145 Lecture 12 – Test-driven Development

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

Dear students,

Last lecture I said we’d have one more day of focus on methods, but then we spent the entire time talking about casting. Today we’ll start the fill-in-the-blank exercises to exercise our method brain. Your task is to jot what goes in each blank of the following code snippets. One of the blanks is the method name, which you should fill with something meaningful.

FIB #1
public static _______ _______(int n) {
  ______ z = n + "";
  return z.startsWith("-");
}
FIB #2
public static _______ _______(______) {
  return text + " :)";
}
FIB #3
public static _______ _______(______) {
  n = -n;
}
FIB #4
public static _______ _______(______) {
  return s.charAt(s.length() - 1);
}
FIB #5
public static _______ _______(int n) {
  _______ = "" + n;
  _______ = s.replace("0", ""); 
  _______ = s.length() - t.length();
  return d;
}

We next turn to a problem that one of you asked on a quarter sheet. Is there anything like charAt for integers? Not exactly, but there’s nothing stopping us from writing our own method to accomplish this task!

Let me share with you a quotation from Maurice Wilkes, one of the developers of the first computers:

By June 1949 people had begun to realize that it was not so easy to get programs right as at one time appeared. I well remember when this realization first came on me with full force. The EDSAC was on the top floor of the building and the tape-punching and editing equipment one floor below… It was on one of my journeys between the EDSAC room and the punching equipment that “hesitating at the angles of stairs” the realization came over me with full force that a good part of the remainder of my life was going to be spent in finding errors in my own programs.

That “hesitating at the angles of stairs” is Wilkes alluding to the poetry of T.S. Eliot.

If we are going to be an inventor—even an inventor of software—we must care to do it right. We must make sure our software does its task well. To ease this burden, we’ll talk a little bit about test-driven development.

Here’s a recipe to follow when writing a method to accomplish some task:

  1. Determine the method name and its inputs and outputs.
  2. Write the method so that it does nothing but compile. Have it immediately return 0 or false or null.
  3. Write a test thats feeds certain values to the method. Pit the expected results from running the method on these values against the actual results.
  4. Fix the method so that the test passes.
  5. Repeat starting at step 3 until perfect.

This process will minimize headache. Writing software can be an enjoyable intellectual activity, but only when you anticipate your mistakes. When you bounce from error to error and each one surprises you, you will start to think you aren’t fit to write code. But really the problem is your blundersome technique.

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

See you next class!

Sincerely,

P.S. It’s Haiku Monday!

f on his breakup
“I can’t function anymore…”
“I want my x back!”

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

Weird.java

package lecture1003;

public class Weird {
  public static void main(String[] args) {
    int f = 10;
    makeNegative(f);
    System.out.println(f);
  }
  
  public static void makeNegative(int n) {
    n = -n;
  }
}

NumberUtilities.java

package lecture1003;

public class NumberUtilities {
  public static void main(String[] args) {
    Certainly.assertEquals("Testing ones place", 7, digitAt(987, 1));
    Certainly.assertEquals("Testing tens place", 8, digitAt(987, 10));
    Certainly.assertEquals("Testing hundreds place", 9, digitAt(987, 100));
    Certainly.assertEquals("Testing thousands place", 0, digitAt(987, 1000));

  }
  
  public static int digitAt(int n, int place) {
    String nAsString = n + "";
    StringBuffer reverser = new StringBuffer(nAsString);
    String nReversed = reverser.reverse().toString();
    int i = ("" + place).length() - 1;
    return nReversed.charAt(i) - '0';
  }
}

Certainly.java

package lecture1003;

public class Certainly {
  public static void assertEquals(String message, int expected, int actual) {
    System.out.printf("%d == %d <- %s%n", expected, actual, message);
  }
}