Author Topic: Redim Select Case  (Read 3328 times)

0 Members and 1 Guest are viewing this topic.

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Redim Select Case
« on: February 06, 2021, 12:08:15 pm »
So another dim (as in stupid) question like the one I had on renaming an array. Is there a work around for adding a new case to an existing Select Case routine? Seems if all the tasks in each case is pretty well the same then I have been able to increase or decrease the number of cases but where I have a group of cases with all different tasks and want to add a new case/Task during the course of a running program is the question.

As an example of what I mean in adding new cases for the same task (and I realize this better done in a simple For Loop)

 REDIM CaseArray(1 TO F)
PRINT "How many files do you want to work on today"
INPUT Numfiles
FOR x = 1 TO file
    CaseArray(x) = x
NEXT
REDIM CaseArray(1 TO Numfiles)

FOR y = 1 TO Numfiles
    SELECT CASE y
        CASE 0 + y
            F$ = "TestFileNumber"
            Num$ = STR$(y)
            FileNum$ = F$ + LTRIM$(Num$)
            OPEN FileNum$ FOR OUTPUT AS #y
            WRITE #y, "Hello"
            CLOSE
    END SELECT
    IF y = Numfiles THEN
        PRINT "Add a New Case y/n"
        INPUT Ans$
    END IF
    IF Ans$ = "n" THEN EXIT FOR
    IF Ans$ = "y" THEN
        PRINT "How Many more Cases?"
        INPUT CaseAns
        FOR w = 1 TO CaseAns
            SELECT CASE w
                CASE Numfiles + w
                    'new file to open and work with
            END SELECT
        NEXT w
    END IF
NEXT

Don't run that code as it will create files if it works . Just an example of the way multiple case for the same task for every case can be created from the input of the user.

To do different tasks, lets assume there already exists a Select Case routine with 10 different tasks for each case and I want to take that same Select Case and either add or remove cases. The only thing I can think of to do this would be something like:

_preserve Select Case (1 to 10)

Print "How Many More Cases"
Input CaseAdd

(Assume the input here is 2)

Select Case ( 1 to 12)
case 11
do something

case 12
do another thing different

end select

Right now I'm thinking the clumsiest way would be calls to a variety of subs 

So that the CASE 0 + y would call a sub containing a variety of Tasks

Sub 1
Do Task 1

Sub 2
Do Task 1
Do Task 2

Sub 3
Do Task 1
Do Task 2
Do Task 3

Sub etc
Do Task All

The For Loop, especially nesting For Loops seems to be the only way to get that flexibility in a running program where the user inputs a value. I do like the elegance and easy to follow logic of the Select Case format though...not sure I like nested Select Cases... anyway, feel free to ignore this question ...ramblings of a mind which stays home too much these days.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Redim Select Case
« Reply #1 on: February 06, 2021, 01:16:31 pm »
Quote
Sub 1
Do Task 1

Sub 2
Do Task 1
Do Task 2

Sub 3
Do Task 1
Do Task 2
Do Task 3


Well you can't change code when exe is running BUT you can do different permutations (different sets of subs in different orders of execution) of routines which might be what you are looking to do? That's how the math routines get done, just permutations on the arrangement of numbers and sub symbols.

Just code each task 1, 2, 3

Then some code to handle the order of tasks, come to think that is an Interpreter the code to handle the order of tasks is a little program.
« Last Edit: February 06, 2021, 01:19:37 pm by bplus »

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Redim Select Case
« Reply #2 on: February 06, 2021, 01:40:31 pm »
Silly Mark, you can change code when a program is running. All you have to do is have your running program access the source, read it, rewrite it, SHELL to recompile it, and then have the program rerun the modified exe. SIMPLE. :D I don't know why everybody doesn't code this way.

Next up on Wide World of Wacky Coding: How to make GOTO using variables for line numbers and labels, without using ON GOTO.

