UNIT 3: Setting conditions and making choices

If you use Windows or a similar operating system, you will be used to working in a WIMP environment . (The term WIMP, by the way, was probably "borrowed" by journalists from computer vocabulary and turned into a political jibe: it was originally an innocent acronym standing for "Windows, Icons, Menus, Pointer"). In a WIMP environment, you select a procedure by clicking on an item in a menu list, which in turn may display another window, with another list, in which you click on another item, in another list, and so on.

By contrast, when you produce a tailor-made BBC BASIC program, you write the selection process into the program itself. Initially it takes more work, but in the longer term you do not need to create, and then maintain, a vast menu of options aimed at a large and diverse market. That said, whether you click on a windows icon or select a sub-program within a BASIC program, the act of selecting from a choice of options is called conditional branching, because the procedures to be adopted can branch off in different directions, depending on what condition is set.

BASIC keywords IF, THEN, OR, ELSE, GOTO

Conditional branching can be illustrated at its simplest level by means of a brief program to remind you what to wear if you have advance information about the weather - say from a small weather station linked to your computer (and yes - they do exist!)

10 PRINT' ' "Is it going to rain or shine? R/S";:INPUT answer$
20 IF answer$="R" OR answer$="r" THEN GOTO 30 ELSE GOTO 50
30 CLS: PRINT' ' "Don't forget to take your umbrella."
40 END
50 CLS: PRINT' ' "Don't forget to take your sunglasses."

In the above program the condition set in line 20 is a string variable - and the keyword OR, which permits the option of upper or lower case in your reply, prevents the program from crashing. But the condition could just as easily have been a numeric variable. Why is the keyword END necessary in line 40? Try it without - and you will find that whether it's rain or shine, the program defaults to sunglasses. Why? Because without the command END, the program option which selects line 30 completes the task set in the designated line and then moves on to the next line, which clears the screen and then moves on to the next command in the last line. The result is that although the instructions in line 30 are carried out, they are carried out so quickly, and the screen then cleared, that we do not see the memo. We will return to this vital use of END in the syntax below for handling procedures. What this mechanism provides is the potential for incorporating executive decisions in a program, depending on whether a given target figure is or is not met.

Procedures: BASIC keywords PROC, END, DEFPROC, ENDPROC

The BASIC keyword GOTO should be used sparingly and only in very short, simple situations such as the one above - otherwise the logical flow of the program becomes like an unravelled sleeve, and the thread becomes lost. A much better approach is to set a condition in such a way that if it is fulfilled, the program sets into motion or "calls" a given "procedure", i.e. a mini-program within the overall program itself.

To illustrate the necessary syntax, we can go back to the short program above, which shows the mechanics of conditional branching. But instead of using GOTO, we will present the choice of options in the form of procedures, as follows:

10 PRINT ' ' "Is it raining or is the sun shining R/S";:INPUT answer$
20 IF answer$="R" OR answer$="r" THEN PROCrain ELSE PROCshine
30 END
40 :
50 DEFPROCrain
60 CLS: PRINT ' ' "Don't forget to take your umbrella."
70 ENDPROC
80 :
90 DEFPROCshine
100 CLS: PRINT ' ' "Don't forget to take your sunglasses."
110 ENDPROC

This sample program appears at first sight to be more complicated than the original one, containing GOTO, but its purpose is to exemplify certain vital rules in drafting procedures, which, if followed, will reveal the underlying simplicity in an otherwise complex operation.

Firstly, in the main body of the program, you give your procedure a name, and prefix that name with the keyword PROC, without any spaces. This is a command which may be summed up as: "Carry out the named procedure as defined below." Note that the defined procedure will simply remain inactive, on standby, unless it is "called" here. When you have thus set up the mechanisms to call the procedures, it is vital that you type END, to separate the command and control section of the program from the section which defines the detail of the procedures to be executed. The colon in lines 40 and 80 is merely a visible separator between sections. The keyword for the definition of each procedure is DEFPROC, which must be prefaced to the mini-program called by the main program. When you reach the end of this mini-program, it must be hermetically sealed off from its immediate environment by means of the command ENDPROC.

This short pattern program illustrates the strategy for creating large-scale programs, in which procedures are stored as sub-divisions of a system for selecting options, where the procedures can be called whenever certain pre-set conditions are fulfilled.

Maintaining your bank balance

