Javascript Structure Loops

Swiftlikeninja's picture

I've attached a composition that will better show whatI am trying to do.

In a vain attempt to use what little knowledge about javascript I have, I tried to make a patch that will go through a structure and sort matching qualifiers into sub arrays (after which ill get into keying the structure, but I actually do know how to do that!!) I've ran into a snag with the patch. Im trying to make it as dynamic as possible since the structure can vary in size. I know I have to loop the code to do what i want but cannot figure out where to initiate the loop. Below is the code I'm using. Ive got k in there because im certain thats what im going to have to loop so its acting as a placeholder. If anyone could assist me in this dilemma you will have serious brownie points with me! :D

Again I've uploaded the qtz to exemplify

function (__structure Out)
main (__structure input,__structure team)
{   
 if (!_testMode)
 {
  var tmp = new Array();
  var build = new Array(team.length);
  var k = 0
     {  
     for (i=0;i<input.length;i++)
     if (input[i][1] == team[k])
     tmp.push(input[i]);
     build[k] = tmp;
    }   
 
 }
   result = new Object();
   result.Out =build
   return result;
}
PreviewAttachmentSize
teamsort.qtz111.05 KB

cwright's picture
Re: Javascript Structure Loops

First, let's clean up the code. this involves indenting, and adding semicolons where they belong.

function (__structure Out) main (__structure input,__structure team)
{ 
   if (!_testMode) {
      var tmp = new Array();
      var build = new Array(team.length);
      var k = 0;   // added semicolon
      // removed curly braces here because they're meaningless
      for (i=0;i<input.length;i++)
         if (input[i][1] == team[k])
            tmp.push(input[i]);
      build[k] = tmp;
    }
   result = new Object();
   result.Out = build;   // added semicolon
   return result;
}

As you might notice, tmp, build, and k are all scoped with the if (!_testMode) block. When the line result.Out = build is executed, it doesn't know what build is because build is then "out of scope." k is also a glorified constant -- it's always 0 (you never make an assignment to it). As such, build[0] might be populated, but that's all (the rest of the elements will be undefined). That's moot, because it's out of scope by the time it's used, but just to let you know.

gtoledo3's picture
Re: Javascript Structure Loops

If you're using SL it might just be simpler to iterate through everything, using conditional (or string compare) to return true or false for your search term, do whatever you need to do, gather the results in a queue, and publish the output.

gtoledo3's picture
Re: Javascript Structure Loops

This might display what I meant by doing it with an iterator and other patches, because I realized this morning it probably sounded obscure.

Is your goal to have something going like this, but to then parse it to where only the "true" parts of the structure are in the structure? Is that why you where thinking about a feedback loop? Maybe this will shed some light on broad concepts of making a boolean structure that you can compare against your incoming structure, to then see if a search term matches. In this instance, the search term matching controls whether or not the model renders.

PreviewAttachmentSize
MD2 with Search Term.zip282.53 KB

gtoledo3's picture
Re: Javascript Structure Loops

This is another twist that shows how to then rebuild structure based on the results of the boolean structure of search term being true/false, so that one has a structure that contains only results that match search term.

Sorry that this is an MD2/K3D thing, and not based on the scoring qtz that you submitted, but it should demonstrate the same principles (and this is something that I had on my mind for an MD2 based scenario).

With built in string patches, and some logic, you could do multiple search terms, etc.

Again, this is Snow Leopard only. I have to say, the ability to use iterators in this way may be my favorite addition to Snow Leopard, hands down.

Sorry for farting off the javascript route, it just doesn't seem as flexible. If there's some over-arching reason why it should be javascript that I'm glossing over, I do apologize for the time waster.

PreviewAttachmentSize
MD2 with Search Term II - Loop 2.zip297.83 KB

gtoledo3's picture
Re: Javascript Structure Loops

I started looking at your example in particular, with the way your data was formatted, to retrofit the concepts into your scenario. I saw that you had a structure of pass/fail terms, so that makes what you need to do a little different.