Kidding aside, Dimster, I feel your pain. I have had a few times I wished something that couldn't be done could be; although once in awhile, something like REDIM _PRESERVE comes along that makes one of those wishes come true. In this CASE, you simply have to modify your source to handle any of the new cases you might come up with in the future, or just anticipate what those modifications would be, and include them all in your current program.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Redim Select Case
« Reply #3 on: February 06, 2021, 01:47:37 pm »
Quote
Silly Mark, you can change code when a program is running. All you have to do is have your running program access the source, read it, rewrite it, SHELL to recompile it, and then have the program rerun the modified exe. SIMPLE. :D I don't know why everybody doesn't code this way.

Foolish Pete, you aren't changing the exec that's running.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Redim Select Case
« Reply #4 on: February 06, 2021, 01:55:20 pm »
Exactly, and you don't need to. The old one closes and the new one starts. What  you would need is a temp file to transfer any active variables to the next run. I know it's complex, but it can be done. Some of things I could have added was to SHELL to a control program to do just that. It would kill the old exe and compile the new source to the same name, and then run it. The main program would look for the temp file and if it existed, as it would be created by the control program, it would input the variables and use those values to resume from where it left off.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Redim Select Case
« Reply #5 on: February 06, 2021, 04:00:59 pm »
I don't honestly understand what the heck you're wanting to do here.   SELECT CASE and FOR NEXT are two completely different things.

SELECT CASE is a decision evaluator, just like IF... THEN.   FOR-NEXT is just a counter and repetition control.  The two things are completely different.

Looking at the code you provided, I honestly don't see where a SELECT CASE would be used at all.  Instead, you'd want something rather simplistic like this:

Code: QB64: [Select]
  1. REDIM CaseArray(1 TO F)
  2. PRINT "How many files do you want to work on today"
  3. INPUT Numfiles
  4. FOR x = 1 TO file
  5.     CaseArray(x) = x
  6. REDIM CaseArray(1 TO Numfiles)
  7.  
  8.  
  9. start = 1
  10.     FOR y = start TO Numfiles
  11.         '    SELECT CASE y 'WHY?
  12.         '        CASE 0 + y 'IF THIS IS THE ONLY CASE, THEN IT'S *ALWAYS* VALID
  13.         F$ = "TestFileNumber"
  14.         Num$ = STR$(y)
  15.         FileNum$ = F$ + LTRIM$(Num$)
  16.         '        OPEN FileNum$ FOR OUTPUT AS #y
  17.         '      WRITE #y, "Hello"
  18.         PRINT "Hello "; FileNum$ 'NOT GOING TO PRINT MULTIPLE FILES TO DRIVE, BUT HERE'S OUTPUT TO SCREEN
  19.         '       CLOSE
  20.         '    END SELECT
  21.         IF y = Numfiles THEN
  22.             PRINT "Add a New Case y/n"
  23.             INPUT Ans$
  24.             'All these need to be inside the IF so you get the Ans$ *BEFORE* you start checking its value
  25.             IF Ans$ = "n" THEN EXIT FOR
  26.             IF Ans$ = "y" THEN
  27.                 PRINT "How Many more Cases?"
  28.                 INPUT CaseAns
  29.                 start = y + 1
  30.                 Numfiles = Numfiles + CaseAns
  31.             END IF
  32.         END IF
  33.     NEXT
  34. LOOP UNTIL y = Numfiles
  35. PRINT "All Done!"

Not a single SELECT CASE in sight.  (Except the one commented out. :P ) 

Now, isn't this what you were looking to do with your example program in the first post?  If not, I'm going to need a better example to figure out exactly what it is you're trying to accomplish here.
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: Redim Select Case
« Reply #6 on: February 06, 2021, 04:42:43 pm »
Exactly, and you don't need to. The old one closes and the new one starts. What  you would need is a temp file to transfer any active variables to the next run. I know it's complex, but it can be done. Some of things I could have added was to SHELL to a control program to do just that. It would kill the old exe and compile the new source to the same name, and then run it. The main program would look for the temp file and if it existed, as it would be created by the control program, it would input the variables and use those values to resume from where it left off.

