Local variables for clean code
A question of style and LV correctness:
I'm quite aware of the risks of these guys, but I see no option here. Right now I have a program with ~35 events in an event structure. I have a wire that contains many device settings that only 2 of these events can change. About 6 events in total require the use of the data on this wire.
Now, I see two choices:
1) I can use a shift register and drag the stupid wire across 35 frames and then remember to do it in any additional frames when I add more
2) I can use a local variable.
This seems much, much cleaner to me, and I see no better way of doing it. My question is, is there? I've looked up feedback nodes, but I think I can only use them in single event cases. Their data doesn't seem accessible beyond one event case. is there some better option? The data on the wire is an array of objects (classes), if that helps.
pobrepablo1 wrote:
Still though, I object on principle to having a wire across every one of my diagrams, it's cluttersome .
I thought of a compromise, how about I use a shift register but wire it around my event structure, through a case structure breaking the wire only when I need to? i.e. see attached
So a single thin 1D object across all event cases is more cluttersome than an additional external 2D case structure, partially wired extra tunnels, and all the extra convoluted logic holding it all together? You priorities seem to be biased.
A nice wire across all cases is much better. It can be read and written in any event case that needs to, and can always be found in exactly the expected location. Remember that a shift register is very efficient. If the data size does not change, it operates fully in place for the duration of the run. It also often contains data that is not directly of interest to the operator so it does not need a display. A local variable requires a front panel object that needs to be updated in the UI thread. In needs a data copy in memory memory for the control/indicator itself as well as another copy for the transfer buffer (because the FP update is asynchronous). Then we have a third copy in the wire itself. Than makes it three copies of your potentially large array. Add another copy for each local variable instance, and you probably end up using 10x more memory compared to a simple shift register. It all adds up!
Local variables can be placed anywhere and keeping track of them is like herding cats. The next programmer to work on your project will have a hard time tracking them all down. In properly designed code, it is just "follow the wire". Much more clear and almost self documenting.
LabVIEW Champion . Do more with less code and in less time .
Similar Messages
-
Using local variables to "clean up" diagram
I have attached a photo with red circles indicating my use of local variables to "clean up" a block diagram. Would I run into any issues doing this? Can I leave this task and error unwired?
-Sarah
Solved!
Go to Solution.I see some possibly really bad race conditions with your VISA Resources. For instance, if Task Out 3 is empty (by default), it is likely that the local to read will happen before the local to write. What this will turn into is you loosing your VISA Reference in the shift register. Use wires. Locals very rarely clean up your diagram.
There are only two ways to tell somebody thanks: Kudos and Marked Solutions -
Material Ledger Additional local currencies for company code
Hi Expert,
I would like to add a second local currency in the "Additional local currencies for company code" in order to have 2 currencies available for material ledger. (Material ledger is not yet activated for this company code)
The second local currency must be the group one "30". Could you please tell me wich valuation I have to choose ? 0 1 or 2.
I went on the SAP library but I didn't find something clear. I tried 1 but I have an error message...
Thanks and regardsHello,
I also recommend:
1442153 Transfer price valuation for material transfers
532932 FAQ: Valuation logic with active material ledger
1253944 Activating actual average moving price posting logic w/ ML
Cheers -
Local currencies for company code RCPL cannot be completely determined
Dear all
how rectified below error
Local currencies for company code RCPL cannot be completely determinedHI,
You can Refer this Post
error message when i use f-02 transaction
Check the necessary setting with the help of FI consultant ( do not make any changes on your own) -
Shall I use global or local variables for my program?
Hello,
1) I am using 2 while loops in parallele. One 50 ms timed and the other one 1000 ms. The 50 ms one gets data from a sensor. I want to display that data every 1000ms in the 1000 ms loop. I have used global variables to do that. Should I better use local variables?
2) This question deals with the VI I have attached
a) Shall I initialise the " Quitter programme " global variable in the main VI aswell ? Or is what I have done enough?
b)
I want the sequence to continue ( finishes the last sequence and goes back to the first one without any delay if possible ) until the user presses Quit. I am concerned about the " wait until " icon of the exterior main while loop ( set to be 250 ms at the moment ). This time, 250 ms, is the time it takes between the end of the last sequence and the beginning of the first sequence? Is that right? Once u start the first sequence, the while loop doesn’t do anything until the end of the last sequence ( my 3 sequences can take several minutes ) ?
Hope I am clear… lol
Don’t hesitate to ask any questions if not clear enough
thanks a lot,
David
Attachments:
Example1.zip 28 KBBonjour Marc. You will definitely have a race condition because you are writing to the global in a parallel loop. You could click the stop button in the quitter program, then before it is read in the main loop, the lower loop writes a false to it, and your click is lost. Why do you want a separate quitter program? You may have a good reason but it isn't clear here. I would not use globals or locals for this, just put your stop button on the main vi. You already have one, so why do you want another one in another vi? If you must do it this way, eliminate both lower loops. They are not necessary. The global default is set to false, so when you run the vi, it is false. The button mechanical action is set to latch when released, so after clicking it will turn true until the main vi reads it, then it will automatically turn false. So you don't need the lower loops to keep writing false to it. If you just eliminate both lower loops, it will work fine. The only purpose I could see for the quitter vi is to have one button cause several vi's to stop. Instead of doing it this way, put one stop button in your main vi, create a reference (right click - create - reference), and wire this reference into all subvi's that the main calls. The subvi's must be changed to accept the reference and use it. This would be a much better method to close all vi's with one button.
You could also get rid of the sequence structure (it hides code and makes it more difficult to read). Just put all your code side by side. The error in/out wire will ensure that the execution order will be fixed, just like in your first sequence with the open file and write file functions. Just wire the error out of the write vi to the second write vi, and then the error out of the second write vi to the close vi. No sequence structure needed, and all your code is viewable on one screen.
- tbob
Inventor of the WORM Global -
Additional local currencies for company code
We are using company code currency INR -The clients wants additional currency USD as 2nd local currency--In OB22 the
2nd local currency -we want to give it to USD
2nd local currency is also by default system is showing INR-
and it is in grey field-how to enter USD for 2nd local currency-
for 2nd local currency we have given the following data:
currency type: 30 group currency
valuation 1 group valuation
exchange rate type: m
CO is active for this company code-
how to enter USD as 2nd local currency
regards
josephHello Joseph,
Currency & valuation are considered as life blood of ERP systems as such those should be managed intelligently right from the day 1.
Additional currencies cannot be activated once the company code is live!
One needs to evaluate various options available, depending upon your requirements and system & solution landscape.
However due to hugh impact of such changes, it would be better to take the help of SAP SLO services.
Ambadas -
Source currency in OB22 (Additional Local Currencies for Company Code)
Hi!
I'm setting up a third local currency for one of my company codes and the only source currency options I have are "Translation taking transaction currency as a basis" and "Translation taking first local currency as a basis". I need to have my third local currency translation basis be the second local currency (which is not an option). I've already set my company code currency and have done postings, so I cannot change that. Is there a way to add another source currency option?
Thanks!
LauraLaura,
I don't think there is way to specify second local currency as a basis for translation. Only options 1 and 2 are available in OB22. -
Local variable for an Array of fixed size
Hello,
I have a two multirate loops in a VI.
In one loop, I want to refer an fixed sized array initialized in the other loop.
But I coudn't name the array, so I can't refer it.
Is there any way to refer it?
Thanks,
Young.If you need a local variable, there is no other way than to create an indicator for it.
In LabVIEW there is no "fixed length" array : you can always add or remove an array element, and you don't need to declare it as in other languages. They are intrinsic dynamic objcets. Of course, the memory manager has to cope with this, that's why it's often better to initialize an array, to give it its final size immediately, resulting in faster running programs. However, this is only noticeable with relatively large arrays (> 10000-100000 elements).
May be you should explain in more details what you intend to do, because trying to reproduce a C approach in LV is probably not the best thing to do. For instance, you said that you are initializing your array in a first loop. You mean that you re-initialize the array at each iteration ? I suppose no, so may be you could put the initialize step out of the loop, and wire the array to your two parallel loops.
Remember also that local variables are not always good programming solutions, since using them will generate copies of their content each time they are refered to. And that can low down your program very significantly...
Message Edité par chilly charly le 11-05-2005 05:05 PM
Chilly Charly (aka CC)
E-List Master - Kudos glutton - Press the yellow button on the left... -
How to add a new Local Variable for DataBase Logging?
Hello
I need to add a Local sequence variable to my STEP_RESULT table, i know i need to modify the schema by adding a new column but not sure on what to write in "Expression" to access the value of local variable.
Please reply asap, as its a little urgent.
Regards
Nitin GoelHi
you can read this here:
http://digital.ni.com/public.nsf/allkb/F5ADBC61222343B586256CE00055E6D6?OpenDocument
Regards
DianaS -
Query on Additional Local Currencies for Company Code
Hi Experts,
Can I know whether there are any differences in the way SAP logic applies to the following currency types?
1. Hard currency 40
2. Index-based currency 50Hi,
Yes I am aware that we can maintain 2 additional parallel currencies for company code.
Hard currency
Hard currency is a country-specific second currency which is used in countries with high inflation.
Index-based currency
Index-based currency is a country-specific fictitious currency which is required in some countries with high inflation for external reporting (for example, tax returns).
But, are there any differences in standard SAP logic between these currencies or it is the same? -
How to: Transform Activity: Read global/local variable, execute java code
Could anyone please show me how to do that???
could you please elaborate your usecase? yes you can read global variable using getVariableData( ) xpath function and pass them as an argument to the processXSLT ( ) xpath function.
You can read the global or local variables inside java exec using, please refer samples/references/javaexec sample. -
Attempting to Save data from an access database file into a local variable for use.
Hello! i'm trying to develop a small text based game in Visual Basic 2013 and I've recently decided i need to use a more sophisticated data storage system then dozens of .txt files and stream-readers. i'm using Microsoft access and i completed my database
last night. it stores the stat and skill values of the player-character and the non-player characters. the problem is i cannot bring the data into visual basic in a usable way. using ado.net i can bring a single record into the system as a detail view and
then read the data in from the labels but i'd far prefer to have it done purely through code. the book i purchased only covers data grid views and detail view and I've spent several hours searching for a solution online.
for clarification. i need to read each value in a record into a variable so i can calculate the stats for the games combat system.So, you want to select from MS Access?
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim connectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Ryan\Desktop\Coding\Microsoft Access\Northwind_2012.mdb"
Dim selectCommand As String
Dim connection As New OleDbConnection(connectionString)
selectCommand = "Select * From MyExcelTable ORDER BY ID"
Me.dataAdapter = New OleDbDataAdapter(selectCommand, connection)
With DataGridView1
.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.ColumnHeader
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.ColumnHeader
End With
Dim commandBuilder As New OleDbCommandBuilder(Me.dataAdapter)
Dim table As New DataTable()
table.Locale = System.Globalization.CultureInfo.InvariantCulture
Me.dataAdapter.Fill(table)
Me.bindingSource1.DataSource = table
Dim data As New DataSet()
data.Locale = System.Globalization.CultureInfo.InvariantCulture
DataGridView1.DataSource = Me.bindingSource1
Me.DataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.Aqua
Me.DataGridView1.AutoResizeColumns( _
DataGridViewAutoSizeColumnsMode.AllCells)
End Sub
Then from DataGridView to a text file, right.
Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim dt As DataTable = New DataTable
Dim DBAdapter As OleDbDataAdapter = New OleDbDataAdapter
Dim connection As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Users\\Excel\\Desktop\\Coding\\Microsoft Access\\Nor"& _
"thwind.mdb;Jet OLEDB:System Database=system.mdw")
Dim query As String = "SELECT * FROM Orders;"
connection.Open
Dim command As OleDbCommand = New OleDbCommand(query, connection)
Dim adapter As OleDbDataAdapter = New OleDbDataAdapter(command)
adapter.Fill(dt)
Dim writer As StreamWriter = New StreamWriter("C:\\Users\\Excel\\Desktop\\FromAccess.txt")
For Each Row As DataRow In dt.Rows
For Each values As Object In Row.ItemArray
writer.Write(values)
Next
Next
writer.Close
End Sub
Knowledge is the only thing that I can give you, and still retain, and we are both better off for it. -
Please help the ignorant...
I know there has to be a cleaner way to do this.
First of all, if you have a date field that is empty, the
database records 1900-01-01 00:00:00.0. So...i certainly dont need
to show this in my form.
Secondly, i know there is a smarter way so i dont need to
write a cfinput 3 times. I am hoping for ... more like once...
Thirdly, if there is anything else that you can pick out of
this that i am not advanced enough to see, that would be GREAT!
I thank you in advance for any efforts on my behalf...
MattYes, you could make it a little "cleaner", but it's not bad.
The logic is fine.
You can however, consolidate a few things and in doing so,
separate the logic from the presentation a bit (always a good thing
to do). Look for things that are common among all the
<cfinput> tags. For example, the message is the same for each
version of your <cfinput> tag. Good practice would be to
create a single copy of the message and then use it in the three
places. That way, if you have to change the message, you only have
to change it in one place. Like this:
<cfset variables.errMsg = "The last field that you have
entered, requires a valid date">
Then, within each <cfinput> tag, do:
message="#variables.errMsg#". (BTW, you can make your messge more
succinct. Do you really need to say "the last field you entered"?
After all, this message pops on-blur, so the user knows which
field.)
You could do the same for the other attributes. However, I
notice that all three instances of the <cfinput> tag have the
same attributes, except for the value attribute. But, the tags that
have no value attribute could have been written with value="". If
they were written that way, then the only difference between the
tags is the value of the "value" attribute. I'll show you how to
exploit that, below.
If you are sure that the query always returns a single
record, then you can eliminate the <cfoutput query=...>
element. That save two lines. (if you're not sure, then you should
add some error-checking.)
Also, your if-then should have an else clause. What happens
if the action is something other than "existing" or "new"? You
might say that could never happen, but you might have an error in
your program, or a user could submit his own form to this page with
the wrong action value. Usually, the last thing that a programmer
adds is error-checking. Here, you could add '<cfelse>Unknown
action: <cfoutput>#action#</cfoutput></cfif>'
which might come in handy while developing the program (or you
could put a <cfthrow> tag in there and throw your own
exception). Alternatively, just eliminate the 'action is "new"'
condition. That way, all actions, other than "existing", are
treated as "new".
Taking it all together, here is another way to write your
code. Notice how the logic is separated from the presentation: -
Does a large amount of "local variable" within a vi cause problems?
Hello -- I am using Labview 7.0 and have a vi where I am going to end up using about 100 "local variables" for indicators that are displaying data. Since I have a lot of true / false case structures I decided to use these local variables instead of having a mess of wiring all over the vi block diagram. It is intimidating though and I was wondering if it causes slowness in vi's?
I actually only have about 8 indicators -- but I am in the process of creating control algorithms so I have to use many case structures if I want to keep the code all within Labview (simplicity). I am simply referencing the 8 or so indicator values many many times (100 X) I am attaching a copy of the vi like you asked but just take a look at the right hand side of the while loop on the right -- it shows an example of an algorithm I created today that has to reference the data from sensors. I would love to know what a better way to do this. Thanks!
Attachments:
ucb drill control daq 1_7.vi 666 KB -
RE: local variable cross-talk?
Jeff
A global can be considered as a variable to the entire code, where lots of
different vi's can operate it. Locals only have any meaning within their
own vi, or instances of their own vi.
If anything writes to a particular global, whether in reenterent vi's or
not, it's available everywhere in the code.
What you were asking was about locals though. If a vi is non-renentrant
(i.e. as they come out of the box) then the values in the locals are vi
specific, no matter where the vi is, where it was last used, it retains the
data from it's last operation. If it is re-entrant, then the values in the
locals for each occurance of the vi are its own for EACH instance, i.e. just
like different locals in different vi's, it doesn't matter where else the vi
is used, the data held is that from the last operation of that specific
instance.
Simple way to demonstrate this. Make a vi that has one numeric control,
then code in +1 and get it to write to a local variable for that control.
Throw in an indicator to wire out the result of what is written to the local
for the control.
Then take this vi, put it in a for loop, then put another copy in the for
loop as well. Wire the indicators to the side of the for loop and create
indicator arrays for them. Get the loop to run 6 times say. Now try
running this with the vi in the for loop non-reentrant and then reenterrant.
One way the arrays will contain either all the odd no.s 1,3,5,7,9,11 and
then the other array 2,4,6,8,10,12 (don't know which array will be which,
depends which executes first in the for loop of this example). The other
way they will both be 1,2,3,4,5,6. In the first example, the same vi has
run 12 times, i.e. one copy of the vi which retains its info and is called
in many places and therefore only has one set of values, and the other with
two re-enterant copies where they have their information specific to that
instance of them i.e. effectively they are different vi's. Both ways are
useful, depends what you want.
If you're looking for a use for non-reenterant vi's then consider this:-
For instance. Supposing you get many things to try to write to a global
array of numbers, and you have two vi's one "A" writes to the first element
in the array and the other "B" writes to the second element. Because in LV
you have to read a global first and then write to it to perform a change,
these independant vi's "A" and "B" (be they re-enterant versions of the same
vi, or different vi's), can be performing the tasks simultaneously in the
code. I.e. "A" reads, "B" reads, "A" writes, and "B" writes over the top
with a modified version of what it read, and "A"'s changes are lost. This
is what's known as a "race condition" as "A" hadn't finished and "B" needed
to know what "A" was going to write before "B" performed "A" read. Try it,
hours of fun if you code this kind of thing in inadvertantly!
If the same vi is used, and is not re enterant, it can only run in one
instance at a time, hence two read / write operations cannot be performed
together, problem solved. Unless that gives you timing issues of course,
waiting for one to finish, to write the other......but that's another whole
can of worms.
cheers
Tim Price
This e-mail, its content and any files transmitted with it are intended
solely for the addressee(s) and are confidential and may be legally
privileged. Access by any other party is unauthorised without the express
prior written permission of the sender. If you have received this e-mail in
error you may not copy, disclose to any third party or use the contents,
attachments or information in any way.
-----Original Message-----
From: [email protected]
[mailto:[email protected]]On Behalf Of Jeffrey W Percival
Sent: 29 November 2001 21:12
To: [email protected]
Subject: Re: local variable cross-talk?
Another useful reply! What a great news group this is.
One last thing I wanted to ask about, though, is global vs. local. I see
you talk about globals, but in fact the variables in my subVI's were locals.
I can easily understand the behavior I observed accompanying the use of
global variables, But I guess the use of the word "local" stumped me.
Should I interpret "local" in LabVIEW's sense to mean "local to all
instances of this VI"? And global to mean "visible to all instances of this
VI as well as other VI's"?
-Jeff
Tim Price wrote:
This facility is actually very useful, for instances where you want to
encapsulate some code so that it can only run in one place at a time,
i.e.
global arrays that are written to in more than one place. This method
can
eradicate race conditions completely for example when used like this.
There
are multiple other uses as well.
However, using a vi as a module of code, to run in more than one
instance at
a time simultaneously, re-entrant is the way to go. Just make sure you
debug it first!!!
Remember though, just because a vi may be re-eneterant, doesn't mean
that
everything inside is; sub-vi's, Globals etc. The classic one I've seen
is
where people think that a re-enterant vi is talking to it's own copy of
any
Globals used within it, i.e. counters etc., where in actual fact of
course,
they are all using the same Globals.
Worth playing with a few examples to get familiar with it.
Tim Price
Jeffrey W Percival, Senior Scientist and Associate Director
Space Astronomy Laboratory, University of Wisconsin - Madison
1150 University Ave, Madison, WI 53706 USA
608-262-8686 (fax 608-263-0361) [email protected]
http://www.sal.wisc.edu/~jwpTim Price wrote:
Tim, thanks very much. I'll try the experiment you suggest.
Thanks for taking the time.
-Jeff
Jeffrey W Percival, Senior Scientist and Associate Director
Space Astronomy Laboratory, University of Wisconsin - Madison
1150 University Ave, Madison, WI 53706 USA
608-262-8686 (fax 608-263-0361) [email protected] http://www.sal.wisc.edu/~jwp
Maybe you are looking for
-
Our internet was hacked really bad, whatever virus/ trojan it was, my two housemates & I didnt realise straight away, by then we had synced our iphones to itunes on our computers, it wasnt long before we noticed our iphones acting strange, they would
-
I paid for an App for my ipod and it doesn't work.
I deleted it and redownloaded it but it still wont work. Comments note that this is a common problem. Can I get my money back or is there something else I can do?
-
I recently got a new iPhone 5S today and I am having some issues setting it up. I got all my contacts and apps and everything back, which is great. However though, whenever I plug it in to my MacBook to put additional music onto it, no matter what I
-
Playing video from a flash media server
Can anyone point me to code to play streaming video from a Flash Media Server in Flex?
-
Regarding file 2 file using BPM
Hi Experts, In file to file using BPM scenario my file is being picked in the server but it is not displaying again after polling interval. please help me one this issue as early as possible.