Author Topic: Select Case  (Read 6735 times)

0 Members and 1 Guest are viewing this topic.

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Select Case
« on: January 22, 2022, 02:31:24 pm »
Looking for some ideas on how to jump to the next case in a series of Select Cases.

Right now the only way I'm having some success is building another Select Case within the case I want to jump.

Here's an example of what I'm trying to accomplish. So I have a Select Case of 4 cases then End Select. I have a counter within each case and when that counter reaches a particular level I do not want that case to perform the tasks it has been performing but rather just jump to the next case.

Select Case Event

Case 1
Count1 = Temperture
If Count1<0 then next case
RainEvent = RainEvent + 1

Case 2
Count2 = SnowDays
If Count2>31 then next case
SnowEvent = SnowEvent + 1


Case 3
Count3 = Windspeed
If Count3>100 then next case
WindEvent = WindEvent + 1

Case 4
HurricaneEvent=HurricaneEvent +1

Enb Select

The thing is there is no CASE NEXT or GOTO CASE. IF THEN CASE 2 doesn't work. I have discover the underscore doesn't work (ie if Count3>100 THEN_)nor does CONTINUE work or EXIT CASE. What I have been doing is building another Select Case within the Case I want to jump but I'm wondering if someone else may have a better/simpler way of going to the next case if a particular circumstance/criteria has been met?

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Select Case
« Reply #1 on: January 22, 2022, 02:46:25 pm »
The way you have described what you're trying to accomplish SELECT CASE isn't going to work for you.

You will need to use an IF THEN nest.
Granted after becoming radioactive I only have a half-life!

Offline CharlieJV

  • Newbie
  • Posts: 89
    • View Profile
Re: Select Case
« Reply #2 on: January 22, 2022, 03:19:09 pm »
Sniffs like a good case for ON Event GOTO.

For years I had subscribed to the "GOTO" is bad bandwagon, but I've been seeing GOTO in a whole new light recently.

Well, GOTO within elegant reason.

EDIT: With those IF THEN conditions you have altered to GOTO "next event" labels.  Something like that ...

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Select Case
« Reply #3 on: January 22, 2022, 03:20:02 pm »
SELECT EVERYCASE, perhaps?

x = 2
SELECT EVERYCASE x
   Case < 10
      PRINT "x is less than 10"
   CASE 1
      PRINT "x = 1"
   CASE 2
      PRINT "x = 2
END SELECT
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Select Case
« Reply #4 on: January 22, 2022, 03:30:50 pm »
The logic is ill concieved:
Code: QB64: [Select]
  1. Count1 = Temperture
  2. If Count1<0 then next case
  3. RainEvent = RainEvent + 1
  4.  
  5. Count2 = SnowDays
  6. If Count2>31 then next case
  7. SnowEvent = SnowEvent + 1
  8.  
  9.  
  10. Count3 = Windspeed
  11. If Count3>100 then next case
  12. WindEvent = WindEvent + 1
  13.  

When is Count1, 2, or 3 ever going to be other than event # ???

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Select Case
« Reply #5 on: January 22, 2022, 03:53:49 pm »
@bplus , perhaps a poor example but the program works on a menu with selections, so in keeping with my poor example, say the menu was calling for an input of a choice of events and a measurement associated with that event...so the menu is 1 for wind, 2 for snow etc and once you chose an event a 2nd question calls for the measurement, then the event triggers the case selection and the measurement the counter. The measurement volume/level can overflow into an event best described in a difference case and this is what I was trying to bring out in the situation where the temperature of rain reaches zero - is that icy rain or snow?? Same with the idea of wind - at what speed is it simply a windstorm v's something much more destructive. So when the values are bleeding into another description I would like the case the program is in to realize it's at it's limit and should stop counting or evaluating or what the task is that it is performing.

Not sure if that answers your question
Quote
When is Count1, 2, or 3 ever going to be other than event # ???


Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Select Case
« Reply #6 on: January 22, 2022, 04:00:03 pm »
Yeah, I was probably being hasty to judge because I need to see more of what you are doing with those other variables. I am thinking that an IF THEN ELSEIF ELSE END IF block is a better choice OR have a Sub(s) to call to handle  other parts of Case block because those return you back to main Select Case block so you wouldn't be jumping all over the place.

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Select Case
« Reply #7 on: January 22, 2022, 04:27:21 pm »
Here's my version of the work around to jump to the next Case...draw back to it is that the Next Case HAS TO BE the very next case and not 2 or 3 cases down the selection process.

Select Case Event

