Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-08 Thread Mike Bonner
Very interesting discussion!  I'm still curious though.  Since the op
already takes the json based file and turns it into an array ( probably
using an existing json library.)  Since this step is already done, and the
array esists, is there an actual benefit to then breaking that array into
separate variables using do?  If so, why? (perhaps this has already been
covered, but information overload is making my brain melt)

On Tue, Nov 8, 2016 at 5:46 AM, Ben Rubinstein  wrote:

> Hi Mark,
>
> There's a reason why I haven't posted the code of explodeRow... but I'm
> sure it _could_ be efficient!
>
> Thanks for reminding me about split with one delimiter - I never use that.
>
> I think when I first encountered it I was so annoyed by the thought that
> it was pointless, because what I was looking for was for it have the
> opposite effect (key on the chunk text, value being the index) that I never
> considered it again. But of course it makes a lot of sense in a context
> where dipping into indexed items repeatedly is going to be expensive - I'll
> try to remember its use in the future.
>
> Ben
>
>
> On 08/11/2016 12:23, Mark Waddingham wrote:
>
>> Apologies - I clicked the wrong button in my email client and managed to
>> send
>> a partially composed message. Here is the correct version!
>>
>> On 2016-11-08 12:48, Ben Rubinstein wrote:
>>
>>> The point is that in my first pattern, I have outside the loop
>>> assigned column (item) indices to named variables (based on the items
>>> of the first, header, row). In the loop LC then has to locate the
>>> indexed items in an individual data row.
>>>
>>
>> In the first pattern:
>>
>> repeat for each line tRec in tTSVdata
>>   doSomething item viUserID of tRec, item viUserName of tRec
>>   ...
>> end repeat
>>
>> The 'item  of tRec' expressions cause the engine to iterate
>> through
>> tRect until it has found the relevant item. This means that this single
>> line
>> will be looking through the tRec string twice from the start - the first
>> time
>> up until the viUserID'd item, the second time up to the viUserName'd
>> item. The
>> speed of this will largely depend on how large the item indicies are, and
>> how
>> large tRec is (and where the items fall in tRec).
>>
>> If the item indices are small, close and near to the start, and tRec is
>> small,
>> and you don't use 'item ... of tRec' anywhere else in the loop, then it
>> will
>> likely be faster than anything else.
>>
>> In the second pattern, the code which happens to be in a function for
>>> neatness has to create a new empty array, and chunk both the data row
>>> and the header row in order to get column names and values to put into
>>> the array. You can loop over one set of items, but not both, so LC
>>> still has to locate indexed items in at least one case.
>>>
>>
>> put line 1 of tTSVdata into tColumnNames
>> delete line 1 of tTSVdata
>> repeat for each line tRec in tTSVdata
>>   put explodeRow(tRec, tColumnNames) into aData
>>   doSomething aData["User ID"], aData["User Name"]
>>   ...
>> end repeat
>>
>> The performance will largely depend on the implementation of explodeRow
>> and
>> (as you said subsequently) how many columns you want from the row.
>>
>> If you only want 2 then unless each tRec is very long and you are
>> fetching two
>> items near the end then the non-array version will likely be faster. If,
>> however, the two items are near the end of the row or you are wanting to
>> access lots of items then this will be faster than either:
>>
>> repeat for each line tRec in tTSVdata
>>   split tRec by tab
>>   doSomething tRec[viUserID], tRec[viUserName]
>>   ...
>> end repeat
>>
>> The difference here is that with the 'item' approach the speed will reduce
>> quadratically with the length of tRec and the max(viUserId, viUserName);
>> with
>> the 'split' approach the speed will reduce linearly with the length of
>> tRec.
>>
>> Depending on the average lengths of tRec and values of viUserId /
>> viUserName,
>> at somepoint the 'item' approach will start to be significantly slower
>> than
>> the 'split' version.
>>
>> The explodeRow approach sounds like it has lots of overhead. A fair
>> amount of
>> the overhead could probably be eliminated by doing 'split tColumnNames by
>> tab', and then using array access in explodeRow to form the aData array
>> (also
>> making sure explodeRow is private will help too).
>>
>> Just my two pence.
>>
>> Mark.
>>
>>
>
>
>
> ___
> use-livecode mailing list
> use-livecode@lists.runrev.com
> Please visit this url to subscribe, unsubscribe and manage your
> subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode
>
___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-08 Thread Ben Rubinstein

