Let’s say that you would like to print the phrase “All work and no play makes Jack a dull boy” infinitely many times. Using the techniques we’ve seen so far, this would require infinitely many lines of code:
print( "All work and no play makes Jack a dull boy." );
print( "All work and no play makes Jack a dull boy." );
print( "All work and no play makes Jack a dull boy." );
print( "All work and no play makes Jack a dull boy." );
// ...
A loop structure directs Javascript to move the program counter to a previous line of code under certain conditions, and loops can cause the same line of code to be executed many times:
while (true) {
print( "All work and no play makes Jack a dull boy." );
}
A while loop has two parts:
a header: the keyword while
followed by parentheses surrounding a boolean expression, called the condition. A boolean expression is an expression that evaluates to the value true
or the value false
. We’ll see more about boolean expressions shortly.
a body: some lines of code between curly braces.
A while loop works in the following way. First, the program counter reaches the header. The interpreter checks the condition. If the condition has the value false
, the interpreter moves the program counter to the first line of code after the body. If the condition has the value true
, the interpreter executes the body, and then moves the program counter back to the header, where the value of the condition is again checked.
In the example above, the interpreter reaches the header. Is the value of the condition true
? Yes. So the interpreter executes the body, printing “All work and no play makes Jack a dull boy.” one time. Then the interpreter moves the program counter back up to the header. The interpreter checks the value of the condition. The value is true
, so the interpreter executes the body, prints “All work and no play makes Jack a dull boy.”, and moves the program counter to the header.
In the above code, the condition always has the value ‘true’, so the body will be executed over and over. We call this an example of an infinite loop. This example should not be run, since it will never stop on its own. The only way to stop the program is for the browser to notice the problem and “kill” it, stopping it using some extreme external means. REDRUM!
Programs with infinite loops are not always bad. A robot might be intended to act forever, and the structure of the code might be an infinite loop considering and taking actions. However, unintentional infinite loops are a common programming error, and can have drastic unintended consequences, like causing the user’s browser to become unresponsive while all available computation power is used running the loop.
Objective: Write a program that implements a repeated behavior.
Here is a robot simulator. The function calls left()
, right()
, and forward()
drive the robot. Without using any loops, write a program that causes the robot to drive in a small square.
Here is a solution.
In the robot square exercise, you almost certainly wrote some repeated code: the robot goes forward, turns left, forward, left, forward, left, forward, left. What if you wanted the robot to keep driving in squares? Here’s some code that makes the robot follow two squares. Click the small triangle next to the while
keyword to unfold the code of the while loop. You’ll see that the body of the while-loop has the expected forward()
and left()
function calls. For now, you may ignore the function call condition()
.
We need to understand boolean expressions in order to write loops that stop in a controlled fashion. In mathematics, the statement 4 < 3 is just nonsense. In Javascript, the boolean expression 4 < 3
is an expression with a computable boolean value. The less-than symbol, <
, is a conditional operator that computes the value true
or the value false
based on a comparison of the operands. So 4 < 3
computes to the value false
, and 4 > 3
computes to the value true
.
The most useful conditional operators are >
, <
, >=
, <=
, and ===
. The conditional operator for testing equality is not a single equals sign, since a single =
symbol is the assignment operator. Getting these confused is a very common programming error.
Conditional operators typically compare numbers and return a boolean true
or false
value. It can also be useful to work with true
and false
values directly. For example, !false
, pronounced “not false,” evaluates to true
; the exclamation point operator flips the value of whatever operand follows it. The operator &&
takes two boolean operands and computes the value true
if and only if both operands are true
. The operator ||
computes the value true
if one or both of the operands is true
. Here are some examples:
Here is a program to print out a phrase three times:
And here is an infinite loop to print the phrase forever:
while (true) {
print( "There's no place like home." );
}
If we want the loop to stop, the condition must change, but true
will always have the value true
. One thing that can change as a program is executed is the value of a variable. Consider this program:
The variable i
is declared and set to have the value 0
. Then the program counter reaches the header of the while loop. The expression i < 3
is computed, and currently has the value true
. So the body of the loop is executed, printing the phrase and increasing the value of i
, before returning to the header. At the header, the expression i < 3
is computed, and since i
has the value 1
, the expression is true
. The body is executed. The process repeats until i
has the value 3
, and the expression i < 3
computes to false. At this point, the program counter moves to the first line of code beyond the body of the loop.
The trick is to choose an expression that might change value from true
to false
as the condition in the header of the loop. One way to ensure that the condition eventually changes from true
to false
is to involve a variable in the expression, and then make sure to change the value somewhere in the body of the loop. Forgetting the line i = i + 1
is a common programming error, and leads to an infinite loop.
Let’s write a simple program that counts from 1 to 5.
Every line of code is different in this example! How can we write a loop that will repeat lines of code, and count from 1 to 5? The trick is that variables can change the behavior of a line of code. First, re-write the code this longer and more awkward way:
Notice that the lines grouped into pairs are repeated five times, and look the same every time. We can use a loop! When should the loop stop? i
has the value 6 after the last step, so we should repeat the body every time that i < 6
evaluates to true
.
This program is not shorter than the first program for counting to 5, but what if you wanted to count to 100?
Exercise: Modify the program to count down from 10 to 1. If you need to, write out all of the print statements by hand, look at what’s changing, and introduce a variable to allow that change using repeated lines of code. Then wrap into a while loop.
Here is an example of string art:
In the simplest version of string art, there are two sticks; several segments of string connect the sticks. In this section, we’ll see how to use a while-loop to draw string art. Here is some code that will draw the first few strings:
Exercise: Modify the code to draw a few more strings.
The four lines of code that draw the four strings are almost identical. They each call the function line
. The left x coordinates of the endpoints of each string are the same: 20. The right x coordinates of the endpoints of each string are also the same: 220.
yLeft
and increase it by 10 each time:
Exercise: Introduce a variable yRight
with the appropriate initial value and use it as the y coordinate of the right endpoints of the strings.
After completing the exercise, notice that there is a repeated group of three lines of code to draw the line and update the variables. We can use a while loop:
The body of a while-loop may be executed any number of times, zero or more. What if you wanted to check whether a condition was true
, and if so, execute some lines of code exactly once? We do so with an if-statement:
Objective: use an if-statement to test if a condition holds.
The number 24 has the integer factors 1, 2, 3, 4, 6, 8, 12, and 24. Write an if statement that tests if a value held in the variable possibleFactor
is an integer factor of a value in the variable number
. If so, the code should print out “Factor!”. Test with several different numbers and factors. (Hint: the modulus operator is useful.)
Here is a solution.
Both while-loops and if-statements allow you to control how Javascript flows from one line of code to another in your program. while and if are therefore called flow-of-control constructs. You can also put one while-loop or if-statement inside another.
It is very common to see an if-statement inside a while-loop. For example, here is a program to print all of the integer factors of a number. The approach is to generate all positive integers between 1 and the number. Each time you generate a new integer, test to see whether it is a factor.
The if-statement header is indented once, because it is part of the body of the while-loop. The line starting with print
is indented once from the if
, since it is part of the if-statement body. The line starting with possibleFactor is indented once from the while-loop’s header, since it is part of the while-loop’s body, but not part of the if-statement’s body. The final print is not indented because it is not part of the while-loop’s body.
We call the pattern that this program follows generate-and-test. We would like to find some answers to a problem. We have a way of testing whether a hypothesized answer is actually a solution. So we generate all reasonably possible answers, and test to see whether each is an answer. Such problems will often have a loop to generate the possible answers, and some series of tests (with if-statements) in the body of the loop to check whether a possible answer is correct.
When you see a new problem, it’s worth figuring out if the new problem could be solved by a generate-and-test approach. If so, you now have an idea about how you might implement a solution in code.
Objective: Make use of different results of a function call to take different actions.
Write a loop that simulates flipping a coin 10 times, and prints out the number of times the coin turned out heads. Hint: you can use the Math.random()
function to generate random numbers between and 1, and use a variable to keep track of how many random numbers were greater than a certain value.
Here is a solution.
Frequently, you want to execute one set of lines of code if a condition holds, but execute a different set of lines if that condition does not hold. In this case, you can use an else-statement:
An else-statement must follow an if-statement.
You can combine else
and if
to check a second condition only if the first condition is false. Here is an example of a program to report on the weather:
The sequence of if
/ else if
statements is called an if-ladder. Notice that there is exactly one else
statement at the end; this catches anything not covered by the previous cases.
Thought exercise: You would never have two else
statements in an if-ladder. Why?
When reading code containing a while-loop, try doing a couple of things:
A classic mistake for beginning programmers is to look for the pattern too soon. Make sure you really step through the code carefully before you make an assumption about the pattern. As a rule of thumb, check that your while-loop works when the body executes zero times, exactly one time, and exactly three times. There’s a little programming ditty that I heard decades ago and still sticks in my mind: Zero, one, three—that’s good enough for me.
Here’s the code to find integer factors again – trace through the execution by hand recording the value of the program counter, the values of variables, the values of interesting expressions, and output to the screen.
Loops for counting are very common in programming. Perhaps you are iterating over stock market data or counting the amount of sales based on some records. The while-loop (in the previous lecture) for counting to 5 had three key features:
var i = 1;
)i < 6
)i = i + 1;
)It would be nice if there were some shorthand for writing a loop where we could put all of that into the header. There is, and it’s called a for-loop.
The variable initialization is put before the first semicolon. The condition to test is put after the second semicolon. And the update of the variable is after the third semicolon.
For even more brevity, there is a shorthand for i = i + 1
. We can write i++
to indicate that the current value of i
should be incremented by one:
Objective: Use a for-loop to count.
Write a for loop that prints the integers from 10 to 1 in descending order, and print “blast off!” after the numbers have all been printed.
Here is a solution.
Objective: Use a for-loop to draw shapes at random locations.
Write a for loop that draws 99 circles at random locations on the 200x200 graphics window. You should use the Math.random()
function, which returns a number between 0 and 1. (You might have to do some multiplication to get your numbers in the right range.) As a bonus challenge, select a random color with r, g, and b in the range 128…255 for each balloon.
Here is a solution.