Pete

It is easier with Interpreters and you can do very interesting stuff, I remember doing something from a DOS Basic modifying the batch file I was running.

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Redim Select Case
« Reply #7 on: February 07, 2021, 12:11:00 pm »
Thanks guys for all the ideas. Definitely will push me to explore areas of coding I have never considered. And comforting to know there is shared Pain out there.

@SMcNeill ... Steve that example code I was giving was to demonstrate how I could manufacture multiple CASES for a Select Case but every Case had to be fixed with the same task (ie opening a file albeit many files with very similar names). And I fully agree with you and your approach to do the same thing without use of Select Case. No, it's how to have a dynamic CASE selection where all the Cases are doing different tasks. So a way to take an existing Select Case procedure .. preserve those tasks... then add addition Cases with new or different tasks.

Maybe adding a case named CASE NEW(), which if blank does not crash the run of logic during the run of the program, should another task be needed (or two or three) that CASE New(1) can be searched for and become a new part of the Selection process. Or maybe also CASE SKIP() which could then skip existing cases.

Anyway, if it wasn't for stupid questions or quests, how could we ever measure smartness and progress.


Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Redim Select Case
« Reply #8 on: February 07, 2021, 01:06:40 pm »
Don't sell yourself short, It's like I always tell Steve, "It takes courage to ask a lot of stupid questions, and you, sir, have a lot of courage!"

What you are looking for is a kind of adaptive programming, where the code evolves itself. This isn't stupid in the least, it's probably even the future of coding. You now, first we build helper robots, and then we build robots to build helper robots, and then we don't need to build anything, anymore; bt we do need to run from Terminators.

In regard to putting in other cases, I will, at times, throw in a CASE ELSE for unexpected conditions. That at least alters me that I need to evolve the code to include another condition I hadn't thought of or that a new set of data triggered.

FOR SKIP CASE, you need to use a conditional statement like...

Code: QB64: [Select]
  1. IF Pete <> smartaacii THEN
  2.     SELECT CASE whatever
  3.         CASE Foo
  4.             ' Stuff
  5.     END SELECT
  6.  

Okay, so that condition will never be met, but you get the picture.

Pete




 
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Redim Select Case
« Reply #9 on: February 07, 2021, 01:26:03 pm »
This sounds like something fun to experiment with, once I have free time again.  I think, with a little effort, one could “future proof” their EXE.

Say in your current example, your program only has 4 tasks which you’ve defined as subs.

Now, you want to make it so this same program might work with 10 tasks, in the future...

One trick would be to compile the 4 tasks as a DLL, with 6 stubs of blank tasks for future expansion.  Then you DECLARE LIBRARY the DLL and reference all 10 tasks, including the stubs.

Now you can write your select case:

SELECT CASE task_level
    CASE 1: Task1
    CASE 2: Task2
    CASE 3: Task3
    CASE 4: Task4
    CASE 5: Task5
... and so on....

Now, just because you only have code which utilizes 4 tasks now, that doesn’t mean you can’t expand the DLL and add new tasks later, just by replacing those blank stubs.

One place I could see this type of future expandability might be for a calculator app.  You might start off with the DLL just doing the most basic of stuff, like +-*/, but then expand later to do ^,%, and !

Instead of having to edit and recompile the whole EXE over, all you’d have to  do is rebuild the DLL and replace it.