Case 1
Count1 = Temperture
RainEvent = RainEvent +1
If Count1<0 then
   Jump = Jump +1
   Select Case Jump
      Case 1
      Jump =0
       RainEvent = RainEvent - 1
   End Select

Case 2
Count2 = SnowDays
If Count2>31 then next case
SnowEvent = SnowEvent + 1


Case 3
Count3 = Windspeed
If Count3>100 then next case
WindEvent = WindEvent + 1

Case 4
HurricaneEvent=HurricaneEvent +1

End Select


It's cumbersome but seems to complete the Case and move onto the next case in line. Not only is it limited to where it can jump within the Select Case but I'm worried that multiple calls are constantly counting and readjusting the count which has me suspecting the accuracy.

Thanks for the advice .... that GOTO comment by @CharlieJV has me wondering if I can insert a Label/Return.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Select Case
« Reply #8 on: January 22, 2022, 05:05:11 pm »
Isn't this best served with an IF block?

IF Event =1 AND Temperature >= 0 THEN
    RainEvent = RainEvent +1
ELSEIF Event =2 AND SnowDays <=31 THEN
    SnowEvent = SnowEvent +1
ELSEIF Event =3 AND WindSpeed <= 100 THEN
   WindEvent = WindEvent +1
ELSE
   Hurricane = Hurricane +1
END IF

At least, it appears to me as if the above matches your current program flow.
« Last Edit: January 22, 2022, 07:20:52 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline tomxp411

  • Newbie
  • Posts: 28
    • View Profile
Re: Select Case
« Reply #9 on: January 22, 2022, 06:59:12 pm »
Looking at the example given, this is not what SELECT CASE is for.

CASE statements are always meant to be mutually exclusive, and you can only pick one. Flow must always go from SELECT to a single CASE to END SELECT. Flow is not allowed to move between cases, or you get "spaghetti code."

So looking at your example... You're doing to much in one CASE block. You're still trying to figure out what your event is, and you need to identify that first, then act on it.

So you need some IF statements first, to properly parse your event and your outside parameters (Temperature, Snow Days, and Wind Speed) and then use the answer to make the correct calculation.

Code: QB64: [Select]
  1. Event1 = Event
  2. IF Event1 = 1 and Temperature < 0 THEN Event1 = 2
  3. IF Event1 = 2 and SnowDays > 31 THEN Event1 = 3
  4. IF Event1 = 3 and WindSpeed > 100 THEN Event1 = 4
  5.  
  6. SELECT CASE Event1
  7.   CASE 1
  8.     RainEvent = RainEvent+1
  9.   CASE 2
  10.     SnowEvent = SnowEvent + 1
  11.   CASE 3
  12.     WindEvent = WindEvent + 1
  13.   CASE 4
  14.     HurricaneEvent=HurricaneEvent +1

Note that I purposely did NOT use ELSE on the series of IF statements, because it's possible for event 1 to fall through to 2, 3, and 4. Event 2 can fall through to 3 and 4, and 3 can fall through to 4. So an event that starts as 1 must be tested up to 3 times. Using ELSE IF would skip the later tests.

@SMcNeill this is why your example doesn't quite work: Take a rain event where it's -10 degrees and the wind is blowing at 120. In this case, the correct case is "Hurricane". However, your code will fall through without incrementing any of the counters.


Offline RhoSigma

  • QB64 Developer
  • Forum Resident
  • Posts: 565
    • View Profile
Re: Select Case
« Reply #10 on: January 22, 2022, 07:20:16 pm »
Hi @tomxp411,

please read the wiki page for Select Case and note well we have a EVERYCASE keyword here in qb64, which was actually used in @SMcNeill 's example.

But on the other hand I do also agree with you, that IFs without ELSE branch do it best here, what is actually what SELECT EVERYCASE does.
My Projects:   https://qb64forum.alephc.xyz/index.php?topic=809
GuiTools - A graphic UI framework (can do multiple UI forms/windows in one program)
Libraries - ImageProcess, StringBuffers (virt. files), MD5/SHA2-Hash, LZW etc.
Bonus - Blankers, QB64/Notepad++ setup pack

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Select Case
« Reply #11 on: January 22, 2022, 07:23:15 pm »
@SMcNeill this is why your example doesn't quite work: Take a rain event where it's -10 degrees and the wind is blowing at 120. In this case, the correct case is "Hurricane". However, your code will fall through without incrementing any of the counters.

Then it should look a little more like this:

