QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: MWheatley on September 23, 2018, 08:09:36 am

Title: Error trapping Y/N input
Post by: MWheatley on September 23, 2018, 08:09:36 am
My QB programs are mostly small routines that I developed for particular types of financial calculations, with some programs going back to the 1980s.

In recent years I've been adding to the collection, and have a query re: text input.

Although the numeric error-trapping that I perform is pretty good, I do no error-trapping on text input, which is usually of the Yes/No variety.

Could some kind soul suggest what might be good practice, ideally accompanied by a code snippet?

In other words, what might follow:

PRINT "Are the above values correct?  Y(es) to continue, N(o) to re-do from start."

I've never really bothered with this, as it has only ever been me using the programs.  But that might now change.

Malcolm


Title: Re: Error trapping Y/N input
Post by: SMcNeill on September 23, 2018, 08:39:44 am
DO
    LOCATE 1,1
   PRINT "Are the above values correct?  Y(es) to continue, N(o) to re-do from start.
   a$ = UCASE$(INPUT$(1))
LOOP UNTIL a$ = "Y" OR a$ = "N"
PRINT a$
Title: Re: Error trapping Y/N input
Post by: TerryRitchie on September 23, 2018, 10:26:12 am
Elaborating on Steve's code a bit. You can stay in the loop until Yes is selected by:

Code: QB64: [Select]
  1.  
  2. ' Your main code here
  3.  
  4.     LOCATE 1,1
  5.    PRINT "Are the above values correct?  Y(es) to continue, N(o) to re-do from start.
  6.   a$ = UCASE$(INPUT$(1))
  7. LOOP UNTIL a$ = "Y" ' loop back to beginning if No selected
  8. PRINT a$
Title: Re: Error trapping Y/N input
Post by: SMcNeill on September 23, 2018, 01:12:48 pm
The best solution in this case, I think, would be to alter Terry's code a bit:

DO
    'Main loop
    PRINT "Yes?  No?"
    DO
         a$ = UCASE$(INPUT$(1))
    LOOP UNTIL a$ = "Y" OR a$ = "N"
    PRINT a$
    'Stuff after
LOOP

************************

As Terry's code is written, it would have to go back and redo the whole program before asking for the Yes or No again, and that's not what you're actually wanting to happen.  You just want to trap the input until they give you the proper response that you're asking for, and the above is the simplest way to achieve that.
Title: Re: Error trapping Y/N input
Post by: Pete on September 23, 2018, 01:28:13 pm
I'm a fan of INKEY$, so...

Code: QB64: [Select]
  1.     REM This is the redo from start part.
  2.     PRINT "Examples of values: " + LTRIM$(STR$((INT(RND * 5 + 1)))) + " apples and " + LTRIM$(STR$((INT(RND * 5 + 1)))) + " oranges."
  3.     LOCATE 3, 1, 1 ' The third number shows the cursor.
  4.     PRINT "Are the above values correct?  Y(es) to continue, N(o) to re-do from start. ";
  5.     DO
  6.         _LIMIT 30
  7.         mykey$ = UCASE$(INKEY$)
  8.     LOOP UNTIL mykey$ = "Y" OR mykey$ = "N"
  9.     SELECT CASE UCASE$(mykey$)
  10.         CASE "Y"
  11.             PRINT mykey$;
  12.             EXIT DO
  13.         CASE "N"
  14.             LOCATE , , 0: REM hide cursor
  15.             PRINT mykey$;
  16.             _DELAY .5
  17.             CLS
  18.             _DELAY .5
  19.     END SELECT
  20.  

Pete
Title: Re: Error trapping Y/N input
Post by: MWheatley on September 23, 2018, 03:04:00 pm
Thanks, guys.  Some useful suggestions there.

I don't think I ever used INKEY$ -- am I right in thinking that it takes input straight from the keyboard without requiring a "return" to be pressed?

I will experiment and report back.

Malcolm
Title: Re: Error trapping Y/N input
Post by: bplus on September 23, 2018, 03:50:50 pm
Thanks, guys.  Some useful suggestions there.

I don't think I ever used INKEY$ -- am I right in thinking that it takes input straight from the keyboard without requiring a "return" to be pressed?

I will experiment and report back.

Malcolm

Yes
Title: Re: Error trapping Y/N input
Post by: MWheatley on September 24, 2018, 06:24:19 am
Thanks, guys.  Some useful suggestions there.

I don't think I ever used INKEY$ -- am I right in thinking that it takes input straight from the keyboard without requiring a "return" to be pressed?

I will experiment and report back.

Malcolm

Yes

Thanks!

Malcolm
Title: Re: Error trapping Y/N input
Post by: OldMoses on September 24, 2018, 08:23:13 am
I generally install the following stock function into all my code. Then reference it in an IF...THEN such as this:

IF Yes_Or_No$("Do you want to do something? Y/N ") = "Y" THEN
    ....yes code here....
ELSE
    ....no code here if applicable...
END IF

or any variation thereof.

Code: QB64: [Select]
  1. FUNCTION Yes_Or_No$ (question AS STRING)
  2.  
  3.     '-------------------------QUERY------------------------------------------------------
  4.     ' FUNCTION: Yes_Or_No$
  5.     '
  6.     ' Purpose:
  7.     ' Display a question and wait for the user to type Y or N
  8.     '
  9.     ' Passed parameters:
  10.     ' question sends string question to display
  11.     '
  12.     '-----------------------------------------------------------------------------------
  13.  
  14.     PRINT question;
  15.     DO
  16.         answer$ = UCASE$(INKEY$)
  17.     LOOP UNTIL answer$ = "Y" OR answer$ = "N"
  18.     PRINT answer$
  19.  
  20.     Yes_Or_No$ = answer$
  21.  
  22. END FUNCTION 'Yes_Or_No$
  23.  