I did some manipulation of your original value table, because I needed to futz around with values to make sure stuff was working correctly. I also lopped off your first structure so that it was of equal size to the test structure, as it was making it awkward for testing (for me).

I would test this a bit to make sure it's working ok in your scenario, particularly to make sure that something like "test1" doesn't yield a true for something like "test10". I don't think it will (works fine in the finished qtz as far as I can see), but as I was editing and queues were shifting I saw something unexpected. I think it shouldn't be an issue, and was because one queue wasn't in synch with another because of my editing.

This has nothing to do w/K3D and is directly applicable to your scenario, hopefully.

PreviewAttachmentSize
Structure Pass or Fail Compare.qtz67.67 KB

gtoledo3's picture
Re: Javascript Structure Loops

What's sort of crappy is that I had someone asking me about a scoring system like this some months back, and I think I was skeptical. The idea being that you would search through data of sensors that would be hit, and then resulting scores get tabulated based on what team hit what. "Hmm, I really don't know if I'm sure about searching through that kind of data". (Hits self in forehead). I don't know what I wasn't thinking...

edit-please disregard the qtz immediately above. There is a bug... it's something about the way I'm resetting the queue that builds the structure back. When there is a "true" result midway through, it resets, and I can't figure out how to remedy that at the moment. Not occurring to me.

That may not matter for your situation(?).

In any event, this is something that will let all of the structure indexes that "match" pass through, and plug in an arbitrary value whenever it doesn't (so for score keeping or rendering things in certain scenarios, you could place in a 0 or nan value).

So, you will see "QC Structure" for all of the places where the "team" name of the structures match, and "nan" for all of the places it doesn't. The structure itself is fully accessible, even though I'm just rendering "QC Structure" instead of all 3 dimensions of each index.

PreviewAttachmentSize
Structure Pass or Fail Compare.qtz68.5 KB

usefuldesign.au's picture
Re: Javascript Structure Loops

This is to follow on from cwrights notes showing you a way to model a data structure in Javascript. Removes the need to resort to Structure Maker patch noodling and allows for niceties like easy randomisation.

Bit concerned if gtoledo is suggesting patches are more flexible than JS Patch for match-testing of QC structures :-) Might be a mis-reading on my part.

I couldn't fathom what you are trying to achieve with this comp so left it at making the data — not testing it or filtering it.

PreviewAttachmentSize
teamsort alt.qtz58.86 KB

gtoledo3's picture
Re: Javascript Structure Loops

In snow leopard you can publish out of an iterator. So, if you take in a bunch of values, and iterate through them with an iterator variable/structure index setup, you can do some kind of math or conditional, connect the result to a queue, and then publish the output.

So, if you are taking in a bunch of values into the iterator, it's easy to test against a conditional or string match, connect to a queue, publish output, and you have a structure that represents whether there is a match or not. There are myriad patches to manipulate strings, you can do logic/math, and you can add in results from other patches quickly. Maybe for me to suggest it's flexible concerns you, but it's expedient, and allows for breaking up each step of the process into a separate macro, which is clear to me. Don't knock it until you at least try to drink the iterator/publish output koolaid.

I have a macro that reports a structure where each index tells me something about the structure I'm feeding it from one source macro, when compared against a structure of search terms from another macro. Then if I want to use the pass/fail structure to "do something" to the values in the main structure, another macro handles that. This makes it clean and modular, to me. It's not right or wrong, it's just taste. For me, by distilling each part to it's base function, I can easily reuse stuff and program more efficiently.

Using this principle, but kind of setup differently, I've been able to make pretty elaborate maps/rules of what an "object" can do when it is at various x/y/z coordinates very quickly.

