One of the things we must usually do with our program is get a response from the user. Unexpected responses can cause the program to crash or display unexpected results. The coder's job is to get the intended response. Often this can be quite simple....
INPUT "Do you wish to continue? (Y/N)"; UR$ 'Get User Response
IF UR$="Y" or UR$="y" THEN [doSomething] 'Branch to next module
'If the response fails the comparison, continue with this code
CLS
PRINT "Okay, come back again. Goodbye!" : GOTO [quit]
This works fine for many applications. We've asked the user for input and recommended a response in the form of (Y/N). If the user enters Da, Ja, Si, or Oui, the code falls through the IF/THEN comparison and closes. Unfortunately, it also falls through if the user responds, YES, Yes, or yes, because more than one character is an invalid response. We can improve the comparison by checking only the left-most letter of the user input.
INPUT "Do you wish to continue? (Y/N)"; UR$
UR$=UPPER$(UR$)
IF LEFT$(UR$, 1)="Y" THEN [doSomething}
CLS
PRINT "Okay, come back again. Goodbye!" : GOTO [quit]
Converting to UPPER$ will also accept y, yes, yeah, yePPers or Yowza Boss. If the left-most character is "Y", the user is sent to [doSomething] where the program can proceed, or the comparison falls through, prints "Goodbye..." and then closes.
Recommending an appropriate response will often get the user pointed in the direction we want, but there are users who will do everything possible to crash your program. This is useful to 'bullet-proof' your code, and is the reason we have people called 'beta testers.'
Getting text input from the user can often lead to unexpected results. You can never tell what text will be provided. Checkboxes or push-buttons are less ambiguous if you can properly word your test.
One way to 'bullet-proof' your code is to limit the user's response by allowing only choices we want, sort of like those annoying automated telephone responses, "Please press 3 if you wish to place an order now." You have to wade through endless responses before you get to, "If you need assistance, please stay on the line." Sometimes you're not even lucky enough to hear those magic words because it is not a programmed response. Don't order... do your shopping elsewhere!
When comparisons are 'bullet-proofed,' the user cannot enter a response you have not allowed for. The following code uses a GUI to trap the user response, and there are only three choices, YES, NO, or click the X to trigger the trapclose and exit the program. Unfortunately, we don't know if the user is truthful. (Well, life always has it's uncertainties.)
'GUI Response Demo
NOMAINWIN
'Array for queries
FOR cntr=1 to 5
READ temp$ 'DATA statements within the main program, data must
'first be read to a temp variable before loading into an array.
UR$(cntr) = temp$
NEXT cntr
WindowWidth = 300
WindowHeight = 200
UpperLeftX=int((DisplayWidth-WindowWidth)/2)
UpperLeftY=int((DisplayHeight-WindowHeight)/2)
STATICTEXT #main.static1, "Bed Time Check List", 25, 25, 250, 36
BUTTON #main.btn1, "YES",[getInput],UL,75,100,60,25
BUTTON #main.btn2, "NO",[negativeReply],UL,175,100,60,25
OPEN "Get User Response" FOR window AS #main
PRINT #main, "trapclose [closeWin]"
PRINT #main.static1, "!font arial 18"
PRINT #main.btn1, "!disable"; 'Prevent fiddling that will cause crash
PRINT #main.btn2, "!disable";
TIMER 2000, [skip]
WAIT
[skip]
TIMER 0
PRINT #main.btn1, "!enable"; 'Okay, now you can fiddle
PRINT #main.btn2, "!enable";
PRINT #main.static1, "!font arial 14"
[getInput]
DO UNTIL k=5
k=k+1
PRINT #main.static1, UR$(k)
WAIT
LOOP
'If all queries answered.
PRINT #main.btn1, "!disable"; 'No more fiddling
PRINT #main.btn2, "!disable";
IF k=5 THEN PRINT #main.static1, "OK, have a good night!"
TIMER 3000, [closeWin]
WAIT
[negativeReply]
PRINT #main.btn1, "!disable"; 'Make sure response is in proper window
PRINT #main.btn2, "!disable";
WindowWidth = 300
WindowHeight = 200
UpperLeftX=75
UpperLeftY=75
STATICTEXT #win2.static1, "", 25, 25, 250, 90
BUTTON #win2.btn1, "CLOSE",[close2],UL,120,120,60,25
OPEN "Are you sure?" FOR window AS #win2
PRINT #win2, "trapclose [close2]"
PRINT #win2.static1, "!font arial 14";
winFlag=1 'Show this window as open.
SELECT CASE k
CASE 1 : PRINT #win2.static1, "It is strongly recommended" _
+" that you put the cat out" _
+" for the night."
CASE 2 : PRINT #win2.static1, "In the interest of power " _
+" conservation, you really should" _
+" turn the lights off."
CASE 3 : PRINT #win2.static1, "For safety sake, the computer " _
+" should be off in the " _
+" event of a storm."
CASE 4 : PRINT #win2.static1, "Worbles do not work as well " _
+" as they could if they dont't " _
+" have a full night's sleep."
CASE 5 : PRINT #win2.static1, "You're simply asking for" _
+" trouble if you leave the " _
+" doors unlocked."
END SELECT
WAIT
[close2]
winFlag=0 'Show this window as closed.
PRINT #main.btn1, "!enable"; 'Allow new response
PRINT #main.btn2, "!enable";
CLOSE #win2
GOTO [getInput]
WAIT
[closeWin]
TIMER 0
IF winFlag<>0 THEN CLOSE #win2 'Close #win2 if still open.
CLOSE #main
END
DATA "Is the cat out?"
DATA "Are the lights off?"
DATA "Is the computer off?"
DATA "Are the Worbles asleep?"
DATA "Are the doors locked?"
DATA "There is no more data."
The flow of code should be fairly easy to follow. First we load an array to display questions to the user. A window is opened and a message displayed for two seconds, telling the user what to expect, a Bed Time Check List. The yes and no buttons are disabled to prevent the user from responding before we want him to.
After the message has been displayed, the response buttons are again enabled and the first question is presented. A Yes answer proceeds to the next question; a No answer branches to a SELECT CASE block where the appropriate caution message is displayed before the next question is presented. Again, buttons are enabled or disabled to prevent fiddling with program flow. Only when all questions have been answered affirmative, or the user has been prompted to perform another action, is the Good Night message displayed and the program terminated.
In this demo, the user can only answer Yes or No by pressing a button, no other option is permitted except closing the window by clicking on the X in the upper right corner. The variable winFlag will close the caution window if the user closes the Check List while the caution window is still open. We can't follow the user around the home to be certain all tasks have been completed, but we can remind the user what needs to be done before retiring. Of course, this is but a simple checklist; other applications with dozens of options can use similar methods to create programs which are nearly 'bullet-proof,' to the best of our ability.
You can also limit the user's options by using a list box, or multiple list boxes. To enter a birthday, for example, the first box would be month, the second, day, and finally a list box for the year. If your expected user is a Boy Scout, you could test to insure the age is greater than 12 or less than 21. If your user might be a member of AARP, test to see if the user's age is more than 50. Combining the two options in the same program is possible, but you'll have to write more code to determine if the user was once a Boy Soout but is now retired. Don't you just love a challenge?