Page 1 of 2

change variable names based on values in repeat loop

Posted: Fri Jun 28, 2013 8:22 pm
by PoLyGLoT
Hi all,

Simple question: I have 5 separate variables I'm working with (data2, data3, data4, data5, and data6). With each data set, I'm trying to do the exact same repeat loop.

Instead of copying the same repeat loop 6 times, and changing the "data" variable to "data2", then "data3", etc., I'm trying to use 1 repeat loop and just change the name of "data" automatically based on a constant array.

I'm trying this, but it's not working:

repeat with z = 2 to 6
put the number of lines in data[z] into numlines <-- Hoping that this will first go with data2, then data3, etc.
repeat with x = 1 to numlines
## LOTS OF CODE HERE ##
end repeat
end repeat

Any suggestions?

Re: change variable names based on values in repeat loop

Posted: Fri Jun 28, 2013 9:20 pm
by bn
Hi PoLy,

here is one way to do it

Code: Select all

on mouseUp
   -- just to fill the variables, you got them already
   put setUpData() into data2
   put setUpData() into data3
   put setUpData() into data4
   put setUpData() into data5
   put setUpData() into data6
   -- end filling variables
   
   longRepeatLoop data2
   longRepeatLoop data3
   longRepeatLoop data4
   longRepeatLoop data5
   longRepeatLoop data6
   -- each line of data(x) is now incremented by 10
   
   -- now lets look at the data just to see what happened
   put data2 & cr & cr & data3 & cr & cr & data4 & cr & cr & data5 & cr & cr & data6 into field 1
end mouseUp

on longRepeatLoop @pData
   -- add 10 to the number in each line of pData
   repeat with i = 1 to the number of lines of pData
      add 10 to line i of pData
   end repeat
end longRepeatLoop


function setUpData
   -- create a random number of lines for the data
   -- each line consists of a random number between 1 and 10
   repeat with i  = 1 to  random(10)
      put random (10) into line i of tCollect
   end repeat
   return tCollect
end setUpData
The idea is to break out the repeat loop into a separate command. Using the @ sign before pData (@pData) means you work on the original data and not on a copy of the data that is sent to the command.

This assumes that you have a button and a field in a stack. Try this on a new stack. Set the script of the button to the code above.



Kind regards
Bernd

Re: change variable names based on values in repeat loop

Posted: Fri Jun 28, 2013 10:16 pm
by dunbarx
Hi.

I think I know what you are after, so is this sort of what you need:

Make a field with five lines of data. In a button:

Code: Select all

on mouseUp
   get fld 1
   repeat with y = 1 to 5
      do "put line y of it into data" & y
   end repeat
   
   repeat with y = 1 to 5
      do "put data" & y && "into line" && y && "of temp"
   end repeat
     answer temp
end mouseUp
You can step through this and see what happens. Is the "do" construction necessary?

Craig Newman

Re: change variable names based on values in repeat loop

Posted: Fri Jun 28, 2013 11:14 pm
by Newbie4
I think what he wants to do is process every line in multiple multi-line variables. (Data2 might have 20 lines, data3 has 30 lines, etc). So the inner repeat loop will vary each time

e.g.

repeat with z = 2 to 6
put the number of lines in ("data" & z) into numlines
-- now loop thru every line in each variable data2->data6
-- and each variable has a different number of lines in it
repeat with x = 1 to numlines
--now process every line in that variable
end repeat
end repeat

If that is not what he meant, it still brings up a problem...

The above code should work but doesn't
I use similar code when I have many objects or a different number of objects
(e.g.
repeat with i = 1 to 20
move button ("enemy" & i) to loc x,y)
end repeat

I also tried using indirection and the "@" but that did not work either.

Any idea why it does not work in this case? or what I am doing wrong?

Thanks

Re: change variable names based on values in repeat loop

Posted: Fri Jun 28, 2013 11:34 pm
by bn
Hi New,

you can force this
put the number of lines in ("data" & z) into numlines
to work the way you want it:

Code: Select all

on mouseUp
   put "a" & cr & "b" & cr & "c" & cr & "d" into data3
   put 3 into z
   put the number of lines in value(("data" & z)) into numlines
   put numlines
