After all, you're only human
By IAN MURRAY
EXCRUTIATING ... UGH! ... what on earth does that mean ... Oh
no - not again!
These are some of the more printable cries of frustration that
a typical home micro user is likely to utter when trying to run
much of the software currently available.
Nor is the home micro user alone in his frustration. There is
a wealth of useless software available for the educational market
as well.
This yields comments such as: "Oi Sir - look what this
does". Or: "Is it meant to do that Miss?"
Or, more insidiously, just silence as the youthful scholar finds
that the program has crashed and begins to roam around the operating
system as if it were a huge doodle-pad.
A user friendly program is one that accepts that the user is
actually a mortal human. Which means he is quite capable of acting
like a demented maniac in charge of a cruise missile.
It assumes that each and every key on the keyboard will be pressed,
in any combination, at some time - even if it is only done 'just
for fun'.
Ideally this should extend to the ON/ OFF switch at the back
of the BBC Micro. But for the purposes of this article I take
it that you have already guarded against that particular act of
malevolence.
User friendliness can be divided into three main areas:
• Anticipating the actions of human beings.
• Helpfully correcting the actions of human beings.
• Making the human being feel he is not dealing with a computer.
The first is the subject of this article while the latter two
will be covered in future issues of The Micro User.
The first two keys to deal with are BREAK and ESCAPE. If you
have version 1.0 of the operating system or later, then your options
are slightly wider. Find out which you have by typing *FX0.
As the BREAK key resets the whole system, this should be dealt
with at the earliest opportunity in any program. The method shown
in the User Guide is probably the best:
10 *KEY10 OLD¦MRUN¦M
The only major problem is if you have used the permanently resident
integer variables (A% to Z%) and assume that they are reset to
zero when you run. They are not.
Your next lines of Basic must then assign the start values you
want to any of these variables, such as:
20 B%=0:D%=0
Now on pressing BREAK your program will not let the user have
a tour of the operating system and will re-run successfully. Provided,
of course, that you haven't used any clever tricks such as deleting
part of the program as you run.
The easiest way of dealing with the ESCAPE key - and this is
applicable to all operating systems - is to trap it with the ON
ERROR command.
This, like trapping the BREAK key, must occur at a very early
stage in the program. For example:
10 ON ERROR GOTO 500
As the ESCAPE key is considered as error message 17, pressing
it directs you to line 500. Subsequent lines at 500 could be as
follows:
500 IF ERR = 17 THEN RUN
520 MODE7
530 REPORT
540 PRINT;" at line "ERL
550 END
The solution is fundamentally unsatisfactory as we now have
two keys on the keyboard which will re-run the program.
Because we reached line 500 via an absolute jump we cannot retrace
our steps to where we came from.
But fear not! Sir Galahad Acorn has provided a solution to the
gallant knights with OS 1.0 and OS 1.2.
We may either 'hang up' the ESCAPE key entirely or re-assign
it to another key:
10 ON ERROR GOTO 1000
20 *FX229,1
30 REPEAT
40 PRINT"PRESS ESCAPE"
50 PRINT"No luck!!"
60 PRINT"Press Q to exit"
70 A$=GET$
80 UNTIL A$="Q"
90 PRINT MISTAKE
1000 MODE 7
1010 REPORT
1020 PRINT;" at line "ERL
1030 *FX229,0
1040 END
The *FX229 call has been used to turn off the ESCAPE key at
line 20 and turn it on again at line 1030, which presumably you
would wish to do. When you run the program you will notice that
the ON ERROR has not been affected and correctly traps the deliberate
error at line 90.
You may, of course, decide that your programs should still have
an ESCAPE get-out. This is possible by assigning the ESCAPE key
to another key, again at line 20.
You ought to choose a key that has no conceivable use. I suggest
CTRL-O:
20 *FX220,0
This is keys CTRL and @ pressed down together. To restore ESCAPE
to its rightful key, line 1030 should be:
1030 *FX220,27
I personally would avoid *FX220 calls in the finished program
as it still provides the user with a combination of keys with
which to experiment, and sooner or later some latent Einstein
will find them.
I suggest using the *FX220 call while developing pre-release
versions of the program.
When using the ON ERROR command make certain that you direct
it to a line that exists. If you don't you will get a program
that gives an impression of locking-up, but is in fact in an endless
ON ERROR loop.
Having dealt with the obvious keys, you still have to out-smart
the nine year old's propensity to destroy all your handiwork.
Now you have to anticipate his every move across the keyboard.
Can you do it? Is it even possible?
The secret is to never use the INPUT or INPUT LINE commands
as up to 255 characters can be entered with these commands. Someone
merely repeating a key could enter a string so long that it would
corrupt the screen display.
The answer is to always use the GET and GET$ commands, which
only collect a single character at a time. You will need to provide
your own delete routine where you think it's needed (see below).
However firstly turn off the auto repeat feature at the beginning
of the program with:
10 *FX1l,0
This will at least protect you from accidental entry of more
than a single character.
Where your programs are menu driven - that is, your progress
through the program depends on an item selected from a screen
menu - then you should lay out your display something like this:
PROGRAM OPTIONS
A) Create a File
B) Amend a File
C) Delete a File
D) Sort a File
E) Search a File
Select a letter from A to E >>
The section of program to select from the menu may look like
this:
200 PRINT "Select a letter from A to E >> ";
210 REPEAT
220 LET Reply$ = GET$
230 UNTIL Reply$ >= "A" AND Reply$ < "F"
No other input will successfully get past this. However you
may be locked in the wrong size letters - small instead of capitals.
Line 230 can be extended with a complicated logical expression
to cater for this or you may use the following alternative:
230 UNTIL INSTR( "ABCDEabcde" , Reply$) > 0
This again is not totally satisfactory as your analysis of the
menu selection will still involve you in converting the lower
case letters to upper case before deciding what action your program
is to take.
For this reason it is better to use numbers on the menu selection.
But take the number in as a character. This would involve a change
of line 230 to:
230 UNTIL Reply$ > "0" AND Reply$ < "6"
with the other obvious changes in any menu.
As a program designer you must decide whether the theory of
your program will allow the user, in answering a question, to
enter any character or a selection from a limited subset of characters.
This is particularly relevant when trying to get in numbers,
or even names.
For example, when entering numbers you may feel that you will
allow 0123456789., but not allow other valid mathematical characters
such as "-/ +*". This is possible using the GET$ command,
but not possible with the INPUT commands.
You will presumably still want the RETURN key to be used to
signal the end of the numbers' input. The following suggestion
may help your thinking:
100 PRINT "Enter a decimal number >> ";
110 REPEAT
120 REPEAT
130 R$=GET$
140 UNTIL R$ = CHR*(13) OR INSTR( "0123456789.",R$ )
> 0
150 PRINT R$;
160 IF R$ <> CHR$(13) THEN Number$ = Number$ + R$
170 UNTIL R$ = CHR$(13)
180 Number = VAL(Number$)
190 PRINT
200 PRINT Number
You can extend your control over the input by putting a restriction
on its length at line 160 with the use of the LEN command. However
the implication of this is that you will need to write your own
delete routine.
This routine involves counting-in every character that passes
any other restrictions you may have, and allowing the delete character,
CHR$(127), to be printed to the screen but not added to the final
accepted string of characters.
Of course you will have to remove the most right hand character
from the string input.
Restricting the length of the string input creates a snag. You
must allow the delete character to be the only character that
can be the "length of the string + 1", so that you may
delete the last character if required. A simple example of this
is shown in Figure I.
With little difficulty this type of routine can be made a procedure
with parameters that can be specified. This will ensure your program
does not slide to an unsuitable length.
The important point is that if the programmer is to be truly
user friendly in controlling and directing the user's general
keyboard inputs, then the program will inevitably be lengthy.
As a rule of thumb, I believe you must expect 90 per cent of
every program to be devoted to user friendliness, and only 10
per cent to the algorithm.
The cursor control and copy keys should also be taken out of
action unless required in the program. From OS 1.0 onwards you
may do this by using the *FX4,1 or *FX4,2 calls.
The former disables cursor editing and the latter permits redefinition
of these keys similar to the red function keys. The normal mode
is turned on with *FX4,0.
Subsequent articles will look at validation, helpful ways of
correcting the user's errors, and how to make your BBC Micro actually
seem relatively human.
Till then, a final tip: Always try your programs out on a complete
dodo. In the business of friendliness there's none better than
a complete idiot to discover what a fool you have been!
100 CLS
110 C=0
120 PRINT 'Enter a four digit number >> ";
130 REPEAT
140 REPEAT
150 R=GET
160 R$=CHR$(R)
170 Z=INSTR( "0123456789" , R$ )
180 UNTIL R=13 OR Z<>0 OR (R=127 AND C>0)
190 C=C+1
200 Number$ = Number$ + R$
210 IF R=13 THEN C=C-1
220 IF R=127 THEN C=C-2
230 N$ = LEFT$(N$,C)
240 IF ( C>4 AND R<>13 ) THEN C=4:R$=""
250 IF R<>13 THEN PRINT R$;
260 UNTIL R=13 AND C=4
270 Number = VAL(Number$)
280 PRINT
290 PRINT Number
Figure I