Hi Mark,

There's a reason why I haven't posted the code of explodeRow... but I'm sure 
it _could_ be efficient!


Thanks for reminding me about split with one delimiter - I never use that.

I think when I first encountered it I was so annoyed by the thought that it 
was pointless, because what I was looking for was for it have the opposite 
effect (key on the chunk text, value being the index) that I never considered 
it again. But of course it makes a lot of sense in a context where dipping 
into indexed items repeatedly is going to be expensive - I'll try to remember 
its use in the future.


Ben

On 08/11/2016 12:23, Mark Waddingham wrote:

Apologies - I clicked the wrong button in my email client and managed to send
a partially composed message. Here is the correct version!

On 2016-11-08 12:48, Ben Rubinstein wrote:

The point is that in my first pattern, I have outside the loop
assigned column (item) indices to named variables (based on the items
of the first, header, row). In the loop LC then has to locate the
indexed items in an individual data row.


In the first pattern:

repeat for each line tRec in tTSVdata
  doSomething item viUserID of tRec, item viUserName of tRec
  ...
end repeat

The 'item  of tRec' expressions cause the engine to iterate through
tRect until it has found the relevant item. This means that this single line
will be looking through the tRec string twice from the start - the first time
up until the viUserID'd item, the second time up to the viUserName'd item. The
speed of this will largely depend on how large the item indicies are, and how
large tRec is (and where the items fall in tRec).

If the item indices are small, close and near to the start, and tRec is small,
and you don't use 'item ... of tRec' anywhere else in the loop, then it will
likely be faster than anything else.


In the second pattern, the code which happens to be in a function for
neatness has to create a new empty array, and chunk both the data row
and the header row in order to get column names and values to put into
the array. You can loop over one set of items, but not both, so LC
still has to locate indexed items in at least one case.


put line 1 of tTSVdata into tColumnNames
delete line 1 of tTSVdata
repeat for each line tRec in tTSVdata
  put explodeRow(tRec, tColumnNames) into aData
  doSomething aData["User ID"], aData["User Name"]
  ...
end repeat

The performance will largely depend on the implementation of explodeRow and
(as you said subsequently) how many columns you want from the row.

If you only want 2 then unless each tRec is very long and you are fetching two
items near the end then the non-array version will likely be faster. If,
however, the two items are near the end of the row or you are wanting to
access lots of items then this will be faster than either:

repeat for each line tRec in tTSVdata
  split tRec by tab
  doSomething tRec[viUserID], tRec[viUserName]
  ...
end repeat

The difference here is that with the 'item' approach the speed will reduce
quadratically with the length of tRec and the max(viUserId, viUserName); with
the 'split' approach the speed will reduce linearly with the length of tRec.

Depending on the average lengths of tRec and values of viUserId / viUserName,
at somepoint the 'item' approach will start to be significantly slower than
the 'split' version.

The explodeRow approach sounds like it has lots of overhead. A fair amount of
the overhead could probably be eliminated by doing 'split tColumnNames by
tab', and then using array access in explodeRow to form the aData array (also
making sure explodeRow is private will help too).

Just my two pence.

Mark.






___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-08 Thread Mark Waddingham
Apologies - I clicked the wrong button in my email client and managed to 
send a partially composed message. Here is the correct version!


On 2016-11-08 12:48, Ben Rubinstein wrote:

The point is that in my first pattern, I have outside the loop
assigned column (item) indices to named variables (based on the items
of the first, header, row). In the loop LC then has to locate the
indexed items in an individual data row.


In the first pattern:

repeat for each line tRec in tTSVdata
  doSomething item viUserID of tRec, item viUserName of tRec
  ...
end repeat

The 'item  of tRec' expressions cause the engine to iterate 
through tRect until it has found the relevant item. This means that this 
single line will be looking through the tRec string twice from the start 
- the first time up until the viUserID'd item, the second time up to the 
viUserName'd item. The speed of this will largely depend on how large 
the item indicies are, and how large tRec is (and where the items fall 
in tRec).