In Unit 1 you used BBC BASIC for simple arithmetical jobs. It would be a good idea to revise the work you did now, in order to bring your current bank balance up to date, since the next learning task is to explore the use of procedures for creating a bank balancing program. When you have obtained your current balance by conventional arithmetic, you need to create a datafile to store it, so that it then forms the INPUT of the bank balance update program every time you use it.

Herewith the program to create the datafile:

10 REM: program to create a bank balance datafile.
20 @%=&20209
30 PRINT '"Enter the current balance of the account"
40 INPUT balance
50 X=OPENOUT "cashbox"
60 PRINT#X,balance
70 CLOSE#X

Everything in this program should be familiar to you now - except, perhaps, line 20 which ensures that for cash transactions your figures are printed with two decimal places. Once you have RUN this program, there is no need to do so again: the datafile has been created, and it will now form the input into, and output from, the main program which follows. (Note the use of lower case for the variables and data, and the use of long variable names: this feature of programming style, made possible by BBC BASIC, has the advantage of making it easier to distinguish commands and statements, in upper case letters, from variables and data in lower case. Note additionally, in the program which follows, the use of colons to separate out the difference sections of the program. There can be drawbacks to using long variable names in lower case, which we shall discuss later. For the moment we need to read and write programs which follow the convention.)

10 CLS
20 @%=&20209
30 PRINT '"Personal account balance"
40 REM BANK BALANCE
50 :
60 X=OPENIN "cashbox"
70 INPUT#X,balance
80 CLOSE#X
90 :
100 PRINT'"The opening balance on ";TIME$;" is GBP";balance
110 :
120 REPEAT
130 PRINT '"Choose the appropriate transaction:"
140 PRINT "deposit/withdrawal. Type END to finish."
150 INPUT T$
160 CLS
170 IF T$="deposit" THEN PROCdeposit
180 IF T$= "withdrawal" THEN PROCwithdrawal
190 IF T$="END" THEN GOTO 420
200 UNTIL T$="END"
210 END
220 :
230 DEFPROCdeposit
240 REPEAT
250 PRINT
260 INPUT "Enter the deposit. Type 0 to finish. GBP",deposit
270 balance=balance+deposit
280 CLS
290 PRINT '"The new balance is GBP";balance
300 UNTIL deposit=0
310 ENDPROC
320 :
330 DEFPROCwithdrawal
340 REPEAT
350 INPUT '"Enter the withdrawal. Type 0 to finish. GBP",withdrawal
360 balance=balance-withdrawal
370 CLS
380 PRINT'"The new balance is GBP";balance
390 UNTIL withdrawal=0
400 ENDPROC
410 :
420 PRINT'"The balance as at ";TIME$;" is GBP";balance
430 :
440 Y=OPENOUT"cashbox"
450 PRINT#Y,balance
460 CLOSE#Y
470 PRINT '"Remember to check standing orders & direct debits."
480 PRINT'"The program is now closed. To restart type RUN."

Now for the detail in the program. Line 60-80 input the balance from the datafile you have created. Line 100 prints the balance out. Lines 120-200 enable you to go through your cheque stubs and salary slips - or any other outgoings or income - and INPUT them into the program. The program goes in a loop: it repeats the possibility of entering every transaction you need to enter until you stop it by typing END. It also branches to the procedure in lines 230 to 310 for deposits, or to the alternative procedure in lines 330 to 400 for withdrawals. Once you type END, the procedures are finished and the program defaults to recording the new balance on the datafile. Now suppose we want to introduce a degree of automation by having standing orders and direct debits automatically deducted on the due dates? For this we need the keyword TIME$, which prints out the date and time as a string.

Operations on strings

In any walk of life certain jobs have to be done at certain times on the calendar. And the computer itself can be programmed to do a given task on a given date. In other words, IF the date tallies with a given condition set in the program, THEN a stored sub-program is put into operation - a "procedure" is "called". But how do we get the date to tally with the condition we want to set?

The easiest way is to print it out as a string, then carry out a "string-slicing" operation to select the "slice" of the date we want, and IF the selected slice corresponds to our given string variable set in the condition, THEN a given procedure can be put into operation. BBC BASIC has excellent string-slicing facilities which make short work of this job. However, we first need a specimen string on which to work, and the one which we shall select - the date and time - is provided as a resident function in BBC BASIC: it is returned when you type in the command PRINT TIME$, and displays the date and time in the following format:

Mon.14 Feb 2000,08:18:08