end mouseUp
(the inner pair of parenthesis is optional but I would keep it. It is cleaner/safer this way since it forces LiveCode to first evaluate the inner parenthesis.
But I try to avoid "do" or "value" since apparently the engine has to recompile these and they are time consuming, especially in a repeat loop and they are confusing to read, in my opinon.

Instead of the way I posted above one could also stuff the data into an array and then work with the keys of the array in the repeat loop.


Kind regards
Bernd

Re: change variable names based on values in repeat loop

Posted: Sat Jun 29, 2013 12:05 am
by bn
Hi New,

if you want to use an array this would be one way to do it.
Create a new stack with 4 buttons. Name the first 3 "button1" to "button3"
into the fourth you put this script

Code: Select all

on mouseUp
   put the width of this card into tWidth
   put the height of this card into tHeight
   repeat with i = 1 to 3
      put random(tWidth) & "," & random(tHeight) into tArray["button" &i]
   end repeat
   
   put the keys of tArray into tKeys
   sort tKeys
   repeat 4
      lock screen
      repeat for each line aButton in tKeys
         set the loc of button aButton to tArray[aButton]
      end repeat
      unlock screen
      wait 1 second
      -- generate new locations
      repeat for each line aButton in tKeys
         put random(tWidth) & "," & random(tHeight) into tArray[aButton]
      end repeat
   end repeat
end mouseUp
Kind regards
Bernd

Re: change variable names based on values in repeat loop

Posted: Sat Jun 29, 2013 12:21 am
by Newbie4
Sorry Bernd,
I was just giving an example of concatenating a variable number to a name worked. It works everywhere else in LiveCode. His example of getting the number of lines of ("data" & z) was the first case that I have seen where it does not work.

I realized that I was moving all the enemies to the same spot but I did not want to make my example too complicated or lead away from the original problem. I apologize. Next time I will think up a better example. (I might have wanted to return them all back to the start!!!)

I was not looking to use an array. If you have a small finite number of objects, sometimes arrays add an extra level of complexity and are not really necessary.

Thanks anyway. That was nice of you to try to help me too.

I may use your code example in the future.

Re: change variable names based on values in repeat loop

Posted: Sat Jun 29, 2013 12:34 am
by bn
Hi Newbie4,

nothing to feel sorry about. I realized that your example was just a "mock-up".
Since I like arrays I wanted to post a working example of using an array. I was not trying to be "smart".
I agree with you that for a small number of elements an array can be just too much.
Kind regards
Bernd

Re: change variable names based on values in repeat loop

Posted: Sat Jun 29, 2013 1:34 am
by Newbie4
You have my curiosity up now.
I do not understand what advantage an array would have in a situation like this. It seems like you are adding a lot of complexity to the code and possibly more overhead to the execution. What are the advantages?

Also, I look at arrays as types of databases, used when you have to look records up (keys), manage pieces (elements) of them and sort the records. Why use it in situations like this where you are working with random objects?

In at least one of my apps, I am wrestling with using an array vs a tab delimited variable, 1 record per line. You can load both into a datagrid and both are easy to save to a file. How do you decide?

Re: change variable names based on values in repeat loop

Posted: Sat Jun 29, 2013 2:12 am
by bn
I don't have a general rule.
Just remember to use the the fastest ways when using lists. Build them by putting "after", access them with "repeat for each" Avoid "repeat with i = x to y" because y is evaluated every time since it is allowed to change y during the repeat loop. Not so in "repeat for each"
Arrays are NOT necessarily faster, so it is more a matter of preference/convenience. And how much time is at your disposal. If you want a frame rate for animation of 25 you have 40 milliseconds for one frame including the screen update. That can be a situation where you need to optimize your code a lot. And that means benchmarking variations of your code.

If your doing a calculation on mouseUp and the result comes after 30 or 70 milliseconds into a field it is not useful to tweak your code. But if it takes 250 milliseconds before the result is in the field the user will feel the slugginess.

http://forums.runrev.com/phpBB2/viewtop ... jat#p56253
here you can move more than thousand elements around and I use a list.

http://forums.runrev.com/phpBB2/viewtop ... tar#p78086
here I use an array for about 150 elements.

So really it is all about what kind of thing you are doing and what you feel more comfortable with as far as programming style is concerned.

Kind regards
Bernd

Re: change variable names based on values in repeat loop

Posted: Sat Jun 29, 2013 5:02 pm
by PoLyGLoT
Hi all,

I ended up using the following code to accomplish what I needed.

Code: Select all

repeat with z = 1 to 5
      if datanum = 0 then #first set of analyses
         put data2 into data
      else if datanum = 1 then 
         put data3 into data
      else if datanum = 2 then
         put data4 into data
      else if datanum = 3 then
         put data5 into data
      else if datanum = 4 then
         put data6 into data
      end if

## Lots of Code Here ##
add 1 to datanum
end repeat
In this manner, it repeats my line of code, and then afterward it immediately puts the next data file into the generic variable "data", and repeats the code again. By using a generic label during the actual analysis process, I can manipulate which information is being put in the generic "data" variable at the beginning.

This code seems to be working for my purposes. I appreciate all of the responses.

Thank you so much.

Re: change variable names based on values in repeat loop

Posted: Sat Jun 29, 2013 7:10 pm
by dunbarx
Good stuff indeed. But I see the script you last wrote, although perfectly sound, as needing refinement. Why use a "repeat with"? You never reference the index "z" at all, only using it as a counter from 1 to 5. Nothing wrong, in and of itself, with that as well, but it is misapplied. I don't know exactly what your script does, but I think you would benefit from stepping through the following. And it seems to me that you use the updated variable each time. I use a random number to distinguish the contents of the variables created.You would do something different of course.:

Code: Select all

on mouseUp
   put 0 into dataNum
   repeat with dataNum = 0 to 4
       do "put random(99) into data" & datanum + 2
         put data2 into data
         put data3 into data
         put data4 into data
         put data5 into data
         put data6 into data
      
      ## Lots of Code Here ##
     
   end repeat
end mouseUp
Craig Newman

Re: change variable names based on values in repeat loop

Posted: Sat Jun 29, 2013 9:05 pm
by PoLyGLoT
dunbarx wrote:Good stuff indeed. But I see the script you last wrote, although perfectly sound, as needing refinement. Why use a "repeat with"? You never reference the index "z" at all, only using it as a counter from 1 to 5. Nothing wrong, in and of itself, with that as well, but it is misapplied. I don't know exactly what your script does, but I think you would benefit from stepping through the following. And it seems to me that you use the updated variable each time. I use a random number to distinguish the contents of the variables created.You would do something different of course.:

Code: Select all

on mouseUp
   put 0 into dataNum
   repeat with dataNum = 0 to 4
       do "put random(99) into data" & datanum + 2
         put data2 into data
         put data3 into data
         put data4 into data
         put data5 into data
         put data6 into data
      
      ## Lots of Code Here ##
     
   end repeat
end mouseUp
Craig Newman
Your code seems interesting. I will try it out perhaps with my next script I write where I need to accomplish the same function. Thanks very much.

You are absolutely correct that the z index is just used as a counter. :D

Re: change variable names based on values in repeat loop

Posted: Sat Jun 29, 2013 10:37 pm
by dunbarx
Hi.

Your original post was about a way of coding so that you did not have to explicitly name, populate and reference a multitude of variables. This is very useful if you have a great many of these things, where it is crucial that LC do the management.

The use of "do" constructions, frequently found in these methods, is invaluable as a tool to learn about how LC resolves statements, and how sometimes more than one level of resolution is required for the parser to make sense of what it is being asked to do. Only practice can help in learning the ins and outs of that.

Do let me know what your experiments come up with. Do try to load a bunch of variables (or an array) with such methods. Then try to extract the data from that group, and place that data into a container somewhere. This will be both frustrating and very rewarding.

Craig

Re: change variable names based on values in repeat loop

Posted: Sun Jun 30, 2013 1:11 am
by rkriesel
PoLyGLoT wrote: I'm trying this, but it's not working:

repeat with z = 2 to 6
put the number of lines in data[z] into numlines <-- Hoping that this will first go with data2, then data3, etc.
repeat with x = 1 to numlines
## LOTS OF CODE HERE ##
end repeat
end repeat

Any suggestions?
Hi, PoLyGLoT. I'm replying to your original post, rather than later posts, because your original code seems close to working.

If you do care about the sequences of handling the datasets and lines, you could try it this way:

Code: Select all

repeat with z = 2 to 6
    put 0 into x
    repeat for each line tLine in value( "data" & z )
        add 1 to x
        ## LOTS OF CODE HERE ##
    end repeat
end repeat
If your variable "data" were an array whose keys match the values of your "z," and you didn't care about the sequences of handling the datasets and lines, then the code could be a little simpler and faster:

Code: Select all

repeat for each key z in data
    repeat for each line tLine in data[ z ]
        ## LOTS OF CODE HERE ##
    end repeat
end repeat
@Newbie4: If you like the compactness and speed of the above code, then you see one advantage of using arrays.

-- Dick