If the item indices are small, close and near to the start, and tRec is 
small, and you don't use 'item ... of tRec' anywhere else in the loop, 
then it will likely be faster than anything else.



In the second pattern, the code which happens to be in a function for
neatness has to create a new empty array, and chunk both the data row
and the header row in order to get column names and values to put into
the array. You can loop over one set of items, but not both, so LC
still has to locate indexed items in at least one case.


put line 1 of tTSVdata into tColumnNames
delete line 1 of tTSVdata
repeat for each line tRec in tTSVdata
  put explodeRow(tRec, tColumnNames) into aData
  doSomething aData["User ID"], aData["User Name"]
  ...
end repeat

The performance will largely depend on the implementation of explodeRow 
and (as you said subsequently) how many columns you want from the row.


If you only want 2 then unless each tRec is very long and you are 
fetching two items near the end then the non-array version will likely 
be faster. If, however, the two items are near the end of the row or you 
are wanting to access lots of items then this will be faster than 
either:


repeat for each line tRec in tTSVdata
  split tRec by tab
  doSomething tRec[viUserID], tRec[viUserName]
  ...
end repeat

The difference here is that with the 'item' approach the speed will 
reduce quadratically with the length of tRec and the max(viUserId, 
viUserName); with the 'split' approach the speed will reduce linearly 
with the length of tRec.


Depending on the average lengths of tRec and values of viUserId / 
viUserName, at somepoint the 'item' approach will start to be 
significantly slower than the 'split' version.


The explodeRow approach sounds like it has lots of overhead. A fair 
amount of the overhead could probably be eliminated by doing 'split 
tColumnNames by tab', and then using array access in explodeRow to form 
the aData array (also making sure explodeRow is private will help too).


Just my two pence.

Mark.

--
Mark Waddingham ~ m...@livecode.com ~ http://www.livecode.com/
LiveCode: Everyone can create apps

___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your 
subscription preferences:

http://lists.runrev.com/mailman/listinfo/use-livecode

___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-08 Thread Mark Waddingham

On 2016-11-08 12:48, Ben Rubinstein wrote:

The point is that in my first pattern, I have outside the loop
assigned column (item) indices to named variables (based on the items
of the first, header, row). In the loop LC then has to locate the
indexed items in an individual data row.


In the first pattern:

repeat for each line tRec in tTSVdata
doSomething item viUserID of tRec, item viUserName of tRec
...
end repeat

The 'item  of tRec' expressions cause the engine to iterate 
through tRect until it has found the relevant item. This means that this 
single line will be looking through the tRec string twice from the start 
- the first time up until the viUserID'd item, the second time up to the 
viUserName'd item. The speed of this will largely depend on how large 
the item indicies are, and how large tRec is (and where the items fall 
in tRec).


If the item indices are small, close and near to the start, and tRec is 
small, and you don't use 'item ... of tRec' anywhere else in the loop, 
then it will likely be faster than anything else.



In the second pattern, the code which happens to be in a function for
neatness has to create a new empty array, and chunk both the data row
and the header row in order to get column names and values to put into
the array. You can loop over one set of items, but not both, so LC
still has to locate indexed items in at least one case.


put line 1 of tTSVdata into tColumnNames
delete line 1 of tTSVdata
repeat for each line tRec in tTSVdata
put explodeRow(tRec, tColumnNames) into aData
doSomething aData["User ID"], aData["User Name"]
...
end repeat

The performance will largely depend on the implementation of explodeRow 
and (as you said subsequently) what



So in short, the function is doing what the inline code is, plus a
whole lot more. (Not to mention that in many cases the 'do something'
code only acts on a subset of the items in each row, whereas the array
of necessity is built out of all of them.) It may or may not be
significantly slower; but it definitely is slower.

Ben


___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your
subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


--
Mark Waddingham ~ m...@livecode.com ~ http://www.livecode.com/
LiveCode: Everyone can create apps

___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-08 Thread Ben Rubinstein


On 07/11/2016 18:05, Richard Gaskin wrote:

I wouldn't care to hazard a guess as to the relative speed of
"aData[x]"  versus "item x": but it's the overhead of the function
which creates the array on that I don't want to pay *on every row*.


The function call itself has very small overheard.  Whether the definition of
that function takes more time than walking through the characters for the
chunk expression can't be known without testing.