This gives us complete information on day, time and date, but we do not necessarily need all this. If we want to print out the date on an invoice or a letter, we only need a "slice" of it. How do we get it?

BASIC keywords LEFT$, RIGHT$, MID$

Assuming we only want the day and the date, then our choice is for the first fifteen characters, including spaces, from the left hand side of the string. The syntax is as follows:

PRINT LEFT$(TIME$,15)

If we only want the time, then our choice is for the last eight characters of the whole string. The syntax is as follows:

PRINT RIGHT$(TIME$,8)

If, on the other hand, we want the date alone, then we want the middle eleven characters, starting at the position of the fifth character in from the left. The syntax is as follows:

PRINT MID$(TIME$,5,11)

This remains true irrespective of whether the number of the day in the month is in single or double figures, since a single-figure day is preceded by a leading zero in BBC BASIC for the PC. (In the PRINT TIME$ function on the Z88, however, the day name is not abbreviated and there is no leading zero! Fortunately the Z88 alarm function can be programmed to execute BASIC commands on any given date.)

BASIC keyword VAL

Assuming that we are using the date function on BBC BASIC for the PC, we can set conditions depending on the figure inside the date string by means of the keyword VAL. This operates on a figure inside a string, where it has no numeric value, and converts the figure back into a number, so that calculations can be performed on it. To illustrate this, let us assume that today is St. Valentine's day, and that we want to print out a date one week ahead of today's date - in other words, the 21st instead of the 14th. Let us first obtain the date for today:

10 PRINT TIME$
20 DAY$=MID$(TIME$,5,2)
30 D=VAL(DAY$)
40 D=D+7
50 PRINT "In seven days the day will be"; D

As an Assignment, try to work out what to do if D runs over the end of the month! It will test your mastery of conditional branching, and we we look at possible answers next time. Meanwhile we will look at further uses of the date, in string form, in setting up a memo program which incorporates the date. If it's Granny's birthday in a week's time, then we need to get her a card.

Equally, returning now to the bank balancing program discussed above, if a direct debit or standing order is due to be paid on a given date, then the sum must be deducted automatically from the balance. It would obviously be a waste of effort to write a separate program for every reminder - so we need a standard framework into which we INPUT each date and the appropriate event, so that the program will PRINT the reminder on the date due. Here's an outline program, which adopts a different strategy from that of VAL for meeting a date condition:

10 INPUT ' ' "Enter the date to be retrieved, in the following form: Mon.14 Feb",date$
20 CLS
30 INPUT ' ' "Enter the memo to be printed on this date. Enclose the memo in speech marks.",memo$
40 T$=TIME$
50 D$=LEFT$(T$,10)
60 IF D$=date$ THEN CLS: PRINT ' 'memo$

Now let us analyse the mechanics of the program. Lines 10 and 30 should, I hope, be self-evident as INPUT lines. Line 50 slices the time and date string supplied by BBC BASIC, so that only the day of the week, and the date within the month, and the month itself (in abbreviated form) are selected. Line 60 then compares today's date in this form with the date you have selected for your reminder. If the two match, then your memo is printed out. As an Assignment, see what you can do to use this combination of conditional branching and string slicing to write procedures into the bank balancing program for paying standing orders and direct debits on given dates.

Incidentally, if you still have a BBC Master, although the TIME$ function "terminates" at the end of the 20th century, the figure 19, representing the previous century, is a fixed string which can be sliced out and replaced by 20. Try it.

Using the Reference Manuals

At this point you have covered enough ground in BBC BASIC to be able to make good use of the online BBC BASIC Reference Manual alongside this Tutor. This will involve starting a glossary - in a notebook or on computer file - of technical terms, which we shall update as we go along.

If you are a veteran of the BBC Micro, and found the User Manual difficult to follow in a systematic way, now is the time to take another look at the Reference Section, containing the Keywords, on p.197 of the Model B manual, or p.170 in that of the Model B+. The key to keywords themselves is to be found in the preamble to the section in question. (Hands up how many BBC Micro veterans actually got as far as reading it???) What the preamble shows at this point is that the BBC Micro, as the then most powerful new machine in its price category, was marketed both for the beginner and the expert. So in order to make use of it now, you need to distinguish what was meant for the beginner from what was meant for the professional expert designing software. Two fundamental rules would be well worth observing :
a)Don't be discouraged if you don't understand everything at once: just incorporate what you can understand into your glossary of keywords.
b)If a point of syntax is designated as optional (i.e. in square brackets), regard the omission of the item as a time-saver for the professional which you yourself should not omit until you know fully what you are doing!

