teaching machines

CS 1: Lecture 32 – Stopwatch

December 1, 2017 by . Filed under cs1, cs145, cs148, fall 2017, lectures.

Dear students,

As with methods, a primary benefit of object-oriented programming is code reuse. We can create a utility and use it over and over again, in many contexts. We will do just that by designing a Stopwatch class. We will use it to time a few operations:

  1. a words-per-minute calculator
  2. the amount of time it takes to brute force crack a password
  3. a competition to type in the alphabet backward

But first, let’s split into pairs and discuss what this Stopwatch should look like. With your neighbor, write down answers to the following questions:

When we model an object, we are tempted to give it every feature imaginable. We humans are enumerators. Completionists. However, this sort of behavior is the undoing of many a project. It’s better to ship a product that does one task well then ten tasks poorly. (Even better is to do ten tasks well. But that’s usually not one of our options.) Modern software development follows the principle of YAGNI—”you ain’t gonna need it.” The spirit of this aphorism is to reign in your dreams to just the required functionality, at least initially. Don’t write code unless it’s meeting a felt need.

Here’s your TODO list for next time:

See you next class!

Sincerely,

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

The bigger your lawn
The less time to enjoy it
Just say no mo-er

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

Midterm.java

package lecture1129;

public class Midterm {
  public static void main(String[] args) {
    System.out.println(abc123("Gods kalpot Latvijai!!1!"));
  }
  
  public static String abc123(String s) {
    String sPrime = "";
    for (int i = 0; i < s.length(); ++i) {
      if (Character.isLetter(s.charAt(i)) ||
          Character.isDigit(s.charAt(i))) {
        sPrime += s.charAt(i);
      }
    }
    return sPrime;
  }
}

Stopwatch.java

package lecture1129;

public class Stopwatch {
  private long startMillis;

  public Stopwatch() {
    startMillis = -1;
  }
  
  public void start() {
    startMillis = System.currentTimeMillis();
  }
  
  public double stop() {
    if (startMillis == -1) {
      throw new IllegalStateException("Can't stop unstarted stopwatches, punk!");
    }
    
    long stopMillis = System.currentTimeMillis();
    return (stopMillis - startMillis) / 1000.0;
  }
}

Password.java

package lecture1129;

public class Password {
  public static final String SECRET2 = "of";
  public static final String SECRET3 = "tri";
  public static final String SECRET4 = "slar";
  public static final String SECRET5 = "three";
  public static final String SECRET6 = "foobag";
  public static final String SECRET8 = "splatbot";
}

BruteForce.java

package lecture1129;

public class BruteForce {
  public static void main(String[] args) {
    Stopwatch excalibur = new Stopwatch();
    excalibur.start();

    // long running operation
    for (char a = 'a'; a <= 'z'; ++a) {
      for (char b = 'a'; b <= 'z'; ++b) {
        for (char c = 'a'; c <= 'z'; ++c) {
          for (char d = 'a'; d <= 'z'; ++d) {
            for (char e = 'a'; e <= 'z'; ++e) {
              for (char f = 'a'; f <= 'z'; ++f) {
                for (char g = 'a'; g <= 'z'; ++g) {
                  for (char h = 'a'; h <= 'z'; ++h) {

                    String possiblePassword = "" + a + b + c + d + e + f + g + h;
                    if (Password.SECRET8.equals(possiblePassword)) {
                      System.out.println(possiblePassword);
                    }
                  }
                }
              }
            }
          }
        }
      }
    }

    System.out.println(excalibur.stop());
  }
}

Stopwatch.java

package lecture1129;

public class Stopwatch {
  private double elapsedSeconds;
  private double startSeconds;
//  private double endSeconds;
  private boolean isRunning;
      
  public Stopwatch() {
    isRunning = false;
  }
  
  public void start() {
    isRunning = true;
    startSeconds = System.currentTimeMillis() / 1000.0;
  }
  
  public void stop() {
    if (!isRunning) {
      throw new IllegalStateException("You can't stop an unstarted stopwatch, \u324A!");
    }
    
    isRunning = false;
    double endSeconds = System.currentTimeMillis() / 1000.0;
    elapsedSeconds = endSeconds - startSeconds;
  }
  
  public double getElapsedSeconds() {
    return elapsedSeconds;
  }
  
//  public void reset() {
//  }
}