Honestly, I think most folks would just keep it simple and recompile to another EXE version, but I like the concept of future compatibility — especially for custom scripting sublanguages and such.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Redim Select Case
« Reply #10 on: February 07, 2021, 01:39:43 pm »
Thanks again. I appreciate the feed back.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Redim Select Case
« Reply #11 on: February 07, 2021, 06:19:37 pm »
Hi Dimster
your request is singular but not stupid.
IMHO it is NOT possible in a modular programming language - You can use some tricks but not have a complete free resizable SELECT CASE.
In the same manner I think that in an OOP language (C++/Java/ ObjectPascal or Delphi/Ruby) or in a selfdefining language (like LISP or PYTHON or Lua) this kind of task (resizable SELECT CASE) is possible.
So if you like BASIC (in specific QB64) you must think in modular mode or event driven mode.
Good Luck
Programming isn't difficult, only it's  consuming time and coffee

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Redim Select Case
« Reply #12 on: February 08, 2021, 05:01:08 am »
I used to make "fake" dlls in QuickBASIC for some apps. Since business apps didn't require that much speed, it was possible to shell to the fake dll minimized, have it calculate whatever, and send those calculations to a database, and close . The calculated data could then be read by the main program, and the fake dll would close. Now if I had to make some modifications in the future, I just modified and recompiled the dll. I think I just did that one time, and later dropped the whole thing, when I got all I needed into the completed program.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Redim Select Case
« Reply #13 on: February 08, 2021, 12:45:57 pm »
Build your own Interpreter, just substitute real tasks for the T(n) Subs, handles up to 16 commands!

Your program hopefully will be more meaningful ;-)) It would be just a string of Hex$ digits.

Code: QB64: [Select]
  1. Do 'b+ builds another demo Interpreter 2021-02-08
  2.     nSteps = Int(Rnd * 20)
  3.     program$ = ""
  4.     For j = 1 To nSteps 'build random program
  5.         r$ = Hex$(Int(Rnd * 16))
  6.         program$ = program$ + r$
  7.         'Print program$
  8.     Next
  9.     Sprint program$
  10.     Sleep
  11.     Cls
  12.  
  13. Sub Sprint (p$) ' a syn of Run
  14.     Print "Program: " + p$: Print
  15.     For i = 1 To Len(p$)
  16.         Select Case Mid$(p$, i, 1)
  17.             Case "0": T0
  18.             Case "1": T1
  19.             Case "2": T2
  20.             Case "3": T3
  21.             Case "4": T4
  22.             Case "5": T5
  23.             Case "6": T6
  24.             Case "7": T7
  25.             Case "8": T8
  26.             Case "9": T9
  27.             Case "A": TA
  28.             Case "B": TB
  29.             Case "C": TC
  30.             Case "D": TD
  31.             Case "E": TE
  32.             Case "F": TF
  33.         End Select
  34.     Next
  35.     Print: Print "End of *run*, press any to continue next program, escape to quit."
  36. Sub T0
  37.     Print "I am from task 0."
  38. Sub T1
  39.     Print "I am from task 1."
  40. Sub T2
  41.     Print "I am from task 2."
  42. Sub T3
  43.     Print "I am from task 3."
  44. Sub T4
  45.     Print "I am from task 4."
  46. Sub T5
  47.     Print "I am from task 5."
  48. Sub T6
  49.     Print "I am from task 6."
  50. Sub T7
  51.     Print "I am from task 7."
  52. Sub T8
  53.     Print "I am from task 8."
  54. Sub T9
  55.     Print "I am from task 9."
  56. Sub TA
  57.     Print "I am from task A."
  58. Sub TB
  59.     Print "I am from task B."
  60. Sub TC
  61.     Print "I am from task C."
  62. Sub TD
  63.     Print "I am from task D."
  64. Sub TE
  65.     Print "I am from task E."
  66. Sub TF
  67.     Print "I am from task F."

Here is something interesting to consider, Subs can take parameters so one task could be to Run another task X times and perhaps incrementing that tasks argument(s) so you have a Looping structure.

Another task Might be an IF THEN equivalent.

Another task Store and Retrieve Variables, might have to be a Function so you can plug-in values into other tasks.

Oh, the arguments thing adds a big wrinkle of complications ;-))

Oh this looks like fun!
« Last Edit: February 08, 2021, 01:30:46 pm by bplus »