teaching machines

CS1: Lecture 24 – For Loops

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.

  • Write a static version of indexOf and lastIndexOf from the String class.
  • Write a method fillDown that mimics filling on a spreadsheet.
  • Write a program to generate a directory named after each day of the year. For example 0131 for January 31.
  • Write a program that prints the numbers from 1 to 100. But for multiples of three, print blu instead of the number, and for multiples of five, print gold. For numbers that are multiples of both three and five print blugold. Read more about this problem at Why Can’t Programmers.. Program?

TODO

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

  • The first homework resubmission period is now open and will close on Friday, November 1, at the end of the day. During this period you may resubmit one of the first three homeworks for full credit. Your fixed up homework must be pushed to GitLab. Send me an email telling which homework to regrade. To be eligible, however, you must complete the Cetvrta exercise on Kattis, a programming challenge website. Write a Java program that reads from System.in, solves the problem, and passes the Kattis tests. Include in your email your solution and a screenshot of Kattis giving you a thumbs-up.
  • Near the end of the semester a second resubmission period will be offered. During that period you will be able to resubmit any of homeworks 1 through 5.
  • CS 145, your lab is posted. Feel free to start early.
  • We will hold homework 3 peer reviews during lab this week.
  • Homework 4 is officially assigned. Unlike the first three homeworks, the next three homeworks are complete applications. They are more involved and are worth more Blugolds, but they are more focused on a single task. Homework 4 is due November 12. You must update your SpecCheckers by pulling from the template remote.
  • Read sections 2.3, 4.2, 5.1, and 5.2 in your book. On a quarter sheet of paper to be turned in at the beginning of next lecture, write down 2-3 questions or observations about loops inspired by your reading.

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

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *