HP Forums
How can I maintain a variables value when editing a Program or App - Printable Version

+- HP Forums (https://www.hpmuseum.org/forum)
+-- Forum: HP Calculators (and very old HP Computers) (/forum-3.html)
+--- Forum: HP Prime (/forum-5.html)
+--- Thread: How can I maintain a variables value when editing a Program or App (/thread-2648.html)



How can I maintain a variables value when editing a Program or App - Bob Frazee - 12-17-2014 06:52 PM

I have about 10 variables I need to save that are defined in an App. If I open up that App for editing, any EXPORTED variables are reset, LOCAL variables disappear when the App ends, and the GLOBAL App variables (variables that are only seen internally in the App) are reset. Searching the manual, I could store to a MATRIX, but that adds another file outside the App. Another thread has talked about using NOTES to programmatically store and retrieve variable values, but I am unclear as to if that can be done with the App note, or how to do it. I've searched the online manual and the calculator help file, tried some of the examples, and it's still unclear to me. If any one could provide some more detail, or even if it is possible to programmatically store and retrieve multiple variables from the App note file, it would be appreciated.
Thanks in advance.
RCF


RE: How can I maintain a variables value when editing a Program or App - Han - 12-17-2014 07:33 PM

One way I thought about doing this the following:

1. Use a user-created variable. If the variable doesn't exist, prompt the user to create it by typing in something like: SaveData:=0; in the Home view. The app should never proceed if this variable doesn't exist. So how do we test if it exists without compile errors? Via indirection.

Code:
LOCAL MyData;
IFERR
 MyData:=EXPR("SaveData");
THEN
  AbortApp();
END;

The AbortApp() routine should display a message telling the user how to create the variable SaveData. It should also contain the KILL command to completely exit the program/app. If there is no error, then all your data is imported into MyData and you can proceed as usual. If MyData is a list of stuff, then MyData(1) will get the 1st element, MyData(2) will get the 2nd element, etc.

2. To save your data, encapsulate everything into a single list and store it into MyData. Now, export using:

Code:

MyData:={ blah, blah, blah };
LOCAL cmd:="SaveData:=";
cmd:=cmd+MyData; // may possibly need to call string(MyData)
EXPR(cmd);

Thus you use MyData to access the data, and the EXPR() command to do your importing and exporting. Anytime you change your code, SaveData is unchanged. And compiling doesn't produce errors since there is no direct reference to SaveData.


RE: How can I maintain a variables value when editing a Program or App - Snorre - 12-17-2014 07:37 PM

Hello,

a dirty solution may look like:
Code:
x:=1,y:=2,z:=3;
// DO NOT TOUCH THIS COMMENT!

EXPORT SELFMODIFY()
BEGIN
  INPUT({x,y,z});  // ... or whatever you want to do with your vars.
  LOCAL code:=Programs("SELFMODIFY");
  LOCAL pos:=INSTRING(code,"// DO NOT TOUCH THIS COMMENT!");
  Programs("SELFMODIFY"):=
    "x:="+STRING(x)+",y:="+STRING(y)+",z:="+STRING(z)+";"+CHAR(10)+
    MID(code,pos,SIZE(code)-pos+1);
END;
This doesn't need external variables or notes since it modifies its own source (assuming the program is named "SELFMODIFY").


RE: How can I maintain a variables value when editing a Program or App - Han - 12-17-2014 08:16 PM

The tradeoff in using self-modifying code is that if your data is large, the use of self-modifying code creates unnecessary bloat in program size. Not to mention the extra scrolling that needs to be done when editing the program. However, if you only have 10 values to save then this is probably not much of an issue.


RE: How can I maintain a variables value when editing a Program or App - cyrille de brébisson - 12-18-2014 07:13 AM

Hello,

Nice creatives solutions to the problem! I am having a hard time finding other ones, so you guys are doing good...

Have you thought about using a note? You could, upon program completion, create a note that contains a sequence of assignments "var1:=value; ....." and create either a function called at program start, or called by hand when you just recompiled the program (actually, even better, upon variable initialization) that would reload everything...

something like the function bellow would save the variables (I think, I have not tested it).
call/use it when exiting your program...

local MyRememberedVarList= { 'var1', 'var2', 'var3' ... }
Notes("MyProgramNave_SavedVars"):= SIGMALIST(EXECON("""&1:=+&2;\n""", MyRememberedVarList, eval(MyRememberedVarList));


Now, for the reloading, as the LAST global variable declared in your program (non exported), do:
RELOAD:= IFTE(POS(Notes, "MyProgramNave_SavedVars"), 0, EXPR(Notes("MyProgramNave_SavedVars")));

This will cause, upon program compilation, the IFTE command to be executed. And that command should reload all program variables automaticaly... unless I messed up somewhere...

convoluted hey!

Cyrille


RE: How can I maintain a variables value when editing a Program or App - Didier Lachieze - 12-19-2014 09:03 AM

(12-18-2014 07:13 AM)cyrille de brébisson Wrote:  Now, for the reloading, as the LAST global variable declared in your program (non exported), do:
RELOAD:= IFTE(POS(Notes, "MyProgramNave_SavedVars"), 0, EXPR(Notes("MyProgramNave_SavedVars")));

This will cause, upon program compilation, the IFTE command to be executed. And that command should reload all program variables automaticaly... unless I messed up somewhere...
Very Nice ! It works with a swap of the IFTE True and False Clauses:
RELOAD:= IFTE(POS(Notes, "MyProgramNave_SavedVars"), EXPR(Notes("MyProgramNave_SavedVars")), 0);


RE: How can I maintain a variables value when editing a Program or App - Bob Frazee - 12-21-2014 11:35 PM

Well, I am still unable to get the instructions to work. This is an APP. I need to preserve the numerical values of DegF and Mph during editing of the APP code and am attempting to store the variables in the APP's note file (called info, I believe). The code below works, so can someone modify the code with the above instructions that Didier and Cyrille has provided, so I don't lose the numerical values of DegF and Mph when I edit the APP. Also, I was unable to find the Instruction SIGMALIST in the online manual or calculator help. I am using Rev 6975 firmware update. Here's the code;
Code:

The name of the APP is "WindChillApp"

//Variables... 
DegF;Mph;
LOCAL wct,wcto,ft;
Local Counter,ChooseVar;

WindChillIntroDisplay();
InputPgm();
FrostBiteEqn();
WindChillEqn();
OutputPgm();

EXPORT WindChillApp()
BEGIN
END;

VIEW "Start WindChill",START()
BEGIN
LOCAL K;

REPEAT
STARTVIEW(-1,1);
WindChillIntroDisplay();
REPEAT
Counter:=Counter+1;
IF Counter>5 THEN
MSGBOX("Program is Paused
Any Key to Continue");
Counter:=0;
BREAK;
END;
WAIT(1);
K:=GETKEY;
UNTIL K>−1;

Counter:=0;

IF K==42 OR K==43 THEN
InputPgm();
END;

IF K==30 THEN
WindChillEqn();
FrostBiteEqn();
STARTVIEW(-1,1);
OutputPgm();
WAIT(0);
END;

UNTIL K==4;
STARTVIEW(-4,0);
END;

WindChillIntroDisplay()
BEGIN
TEXTOUT("1: DegF= "+DegF,-15,9);
TEXTOUT("2: Mph= "+Mph,-15,7);
TEXTOUT("Enter: Calculate WindChill",-15,1);
TEXTOUT("Esc=Quit",-15,-1);
END;

InputPgm()
BEGIN
REPEAT
INPUT({DegF,Mph},"Input Values",{"DegF= : ","Mph=  : "},{"Air Temperature (-45 to 40 °F)","Wind Speed (3 to 60 Mph)"},{DegF,Mph});
UNTIL DegF>=-45. AND DegF<=40. AND Mph>=3. AND Mph<=60.; 
END;

FrostBiteEqn()
BEGIN

//Calculate frostbite time
CASE
IF DegF≤-45 AND Mph≥12 THEN 5▶ft END;
If DegF≤-45 and Mph≥0 Then 10▶ft END;
If DegF≤-40 and Mph≥14 Then 5▶ft END;
If DegF≤-40 and Mph≥0 Then 10▶ft END;
If DegF≤-35 and Mph≥17 Then 5▶ft END;
If DegF≤-35 and Mph≥7 Then 10▶ft END;
If DegF≤-35 and Mph≥0 Then 30▶ft END;
If DegF≤-30 and Mph≥21 Then 5▶ft END; 
If DegF≤-30 and Mph≥7 Then 10▶ft END;
If DegF≤-30 and Mph≥0 Then 30▶ft END;
If DegF≤-25 and Mph≥26 Then 5▶ft END;
If DegF≤-25 and Mph≥9 Then 10▶ft END;
If DegF≤-25 and Mph≥0 Then 30▶ft END;
If DegF≤-20 and Mph≥37 Then 5▶ft END;
If DegF≤-20 and Mph≥12 Then 10▶ft END;
If DegF≤-20 and Mph≥0 Then 30▶ft END;
If DegF≤-17 and Mph≥35 Then 5▶ft END;
If DegF≤-15 and Mph≥42 Then 5▶ft END;
If DegF≤-15 and Mph≥16 Then 10▶ft END;
If DegF≤-15 and Mph≥45 Then 30▶ft END;
If DegF≤-12 and Mph≥45 Then 5▶ft END;
If DegF≤-10 and Mph≥57 Then 5▶ft END;
If DegF≤-10 and Mph≥22 Then 10▶ft END;
If DegF≤-10 and Mph≥0 Then 30▶ft END;
If DegF≤-5 and Mph≥33 Then 10▶ft END;
If DegF≤-5 and Mph≥7 Then 30▶ft END;
If DegF≤-2 and Mph≥35 Then 10▶ft END;
If DegF≤0 and Mph≥54 Then 10▶ft END;
If DegF≤0 and Mph≥12 Then 30▶ft END;
If DegF≤2 and Mph≥55 Then 10▶ft END; 
If DegF≤2 and Mph≥15 Then 30▶ft END;
If DegF≤5 and Mph≥28 Then 30▶ft END;
If DegF≤7 and Mph≥30 Then 30▶ft END;
If DegF≤10 and Mph≥52 Then 30▶ft END;
If DegF≤12 and Mph≥55 Then 30▶ft END; 
" NOT LIKELY"▶ft;
END;
END;

WindChillEqn()
BEGIN
//New WindChill Equation
35.74+.6215*DegF−35.75*Mph^.16+.4275*DegF*Mph^.16▶wct;
round(wct,0)▶wct;

//Old WindChill Equation(Prior to 2001)
.0817*(3.71*Mph^.5+5.81-.25*Mph)*(DegF-91.4)+91.4▶wcto;
round(wcto,0)▶wcto;
END;

OutputPgm()
BEGIN
TEXTOUT("DegF= "+DegF,-15,9);
TEXTOUT("Mph= "+Mph,-15,7);
TEXTOUT("New WindChill= "+wct,-15,5);
TEXTOUT("Old WindChill= "+wcto,-15,3);
TEXTOUT("Frostbite,≤min "+ft,-15,1);
TEXTOUT("Enter=Back",-15,-1);
END;
Thanks
RCF


RE: How can I maintain a variables value when editing a Program or App - Didier Lachieze - 12-22-2014 09:42 AM

Here is an updated code that should work as you want. It saves the value of DegF and Mph in a Note called “WindChillApp_SavedVars” and retrieve the saved values when the variables are reinitialized. I’ve not found a way to access the App internal note (Info) with the new programmatic command Notes(), this is why I used a separate Note.

Changes:
  • RELOAD line added after your variables list
  • Variables saving to Note added to InputPgm()
I removed the + and the \n from the code provided by Cyrille (in the EXECON string) as they were not recognized by EXPR (Syntax Error). I had also to remove the brackets from the string generated by EXECON (they were added around the variable name and the value and I don't know how to tell EXECON not to add them).

Code:
//Variables... 
DegF;Mph;
LOCAL wct,wcto,ft;
Local Counter,ChooseVar;
RELOAD:= IFTE(POS(Notes, "WindChillApp_SavedVars"), EXPR(Notes("WindChillApp_SavedVars")), 0);

WindChillIntroDisplay();
InputPgm();
FrostBiteEqn();
WindChillEqn();
OutputPgm();

EXPORT WindChillApp()
BEGIN
END;

VIEW "Start WindChill",START()
BEGIN
LOCAL K;

REPEAT
STARTVIEW(-1,1);
WindChillIntroDisplay();
REPEAT
Counter:=Counter+1;
IF Counter>5 THEN
MSGBOX("Program is Paused
Any Key to Continue");
Counter:=0;
BREAK;
END;
WAIT(1);
K:=GETKEY;
UNTIL K>−1;

Counter:=0;

IF K==42 OR K==43 THEN
InputPgm();
END;

IF K==30 THEN
WindChillEqn();
FrostBiteEqn();
STARTVIEW(-1,1);
OutputPgm();
WAIT(0);
END;

UNTIL K==4;
STARTVIEW(-4,0);
END;

WindChillIntroDisplay()
BEGIN
TEXTOUT("1: DegF= "+DegF,-15,9);
TEXTOUT("2: Mph= "+Mph,-15,7);
TEXTOUT("Enter: Calculate WindChill",-15,1);
TEXTOUT("Esc=Quit",-15,-1);
END;

InputPgm()
BEGIN
LOCAL MyRememberedVarList= { 'DegF', 'Mph' };
LOCAL MySavedVarString;
REPEAT
INPUT({DegF,Mph},"Input Values",{"DegF= : ","Mph=  : "},{"Air Temperature (-45 to 40 °F)","Wind Speed (3 to 60 Mph)"},{DegF,Mph});
UNTIL DegF>=-45. AND DegF<=40. AND Mph>=3. AND Mph<=60.; 
MySavedVarString:= ΣLIST(EXECON("""&1:=&2;""", MyRememberedVarList, eval(MyRememberedVarList)));
Notes("WindChillApp_SavedVars"):= REPLACE(REPLACE(MySavedVarString,"(",""),")","")
END;

FrostBiteEqn()
BEGIN

//Calculate frostbite time
CASE
IF DegF≤-45 AND Mph≥12 THEN 5▶ft END;
If DegF≤-45 and Mph≥0 Then 10▶ft END;
If DegF≤-40 and Mph≥14 Then 5▶ft END;
If DegF≤-40 and Mph≥0 Then 10▶ft END;
If DegF≤-35 and Mph≥17 Then 5▶ft END;
If DegF≤-35 and Mph≥7 Then 10▶ft END;
If DegF≤-35 and Mph≥0 Then 30▶ft END;
If DegF≤-30 and Mph≥21 Then 5▶ft END; 
If DegF≤-30 and Mph≥7 Then 10▶ft END;
If DegF≤-30 and Mph≥0 Then 30▶ft END;
If DegF≤-25 and Mph≥26 Then 5▶ft END;
If DegF≤-25 and Mph≥9 Then 10▶ft END;
If DegF≤-25 and Mph≥0 Then 30▶ft END;
If DegF≤-20 and Mph≥37 Then 5▶ft END;
If DegF≤-20 and Mph≥12 Then 10▶ft END;
If DegF≤-20 and Mph≥0 Then 30▶ft END;
If DegF≤-17 and Mph≥35 Then 5▶ft END;
If DegF≤-15 and Mph≥42 Then 5▶ft END;
If DegF≤-15 and Mph≥16 Then 10▶ft END;
If DegF≤-15 and Mph≥45 Then 30▶ft END;
If DegF≤-12 and Mph≥45 Then 5▶ft END;
If DegF≤-10 and Mph≥57 Then 5▶ft END;
If DegF≤-10 and Mph≥22 Then 10▶ft END;
If DegF≤-10 and Mph≥0 Then 30▶ft END;
If DegF≤-5 and Mph≥33 Then 10▶ft END;
If DegF≤-5 and Mph≥7 Then 30▶ft END;
If DegF≤-2 and Mph≥35 Then 10▶ft END;
If DegF≤0 and Mph≥54 Then 10▶ft END;
If DegF≤0 and Mph≥12 Then 30▶ft END;
If DegF≤2 and Mph≥55 Then 10▶ft END; 
If DegF≤2 and Mph≥15 Then 30▶ft END;
If DegF≤5 and Mph≥28 Then 30▶ft END;
If DegF≤7 and Mph≥30 Then 30▶ft END;
If DegF≤10 and Mph≥52 Then 30▶ft END;
If DegF≤12 and Mph≥55 Then 30▶ft END; 
" NOT LIKELY"▶ft;
END;
END;

WindChillEqn()
BEGIN
//New WindChill Equation
35.74+.6215*DegF−35.75*Mph^.16+.4275*DegF*Mph^.16▶wct;
round(wct,0)▶wct;

//Old WindChill Equation(Prior to 2001)
.0817*(3.71*Mph^.5+5.81-.25*Mph)*(DegF-91.4)+91.4▶wcto;
round(wcto,0)▶wcto;
END;

OutputPgm()
BEGIN
TEXTOUT("DegF= "+DegF,-15,9);
TEXTOUT("Mph= "+Mph,-15,7);
TEXTOUT("New WindChill= "+wct,-15,5);
TEXTOUT("Old WindChill= "+wcto,-15,3);
TEXTOUT("Frostbite,≤min "+ft,-15,1);
TEXTOUT("Enter=Back",-15,-1);
END;

(12-21-2014 11:35 PM)Bob Frazee Wrote:  Also, I was unable to find the Instruction SIGMALIST in the online manual or calculator help.
SIGMALIST stands for ΣLIST which is item 8 in Toolbox>List.

EDIT: If you want to keep your variables value inside your App, there is a simple way to do it in your case (limited number of simple variables): you can use the unused App internal variables to keep track of DegF and Mph. This is simpler but less generic than the solution above.
For example if you have created the “WindChillApp” from the “Function App”, you can store DegF in F1 and Mph in F2.

Here is an example with two lines added to START():
Code:
IFERR DegF:=F1 THEN DegF:=0 END;
IFERR Mph:=F2 THEN Mph:=0 END;
And two lines added to InputPgm():
Code:
F1:=DegF;
F2:=Mph;

Code:
//Variables... 
DegF;Mph;
LOCAL wct,wcto,ft;
Local Counter,ChooseVar;

WindChillIntroDisplay();
InputPgm();
FrostBiteEqn();
WindChillEqn();
OutputPgm();

EXPORT WindChillApp()
BEGIN
END;

VIEW "Start WindChill",START()
BEGIN
LOCAL K;
IFERR DegF:=F1 THEN DegF:=0 END;
IFERR Mph:=F2 THEN Mph:=0 END;
REPEAT
STARTVIEW(-1,1);
WindChillIntroDisplay();
REPEAT
Counter:=Counter+1;
IF Counter>5 THEN
MSGBOX("Program is Paused
Any Key to Continue");
Counter:=0;
BREAK;
END;
WAIT(1);
K:=GETKEY;
UNTIL K>−1;

Counter:=0;

IF K==42 OR K==43 THEN
InputPgm();
END;

IF K==30 THEN
WindChillEqn();
FrostBiteEqn();
STARTVIEW(-1,1);
OutputPgm();
WAIT(0);
END;

UNTIL K==4;
STARTVIEW(-4,0);
END;

WindChillIntroDisplay()
BEGIN
TEXTOUT("1: DegF= "+DegF,-15,9);
TEXTOUT("2: Mph= "+Mph,-15,7);
TEXTOUT("Enter: Calculate WindChill",-15,1);
TEXTOUT("Esc=Quit",-15,-1);
END;

InputPgm()
BEGIN
REPEAT
INPUT({DegF,Mph},"Input Values",{"DegF= : ","Mph=  : "},{"Air Temperature (-45 to 40 °F)","Wind Speed (3 to 60 Mph)"},{DegF,Mph});
UNTIL DegF>=-45. AND DegF<=40. AND Mph>=3. AND Mph<=60.; 
F1:=DegF;
F2:=Mph;
END;

FrostBiteEqn()
BEGIN

//Calculate frostbite time
CASE
IF DegF≤-45 AND Mph≥12 THEN 5▶ft END;
If DegF≤-45 and Mph≥0 Then 10▶ft END;
If DegF≤-40 and Mph≥14 Then 5▶ft END;
If DegF≤-40 and Mph≥0 Then 10▶ft END;
If DegF≤-35 and Mph≥17 Then 5▶ft END;
If DegF≤-35 and Mph≥7 Then 10▶ft END;
If DegF≤-35 and Mph≥0 Then 30▶ft END;
If DegF≤-30 and Mph≥21 Then 5▶ft END; 
If DegF≤-30 and Mph≥7 Then 10▶ft END;
If DegF≤-30 and Mph≥0 Then 30▶ft END;
If DegF≤-25 and Mph≥26 Then 5▶ft END;
If DegF≤-25 and Mph≥9 Then 10▶ft END;
If DegF≤-25 and Mph≥0 Then 30▶ft END;
If DegF≤-20 and Mph≥37 Then 5▶ft END;
If DegF≤-20 and Mph≥12 Then 10▶ft END;
If DegF≤-20 and Mph≥0 Then 30▶ft END;
If DegF≤-17 and Mph≥35 Then 5▶ft END;
If DegF≤-15 and Mph≥42 Then 5▶ft END;
If DegF≤-15 and Mph≥16 Then 10▶ft END;
If DegF≤-15 and Mph≥45 Then 30▶ft END;
If DegF≤-12 and Mph≥45 Then 5▶ft END;
If DegF≤-10 and Mph≥57 Then 5▶ft END;
If DegF≤-10 and Mph≥22 Then 10▶ft END;
If DegF≤-10 and Mph≥0 Then 30▶ft END;
If DegF≤-5 and Mph≥33 Then 10▶ft END;
If DegF≤-5 and Mph≥7 Then 30▶ft END;
If DegF≤-2 and Mph≥35 Then 10▶ft END;
If DegF≤0 and Mph≥54 Then 10▶ft END;
If DegF≤0 and Mph≥12 Then 30▶ft END;
If DegF≤2 and Mph≥55 Then 10▶ft END; 
If DegF≤2 and Mph≥15 Then 30▶ft END;
If DegF≤5 and Mph≥28 Then 30▶ft END;
If DegF≤7 and Mph≥30 Then 30▶ft END;
If DegF≤10 and Mph≥52 Then 30▶ft END;
If DegF≤12 and Mph≥55 Then 30▶ft END; 
" NOT LIKELY"▶ft;
END;
END;

WindChillEqn()
BEGIN
//New WindChill Equation
35.74+.6215*DegF−35.75*Mph^.16+.4275*DegF*Mph^.16▶wct;
round(wct,0)▶wct;

//Old WindChill Equation(Prior to 2001)
.0817*(3.71*Mph^.5+5.81-.25*Mph)*(DegF-91.4)+91.4▶wcto;
round(wcto,0)▶wcto;
END;

OutputPgm()
BEGIN
TEXTOUT("DegF= "+DegF,-15,9);
TEXTOUT("Mph= "+Mph,-15,7);
TEXTOUT("New WindChill= "+wct,-15,5);
TEXTOUT("Old WindChill= "+wcto,-15,3);
TEXTOUT("Frostbite,≤min "+ft,-15,1);
TEXTOUT("Enter=Back",-15,-1);
END;



RE: How can I maintain a variables value when editing a Program or App - Bob Frazee - 01-24-2015 01:41 AM

Thanks very much for all your suggestions. I used the "edit" suggestion by Didier, because I wanted to keep the variables inside the app. I had not even thought of doing something like that. Thanks again.
rcf