2.5 Basic Conditional Loops

One of the things that make computers very useful is the ability to do repetitive tasks. In programming terms this is often called looping. Programming languages usually have two or more different types of loop statements. Turing has two kinds. One type (called a for loop) is used when code needs to be repeated a known, specific number of times. We'll see this kind of loop in the next chapter. The other type (called a loop) is used when it is unknown how many times the code will need to be repeated. This type of loop ends when a certain condition is met. It is a bit like an if statement that is repeated.

Another issue that can arise with conditional loops is that the code can end up being repeated endlessly if you don't set up your exit condition properly (or not at all. This is known as an endless or infinite loop. If this happens you need to press Turing's stop button (where the run button was) to terminate the program, otherwise it will continue running indefinitely (until you turn off the computer or the power fails).

The code that is to be repeated starts with the reserved word loop. At the end of the code to be repeated there is an end loop statement, similar to the way that an if statement is ended. In order to exit the loop there is an exit when statement placed somewhere inside the loop with a boolean expression that states the condition that needs to be true to exit the loop.

Here is an example of a loop that doesn't have an exit when statement. It will be an endless loop. It will keep printing the message Endless loop until the stop button is pressed.

loop
   put "Endless loop"
end loop 

Suppose we wanted to write a program that asked simple addition questions. After each question we will give the correct answer and ask the user if they'd like another question. If they do we'll ask another. If they don't we'll thank them for using the program. Here is an example of such a program (we could make it smarter by only printing the answer if they got it wrong but we'll leave that out):

var n1, n2, answer: int
var response : string

loop
   randint(n1, 1, 10)
   randint(n2, 1, 10)
   put "What is ", n1, " + ", n2, "?"
   get answer
   put "The correct answer is ", n1 + n2
   put "Would you like another question?"
   get response:*
   exit when response = "n"
end loop 

Here is a sample run of the program. It will keep asking random questions until the user types n when asked if they'd like another queston. Any other response will make the exit when condtion false, so the loop will not exit, but will go back to the top of the loop and run again.

What is 5 + 8?
12
The correct answer is 13
Would you like another question?
y
What is 6 + 5?
65
The correct answer is 11
Would you like another question?
yes please
What is 3 + 2?
5
The correct answer is 5
Would you like another question?
no way
What is 4 + 10?
14
The correct answer is 14
Would you like another question?
n

Suppose we wanted to find the mean of a group of positive integers entered by the user. The user will indicate that they are done entering values by entering a negative value. Here is a program to do this:

var count, number, total : int := 0

loop
   put "Enter value # ", count + 1, ", or a negative to stop"
   get number
   % exit the loop if they enter a negative value
   exit when number < 0
   % not a negative so add 1 to count & add number to total
   count := count + 1
   total := total + number
end loop

% compute and print the mean but be careful if no positive values were entered
if count > 0 then
   put "The mean of the ", count, " numbers is ", total / count, "."
else
   put "You didn't enter any positive values.  Can't compute mean."
end if 

The statements between loop and end loop will be executed over and over as long as the condition after the exit when is false. The loop ends when the exit when is true and that statement is executed. Here is a sample run of the program.

Enter value # 1, or a negative to stop
10
Enter value # 2, or a negative to stop
20
Enter value # 3, or a negative to stop
40
Enter value # 4, or a negative to stop
30
Enter value # 5, or a negative to stop
-1
The mean of the 4 numbers is 25.

The if statement at the end of the program is needed in case the user enters a negative right away. If they do, then count will still be 0. If it is we can't divide by it or our program will crash. Here's what the output would be like in that situation.

Enter value # 1, or a negative to stop
-4
You didn't enter any positive values.  Can't compute mean.

You can place the exit when statement any where in the loop that is convenient. Often that will be either at the very beginning or end of the loop. You can even have more than one exit when if you like. However, it is good programming practice to use a few as possible (usually one per loop).

Exercise 2.5

  1. How many times will the body of each loop be at least partially executed?
    1. var term : int := 3
      var sum : int := 0
      
      loop
         exit when term > 60
         sum := sum + term
         term := term + 10
      end loop 
    2. var x : int := 100
      var y : real
      
      loop
         exit when x <= 0
         y := sqrt(x)
         put x, y
         y := y - 1
      end loop 
  2. Write a program that reads a positive integer and then finds the smallest power of two greater than or equal to the number that was read.
  3. Write a program that asks the user for a password (defined by a constant within the program). The program should then test the validity of the password. If it is correct, the user should be given a welcoming message. If it is incorrect, tell the user that it is incorrect and make them keep trying until they get it right.
    1. Write a program that asks the user to guess the value of a letter, from A to Z, that has been defined by a constant within the program. After each incorrect guess, the program should tell the user whether the guess was too low or too high and ask for another guess. This should continue until the correct letter is guessed.
    2. What guessing strategy will minimize the number of expected incorrect responses?