Select Case Event
    Case 1
        check_rain:
        If Temperture < 0 GoTo check_snow
        RainEvent = RainEvent - 1
    Case 2
        check_snow:
        If SnowDays > 31 GoTo check_wind
        SnowEvent = SnowEvent + 1
    Case 3
        check_wind:
        If Windspeed > 100 GoTo check_hurricane
        WindEvent = WindEvent + 1
    Case 4
        check_hurricane:
        HurricaneEvent = HurricaneEvent + 1
End Select

Folks seem to hate GOTO nowadays, but in some cases, it really is the simplest way to do things.  For what Dimster posted above, I honestly think I'd write my code like the above.   SELECT CASE event will jump me into the 1 to 4 block, and the GOTOs, if necessary, will advance me down to the next case until I get to the proper result.

Here, it's a simple one directional downflow of code, with expressive labels to indicate what's going on in the code.  I don't really consider this "spaghetti code" as it doesn't weave up and down and get in a tangled mess, and I'd honestly have no issues at all in using GOTO in such a manner in my code.  GOTO is a tool in our toolbox for a reason, and sometimes, it just makes sense.  ;)
« Last Edit: January 22, 2022, 07:43:53 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline CharlieJV

  • Newbie
  • Posts: 89
    • View Profile
Re: Select Case
« Reply #12 on: January 22, 2022, 08:01:07 pm »
Just because I enjoy coding and this felt like a good "brain age" exercise ...

Without even trying to understand what you are trying to do, I just wanted to mimic the code in the original post, trying to do the same thing with ON ... GOTO and GOTO statements instead of select case.

This may be at best just something good for the giggles of code that is a little bit out there.

Note that I've set this up just for testing, seeing results of various test values.

Kind of verbose, but maybe helpful in seeing what's going on.

Code: QB64: [Select]
  1. get_values:
  2.         input "Event Number: "; Event
  3.         input "Temperature: "; Temperature
  4.         input "SnowDays: "; SnowDays
  5.         input "Windspeed: "; Windspeed
  6. '
  7. on Event goto Event1, Event2, Event3, Event4
  8. Event1:
  9.         Count1 = Temperature
  10.         if Count1 < 0 then
  11.                 goto Event2
  12.         end if
  13.         print "RainEvent = RainEvent + 1"
  14.         goto DoneEvents
  15. Event2:
  16.         Count2 = SnowDays
  17.         if Count2 > 31 then
  18.                 goto Event3
  19.         end if
  20.         print "SnowEvent = SnowEvent + 1"
  21.         goto DoneEvents
  22. Event3:
  23.         Count3 = Windspeed
  24.         if Count3 > 100 then
  25.                 goto Event4
  26.         end if
  27.         print "WindEvent = WindEvent + 1"
  28.         goto DoneEvents
  29. Event4:
  30.         print "HurricaneEvent = HurricaneEvent + 1"
  31. DoneEvents:
  32. '
  33. goto get_values

Now for extra giggles, I think I'm going to redo that with GOSUB.

Offline tomxp411

  • Newbie
  • Posts: 28
    • View Profile
Re: Select Case
« Reply #13 on: January 22, 2022, 08:09:40 pm »
Here, it's a simple one directional downflow of code, with expressive labels to indicate what's going on in the code.  I don't really consider this "spaghetti code" as it doesn't weave up and down and get in a tangled mess, and I'd honestly have no issues at all in using GOTO in such a manner in my code.  GOTO is a tool in our toolbox for a reason, and sometimes, it just makes sense.  ;)

Yeah, GOTO is usually okay if you're branching forward and not out of control blocks.

For example, you should never do this:

Code: QB64: [Select]
  1. FOR I = 1 TO 10  
  2.    GOTO Done
  3. Done:

(I have seen BASIC programs that do this, especially early stuff from the 70s.)

Having said that... I prefer to avoid it unless there's not another clear way to branch where I need to go. The example above should work in BASIC, but it will not work in many other languages, where GOTO is either not present or jumping around in a CASE block is not allowed.

Offline tomxp411

  • Newbie
  • Posts: 28
    • View Profile
Re: Select Case
« Reply #14 on: January 22, 2022, 08:15:00 pm »
Hi @tomxp411,

please read the wiki page for Select Case and note well we have a EVERYCASE keyword here in qb64, which was actually used in @SMcNeill 's example.

But on the other hand I do also agree with you, that IFs without ELSE branch do it best here, what is actually what SELECT EVERYCASE does.

His last message was an IF/ELSE block, which would have failed in exactly the way I described.

EVERYCASE could be made to work, but it's also going to be more complex than what I posted, for the reasons I already gave: he really needs to settle all of his conditions before entering his CASE statement.