I think the point of the problem was that there is a first structure that has a bunch of indices that are three dimensions. One needs to be able to search through those indices, and return whether or not there is a match. On first opening, I'm not sure how what you did applies... but I may be misunderstanding the nature of what was trying to be accomplished. I don't think there was a problem of setting up initial structures. It seemed to me that the eventual thing here is that at least one of the structures if not both will be coming in dynamically. I may be off-base on that.

usefuldesign.au's picture
Re: Javascript Structure Loops

gtoledo3 wrote:
In snow leopard you can publish out of an iterator. So, if you take in a bunch of values, and iterate through them with an iterator variable/structure index setup, you can do some kind of math or conditional, connect the result to a queue, and then publish the output.
Yeah, I get that.

gtoledo3 wrote:
Don't knock it until you at least try to drink the iterator/publish output koolaid.

I'm hangin' for that cool aid don't worry 'bout that. I just generally find when it comes to logic based stuff JS gets the job done so much easier that patches but your point about the string compare, string into structure, etc etc patches is a good one. It's especially easier if your JS is still a struggle which it was/is for me. As for flexibility, I don't think you can argue a string of QC patches is more flexible for parsing/filtering/modify QCstructures than JS, unless JS array methods etc are a turn off, off course. I really can't image something you can do with patches regarding this kind of thing that JS patch can't handle and a lot of case where it would take me a while to think in terms of patches.

Guess it's possibly one of those radians or degrees things where you 'think' more in one system that the other until fluent in both.

gtoledo3 wrote:
I have a macro that reports a structure where each index tells me something about the structure I'm feeding it from one source macro, when compared against a structure of search terms from another macro. Then if I want to use the pass/fail structure to "do something" to the values in the main structure, another macro handles that. This makes it clean and modular, to me. It's not right or wrong, it's just taste. For me, by distilling each part to it's base function, I can easily reuse stuff and program more efficiently.

Using this principle, but kind of setup differently, I've been able to make pretty elaborate maps/rules of what an "object" can do when it is at various x/y/z coordinates very quickly.

Yeah if your set up with tools in that way it becomes the first choice for sure.

gtoledo3 wrote:
I think the point of the problem was that there is a first structure that has a bunch of indices that are three dimensions. One needs to be able to search through those indices, and return whether or not there is a match. On first opening, I'm not sure how what you did applies... but I may be misunderstanding the nature of what was trying to be accomplished. I don't think there was a problem of setting up initial structures. It seemed to me that the eventual thing here is that at least one of the structures if not both will be coming in dynamically. I may be off-base on that.

Yes I made that JS patch before your posts went up but didn't post it. I had in my mind some comment like "…next I'll work on assigning the 'keys' in JS" but I think I must have actually read that in another thread. Then I thought may as well post comp anyhow. As I said, I wasn't attempting to solve the problem because I couldn't decipher it — if you cracked it you've demonstrated much insight!

Just showing a way to make the data model in JS to show key making with variables etc. etc. Often it takes me as about as long to do that in JS than just noodle away Structure Maker patches but I figure I'm improving my JS at the same time, win/win :-).

gtoledo3's picture
Re: Javascript Structure Loops

Funnily enough, if I was going to make a big table of structure to compare against for a test, I would probably just do it with the javascript patch. I totally agree on the structure maker, I pretty much never use it, unless I'm working on something where it was already used.

It's not a matter of javascript methods being a turn-off. Again, the reason it's more flexible for me is that I'm dividing up each function into separate macro. For instance, it was extremely simple for me to dictate things like which of the "three dimensions" of the structure to check for, which could be dynamic, along with things like the search term, without having to take anytime to declare input ports.

So, I wouldn't argue that it's more flexible, but I will describe the reasons why it works for me. For me, the coding patches are sort of for "if it can't be done with the other patches". I carry some thought of the javascript patch being less efficient for certain logic intensive things as well, but I may be wrong.

