Multiple Choice for CHOOSE command
08-09-2018, 07:07 AM
Post: #1
 Giancarlo Member Posts: 237 Joined: Dec 2013
Multiple Choice for CHOOSE command
Hello,
I was wondering if there was the possibility to choose multiple items through the CHOOSE interface but this command just give the possibility to choose one item...

Then I decided to nest the choose command into a repeat...until loop in order to show the choose interface again and again modifying the element chosen by the user from ‘element nth’ to ‘* element nth’ to show the list of item already selected.

For example if the program asks for ‘ice cream preferred flavors’ the user could select multiple flavors like ‘vanilla’, ‘strawberry’ and ‘coffee’.

This system (CHOOSE command nested into a REPEAT...UNTIL loop) work until you don’t have to exit from the loop. Which condition? I don’t know how to exit from the test because there is no way to understand when the user stops the selection of items...

What do you suggest here?

The only solution I see is to ask the development team to provide the CHOOSE command with multiple selection (yes the variable would be a list at this point) and a menu selection (CANCEL....OK) to complete or cancel the execution of this command.

And since I am here asking to modify some code ;-) I’d like to ask to enlarge the space given to the CHOOSE command graphical interface in order to fill the whole screen and not just a small window. The current size of the interface limit the size of the strings to show.

Thanks

Giancarlo
08-09-2018, 08:13 AM (This post was last modified: 08-09-2018 08:42 AM by Carlos295pz.)
Post: #2
 Carlos295pz Senior Member Posts: 362 Joined: Sep 2015
RE: Multiple Choice for CHOOSE command
(08-09-2018 07:07 AM)Giancarlo Wrote:  For example if the program asks for ‘ice cream preferred flavors’ the user could select multiple flavors like ‘vanilla’, ‘strawberry’ and ‘coffee’.

This system (CHOOSE command nested into a REPEAT...UNTIL loop) work until you don’t have to exit from the loop. Which condition? I don’t know how to exit from the test because there is no way to understand when the user stops the selection of items...

It can be achieved like this:
Code:
  LOCAL List={"vanilla","strawberry","coffee","coconut","chocolate"};   LOCAL X,SList={};   WHILE CHOOSE(X,"Chosen ("+SIZE(SList)+")",List) DO     SList:=UNION(SList,X)   END;   L1:=List;   MSGBOX(EXECON("L1(&1)",SList))

[Esc] on CHOOSE return a 0

Viga C | TD | FB
08-09-2018, 08:35 AM (This post was last modified: 08-09-2018 08:46 AM by Carlos295pz.)
Post: #3
 Carlos295pz Senior Member Posts: 362 Joined: Sep 2015
RE: Multiple Choice for CHOOSE command
Another more visual alternative

Code:
GENLIST(List,Chosen) BEGIN   FOR X:=1 TO SIZE(List) DO     List(X):=IFTE(POS(Chosen,X),"● ","○ ")+List(X)   END END; EXPORT CHOSEN BEGIN   LOCAL List={"vanilla","strawberry","coffee","coconut","chocolate"};   LOCAL X,SList={};   WHILE CHOOSE(X,"Chosen ("+SIZE(SList)+")",GENLIST(List,SList)) DO     SList:=IFTE(POS(SList,X),DIFFERENCE(SList,X),UNION(SList,X))   END;   L1:=List;   MSGBOX(EXECON("L1(&1)",SList)) END;

It is possible to add the exit option without problems

Viga C | TD | FB
08-09-2018, 11:14 AM (This post was last modified: 08-09-2018 09:06 PM by StephenG1CMZ.)
Post: #4
 StephenG1CMZ Senior Member Posts: 838 Joined: May 2015
RE: Multiple Choice for CHOOSE command
It is possible to select multiple choices from an arbitrary list without repeatedly asking for one choice at a time.
I asked this question a long time ago and Cyrille and I found a solution:

On later compilers, Perhaps an easier syntax is now available?

Stephen Lewkowicz (G1CMZ)
08-09-2018, 12:02 PM
Post: #5
 DrD Senior Member Posts: 1,132 Joined: Feb 2014
RE: Multiple Choice for CHOOSE command
You could use the input() form with a multiple check box selection.
08-11-2018, 09:19 PM
Post: #6
 Giancarlo Member Posts: 237 Joined: Dec 2013
RE: Multiple Choice for CHOOSE command
Hello,
The solution provided by Carlos works like a charm. Every time the user selects an element, the item is flagged, the counter is updated (in the title) and the result of the choices is stored into a variable (a list).

The user by the way, as you write, exit the choose menu with ESC which is not very intuitive but it works.

Thank you very much. Still have to verify the other solutions provided in this thread. I will try them in the next days,

Thanks

Giancarlo

P.S. not sure i under what you had in mind with the EXECON command. I just put in the message box the SList.
08-12-2018, 07:36 AM
Post: #7
 Giancarlo Member Posts: 237 Joined: Dec 2013
RE: Multiple Choice for CHOOSE command
Hello Carlos,
Which exit option do you see to close the WHILE...DO loop?

Thanks

Giancarlo

P.S I understood the execon command. You use the position of the chosen item until the end of the code where you use the execon command to replace the position in the list with its string.
08-12-2018, 07:46 AM (This post was last modified: 08-12-2018 07:47 AM by Carlos295pz.)
Post: #8
 Carlos295pz Senior Member Posts: 362 Joined: Sep 2015
RE: Multiple Choice for CHOOSE command
Pressing Esc or pressing the screen outside of the options, that will cause CHOOSE to return 0, meaning that no option was chosen

Viga C | TD | FB
08-13-2018, 09:38 AM
Post: #9
 Carlos295pz Senior Member Posts: 362 Joined: Sep 2015
RE: Multiple Choice for CHOOSE command
To complete the cases, when it is necessary confirm the change of elections, it can be done as follows:

Final option to save changes

Code:
 GENLIST(List,Chosen) BEGIN   CONCAT(MAKELIST(IFTE(POS(Chosen,A),"● ","○ "),A,1,SIZE(List))+List,{"➪ Check all","➪ Uncheck all","➪【 Save changes 】 "}) END; GENCHOOSE(List,SList) BEGIN   LOCAL X,Size=SIZE(List),Prev=SList;   WHILE CHOOSE(X,"Chosen ("+SIZE(SList)+")",GENLIST(List,SList)) DO     CASE       IF X≤Size THEN SList:=IFTE(POS(SList,X),DIFFERENCE(SList,X),UNION(SList,X)) END       IF X=Size+1 THEN SList:=MAKELIST(A,A,1,Size) END       IF X=Size+2 THEN SList:={} END         RETURN SORT(SList);     END   END;   Prev END; PRINTCHOSEN(List,SList) BEGIN   IF SIZE(SList) THEN     MAKELIST(PRINT("- "+List(SList(A))),A,1,SIZE(SList))   ELSE     PRINT("** Empty **")   END END; EXPORT CHOSEN BEGIN   LOCAL List,SList;   PRINT;   List:={"vanilla","strawberry","coffee","coconut","chocolate"};   SList:={2,3}; //Initial   SList:=GENCHOOSE(List,SList); //Final   PRINT("Chosen 1");   PRINTCHOSEN(List,SList);   List:={"Red","Green","Blue","Cyan","Magenta","Yellow","Black","White"};   SList:={1,4,5}; //Initial   SList:=GENCHOOSE(List,SList); //Final   PRINT("-----\nChosen 2");   PRINTCHOSEN(List,SList) END;

Ask if changes are saved when leaving if they exist

Code:
GENLIST(List,Chosen) BEGIN   CONCAT(MAKELIST(IFTE(POS(Chosen,A),"● ","○ "),A,1,SIZE(List))+List,{"➪ Check all","➪ Uncheck all"}) END; GENCHOOSE(List,SList) BEGIN   LOCAL X,Y,Size=SIZE(List),Prev=SORT(SList);   WHILE CHOOSE(X,"Chosen ("+SIZE(SList)+")",GENLIST(List,SList)) DO     CASE       IF X=Size+1 THEN SList:=MAKELIST(A,A,1,Size) END       IF X=Size+2 THEN SList:={} END         SList:=IFTE(POS(SList,X),DIFFERENCE(SList,X),UNION(SList,X))     END   END;   IF NOT EQ(Prev,SORT(SList)) AND CHOOSE(Y,"Save Changes?",{"Yes","No"})=1 THEN     SORT(SList)   ELSE     Prev   END END; PRINTCHOSEN(List,SList) BEGIN   IF SIZE(SList) THEN     MAKELIST(PRINT("- "+List(SList(A))),A,1,SIZE(SList))   ELSE     PRINT("** Empty **")   END END; EXPORT CHOSEN BEGIN   LOCAL List,SList;   PRINT;   List:={"vanilla","strawberry","coffee","coconut","chocolate"};   SList:={2,3}; //Initial   SList:=GENCHOOSE(List,SList); //Final   PRINT("Chosen 1");   PRINTCHOSEN(List,SList);   List:={"Red","Green","Blue","Cyan","Magenta","Yellow","Black","White"};   SList:={1,4,5}; //Initial   SList:=GENCHOOSE(List,SList); //Final   PRINT("-----\nChosen 2");   PRINTCHOSEN(List,SList) END;

Viga C | TD | FB
08-16-2018, 02:57 PM
Post: #10
 Giancarlo Member Posts: 237 Joined: Dec 2013
RE: Multiple Choice for CHOOSE command
Hello Carlos,
Just found some time to play with your code. Very compact code!
I like the way you shrink the code.

Adding “check all” and “uncheck all” is very helpful. At this point do you think it is possible to add another item like “end” to close the choose interface to act like the [ESC] command?

Very good job!

Giancarlo
08-21-2018, 09:05 PM
Post: #11
 Han Senior Member Posts: 1,820 Joined: Dec 2013
RE: Multiple Choice for CHOOSE command
Another approach is to use the INPUT() command and use check boxes that are linked. If you need some code snippet, you can check out the settings within the Graph3D or SolveSys apps I created. If you prefer a self-contained code sample, let me know.

Graph 3D | QPI | SolveSys
08-22-2018, 10:16 AM
Post: #12
 Giancarlo Member Posts: 237 Joined: Dec 2013
RE: Multiple Choice for CHOOSE command
Hello Han,
Thanks for the hint. While I am able to build INPUT check boxes, the difficult part here is the dinamic creation of variables to feed the INPUT command.

I still didn’t check how you did it for your Equation solver but I will do it as soon as possible. If we consider a list of options like:
LST:={“arancio”, “limone”,”mandarino”,...};

You can’t use this list as variables because they are strings and, if you remove the “” then it create another errore maybe because the system doesn’t recognize these words since they are not declared.

So, what could be the approach here to bypass this issue?

On more, while for an input box it makes sense that the ‘tick’ box is drawn on the right side of the label, for a check list it would be better to have the ‘tick’ box on the left side of the label. This is just an aesthetic comment, not very important at this stage.

Thanks

Giancarlo from the cappuccino state
08-22-2018, 08:56 PM
Post: #13
 Han Senior Member Posts: 1,820 Joined: Dec 2013
RE: Multiple Choice for CHOOSE command
(08-22-2018 10:16 AM)Giancarlo Wrote:  Hello Han,
Thanks for the hint. While I am able to build INPUT check boxes, the difficult part here is the dinamic creation of variables to feed the INPUT command.

I still didn’t check how you did it for your Equation solver but I will do it as soon as possible. If we consider a list of options like:
LST:={“arancio”, “limone”,”mandarino”,...};

You can’t use this list as variables because they are strings and, if you remove the “” then it create another errore maybe because the system doesn’t recognize these words since they are not declared.

So, what could be the approach here to bypass this issue?

On more, while for an input box it makes sense that the ‘tick’ box is drawn on the right side of the label, for a check list it would be better to have the ‘tick’ box on the left side of the label. This is just an aesthetic comment, not very important at this stage.

Thanks

Giancarlo from the cappuccino state

The "simple" answer on building dynamic (i.e. using input parameters that are not statically defined) is to use strings and use the expr() command. The following is not intended as working code, but to give you an idea of how to build the string to evaluate.

Code:
 LOCAL vars1, vars2, vars3; // use however many you need LOCAL cmd:="input("; LOCAL result; // create the input command using strings cmd:=cmd + string(vars1) + "," + string(vars2), <and so on...> ; result:=expr(cmd);

If you look at the equation library, it generates the input forms for each set of equations without knowing a priori which set of equations/variables are selected.

Graph 3D | QPI | SolveSys
08-22-2018, 09:12 PM
Post: #14
 Carlos295pz Senior Member Posts: 362 Joined: Sep 2015
RE: Multiple Choice for CHOOSE command
In the latest version we already have available the use of INPUT with EVAL to configure a dynamic list of variables

Viga C | TD | FB
08-22-2018, 09:13 PM (This post was last modified: 08-24-2018 12:11 AM by Han.)
Post: #15
 Han Senior Member Posts: 1,820 Joined: Dec 2013
RE: Multiple Choice for CHOOSE command
Here's is the code for deleting systems of equations (see SovleSys in my signature below). I added extra comments to help understand the general idea:

PHP Code:
// UI for deleting systemsssDeleteSys()begin  local cmd:="input({";  local systitles;  local j,p,p0,p1,k;  local selected:={};  local lib:={};  local pages:=0;  if ssLibSize then    // 'selected' is a list of which systems have been selected for deletion    selected:=makelist(0,j,1,ssLibSize);    // dynamically create the entries using the title of each system of equations    systitles:=makelist(ssCurLib(j,1),j,1,ssLibSize);    // max of 10 pages, with 7 entries per page so break into groups of 70    pages:=ip((ssLibSize-1)/70);    // now work on each block of 70    for p from 0 to pages do      p0:=p*70+1; p1:=min(p0+69,ssLibSize);      k:=0;      // here we modify 'cmd' to create a complete INPUT command sequence      // first create a list of variables, which for us is a list of entries      // each entry needs to be of the form { var_name, type, { location_list } }      // in our case, var_name is actually 'selected(#)' where # is dynamically      // generated by the index j; and k is the row number      for j from p0 to p1 do        k:=k+1;        cmd:=cmd + "{selected(" + string(j,1,0) + "),0,{94,5," + string(k-1,1,0) + "}}";        if (j<p1) then cmd:=cmd + ",\n"; end; // this line return is for debugging purposes      end;      // now add the title (and the page number if we have more than 70 systems)      cmd:=cmd + "},\n" + string(ssTDeleteSys +         "[" + string(p0,1,0) + "-" + string(p1,1,0) + "]" ) + ",\n{";      // now for the list of the labels of each entry (titles of each system of equations)      for j from p0 to p1 do        cmd:=cmd + string(systitles(j));        if (j<p1) then cmd:=cmd + ",\n"; end;      end;      cmd:=cmd + "},\n{";      // add list of help text, which is the same for all entries      for j from p0 to p1 do        cmd:=cmd + string(ssHMarkDel);        if (j<p1) then cmd:=cmd + ",\n"; end;      end;      cmd:=cmd + "})";      // leave a copy of the actual cmd string for debugging purposes      Notes(ssLogFile):=cmd;      // j can be used to detect if user canceled the UI      // the actual results are stored in 'selected'      j:=expr(cmd);      cmd:="input({"; // reset for next loop    end; // for p    // current system deleted? if so set index to 0    if ssCurSysIndex then      if selected(ssCurSysIndex) then        ssCurSysIndex:=0;      end;    end;    // rebuild library and adjust index    for j from 1 to ssLibSize do      if selected(j) then        if j < ssCurSysIndex then          ssCurSysIndex:=ssCurSysIndex - 1;        end;      else        lib(0):=ssCurLib(j);      end;    end;    ssCurLib:=lib;    AFiles(ssLibFN):=lib;  else    ssWarn(ssNoSystems);  end;end;

Graph 3D | QPI | SolveSys
08-22-2018, 09:18 PM (This post was last modified: 08-22-2018 09:25 PM by Han.)
Post: #16
 Han Senior Member Posts: 1,820 Joined: Dec 2013
RE: Multiple Choice for CHOOSE command
(08-22-2018 09:12 PM)Carlos295pz Wrote:  In the latest version we already have available the use of INPUT with EVAL to configure a dynamic list of variables

In your example, you are still using statically-defined variables (i.e. 'Vars' is hard coded into the source). In SolveSys, the list of variables (referred to by 'selected' in the code above) is unknown in both size and content.

EDIT: For further clarity, in your example, the X variable will always appear on row 1. But what happens if we wanted to remove 'X' from the list while the program was still running? Then the remaining variables 'Y' and 'Z' will never appear in row 1 because they have been hard coded to row 2 and row 3 respectively.

Graph 3D | QPI | SolveSys
08-23-2018, 09:47 PM (This post was last modified: 08-25-2018 07:42 PM by StephenG1CMZ.)
Post: #17
 StephenG1CMZ Senior Member Posts: 838 Joined: May 2015
RE: Multiple Choice for CHOOSE command
For comparison, here is my earlier example, re-coded as a callable function.

Code:
  EXPORT MULTICH(CHKLST,TTL,HLP,RSTV,INITV)  //CHKLST: SELECTABLE LIST  //TTL:TITLE  //HLP:HELP  //RSTV:RESETVALUE  //INITV:INITVALUE //as written uses I global  BEGIN   LOCAL ST:="{";   LOCAL LST:=MAKELIST(0,I,1,SIZE(CHKLST));//MAKE LIST FOR RESULTS   LOCAL OKC;   //MAKE STRING FOR INPUT   FOR I FROM 1 TO SIZE(CHKLST) DO    ST:=ST+"{LST("+I+"),1}";   END;   ST:=REPLACE(ST,"}{","},{");//COMMA SEPERATOR   ST:=ST+"}";    OKC:=EVAL(EXPR("INPUT("+ST+",TTL,CHKLST,HLP,1,1)"));   IF OKC THEN    RETURN LST;   ELSE    //INPUT CANCELLED    //MAY WANT TO EMPTY LST?    RETURN {};   END; END;  EXPORT MCEXAMPLE()   BEGIN   //NB ALL AND NONE ARE ORDINARY CHECKBOXES   LOCAL COMETS:={"ALL","Halley","Lewkowicz","lots more","NONE"};   LOCAL TTL:="Select Some";   LOCAL HLP:="Input Help";   LOCAL RSTV:=1;   LOCAL INITV:=1;   MULTICH(COMETS,TTL,HLP,RSTV,INITV);  END;   EXPORT CHOOSER() BEGIN END; Update: The 1,1 should be RSTV,INITV

Perhaps useful, but not as nice as Carlos's visual solution.

Stephen Lewkowicz (G1CMZ)
 « Next Oldest | Next Newest »

User(s) browsing this thread: 1 Guest(s)