Jump to content

Possible to define cases based on variables?


Daklu

Recommended Posts

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?

Link to comment

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.

Link to comment

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...	 } }

Link to comment

[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.

Link to comment

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.

Link to comment

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.

Link to comment

QUOTE(Daklu @ Aug 17 2007, 05:19 PM)

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.

Link to comment

QUOTE(Aristos Queue @ Aug 18 2007, 09:47 AM)

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.

Link to comment

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.

Link to comment

QUOTE(jpdrolet @ Aug 18 2007, 03:26 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.

Link to comment

<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)

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&lt;X then  ' Do something interesting  If A=Z then	' Wow! Hold on to your shorts!  Else	' Meh, go home  End IfElseIf A&gt;Y then  ' Do something more interesting  ' Meh, go homeElseIf A=Z then  ' Wow! Hold on to your shorts!Else  ' Meh, go homeEnd If

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.