At the same time, I would yearn for integration of obj-c/quartz methods in QC... being able to set up points, and then create paths relative to those points, put images at the points, doing color fill, etc. That just doesn't seem like it's a humongous hurdle, and I'm surprised it doesn't already exist in some way. I get the impression from you that you think I'm anti-coding - I'm just pro-efficiency, quickness, modularity, and whatever seems like the most clear way to do something to me. I also have a mild fetish for seeing how far boxes and noodles can be pushed to do stuff without adding lines of code, as I think the paradigm is strong, and it proves the strength of the QC paradigm.

I'm actually curious if it did solve the problem! The resulting macros actually proved useful for me. I know that given a bunch of incoming data tagged with different team names, and different values, I could tabulate results, do scores, etc., at various times based on the macros (save for the one that I pointed out that I found a bug in after the fact).

I do get kind of quirky about efficiency. Sometimes I gauge stuff like how many clicks it takes to do something one way vs. another, or

usefuldesign.au's picture
Re: Javascript Structure Loops

Don't get me wrong! I was saying anything QC Structure filtering/testing you can do with patch, you can do with JS patch and, to my way of thinking, other stuff besides. This in NO WAY means that doing it in JS is superior. QC is always horses for courses and end results trump theories every time. (As cwright always says, prototype it and test it, this beats his hand waving about theoretical speed advantages).

What ever method one employs one learns more and stores more utilities in that direction. I certainly 'aux-out' functionality from the JS patch at any opportunity if I can reduce execution cycles or execution elapsed time or just JS debug brain drain :/. Sometimes I 'aux-return' the patch results too but pretty rare. Debugging QC patches is usually easier for me than JS just because you can PEEK and POKE so easily. (Typing in Log statements is invaluable for JS debugging but no comparison to mousing over nodes or porting to a billboard!)

QC is a nodal environment after all. (to paraphrase somebody great).

Having said that what I'm currently doing runs rings around patches for speed and crossover/interdependent functional logical (if I can put it lazily like that!). I actually started doing it with 25+ QCButton patches feeding results to math expression and different logic patches b/c I guessed it would be faster/easier/flexible.

I intuitively felt I'd end up having to try JS at some point just to handle the complexity of all the 'modes' I have to switch between. Turned out JS is faster too so I just kept going in that direction. There are no doubt other Patch based ways to try but I tried a few and the need to RII heaps of sprites or use daisy-chains of CI Additions just to create a mask was in the end a fps sink and layout PITA. Will send you an update of that PATCHbANK project soon so you can see what I mean.

usefuldesign.au's picture
Re: Javascript Structure Loops

gtoledo3 wrote:
For instance, it was extremely simple for me to dictate things like which of the "three dimensions" of the structure to check for, which could be dynamic, along with things like the search term, without having to take anytime to declare input ports.
Yes definitely JS patch has a time to roll overhead plus a time to reorganise overhead when you want to branch off into something else. Not to mention debug :/
gtoledo3 wrote:
So, I wouldn't argue that it's more flexible, but I will describe the reasons why it works for me. For me, the coding patches are sort of for "if it can't be done with the other patches". I carry some thought of the javascript patch being less efficient for certain logic intensive things as well, but I may be wrong.
Flexibility was all I was talking about really. However to state "For me, the coding patches are sort of for 'if it can't be done with the other patches' " is to me a kind of arbitrary judgement based on personal aesthetics / preferences rather than any fundamental QC rules or observances. Even though the paradigm is one of a functional programming graph which JS, CIFilter, GLSL patches subvert/make-exceptions-to I suppose.

gtoledo3's picture
Re: Javascript Structure Loops

Yeah, I would argue that the RII stuff you were doing was totally unneeded (and did).... but we're now talking about something no one really knows about, so it's lost on anyone. With the patch bank qtz that I saw, there was totally no need to be doing CI Blend modes, RII's.