Not to flog this horse, but in this case it definitely does.

The point is that in my first pattern, I have outside the loop assigned column 
(item) indices to named variables (based on the items of the first, header, 
row). In the loop LC then has to locate the indexed items in an individual 
data row.


In the second pattern, the code which happens to be in a function for neatness 
has to create a new empty array, and chunk both the data row and the header 
row in order to get column names and values to put into the array. You can 
loop over one set of items, but not both, so LC still has to locate indexed 
items in at least one case.


So in short, the function is doing what the inline code is, plus a whole lot 
more. (Not to mention that in many cases the 'do something' code only acts on 
a subset of the items in each row, whereas the array of necessity is built out 
of all of them.) It may or may not be significantly slower; but it definitely 
is slower.


Ben


___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-08 Thread Kay C Lan
On Mon, Nov 7, 2016 at 1:21 AM, Mark Wieder  wrote:
> But maybe Bramanathaswami has some special use case?

Assuming that is the case then 'do' is the answer and you'll find an
example in the Dictionary under the 'local' command; the last example.

Unfortunately the example is a bit of negative learning and the use of
'local' inside a 'do' statement is unlikely to behave the way you
expect. A discussion, with an excellent explanation by Mark Waddingham
is available on the List under the Subject "local and do  -
what NOT to do" dated 18Feb16.

Sorry I don't know how to link to old posts.

___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-07 Thread Richard Gaskin

Ben Rubinstein wrote:

> On 07/11/2016 16:52, Richard Gaskin wrote:
>> On the one hand, each array access requires a small amount of
>> overhead to run the key through a hash to find the value's address.
>>  However, that overhead is pretty small...
>
> No, no - the meat here is this:
>
>> do makeAccessVars("vi", line 1 of tTSVdata)
>> ...
>> repeat for each line tRec in tTSVdata
>
> vs
>
>> repeat for each line tRec in tTSVdata
>> put explodeRow(tRec, tColumnNames) into aData

Ah, thanks.

Without seeing the code for explodeRow it's not possible for me to have 
an informed assessment of its impact.



> I wouldn't care to hazard a guess as to the relative speed of
> "aData[x]"  versus "item x": but it's the overhead of the function
> which creates the array on that I don't want to pay *on every row*.

The function call itself has very small overheard.  Whether the 
definition of that function takes more time than walking through the 
characters for the chunk expression can't be known without testing.


--
 Richard Gaskin
 Fourth World Systems
 Software Design and Development for the Desktop, Mobile, and the Web
 
 ambassa...@fourthworld.comhttp://www.FourthWorld.com

___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-07 Thread Ben Rubinstein

On 07/11/2016 16:52, Richard Gaskin wrote:

But more seriously, the meat here is this:


  doSomething item viUserID of tRec, item viUserName of tRec


...vs:


  doSomething aData["User ID"], aData["User Name"]


On the one hand, each array access requires a small amount of overhead to run
the key through a hash to find the value's address.  However, that overhead is
pretty small...



No, no - the meat here is this:


do makeAccessVars("vi", line 1 of tTSVdata)
...
repeat for each line tRec in tTSVdata



vs



repeat for each line tRec in tTSVdata
put explodeRow(tRec, tColumnNames) into aData



I wouldn't care to hazard a guess as to the relative speed of "aData[x]" 
versus "item x": but it's the overhead of the function which creates the array 
on that I don't want to pay *on every row*.


Ben

___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-07 Thread Dr. Hawkins
On Mon, Nov 7, 2016 at 8:52 AM, Richard Gaskin 
wrote:

> There's your first bug right there - that should be:
>
> do makeAccessVars("emacs", line 1 of tTSVdata)
>

damned heretics are everywhere . . .

:)


-- 
Dr. Richard E. Hawkins, Esq.
(702) 508-8462
___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-07 Thread Richard Gaskin

Ben Rubinstein wrote:

> So the typical routine is something like
>
>do makeAccessVars("vi", line 1 of tTSVdata)

There's your first bug right there - that should be:

do makeAccessVars("emacs", line 1 of tTSVdata)

(Ducking from Mark Wieder who will no doubt groan at the pun )

But more seriously, the meat here is this:

>   doSomething item viUserID of tRec, item viUserName of tRec

...vs:

>   doSomething aData["User ID"], aData["User Name"]

On the one hand, each array access requires a small amount of overhead 
to run the key through a hash to find the value's address.  However, 
that overhead is pretty small as hashes go, since it's not using 
anything heavy-duty like a cryptographic hash (no sha1Digest or even 
md5Digest), but some very small bit-shifting hash that only works as 
hard as it needs to to distribute addresses somewhat uniformly across 
internal buckets of addresses.


On the other hand, any chunk expression like "item viUserID of tRec" 
will require tRec to be traversed from its beginning, evaluating each 
character along the way, counting item delimiters as it goes.


Of course the loop you have there is much better than "repeat with", 
since at least each line itself is efficiently isolated for the 
item-test traversal.   But within each line traversal is still needed to 
identify items.


The cases I've seen where chunk expressions can outperform arrays tend 
to be those with a large number of lines and a small number of items, in 
which each item is itself a fairly short string.  And even then, other 
specifics about the data can come into play affecting measurable outcomes.


But given how lean the hash used for arrays is, I've found only a 
relatively small number of such cases.


The bigger difference by far will be with loading whichever structure 
you use.  While it does indeed require more or less the same 
character-by-character evaluation to split a chunk into an array, when 
the alternative leaves you with "do" you're up against the performance 
weaknesses inherent in it, which require dynamic evaluation of the 
expression and its context.


