Page 1 of 1
Using "do" with variable names defined by user at runtime
Posted: Mon Sep 08, 2014 11:45 pm
by pthirkell
I am building a simple formula calculator where I want the result to be evaluated using the "do" command. The user types several variable names into fields provided, along with a value for each variable in a matching field. Then the user creates a formula in a field (called say "Formula") using LC syntax. Any or all of the named variables can be used in the formula as many time as required and in any order. Ideally the user then just clicks a button to "do" whatever is in the formula.
So let's say that the user chooses three variable names such as "monetary" "recreation" and "parking" and types then into the provided fields. In the matching value fields each variable is then assigned a value of say "2" "3" and "4" respectively. He/she then creates a formula to be evaluated in the "Formula" field. So for example it could be:
monetary*3 + 24 + recreation^2 + sqrt(parking) - monetary/2 +10
I want to evaluate this expression. My problem is how to create variables in a predefined script using variable names defined by the user at runtime.
I tried replacetext() to replace the user-defined variables with my own variable names, but the "stringToChange" is the formula which Livecode tries to resolve to a string rather than taking it as a literal string. I tried offset() with essentially the same problem - it tries to resolve the formula to a string. I even tried declaring a local (field "FirstVariableName") but of course LC didn't know what to do with that ... and even if it did then what name would I subsequently use to reference that declared local?
I thought maybe there was a way to "lock" the formula string until after I had replaced the named variables with my own, but not that I could find.
In short I'm stuck. Any advice or pointing in the right direction welcome!
Re: Using "do" with variable names defined by user at runtim
Posted: Tue Sep 09, 2014 3:30 am
by dunbarx
Hi.
You are trying to write a parser. Nothing wrong with that, but I bet if you rethink your application, you can come up with simpler gadgetry.
But anyway, what you need is to use the "value" function, not evaluate with "do" (though I am sure this can be worked as well).
In a new card, make seven fields and a button. Name the fields "a", "b", "c", "a1", "b1" and "c1" and "formula". In flds "a" through "c", put an "a", a "b" and a "c'. So fld "a" contains "a" as its text. In "a1" through "c1", put a number. So fld "a1", say, contains "3". In the "fomula" field, place something like
4*a +24 + 2*b +c*8
In the button script:
Code: Select all
on mouseUp
put fld "a1" into a
put fld "b1" into b
put fld "c1" into c
answer the value of fld "formula"
end mouseUp
Now this is all doable, but the real question is: should it be done this way. This example assumes a lot, in that each element of the equation can be parsed so that the "value" function can make sense of it. It may not always be so easy; you may have to do some prechunking before you can trust the form of the equation. That sort of thing. So though this is a fun learning exercise, it points to the fact that the whole shootin' match may well cry out to be reformulated.
I don't mean to be a downer. Play with what I did, and see how far it can be taken. But all the while, think about whether this is the best way to execute your ideas. Write back. I am keen to see how home-made parsers can be developed.
Craig Newman
Re: Using "do" with variable names defined by user at runtim
Posted: Tue Sep 09, 2014 4:43 am
by Thierry
pthirkell wrote:Any advice or pointing in the right direction welcome!
Something like that as a start?
Code: Select all
on DoTheCalculation
local myVars, myFormula
-- Well, I assume you know how to transform
-- these 2 lines to fit with your list of fields
put field "Fvars" into myVars
split myVars by return and tab
put fld "Fformula" into myFormula
repeat for each key K in myVars
replace K with myVars[ K] in myFormula
end repeat
-- undeclared vars?
if matchText(myFormula, "(?i)\b([A-Z]+)\b", theCulprit ) then
answer myFormula &cr& theCulprit && "is not declared" with "Cancel"
put "..." into fld "Fresult"
else
-- looks good, go ahead
answer myFormula with "Cancel" or "Ok"
if IT is "Ok" then put value( myFormula) into fld "Fresult"
end if
end DoTheCalculation
HTH,
Thierry
Re: Using "do" with variable names defined by user at runtim
Posted: Tue Sep 09, 2014 10:16 am
by pthirkell
Thanks Craig and Thierry. I love the creative solutions proposed, and they helped me to think more laterally about the issue and setting the scene for a more generalised approach.
Sticking with the simple (three variable) example provided, I found that a combination of "do" commands and a value call did the trick.
The variable names and matching values were typed by the user into fields called in this example "VariableName1" (to 3) and "VariableValue1" (to 3). The following script creates variables with the user chosen names, assigns the user chosen values, and calculates the value of the formula also entered by the user.
on mouseup
-- create (three) local variables using the names chosen by the user at runtime
put "local " & fld "VariableName1" & comma & fld "VariableName2" & comma & fld "VariableName3" into VariableNameDeclares
do VariableNameDeclares
-- assign values to each local variable using values chosen by user at runtime (held in fields "VariableValue1" to "VariableValue3")
do "put " & fld "VariableValue1" & " into " & fld "VariableName1"
do "put " & fld "VariableValue2" & " into " & fld "VariableName2"
do "put " & fld "VariableValue3" & " into " & fld "VariableName3"
-- calculate the formula
answer the value of fld "formula"
end mouseup
Re: Using "do" with variable names defined by user at runtim
Posted: Tue Sep 09, 2014 11:23 am
by Thierry
pthirkell wrote:
on mouseup
-- create (three) local variables using the names chosen by the user at runtime
put "local " & fld "VariableName1" & comma & fld "VariableName2" & comma & fld "VariableName3" into VariableNameDeclares
do VariableNameDeclares
-- assign values to each local variable using values chosen by user at runtime (held in fields "VariableValue1" to "VariableValue3")
do "put " & fld "VariableValue1" & " into " & fld "VariableName1"
do "put " & fld "VariableValue2" & " into " & fld "VariableName2"
do "put " & fld "VariableValue3" & " into " & fld "VariableName3"
-- calculate the formula
answer the value of fld "formula"
end mouseup
Ok, for fun..
another one using your context.
Code: Select all
repeat with i=1 to 3
replace (fld ("VariableName" & i)) with (fld ("VariableValue" & i)) in fld "formula"
end repeat
answer 0 + fld "formula"
Regards,
Thierry
Re: Using "do" with variable names defined by user at runtim
Posted: Sun Sep 14, 2014 8:12 pm
by sturgis
You might also look at the interesting things you can do with merge.