You just make parts of an image you wish to be transparent as alpha black, then place it at the top layer, and in over blend mode. Simple. You can't blame the incorporation of a bunch of expensive CI stuff in one setup that you were putting together, and the fps reduction that causes, on patches that aren't actually causing the fps-sappage, especially because that was an arbitrary choice on your part, not a needed one. If you simply placed the buttons behind your main art image, and made the areas you want to be clear, alpha, you would be using less patches, and avoiding CI processing that doesn't have to be happening in realtime.

gtoledo3's picture
Re: Javascript Structure Loops

To me, the whole point of Cocoa is code re-use and modularity, so it's not an arbitrary judgment, but it's definitely a personal aesthetic and view based on trying to work as efficiently, quickly, modularly, and bug-free as possible. I pretty much always stand by the thought that the best piece of code is the one that I didn't have to write, or have already tested. No possibility of typo, it's already been proven, etc. In fact, I wish I had a dollar for every time I've put together a bunch of spaghetti logic that works correctly and with more function and no bugs, compared to posted javascript logic on this site that I've seen that doesn't even correctly function or come remotely close to addressing the original issue at hand.

I don't view the program patches as a subversion of QC. I don't see the two facets of QC as being in opposition to one another, or have a view that expansion in one direction negates the other. For instance, it would be GREAT to have actual code available in the CI patches we pull up. That would be a cool feature that would amplify QC programming function.

usefuldesign.au's picture
Re: Javascript Structure Loops

Thanks for the public slap down (again), Gt.

gtoledo3 wrote:
You just make parts of an image you wish to be transparent as alpha black, then place it at the top layer, and in over blend mode. Simple…
That's exactly what I was doing. Simple. No RII. No CI Add chain (which both can be very fast actually, it's all in the context they are used).

I was already attempting to use alpha black-'off' before you suggested it, it required getting the individual ON images into each button. That's where the maths came in cropping the screen sized image inside each QCButton based on the QCButtons own dimensions. The maths had given me pause.

At time I queried your emails because thought you were suggesting something else involving White 'on'/Alpha Black 'off' coloured buttons on a intermediate layer_2 between 'off' image layer_1 and 'on' image layer_3. Something that would avoid needing the ON image for each button, which would have been great but I can't find a blend mode combo to do that!

An issue that was possibly slowing down that approach (dropping to 30fps on my G5s with trivial maths exp patches and 25 QCButtons) was that each button had to crop a very small portion of the screen-sized button "ON" image-sheet. This may have created 25 full size copies of the same texture being sent to the GPU for cropping?! If it wasn't that it was just the large number of patches executing on every mouseDown. I assume the CIFilter patch results in QCButton get cached when their inputs (position and size) don't change, so it must just be the total volume of patches. Probably should buy performance inspector and have a closer look some day.

The whole technical aspect of this problem (which I'm sure you get btw), and need to test various solutions, is about using an image sheet so one does not have to manufacture and import to QC every single ON-image (>25) for each button each time one edits the front panel artwork. Add to that that each button can 3 different ON states images (colors) and its just BS that way. We're talking hours of extra labour and I'm not sure it would even speed the Virtual patches up any (would have to test that too).

You seem to have developed a habit of assuming people are more "brain-dead" than they would like to believe ;-) Will send source for your examination tonight (EST .au).

usefuldesign.au's picture
Re: Javascript Structure Loops

gtoledo3 wrote:
I pretty much always stand by the thought that the best piece of code is the one that I didn't have to write, or have already tested. No possibility of typo, it's already been proven, etc.
Roger that.

Quote:
In fact, I wish I had a dollar for every time I've put together a bunch of spaghetti logic that works correctly and with more function and no bugs, compared to posted javascript logic on this site that I've seen that doesn't even correctly function or come remotely close to addressing the original issue at hand.
If that's a reference to what I posted in this thread, I already explained why I posted it. Usually people are pretty grateful for JS code on this forum even if it's a little off target. I know I was when I started.
Quote:
For instance, it would be GREAT to have actual code available in the CI patches we pull up. That would be a cool feature that would amplify QC programming function.
Now there's a good idea. You'd guess it was probably considered at some point and rejected for whatever reasons. Wonder if they are all written in a way that it could be exposed (ie zero cocoa code)?