This latter point can best be illustrated by an example drawn from the keywords we use in conditional branching itself. The preamble in the BBC Micro Manual states that square brackets - [ ] - enclose commands which you can omit. You are then given an example of the omission of the keyword THEN in IF...THEN statements. But beware: the Z88 BBCBASICZ80 manual goes into even smaller print and states that you do need to use THEN if it is followed by a line number, a star (*) command or an "assignment of a pseudo-variable" - clearly for the techie! What neither manual tells you is that if you are a beginner, you should play safe and postpone decisions about omitting "optional" items of syntax until a later date. Once you accept that the reference section is alphabetic rather than logically sequential, you are free to select only what you understand at any given time, and to return later.

Whilst on the subject of brackets, two of the most frequently encountered abbreviations to be met inside triangular brackets - <> - in the manual definitions, are num-var and string-var. These mean, respectively, "numeric variable" and "string variable", with which you are familiar. The brackets like those in musical notation {}show you can have more than one item inside the brackets, and the vertical bar | indicates a choice between two items.Two more essentials in the understanding of syntactical definitions are the words "arguments" and "return". The term "arguments" has nothing to do with having a row! In logic it simply means a set of linked propositions, pointing towards a conclusion, and in arithmetic it has an even simpler meaning: if you say 2+2=4, then 2 and 2 are the "arguments" which "return" the answer of 4. Note that the "Enter" key on the keyboard is also called the "Return" key. Although in origin the carriage return key on a typewriter, it "enters" data and "returns" the answer in a mathematical operation. These notes should enable you to start navigating your way through the online reference manual for BBC BASIC on the website. That is your second Assignment for Unit 3. Your third Assignment is to become fluent in using the syntax for procedures by reworking some of your earlier programs to include them.

Similarly, although BBC BASIC has migrated from the Acorn machines to the IBM PC and compatibles, there are websites related to the old machines will still - for a limited period now - provide support. If you still have a BBC Micro, and want to access vast libraries of historic PD software - before it gets swept into the bin of history - then visit the webpage of Solinet, the last national disk-based BBC Micro user group, at http://www.solinet.org.uk. Classic BBC Micro machines, and spares, are still available from Chris Richardson at 8bs.


UNIT 3Z Printing out from BBCBASIC on the Z88

As was stated in Unit 2, the task of printing out from BBC BASIC on the Z88 is more complex than on the PC, and needs individual treatment. Although this appendix to Unit 3 is directly intended for the Z88 user, the principles discussed will be of interest to the general student of BBC BASIC for the PC.

At this point we need to take a long, hard look at the program for "Printing from BASIC", which is to be found in the middle of Section 10 (BBC BASIC) of the Cambridge Z88 User Guide. It is all too easy for the beginner to take for granted that everything in the program is necessary for printing out from BASIC, whereas in reality the program is intended to demonstrate a wide range of features, from which the user can select what he or she requires. For the sake of convenience, the program can be cited here:

100 LET PRT_ON$=CHR$(5)+"["
110 LET PRT_OFF$=CHR$(5)+"]"
120 LET LF$=CHR$(10)
130:
140 LET PRT=OPENOUT":PRT"
150 IF PRT=0 THEN PRINT" CAN'T OPEN PRINTER ":STOP
160 :
170 PRINT#PRT,PRT_ON$
180 FOR I=1 TO 4
190 PRINT#PRT,"Text "+STR$(I*PI)+" and numbers!"+LF$
200 NEXT I
210 PRINT#PRT,PRT_OFF$
220:
230 CLOSE#PRT

When run it prints the following:

Text 3.14159265 and numbers!
Text 6.28318531 and numbers!
Text 9.42477796 and numbers!
Text 12.5663706 and numbers!

To make sense of this catalogue of features, you have to go back to Unit 1 and revise the keyword PRINT. Although the screen is the default device, it is not the only device to which data for printing can be routed after the command PRINT is issued. When you type VDU2, either on the BBC Micro or within BBC BASIC for the PC, keyboard output is routed to the printer. However, whereas the BBC Micro and the PC have both a printer port and a communications port, the Z88 has only one "input/output" port, which has to double up as a printer and communications port. So the device to which the output from the keyboard is to be routed has to be named in the program as the printer. Now for the program in detail.

