 ## Chapter 12 - Other loops: REPEAT and WHILE

REPEAT .. UNTIL

Our little circle program has had a rest just recently, so let's wake it up again and discuss conditional loops. As we last left it when the user had finished, they had to run it again. It would be nice if the program looped until the user had finished with it. A FOR loop would be no good here as we have no idea how many times our user would want to run the program. This is where we meet our first conditional loop: REPEAT UNTIL. As usual, here's an example which I'll explain afterwards:

 REM Area of a circle REPEAT INPUT "Enter a radius: " Radius Area = PI*Radius^2 PRINT "Area of your circle is ";Area INPUT "Another go? Y/N " Reply\$ UNTIL Reply\$="N" END
You can guess here that the program carries on looping until the user presses "N". The loop starts with line 2: REPEAT. There are no conditions or other keywords here, just the one word. BB4W indents all the code following and recognizes UNTIL in line 7 as the end of the loop. UNTIL tests for a condition in the same way as an IF does. If the condition is false, back we go to line 2 for another round. If the condition is true, the loop is ended and execution continues at the next line. All the intelligence happens in the UNTIL line, REPEAT just marks the beginning of the loop.

If you've tried the program, you'll have noticed that we've got our old problem back again: assuming the user enters an uppercase "N". The test that UNTIL does can be as complex as any IF statement and uses exactly the same logic to work things out, so we can change line 7 to:

 UNTIL Reply\$="N" OR Reply\$="n"
... and all will be well again. Armed with our new knowledge, I'm sure you can see another candidate for a REPEAT. Line 6 asks for Reply\$, we can test this until we get a valid response before continuing. Try it yourself first then compare results.
 REM Area of a circle REPEAT INPUT "Enter a radius: " Radius Area = PI*Radius^2 PRINT "Area of your circle is ";Area REPEAT INPUT "Another go? Y/N " Reply\$ UNTIL INSTR("YyNn",Reply\$)<>0 UNTIL INSTR("Nn",Reply\$)<>0 END
I used INSTR here, but you could equally have used Reply\$="Y" OR Reply\$="y" etc.

The main problem you will find with conditional loops is the endless loop syndrome: always be sure to set an exit condition in the loop.

 REM Endless REPEATs Done = FALSE REPEAT PRINT "Have I missed something here?" UNTIL Done END
WHILE .. ENDWHILE

REPEAT loops test for a condition at the end of the loop. This means that you always run the code in the body of the loop at least once. Sometimes this is not desirable. A WHILE loop tests for a condition before entering the loop and running the code therein. Somewhat differently, the code is only run when the test condition is true, as opposed to REPEAT which runs while the test condition is false. Watch for this one. The end of the loop is denoted by ENDWHILE, with the usual warning about not splitting into two words.

Here is a program that starts with 1 and keeps halving it until BASIC rounds to zero, to try and find the smallest number BB4W will hold. This doesn't actually give quite the smallest number, but it's pretty close.

 REM Smallest floating point using WHILE Number = 1 WHILE Number > 0 LastNumber = Number Number = Number / 2 ENDWHILE PRINT "The value of number is ";Number PRINT "The previous value was ";LastNumber END
Again, the logic for the test condition can be as complex as is necessary.

Tip: Exiting loops
The FOR loop is quite forgiving when it comes to testing the exit condition. If you exceed the final value BASIC will not mind and terminate the loop as expected. Not so with REPEAT and WHILE. Look at the following code:
 REM Endless loops I%=1 REPEAT I%+=2 PRINT I% UNTIL I%=10 END
The loop will never exit because BASIC looks for an exact match. It is much better with REPEAT and WHILE not to use precise values unless you are 100% sure they can be met. This is particularly true in the case of floating point numbers. To fix the example, replace '=' with '>=' in the UNTIL line and all will be well again.

Exercises

1) Produce a program that will ask for a string and print the ASCII code of the first character. Have it continue until the string entered is empty ("").
2) Write a program that will ask for a number. Add this number to a running total. Repeat until the number entered is 0. Print the result.

### CHAPTER 13   © Peter Nairn 2006