Daklu Posted August 18, 2007 Report Share Posted August 18, 2007 I have one variable I need to compare against several other variables in order to choose which case to run. It's easy to do in text languages using ElseIf or Select statements, but I can't figure out if it is possible for Labview case structures to be defined by variables. If A<X then ' Do something interestingElseIf A>Y then ' Do something more interestingElseIf A=Z ' Wow! Hold on to your shorts!Else ' Meh, go home.End If I could do a series of comparisons and send a string to the case structure telling it which case to execute but anything more than a couple cases makes the block diagram very ugly very quickly. Is there any way to define a case using a variable? Quote Link to comment
Val Brown Posted August 18, 2007 Report Share Posted August 18, 2007 QUOTE(Daklu @ Aug 17 2007, 01:06 PM) I have one variable I need to compare against several other variables in order to choose which case to run. It's easy to do in text languages using ElseIf or Select statements, but I can't figure out if it is possible for Labview case structures to be defined by variables. If A<X then ' Do something interestingElseIf A>Y then ' Do something more interestingElseIf A=Z ' Wow! Hold on to your shorts!Else ' Meh, go home.End If I could do a series of comparisons and send a string to the case structure telling it which case to execute but anything more than a couple cases makes the block diagram very ugly very quickly. Is there any way to define a case using a variable? There are any number of ways to go about this and that partly depends on the data type of your A variable. One option is to "hide" all of your "dirty laundry" comparisons in a subVI. That subVI would output a typdef'd enum that resolved the operations on A (which would be input to the SubVI using an appropriate control. Keeps the kludge limited to a single subVI that is scalable by adding to the typdef'd enum output. Quote Link to comment
Daklu Posted August 18, 2007 Author Report Share Posted August 18, 2007 All variables are doubles in this particular instance. Hiding all the comparisons in a sub vi is a valid option... I was just hoping for something a little more elegant. Quote Link to comment
Aristos Queue Posted August 18, 2007 Report Share Posted August 18, 2007 QUOTE(Daklu @ Aug 17 2007, 03:34 PM) All variables are doubles in this particular instance. Hiding all the comparisons in a sub vi is a valid option... I was just hoping for something a little more elegant. Nested case structures is as close as you get. If (x) blah else { if (y) blah2 else { etc... } } Quote Link to comment
Val Brown Posted August 18, 2007 Report Share Posted August 18, 2007 QUOTE(Aristos Queue @ Aug 17 2007, 01:46 PM) Nested case structures is as close as you get. If (x) blahelse { if (y) blah2 else { etc... }} Hence the subVI approach -- encapsulate the kludge and at least give the appearance of an elegant else-if construction. Quote Link to comment
Aristos Queue Posted August 18, 2007 Report Share Posted August 18, 2007 [LATER] Oh, I just thought of another solution that may meet with boos from some people... the Formula Node can do the if-elseif-else type work. You could use it to either do your calculations directly or to generate the aforementioned enum. It isn't dataflow, but it might be cleaner depending upon what you're testing. Quote Link to comment
Daklu Posted August 18, 2007 Author Report Share Posted August 18, 2007 I figured out something that is (IMO) better than nested case structures and slightly cleaner than a series of comparisons with string assignments. (Probably not as good as a formula node though.) Instead of doing comparisons in series, I do them in parallel and output the results to a boolean array. Then I convert the array to a number and wire the number into the case structure. By setting cases for conditions number=2^n I can easily cover all my cases. The case names are numbers rather than descriptive but I can work around that by putting a test comment in the case. Quote Link to comment
Omar Mussa Posted August 19, 2007 Report Share Posted August 19, 2007 QUOTE(Daklu @ Aug 17 2007, 03:19 PM) Instead of doing comparisons in series, I do them in parallel and output the results to a boolean array. Then I convert the array to a number and wire the number into the case structure. By setting cases for conditions number=2^n I can easily cover all my cases. The case names are numbers rather than descriptive but I can work around that by putting a test comment in the case. If you do take such a route, make sure to use error handling and that the 'default' case is used to generate an error otherwise you will have no feedback of 'unhandled' cases that might arise in the future... This will help at run time, the problem with your design is that it is difficult to tell at edit time if you handle every case (aside from the fact that the cases cannot be named). I would avoid this route if possible. Quote Link to comment
Tomi Maila Posted August 19, 2007 Report Share Posted August 19, 2007 QUOTE(Daklu @ Aug 18 2007, 01:19 AM) Instead of doing comparisons in series, I do them in parallel and output the results to a boolean array. Then I convert the array to a number and wire the number into the case structure. By setting cases for conditions number=2^n I can easily cover all my cases. The case names are numbers rather than descriptive but I can work around that by putting a test comment in the case. You forget that more than one of the case may be true simultaneously. Then the result would not be 2^n but something else instead. I think manually computing the proper case is too error prone. Therefore I suggest the following modification. The loop part can be converted into a subVI. Also while loop can do the same thing but this new (8.5) for loop is a little easier to use. And this is a good excuse to use it... http://forums.lavag.org/index.php?act=attach&type=post&id=6678''>http://forums.lavag.org/index.php?act=attach&type=post&id=6678'>http://forums.lavag.org/index.php?act=attach&type=post&id=6678 Quote Link to comment
TG Posted August 19, 2007 Report Share Posted August 19, 2007 QUOTE(Tomi Maila @ Aug 17 2007, 11:08 PM) but this new (8.5) for loop is a little easier to use. And this is a good excuse to use it...http://forums.lavag.org/index.php?act=attach&type=post&id=6678''>http://forums.lavag.org/index.php?act=attach&type=post&id=6678'>http://forums.lavag.org/index.php?act=attach&type=post&id=6678 Havn't seen that new for loop, not having 8.5 in yet.. What does it do again? Quote Link to comment
Aristos Queue Posted August 19, 2007 Report Share Posted August 19, 2007 QUOTE(Daklu @ Aug 17 2007, 05:19 PM) http://forums.lavag.org/index.php?act=attach&type=post&id=6679''>http://forums.lavag.org/index.php?act=attach&type=post&id=6679'>http://forums.lavag.org/index.php?act=attach&type=post&id=6679 The biggest objection I have to this solution is that it requires LV to evaluate all possible tests. In this particular case, the tests are all cheap, but one could imagine one of the tests being expensive (i.e. "if this number is prime" or "if this number is found in this array"). Even though LV will work to try to schedule the tests in parellel, there's still the cases where you shouldn't run one of the tests at all unless the previous test fails (if device is not installed { fail } else if device is not enabled {fail} else {success}). I think we should look for an idea that doesn't evaluate all the code paths. Quote Link to comment
Tomi Maila Posted August 19, 2007 Report Share Posted August 19, 2007 QUOTE(Aristos Queue @ Aug 18 2007, 09:47 AM) The biggest objection I have to this solution is that it requires LV to evaluate all possible tests. There is always the possibility to encapsulate the tests into classes so that each test has its own class and all tests derive from common parent class. The classes test express the http://en.wikipedia.org/wiki/Command_pattern' target="_blank">command design pattern in that they have 'evaluate' dynamic dispatch method for evaluating the test. Now we can write a VI that takes an array of test classes as arguments, calls evaluate for each of them until it one of the tests evaluate to TRUE. Then it returns the index of this test in the array. If none of the tests evaluate TRUE it returns -1. The returned index can then be passed to case structure. This is an overkill for the example in this thread. But this is not overkill when the tests are complicated and actually encapsulating the tests into classes can make the application design much cleaner easier to read. Quote Link to comment
Val Brown Posted August 19, 2007 Report Share Posted August 19, 2007 QUOTE(TG @ Aug 17 2007, 07:47 PM) Havn't seen that new for loop, not having 8.5 in yet..What does it do again? It allows for a conditional stop, pre-empting the index count number of iterations given to it. So you could index the for loop to iterate 10 times but have a test for the first TRUE value (as in the example). In 8.5 the loop will stop whatever regardless of how many iterations it has completed whereas in prior versions, the for loop would continue to iterate all 10 times regardless of the test value. Quote Link to comment
jpdrolet Posted August 19, 2007 Report Share Posted August 19, 2007 I don't like embedded cases so the following structures most closely look like an elseif structures: http://forums.lavag.org/index.php?act=attach&type=post&id=6681 Quote Link to comment
Aristos Queue Posted August 20, 2007 Report Share Posted August 20, 2007 QUOTE(jpdrolet @ Aug 18 2007, 03:26 PM) http://forums.lavag.org/index.php?act=attach&type=post&id=6681''>http://forums.lavag.org/index.php?act=attach&type=post&id=6681'>http://forums.lavag.org/index.php?act=attach&type=post&id=6681 AH. That looks like the elegant solution that I was hoping for. Yes, that looks like good LV style. We should record that somewhere; add it to the recommended design of block digrams. Quote Link to comment
MikaelH Posted August 22, 2007 Report Share Posted August 22, 2007 QUOTE(Aristos Queue @ Aug 19 2007, 04:17 PM) AH. That looks like the elegant solution that I was hoping for. Yes, that looks like good LV style. We should record that somewhere; add it to the recommended design of block digrams. But of cause you shouldn't use Equal, when comparing floating point numbers. Use something like this instead: http://forums.lavag.org/index.php?act=attach&type=post&id=6696''>http://forums.lavag.org/index.php?act=attach&type=post&id=6696'>http://forums.lavag.org/index.php?act=attach&type=post&id=6696 //Mikael Quote Link to comment
Daklu Posted August 22, 2007 Author Report Share Posted August 22, 2007 <smartass> QUOTE If you do take such a route, make sure to use error handling and that the 'default' case is used to generate an error otherwise you will have no feedback of 'unhandled' cases that might arise in the future... Yep, did that. There are serious problems if A<X and A>Y at the same time... QUOTE the problem with your design is that it is difficult to tell at edit time if you handle every case True. Luckily for me my code only requires three cases to be handled so it's not *that* difficult. QUOTE I would avoid this route if possible. Too late! The tablets have already been chiselled and given to Moses. QUOTE You forget that more than one of the case may be true simultaneously. In the general case, yes. In my particular case, no. (At least, not under normal human circumstances. I make no claims as to validity of my statement when applied on the quantum scale, at relativistic speeds, or in alternate dimensions.) QUOTE Therefore I suggest the following modification. My mind's made up. Don't confuse me with the facts! QUOTE This is an overkill for the example in this thread. Truer words were never spoken... </smartass> In all honesty I really appreciate the comments and suggestions. Since I've moved beyond that section of code I doubt I'll go back and change it but now I have better ideas of how to handle it the next time the issue arises. Despite its ease of use, one of the Labview annoyances that still gets to me from time to time is the amount of clicking through to different frames are required to grasp the big picture. Case structures, event frames, diagram disable, and stacked sequences all hide code increasing, for me, the amount of time required to absorb the code. In my original post the text algorithm took 9 lines and it is easy to see all the code at once and grasp the meaning. Labview implementations are a little more obscure and require more effort to implement and decipher. </whining> QUOTE(jpdrolet @ Aug 18 2007, 01:26 PM) I don't like embedded cases so the following structures most closely look like an elseif structures: http://forums.lavag.org/index.php?act=attach&type=post&id=6681''>http://forums.lavag.org/index.php?act=attach&type=post&id=6681'>http://forums.lavag.org/index.php?act=attach&type=post&id=6681 Actually, if I'm reading this right I don't think it works. The case containing "Meh, go home" is supposed to be evaluated only when all other cases are false. The way I see it there are multiple cases being evaluated when A<X or A>Y. One way to write the text equivalent of your code is: If A<X then ' Do something interesting If A=Z then ' Wow! Hold on to your shorts! Else ' Meh, go home End IfElseIf A>Y then ' Do something more interesting ' Meh, go homeElseIf A=Z then ' Wow! Hold on to your shorts!Else ' Meh, go homeEnd If Quote Link to comment
LAVA 1.0 Content Posted August 22, 2007 Report Share Posted August 22, 2007 If you want readability, why not use a formula node? http://forums.lavag.org/index.php?act=attach&type=post&id=6699http://forums.lavag.org/index.php?act=attach&type=post&id=6701 (LV 8.2) Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.