Since in Unit 2 you learnt how to do a FOR...NEXT loop, you will see here that there is a loop running from lines 180 to 200. It has to be stressed that the loop is not necessary for the task of printing out itself, and merely illustrates the syntax for including a loop: the counting character I multiplies the value of PI four times in a row, by a factor which increases by one each time it goes through the loop. To verify this for yourself, cancel the loop by deleting lines 180 and 200, and substitute, in line 190, the very simplest data to be printed, by typing PRINT "HI!" OR PRINT 2+2.

To sum up so far, you use the same syntax to send print to the printer as you do to send print to the screen, except that you route it to the printer by treating it as if it were a file with the filename PRT.

That said, the business of switching the printer on and off is also more complex on the Z88 than on the PC, and the commands VDU2 and VDU3 don't work on the Z88. Let us now look at the program, quoted above, and interpret line by line:

100 The variable name PRT_ON$ is assigned as an easily intelligible BASIC equivalent of the code which switches the printer on. Similarly, in line 110, PRT_OFF$ is assigned to represent the code for switching the printer off.

120 If you now turn to Appendix D -(Character Set) of the Z88 User Guide, and look down the Decimal column, you will find that CHR$10 represents Line Feed, which is represented in this line by the string variable LF$.

130,150,220 The colons in these lines serve simply to provide visible spaces between the separate sections of the program.

140 If, in addition to the Cambridge Z88 User Guide, you also have D.J. Mounter's The BBCBASIC(Z80) Reference Manual for the Z88, turn to Section 6 on the Operating System Interface. Here you will find that the code for output to the printer (:PRT.0) is classified under the heading of File Specifiers. In other words, just as you can file a Z88 program or text to the two memory devices :RAM.0 or :RAM.1, you treat the output from BASIC to the printer as if it were a file, and you use the same keyword, OPENOUT, which you met for printing data to file in Unit 2 of this Tutor.

150 If you share a printer between your Z88 and your PC, and you forget to plug in your Z88 printer cable, this line tells you that there is a break in the line of communication between the Z88 operating system and the printer.

Clearly the authors of the User Guide designed this demonstration program to show the range of options available. At a later stage in our studies, more options will be added in the way of inserting codes for underlining, printing bold and using italics. For the moment it has to be stressed that the loop in the demonstration program is there as an illustration and is not part of the essentials for printing from BBC BASIC!

170 In accordance with the syntax detailed above, this program line switches on the physical line of communication from BBC BASIC on the Z88 to the printer.

180 This sets the counter variable at 4 for the loop which follows.

190 This sends the output from the program to the printer as if it were a file, as detailed above. The inverted commas act in the same way as they do for printing text on the screen - but here the device to which the text is sent is the printer. The plus sign is like a link in a chain: it joins together each separate item that is to be printed out on the same line. STR$ is a function which converts the numeric result of the calculation in brackets into a string. The reason for this is that the plus sign, which "concatenates" or links together the text and numbers to be printed out, must not be allowed to operate arithmetically on the numbers themselves. I*PI multiplies the value of PI (3.14) by 1,2,3 and 4 in succession, as set up by the counter variable I in line 180. You can control the number of decimal places in the answer to the calculation if you wish. If you are doing cash calculations, for example, and only want two decimal places, then type the command @%=&20209 at the beginning of your program.

200 This sends the program round in a loop back to line 180, and thus causes the value of I to be incremented by one each time it goes round.

210 This switches off the printer.

230 This closes the file which has provided the communication line between BBC BASIC and the printer.

To emphasise that the program in the Z88 User Manual is intended to illustrate a wide range of possibilities, try this shorter program from the leaflet accompanying the Z88 printer cable, supplied by Rakewell Ltd. It is reproduced here by kind permission of Vic Gerhardi:

10 ch=OPENOUT(":PRT")
20 PRINT#ch,CHR$(5)+"["
30 PRINT#ch,"This is some text"+CHR$(10)
40 PRINT#ch,STR$(PI)+CHR$(10)
50 PRINT#ch,CHR$(5)+"]"
60 CLOSE#ch

Finally, if you want to toggle printer attributes such as bold print, underline, italics, etc., you will find them in section 7-13 of D.J. Mounter's BBCBASIC(Z80) Reference Manual. You should now have enough information to read Unit 2 in this Tutor again and adapt the printing routines described there from the PC to the Z88

Left UNIT 2

UNIT 4Right


Best viewed with Any Browser Valid HTML 3.2!
© Edmund Burke 2000