Title: Re: Error trapping Y/N input
Post by: Pete on September 24, 2018, 01:00:43 pm
@OldMosses: You may want to consider adding _LIMIT 30 in your INKEY$ DO:LOOP. It helps reduce CPU usage a lot. This was never an issue with QB/QB45, which moved a lot slower through loops than QB64 does.

Pete
Title: Re: Error trapping Y/N input
Post by: SMcNeill on September 24, 2018, 02:13:07 pm
@OldMoses:  I've used a very similar approach for input, in the past.

FUNCTION Limit$ (prompt$, limiter$)
   PRINT prompt$;
   DO
      Limit$ = INPUT$(1)
   LOOP UNTIL INSTR(limiter$, Limit$)
   PRINT Limit$
END FUNCTION

Then you just call it as needed:

answer$ = Limit$("Are you M)ale or F)emale? ", "MFmf")
answer$ = Limit$("Enter a number from 1 to 5", "12345")

It's s great little way to validate single keypress input.  ;)
Title: Re: Error trapping Y/N input
Post by: OldMoses on September 24, 2018, 05:51:54 pm
@OldMosses: You may want to consider adding _LIMIT 30 in your INKEY$ DO:LOOP. It helps reduce CPU usage a lot. This was never an issue with QB/QB45, which moved a lot slower through loops than QB64 does.

Pete

I've been using it for so long, I just took it for granted. Nice catch, I'll add that in.

@OldMoses:  I've used a very similar approach for input, in the past.

FUNCTION Limit$ (prompt$, limiter$)
   PRINT prompt$;
   DO
      Limit$ = INPUT$(1)
   LOOP UNTIL INSTR(limiter$, Limit$)
   PRINT Limit$
END FUNCTION

Then you just call it as needed:

answer$ = Limit$("Are you M)ale or F)emale? ", "MFmf")
answer$ = Limit$("Enter a number from 1 to 5", "12345")

It's s great little way to validate single keypress input.  ;)

I like the versatility of this.
Title: Re: Error trapping Y/N input
Post by: MWheatley on September 25, 2018, 10:44:40 am
I may have played with functions back in the 80s and 90s, but they aren't part of my coding repertoire now.  Still, I understand what they do, and so I thought I'd try out this latest suggestion first, based on people's comments.

Test program below:

Code: QB64: [Select]
  1. FUNCTION Limit$ (prompt$, limiter$)
  2.    PRINT prompt$;
  3.    DO
  4.       Limit$ = INPUT$(1)
  5.    LOOP UNTIL INSTR(limiter$, Limit$)
  6.    PRINT Limit$
  7.  
  8.  
  9. answer$ = Limit$("Are you M)ale or F)emale? ", "MFmf")
  10. 'answer$ = Limit$("Enter a number from 1 to 5", "12345"
  11.  
  12. Print "Answer= "; answer$

For simplicity, I ran it under QB45, running on a Linux machine.

Two things:

1) In "editor" mode, the program appeared to consist solely of the final three lines -- in other words, the function definition was missing.  I assume that this is normal, but doesn't it make editing and de-bugging rather difficult?

2) Second, when run, the program displayed an "argument-count mismatch" error, with "Limit$" highlighted, on this line:

Code: QB64: [Select]
  1. LOOP UNTIL INSTR(limiter$, Limit$)

I've attached a screenshot to this message.

Any thoughts, anyone?  It's not a showstopper, as I can switch to one of the other methods.  I just thought I'd try this one first.

Malcolm
Title: Re: Error trapping Y/N input
Post by: SMcNeill on September 25, 2018, 10:54:16 am
Try this:

Code: QB64: [Select]
  1. FUNCTION Limit$ (prompt$, limiter$)
  2.    PRINT prompt$;
  3.    DO
  4.       L$ = INPUT$(1)
  5.    LOOP UNTIL INSTR(limiter$, L$)
  6.    PRINT L$
  7.    Limit$ = L$
  8.  
  9.  
  10. answer$ = Limit$("Are you M)ale or F)emale? ", "MFmf")
  11. answer$ = Limit$("Enter a number from 1 to 5", "12345"
  12.  
  13. Print "Answer= "; answer$[code=qb64]
Title: Re: Error trapping Y/N input
Post by: MWheatley on September 25, 2018, 12:00:15 pm
That works!  Thank you. Why did the contraction do the trick? Does QB45 only recognize the first few characters of a variable name?

And I found where the function definition went -- "F2 Subs" brought it up. Now to figure out how to return from there....!

But yes; that seems like a nice robust means of achieving what I want.  Thank you again.

Malcolm
Title: Re: Error trapping Y/N input
Post by: SMcNeill on September 25, 2018, 12:17:47 pm
I'm guessing the LOOP UNTIL INSTR(limiter$, Limit$) issue was with Limit$ trying to call itself as a FUNCTION there, which errored out.  A temp variable stops the recursion and lets it run properly.  ;)
Title: Re: Error trapping Y/N input
Post by: MWheatley on September 25, 2018, 02:03:24 pm
Well, it works now, so that's fine!

Malcolm