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.
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:
An if-statement has two parts:
a header: the keyword if
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
.
a body: some lines of code between curly braces.
A if-statement 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.
In the example above, the interpreter reaches the header. Is the
value of the condition true
? Yes.
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.
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:
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." );
}
Like an if-statement, a while loop has a header
followed by a body. If the condition in the header is
false
, then the program counter jumps to the first line of
code after the body.
If the condition evaluates to true
, the interpreter
executes the body, and then moves the program
counter back to the header, where the value of the condition is
checked again.
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.
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.
Exercise: Write a program that counts down from 10 to 1, printing out the numbers as it goes. After the numbers, it should print out “Blast off!”. 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 a solution.
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:
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.