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 ofindexOf
andlastIndexOf
from theString
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, printgold
. For numbers that are multiples of both three and five printblugold
. 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!
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;
}
}