It takes a fair bit of exploration to find anything slower than "do" 
(though I'm sure there are a few cases if we look hard enough).


"do" is great for those rare moments when we truly have no alternative.

And since HyperCard didn't offer arrays, that was usually every day. :)

But arrays are a natural fit for cases where not only elements within a 
collection are variables, but also the names of those elements as well.


Indeed, that's the use case they were introduced to support.

--
 Richard Gaskin
 Fourth World Systems
 Software Design and Development for the Desktop, Mobile, and the Web
 
 ambassa...@fourthworld.comhttp://www.FourthWorld.com

___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-07 Thread Ben Rubinstein

On 07/11/2016 15:02, Richard Gaskin wrote:

Ben Rubinstein wrote:


(Re Mike and Mark's comments, if it's a small thing I'll use an
array; but for large quantities of data - I'm often dealing with
very large files, and after calling this function will loop over
tens or hundreds of thousands of rows using the variables - I feel
the need for speed outweighs the simplicity.)


Indeed, contrary to popular belief I've seen cases where certain aggregate
operations on an array take more time than achieving the same outcomes with
delimited lists.

But so far only a few.

How did you benchmark that, and what was the measured difference?


I'll confess: no benchmarking has taken place, just intuition.

I love arrays - coming from a HyperCard world in which I was similarly doing 
large amounts of processing over files, the ability to use hashed arrays when 
I discovered MetaCard made an enormous difference. I was and am blown away by 
the speed of access they allow.


The context in which I'm typically using this 'makeAccessVars' functionality 
is where the code loads a massive TSV file and then iterates through the rows 
doing various processing on the data. I don't want to hard-code the columns in 
which the data will be, because very occasionally that may change, and it's 
too easy to have a subtle bug here.


So the typical routine is something like

do makeAccessVars("vi", line 1 of tTSVdata)
delete line 1 of tTSVdata
repeat for each line tRec in tTSVdata
doSomething item viUserID of tRec, item viUserName of tRec
...
end repeat


If I'm doing something that _isn't_ going to repeat a vast number of times, I 
often use a variation more along these lines:


put line 1 of tTSVdata into tColumnNames
delete line 1 of tTSVdata
repeat for each line tRec in tTSVdata
put explodeRow(tRec, tColumnNames) into aData
doSomething aData["User ID"], aData["User Name"]
...
end repeat

where 'explodeRow' does the obvious thing to construct an array containing the 
data from the row, each value indexed by the name of the column in which it 
appeared.  I prefer that style, as it makes the "doSomething" part of the code 
- which is generally the most interesting bit, and therefore the one that 
needs easiest to understand - clearer. Obviously it must be slower though: but 
I admit I've never done the experiment to find out how significant the 
difference is.


(Actually I'd probably get better performance in the latter case, and further 
enhance readability, if I combined the two approaches, i.e modify 
'makeAccessVars' to that instead of returning a string which when passed to 
'do' declares variables named for each column and assigns indices to them, 
it's called for each row to assign the actual values to the variables.I'm not 
sure why I don't do this.)


Ben

___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-07 Thread Richard Gaskin

Ben Rubinstein wrote:

> (Re Mike and Mark's comments, if it's a small thing I'll use an
> array; but for large quantities of data - I'm often dealing with
> very large files, and after calling this function will loop over
> tens or hundreds of thousands of rows using the variables - I feel
> the need for speed outweighs the simplicity.)

Indeed, contrary to popular belief I've seen cases where certain 
aggregate operations on an array take more time than achieving the same 
outcomes with delimited lists.


But so far only a few.

How did you benchmark that, and what was the measured difference?

--
 Richard Gaskin
 Fourth World Systems
 Software Design and Development for the Desktop, Mobile, and the Web
 
 ambassa...@fourthworld.comhttp://www.FourthWorld.com

___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-07 Thread Ben Rubinstein
It's easy to dynamically create and set the values of variables, using the 
"do" command, e.g.:


do format("put tValue into %s", tVarName)

I do lots of work with TSV files, which have a first row of field names, and 
for years have used a function like this to create local variables, named for 
each column, with the index to that column as their value


do makeAccessVars("vi", line 1 of tTSVdata)

where the function creates a script doing essentially the above for all the 
field names, with a prefix (and taking care of spaces etc), which I then "do" 
in the individual procedure so that the variables are declared local to the 
procedure.


(Re Mike and Mark's comments, if it's a small thing I'll use an array; but for 
large quantities of data - I'm often dealing with very large files, and after 
calling this function will loop over tens or hundreds of thousands of rows 
using the variables - I feel the need for speed outweighs the simplicity.)


A minor isse with this is that it doesn't play nice with explicitVars: in 
order to nicely compile a script that invokes this function and then goes on 
to, for example,


repeat for each line tRec in tTSVdata
doSomething item viUserID of tRec, item viUserName of tRec


I have to have declared viUserID, and viUserName in the handler.


HTH,

Ben




On 06/11/2016 15:50, Sannyasin Brahmanathaswami wrote:

Given this scenario:

We fetch a preference array from some json on disk
We want to insert the key-values into separate discrete local vars in the stack 
script

function getUserPreferences

# the following function fetches an object in a JSON file:

put getPref ("preferences/modules/color-meditation") into aColorMedPrefs

# aColorMedPrefs now appears in variable watcher with keys
# aColorMedPrefs["BreathCount"] # value = 5
# aColorMedPrefs["BreathPace,"] # value = 1
# aColorMedPrefs["Cycles "] # value = 2
# aColorMedPrefs["AudioOn"] # value = "true"

# we want to pass each to a discrete local:
# sBreathCount,sBreathPace,sCycles,sAudioOn

 repeat for each key x in aColorMedPrefs
put "s" & x into tNextPref
put aColorMedPrefs[x] into tNextPref
put tNextPref & comma after tSettings
end repeat

return tSettings

# result:  "5,1,2,true"  i.e. the values

# But what we really want to do was insert those values in the local vars on 
each iteration.

  return (sBreathCount,sBreathPace,sCycles,sAudioOn) # would also return
"5,1,2,true"# but we get ",,," i.e now values.
end getUserPreferences

i.e. how do we dynamically create/name/instantiate variables & set their values 
from values in a loop?

it begs for some syntax like

create var ("s" & x); put x into the last var

BR

___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode



___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-06 Thread dunbarx
Hi.

Arrays are so new_fashioned.

But do you mean something like this, from the stone age, that creates
variables on the fly, in this case with 2X the value of an index?

on mouseUp
   repeat with y = 1 to 10
  do "put y * 2 into onTheFlyVar" & y
   end repeat
end mouseUp

Craig





--
View this message in context: 
http://runtime-revolution.278305.n4.nabble.com/How-can-we-dynamically-create-variable-names-from-changing-value-x-on-a-loop-tp4710128p4710142.html
Sent from the Revolution - User mailing list archive at Nabble.com.

___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


Re: How can we dynamically create variable names from changing value "x" on a loop?

2016-11-06 Thread Mike Bonner
Why not just leave it as an array?  In fact, if you want to have separate
preferences categories, that's easy enough to do too.

local sPrefsA

put getPref ("preferences/modules/color-meditation") into
sPrefsA[ColorMedPrefs]

at this point you have an local script array variable structured like so..
sprefsA
  colormedprefs
  breathcount = 5
  breathPace = 1
  cycles = 2
  audio on = true

to get a value from above, a simple function works..

function getSinglePref prefCat,prefName
 if prefcat is among the keys of sPrefsA
 if prefName is among the keys of sPrefsA[prefCat] then
  return sPrefsA[prefCat][prefName]
 else
  answer information "No such preference"
 end if
 else
  answer information "No such preference category"
  end if
end getSinglePref

If you don't need to categorize, change it to this..

put getPref ("preferences/modules/color-meditation") into sPrefsA

at which point you can retrieve a value with sPrefsA[prefname]


The code above is just off the top of my head, but it should be close.

On Sun, Nov 6, 2016 at 8:50 AM, Sannyasin Brahmanathaswami  wrote:

> Given this scenario:
>
> We fetch a preference array from some json on disk
> We want to insert the key-values into separate discrete local vars in the
> stack script
>
> function getUserPreferences
>
> # the following function fetches an object in a JSON file:
>
> put getPref ("preferences/modules/color-meditation") into aColorMedPrefs
>
> # aColorMedPrefs now appears in variable watcher with keys
> # aColorMedPrefs["BreathCount"] # value = 5
> # aColorMedPrefs["BreathPace,"] # value = 1
> # aColorMedPrefs["Cycles "] # value = 2
> # aColorMedPrefs["AudioOn"] # value = "true"
>
> # we want to pass each to a discrete local:
> # sBreathCount,sBreathPace,sCycles,sAudioOn
>
>  repeat for each key x in aColorMedPrefs
> put "s" & x into tNextPref
> put aColorMedPrefs[x] into tNextPref
> put tNextPref & comma after tSettings
> end repeat
>
> return tSettings
>
> # result:  "5,1,2,true"  i.e. the values
>
> # But what we really want to do was insert those values in the local vars
> on each iteration.
>
>   return (sBreathCount,sBreathPace,sCycles,sAudioOn) # would also return
> "5,1,2,true"# but we get ",,," i.e now values.
> end getUserPreferences
> 
> i.e. how do we dynamically create/name/instantiate variables & set their
> values from values in a loop?
>
> it begs for some syntax like
>
> create var ("s" & x); put x into the last var
>
> BR
>
> ___
> use-livecode mailing list
> use-livecode@lists.runrev.com
> Please visit this url to subscribe, unsubscribe and manage your
> subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode
>
___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


How can we dynamically create variable names from changing value "x" on a loop?

2016-11-06 Thread Sannyasin Brahmanathaswami
Given this scenario:

We fetch a preference array from some json on disk
We want to insert the key-values into separate discrete local vars in the stack 
script

function getUserPreferences

# the following function fetches an object in a JSON file:

put getPref ("preferences/modules/color-meditation") into aColorMedPrefs

# aColorMedPrefs now appears in variable watcher with keys
# aColorMedPrefs["BreathCount"] # value = 5
# aColorMedPrefs["BreathPace,"] # value = 1
# aColorMedPrefs["Cycles "] # value = 2
# aColorMedPrefs["AudioOn"] # value = "true"

# we want to pass each to a discrete local:
# sBreathCount,sBreathPace,sCycles,sAudioOn

 repeat for each key x in aColorMedPrefs
put "s" & x into tNextPref
put aColorMedPrefs[x] into tNextPref
put tNextPref & comma after tSettings
end repeat

return tSettings

# result:  "5,1,2,true"  i.e. the values

# But what we really want to do was insert those values in the local vars on 
each iteration.

  return (sBreathCount,sBreathPace,sCycles,sAudioOn) # would also return
"5,1,2,true"# but we get ",,," i.e now values.
end getUserPreferences

i.e. how do we dynamically create/name/instantiate variables & set their values 
from values in a loop?

it begs for some syntax like

create var ("s" & x); put x into the last var

BR

___
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode