HP Forums
Multiple Choice for CHOOSE command - Printable Version

+- HP Forums (http://www.hpmuseum.org/forum)
+-- Forum: HP Calculators (and very old HP Computers) (/forum-3.html)
+--- Forum: HP Prime (/forum-5.html)
+--- Thread: Multiple Choice for CHOOSE command (/thread-11190.html)



Multiple Choice for CHOOSE command - Giancarlo - 08-09-2018 07:07 AM

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


RE: Multiple Choice for CHOOSE command - Carlos295pz - 08-09-2018 08:13 AM

(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


RE: Multiple Choice for CHOOSE command - Carlos295pz - 08-09-2018 08:35 AM

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


RE: Multiple Choice for CHOOSE command - StephenG1CMZ - 08-09-2018 11:14 AM

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:
http://www.hpmuseum.org/forum/thread-5098.html?highlight=comet

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


RE: Multiple Choice for CHOOSE command - DrD - 08-09-2018 12:02 PM

You could use the input() form with a multiple check box selection.


RE: Multiple Choice for CHOOSE command - Giancarlo - 08-11-2018 09:19 PM

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.


RE: Multiple Choice for CHOOSE command - Giancarlo - 08-12-2018 07:36 AM

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.


RE: Multiple Choice for CHOOSE command - Carlos295pz - 08-12-2018 07:46 AM

Pressing Esc or pressing the screen outside of the options, that will cause CHOOSE to return 0, meaning that no option was chosen


RE: Multiple Choice for CHOOSE command - Carlos295pz - 08-13-2018 09:38 AM

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;



RE: Multiple Choice for CHOOSE command - Giancarlo - 08-16-2018 02:57 PM

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


RE: Multiple Choice for CHOOSE command - Han - 08-21-2018 09:05 PM

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.


RE: Multiple Choice for CHOOSE command - Giancarlo - 08-22-2018 10:16 AM

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


RE: Multiple Choice for CHOOSE command - Han - 08-22-2018 08:56 PM

(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.


RE: Multiple Choice for CHOOSE command - Carlos295pz - 08-22-2018 09:12 PM

In the latest version we already have available the use of INPUT with EVAL to configure a dynamic list of variables Smile
http://www.hpmuseum.org/forum/thread-11114.html


RE: Multiple Choice for CHOOSE command - Han - 08-22-2018 09:13 PM

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 systems
ssDeleteSys()
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+1p1:=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<p1then 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<p1then 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<p1then 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(ssCurSysIndexthen
        ssCurSysIndex
:=0;
      
end;
    
end;

    
// rebuild library and adjust index
    
for j from 1 to ssLibSize do
      if 
selected(jthen
        
if ssCurSysIndex then
          ssCurSysIndex
:=ssCurSysIndex 1;
        
end;
      else
        
lib(0):=ssCurLib(j);
      
end;
    
end;
    
ssCurLib:=lib;
    
AFiles(ssLibFN):=lib;


  else
    
ssWarn(ssNoSystems);
  
end;
end



RE: Multiple Choice for CHOOSE command - Han - 08-22-2018 09:18 PM

(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 Smile
http://www.hpmuseum.org/forum/thread-11114.html

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.


RE: Multiple Choice for CHOOSE command - StephenG1CMZ - 08-23-2018 09:47 PM

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.