The dictionary refers to a “convention” as a set or standardized way of doing something. In LabVIEW programming, conventions are an effective organizational tool that provides an avenue for solving many common problems. In fact there are far more opportunities for defining useful conventions than there is room in this post, so to get you thinking we’ll just cover some of the key areas.
The topic of directory structure is a good place to start this discussion because this area is often neglected by developers. As you might expect their primary focus is getting their code running — not where to store the code on disk. After all, one place is as good as any other, right?/p>
Uh, not so much, no… Storing files just anywhere can cause or facilitate a variety of problems. For example, one of the most common ones is that you can end up with multiple VIs sporting the same file name at various locations on disk. The best case scenario is that your application gets cross-linking to the wrong version of a file. The worst case situation is that your code gets cross-linked to a completely different file that just happens to have the same name. And if you’re really unlucky, the wrong file will have the same connector pane and IO as the one you want, so your code won’t even show up as being broken — it just stops working.
More problems can also arise when you decide to try to reuse the code on a new project or backup your work. If the files are spread all over your disk, how can you be absolutely sure you got everything? And the right version of everything? Of course, I have seen the opposite problem too. A developer puts EVERYTHING in one directory. Now you have a directory containing hundreds of files, so how do you find anything?
The correct answer is to go back to first principles and put a little effort into designing your development environment. So if you think about it, there basically two kinds of code you need to store: code that is specific to a particular project, and code that you are planning on reusing. Likewise, you want to minimize the code “changes” that are associated with a VI having been moved on disk. Consequently, I like to start at the root of a hard drive (doesn’t matter which one) and create a folder called Workspace.
This directory could actually be named anything, the point is that it will be the home of all my LabVIEW code. Inside this directory I create two sub-folders. The Toolbox sub-folder contains all my code that is intended for reuse. To keep it organized, its contents are further broken up into sub-folders by function type. In addition, I make it easy to get to my reusable code, by point the user.lib menu link for the LabVIEW function palette to this toolbox directory.
The other sub-folder inside my workspace directory is called Projects. It contains sub-folders for the various projects I am working on. Because I sometimes work for multiple clients, I also have my projects segregated by the year that I got the contract. If you work for a single company but support multiple departments, you might want to have separate folders for the various departments.
Please note that this directory structure is one that has worked well for me over the years but it isn’t written in stone. The main thing is that you be consistent so you (and people who in the future might be supporting your code) can find what is needed.
The next area where having some set conventions can pay big dividends is in the area of naming things. If you are a part of a larger organization, this is also an area where you should consider having a meeting to discuss the issue because it can have long-term effects of the way you and your group operate.
Online you will find a lot of recommendations as to how to name all sorts of things from entire projects to individual controls and indicators. The thing to remember is that some of these suggestions originated years ago and so are no longer appropriate — or necessary. For example, some people still advise you to prefix the name of a VI with the name of the project in which the VI is used. This technique, however, is counter-productive because it complicates the reuse of the VI. In addition, if you are making appropriate use of LabVIEW libraries (*.lvlib) it is unnecessary because the name of the library creates a namespace that, for LabVIEW’s internal use, is prepended to the VI’s file name.
Say for instance you have a library called Stop Application.lvlib and let’s further say that the library references a VI called Generate Event.vi. Now without the library, this VI name would be a problem because it is too non-specific. It is easy to imagine dozens of VIs that could have that same name. But because the VI is associated with a library, as far as LabVIEW is concerned, the name of that VI is Stop Application.lvlib:Generate Event.vi. By the way, you’ll notice that this composite name reads pretty nice for human beings too. The only remaining issue is that your OS doesn’t know about LabVIEW’s naming conventions, which is why I always put libraries (and the files they reference) in separate directories with the same name as the library, but minus the lvlib part.
Another common place where a naming convention can be helpful is in showing fixed relationships that LabVIEW doesn’t otherwise illustrate. A good use case for this type of naming convention would be with LabVIEW classes. Currently (as of LV2014) you can name a class anything you want but LabVIEW doesn’t organize the class lists in the project file to illustrate inheritance relationships. Until NI decides to fill this gaping hole, you can work around it by implementing a naming convention that (when sorted by name) shows the inheritance relationships. Starting with a top-level parent class, like database.lvclass, you build a hierarchical name for the subclasses by prepending the base name and an underscore character to the subclass name. In this case you might have two subclasses: one for ADO connections and one for SQLite (which uses its own dll). So you would create classes with the names database_ado.lvclass and database_sqlite.lvclass. Now within ADO-compatible databases there is a lot of commonality, but there can be differences so to cover those cases you might want to further define subclasses like database_ado_access.lvclass, database_ado_sqlserver.lvclass and database_ado_oracle.lvclass. Obviously this technique has limitations — like it has to be maintained manually, and you can end up with very long file names — but until NI addresses the basic issue, it is better than nothing.
Two other important conventions are that you should never use the same name to refer to two things that are structurally or different. Likewise, you should never use two different names to refer to the same object.
At NIWeek this year, I had an interesting meeting. I had a young developer come up to me and asked me whether he was right in assuming that I had written a particular application. I said I had, but asked how he knew. He replied that he had worked on some code of mine on an earlier contract and said he recognized my coding style. For him it was an advantage because when making a modification he knew where to start looking.
Basically, style conventions define a standardized way of addressing certain common situations. For example, I make use of units for floating-point numbers to the greatest degree that I can because it simplifies code. One common situation that illustrates this point is the need to perform math on time values. If you want to generate a time that is exactly 1 day in the future you have a few options:
This works, but it assumes that the maintainer is going to recognize that 86,400 is the number of seconds in a day.
This is also a possibility and, thanks to constant folding, is just as efficient as the previous example. However it takes up an awful lot of space on the diagram and it essentially hardcodes a 1 day decrement — though that might not be clear at first glance either.
Personally, I like this solution because it literally expresses the math involved: Take the current time expressed in days, subtract one day from it and express the result in seconds. Remember that the point of good style is to make it clear what the code is logically doing. Great style makes it clear what you were thinking.
So that’s enough for now to introduce you to the concept of conventions. But be assured, it will come up again.
Until next time…