teaching machines

CS1: Lecture 24 – For Loops

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

Dear students,

While loops put a heartbeat in our code that makes it feel alive. We can feel the CPU pulse through our data while we sit back and await the result. But while is not the only way to make code repeat. Today we consider the for loop.

For Loops

Last week we broke down this general pattern of while loops:

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

The while loop has three unfortunate qualities. First, it’s heavy. It takes five lines of code to count to 10. Second, it’s very easy to forget that update step. Third, the variables introduced in the initialize step may have a broader scope than they need. Generally, we want variables to have as narrow a scope as possible.

None of these are deal-breaker issues, but we have an alternative that fixes all of them: the for loop, which is just a rearrangement of the while pattern:

for (initialize; keep-going?; update) {
  action
}

The for loop restricts the scope of its variables to the header and body of the loop. It syntactically forces us to consider the update step. And it shimmies down to a mere three lines of code in many situations.

Don’t be deceived by the location of the update step. As with while, it executes after the action.

The two kinds of loops are technically equivalent—any for loop can be rewritten as a while loop, and vice versa. But just as some bikes are meant for roads and others for Lowe’s Creek, each loop lends itself to certain applications. My criteria is this: when the loop logic can be written compactly, I use for. Otherwise, I use while. Your book talks about definite vs. indefinite loops. I don’t find that dichotomy well-defined or helpful.

There’s also a do-while loop that you might want to read about. We won’t discuss it formally. There’s also a for-each loop that we’ll talk about when we hit arrays.

Let’s see for loops at work in some programs.

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!

Count down on New Year’s
Yell out 16, 9, 4, 1!
When you’re in Times Square

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

ForLoop.java

package lecture1028.cs145;

public class ForLoop {
  public static void main(String[] args) {
//    System.out.println(lastIndexOf("achoo", 'o'));
    fillDown(8, 7, 6);
  }

  public static int indexOf(String haystack, char needle) {
    for (int i = 0; i < haystack.length(); i += 1) {
      if (haystack.charAt(i) == needle) {
        return i;
      }
    }

    return -1;
  }

  public static int lastIndexOf(String haystack, char needle) {
    for (int i = haystack.length() - 1; i > -1; i -= 1) {
      if (haystack.charAt(i) == needle) {
        return i;
      }
    }

    return -1;
  }

  public static void fillDown(int first, int second, int n) {
    int delta = second - first;
    for (int i = 0; i < n; i += 1) {
      System.out.println(first + i * delta);
    }
  }
}

Foring.java

package lecture1028.cs148;

import java.io.File;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class Foring {
  public static void main(String[] args) {
//    System.out.println(indexOf("foobag", 'o'));
//    System.out.println(lastIndexOf("foobag", 'o'));
//    fillDown(13, 25, 4);
    generateYearDirs();
  }

  public static void generateYearDirs() {
    GregorianCalendar day = new GregorianCalendar(1970 + 2009 + 400, 0, 1);

    for (int i = 0; i < 365; i++) {
      String directoryName = String.format("%02d%02d", day.get(Calendar.MONTH) + 1, day.get(Calendar.DAY_OF_MONTH));
      File file = new File("/Users/johnch/Desktop/yeardirs", directoryName);
      file.mkdir();
      day.add(Calendar.DAY_OF_MONTH, 1);
    }
  }

  public static void fillDown(int a, int b, int n) {
    int delta = b - a;
    for (int i = 0; i < n; i++) {
      System.out.println(a + delta * i);
    }
  }

  public static int indexOf(String haystack, char needle) {
    for (int i = 0; i < haystack.length(); i++) {
      if (haystack.charAt(i) == needle) {
        return i;
      }
    }
    return -1;
  }

  public static int lastIndexOf(String haystack, char needle) {
    for (int i = haystack.length() - 1; i >= 0; i--) {
      if (haystack.charAt(i) == needle) {
        return i;
      }
    }
    return -1;
  }
}