## Back To Basics - Part 5

Getting less basic by the month, Mark 'Maestro' Moxon takes us through a couple of control structures that will prove fundamental to your programming skills

If you've made it this far, you're in control. Seriously: give it a couple of months, and you'll be able to understand 90 per cent of the programs you see. And you'll be able to criticise them. And make loads of new friends with your new-found knowledge. That's a promise.

On the other hand, there's plenty to learn, like all the other control statements I hinted at last month. On with the show, maestro ...

### A Case Study

After last month's foray into the exciting yet educational world of the IF-THEN construct, it's time to move on to the next stage: the CASE-ENDCASE construct. Time for a practical example? I think so.

Imagine we wanted to write a program which presented a number of mathematical problems, based around the four rules of arithmetic. When the program is run, it asks which rule we want to test, be it addition, subtraction, multiplication or division; the program asks a specific question, using the specified rule.

This program could be implemented using IF-THEN statements, but it would be a little clumsy, so what we need is CASE-ENDCASE. Before I explain how it works, have a look at Listing1.

### Listing 1

```REM >Listing1
:
ON ERROR REPORT:PRINT " at line ";ERL/10:END
MODE 0
:
PRINT "Which rule do you want to test?"
PRINT "   (A)ddition"
PRINT "   (S)ubtraction"
PRINT "   (M)ultiplication"
PRINT "   (D)ivision"
INPUT "Please enter A,S,M or D: "rule\$
:
CASE rule\$ OF
WHEN "A"
A=RND(10):B=RND(10)
PRINT "What is ";A;" + ";B;" ";
INPUT result
IF result=A+B THEN PRINT "Correct" ELSE PRINT "Wrong"
WHEN "S"
A=RND(10):B=RND(10)
PRINT "What is ";A;" - ";B;" ";
INPUT result
IF result=A-B THEN PRINT "Correct" ELSE PRINT "Wrong"
WHEN "M"
A=RND(10):B=RND(10)
PRINT "What is ";A;" x ";B;" ";
INPUT result
IF result=A*B THEN PRINT "Correct" ELSE PRINT "Wrong"
WHEN "D"
B=RND(10):A=B*RND(10)
PRINT "What is ";A;" / ";B;" ";
INPUT result
IF result=A/B THEN PRINT "Correct" ELSE PRINT "Wrong"
OTHERWISE
PRINT "Sorry, I don't know that rule."
ENDCASE
END
```

First of all, have a look at the way the CASE statement is constructed. The first line of it is in the form:

```CASE <variable> OF
```

where the variable in this case is the letter we've entered: one of A, S, M or D. The next set of lines is in groups, each starting with a line like:

```WHEN <match>:
```

Effectively, what happens is that the program searches through these WHEN statements, one after the other, until the variable in the CASE line matches the match in the WHEN line. When a match is found, the lines after the WHEN are executed (up until the next WHEN). If no match is found, then the lines after the OTHERWISE line are executed.

So, how does this work in our example? First, the program asks which rule we should be testing, and the user enters the relevant letter into the variable rule\$. Now we start our CASE check, which does one of the following:

• When it is "A", set A and B to random values between 1 and 10 (inclusive); that's what the RND function does. Next, print the question, ask for an answer in the variable result, and check to see if it is right. If it is, print Correct, otherwise print Wrong. This shows the power of the CASE construct: we can include an IF-THEN statement as one of the lines to be executed, and it is still very easy to see what is happening.
• When it is "S', do exactly the same, except print a subtraction question, and check the answer against A-B, rather than A+B.
• When it is "M", do exactly the same, except print a multiplication question, and check the answer against A*B. When it is "D", we have a division question, which is slightly different. As we want to deal with integer division (as entering decimals is inaccurate with recurring answers, like 0.3333....) set B to a random value between 1 and 10, and then set A to a random multiple of B; in this way we are guaranteed an integer division question. Print the question, get the answer into result, and check it as normal.
• If we get to the OTHERWISE statement, then no match for rule\$ has been found out of "A", "S", "M", or "D", so the user hasn't entered a valid arithmetic rule. In this case we should complain bitterly.

The ENDCASE line simply marks the end of the construct: this is how we know where to continue execution after one of the WHEN or OTHERWISE branches has been executed.

### Mean-While

The next control statements you'll find useful are WHILE-ENDWHILE and REPEAT-UNTIL, which are closely linked. As the names suggest, these allow you to repeat sections of your programs again and again, dependent on certain conditions which you specify.

Let's have a look at WHILE-ENDWHILE first by considering Listing 2; this simple-looking program implements a very basic password protection system. Let's see how it works.

### Listing 2

```REM >Listing2
:
ON ERROR REPORT:PRINT " at line ";ERL/10:END
MODE 0
:
WHILE pword\$<>"AU"
ENDWHILE
END
```

First, we get the password into pword\$ in line 6. The construct between lines 7 and 10 executes in very much the same way as it reads: 'while the password is not "AU", print Access denied, get another password, and go back to check the password again.' The tricky part is looping back: this is what ENDWHILE does.

If the condition in line 7 is not met - in other words, the password entered is in fact correct - then none of the lines between the WHILE and ENDWHILE are executed, so if the correct password is entered, the program simply prints that the password is accepted, and it terminates. Otherwise the program goes round and round until the correct password - AU - is entered.

Do note that in this particular example, pressing ESCAPE will terminate the program; if we wanted to prevent this, we could simply change line 3 to ON ERROR RUN, which would mean that if an error occurred (such as the user pressing ESCAPE) the program would be re-run. Try the change, but make sure you've saved all your desktop files first, just in case you make a typing error.

The second construct is REPEAT-UNTIL. Look at Listing 3.

### Listing 3

```REM >Listing3
:
ON ERROR REPORT:PRINT " at line ";ERL/10:END
MODE 0
:
count%=0
REPEAT
count%=count%+1