gtoledo3's picture
Re: Javascript Structure Loops

Sorry that it came off that way, I meant no slap down. I thought you were giving me a bit of a slap down!

I thought that your reference to efficiency in this scenario was very apples/oranges and unscientific, and on top of that, how can I really even respond to it, because the last version I saw was setup in a way counter to how I envisioned it being most effectively used, and you're using an example that no one can see to shore up your point. So I see you making this kind of argument of "well in this totally different scenario, I see worse performance".

To wit, I've set up tons of the "QCbuttons" and a related slider patch I made, and see no fps generated by them.

"You seem to have developed a habit of assuming people are more "brain-dead" than they would like to believe ;-)"

Sorry that it came off that way. I'm critical about ideas, methods, aesthetics, but I don't mean that as an inherent criticism of the individual. In fact, if there is one thing I've learned, it's how little I know and how often being dogmatic about one side or another winds up in me eating my words. So as always, "whatever works", and to paraphrase Don Quixote - "the proof of the pudding is in the eating".

gtoledo3's picture
Re: Javascript Structure Loops

No, it's not a reference to your code on the thread - it's a reference to the fact that I've seen some really long discussions about javascript functions for things that have spanned over days, where all kinds of non - working permutations have been made, when a few stock patches could have sufficed. If there is extra functionality to be gained, or if it's a performance test, it totally makes sense to me. Yeah, please don't take discussion of philosophy personally, you're obviously talented and I have a great deal of respect for you as a peer.

As far as the CI stuff goes, I think it's right on that not all of the stuff is really coded in CI style. I highly doubt that the gaussian blur is, as well as many other patches.

usefuldesign.au's picture
Re: Javascript Structure Loops

Cool.

Swiftlikeninja's picture
Re: Javascript Structure Loops

Interesting Topics developing from my query, First of all thank you cwright for prettying up my code and giving me a little more insight into the proper way to write out my JavaScript. I'm aware that K was left untouched and therefore un-needed but that variable was left in there through my entire trial and error so for the current function of the code it is indeed just fluff but I was intending on modifying my code to include another loop involving the k variable. @gtoledo3 I did drop everything into an iterator to get the job done per you suggestion and it did indeed work but ran into two issues, 1. A severe drop in performance which i was able to offset by briefly activating the patch and using a sample and hold to store the values when the iterator was not active. 2. (this is the important one) My developing machine is indeed SL. But unfortunately The machines that will run the code are only Leopard and therefore I will not be able to publish out of iterators. Unfortunately I wont be able to rectify that issue.

Thank you Usefuldesign for the sample QTZ, I will sort through you coding and see what comes of it. I will keep pounding on the qtz until I get a sufficient result and post it back on here with my findings.

Again thank you

gtoledo3's picture
Re: Javascript Structure Loops

Oh, that's too bad about performance. How big was the structure/iteration count, out of curiosity?

Swiftlikeninja's picture
Re: Javascript Structure Loops

Im working off of a structure that ranges between 450 and 500 members.

gtoledo3's picture
Re: Javascript Structure Loops

Wow, it really ends up slow? Crud. I guess whatever use cases I've thrown at it seem ok so far.

I'm going to take a look at the javascript method as well now to satisfy my curiosity.

Let me ask - do want to be able to test for just team name, or do the other values matter?

Swiftlikeninja's picture
Re: Javascript Structure Loops

well, just testing for team name really seams to be all thats important now. As it stands I'm just trying to take a feed that doesn't provide any real order and separate the individuals into groups by team name, then parse the data from my newly created feed.

I really think something may be quirky with my machine in terms of iterator performance 'cause the same thing happens with host info. (Ive tried all the tricks to speed things up, including removing all cache files for quartz. But host info takes at leaste 10 mins to add to a blank patch...) But thats a battle for another day. :D