Thursday, December 18, 2008

Tinkering

Around this time of year, things seem to slow down. Or else they speed up. Nobody's around at work, but the ones who are there want their systems running NOW!

This leads to the dreaded schedule pressure. Every five minutes you have an email or a phone call or a personal visit from your favorite customer asking, "are you done yet?" It's like the quintessential child in the back seat of the station wagon on the road trip. No matter how many times they ask, it won't be done quicker. Actually when the customer's harassing you for the LabVIEW code, it's worse than the car ride. They slow you down with their distractions.

In addition to that, there's always this desire to tinker. Whenever faced with important tasks, due ASAP, it is easy to fall into a comfortable trap of tinkering.

So what do I mean when I say, "tinkering"? I mean messing with non-essential code. Straightening, rearranging, questioning stuff that works, and so on. Consider an example:

OK, Alarms and Shutdowns need to be ready yesterday. Better finish up that adaptation of the old code. You know, I always wished it was a little more direct here. And I think that I could improve the readability of that section of logic. Oh, look at that crooked wire and redundant shift register.

All that is tinkering. It doesn't contribute to the deliverable in a way that benefits the customer. But it is so damn tempting! Especially when everyone else is standing around chatting all day about vacations and holidays and stuff, the tinkering is so tempting. It reminds me of college, where I had my engineering finals while all the Sociology majors went to bars and parties night after night.

In college, you could go to the parties and study a little and still get a decent grade sometimes. But in life, you often must put your head down, and take care of business to get it done. And in the end, it isn't as bad as it seems.

In these urgent times, even though the urgency is occasionally artificial, if you're to meet your business objectives, it's best to avoid tinkering and stick to the most important functional features.

Thursday, October 9, 2008

Deterministish

Often times we want a bit of code to run in a very reilable way. There are some things that simply must happen on a regular interval, like a watchdog timer or critical control loops or data logging. It is at these times when the word determinism comes up. We like to make our things deterministic. We want to make sure that the whole thing can happen in a certain known period of time, every time.

A lot of these times, deterministish is enough. When I say that, I mean that many of these processes don't have to necessarily run on a perfectly predictable interval. Deterministic might just be too strong of a word sometimes. Most of the time, it's perfectly acceptable to run "regularly". It is just important that the processes not get starved and ignored for a long time by the program. As long as they run again "soon", everything will be fine.

Fortunately, deterministish is a lot more achievable than deterministic. Make sure you know what your customer really needs before you drive yourself crazy making something deterministic that could be accomplished perfectly with deterministish behavoir.

Sunday, October 5, 2008

Refactoring Code

Last time I wrote a bit about huge projects. I glossed over it a bit.

Truth is, many big projects aren't fully or adequately spec'd out at the start, and come crunch time...let's just say that compromises are made.

So often you can look back at code and wonder who made that terrible design decision or atrocious wire layout. Why did this guy document his code so poorly? What the heck does that VI name mean? This page-long diagram could have been done with three nodes! And the list of criticisms goes on. Until you realize you're the one that wrote that VI.

Every now and then you get a great chance to rework an old peice of less-than-optimal code. I am fortunate enough right now to have that times two. I have the big project that's just about almost got the complete confidence of the customer. In the mean time, there's the immediate follow-on from the big project, which is a clone of the first with enhancements. At the same time, there's a separate project for a different group in the same company that intends to leverage a large part of the original big project.

This means that I'm making additions to the main project at the same time as borrowing sub VIs for another project. It's a really eye-opening opportunity. When you delete all but a dozen nodes from a ten-state state machine VI to replicate the functionality of that VI in another project, you really start to wonder about the tradeoff between overhead and flexibility.

Thursday, October 2, 2008

Little Projects

Most of the time we get to work on massive projects. The sorts of things where you spend weeks or even months in meetings at the start of the thing to try to figure out what exactly it is the program's supposed to do.

These are great fun. You get to come up with a few grand new ideas to incorporate into your standard approach and architecture. And then you get to do it. And in the end, you have this big thing that you contributed in large part to that does something significant.

At the other end of the spectrum, you sometimes get these little one day jobs. Just a simple data logger or temperature controller. These are really fun in their own way, too. There's something to be said for sitting in front of a blank VI at 9AM and walking away from a screen full of graphs and a disk full of data files at 5PM. Just an hour's worth of defining requirements and a few hours of coding and a few hours of touch-up and you're done.

It speaks to the power of LabVIEW that you can perform both of the above tasks with the same environment.

Tuesday, September 23, 2008

LabVIEW Shipping Examples

There is a shipping example with LabVIEW, Parse Arithmetic Expression.vi, that DOES NOT WORK!

Today I found an expression A+B*(C/D)+E*(F/G)+H*(I/J). The example VI does not correctly evaluate this expression.

Granted, the parenthesis are not really appropriately placed in this expression, but still, the evaluator doesn't work. It does all the divisions inside the parenthesis correctly, but then it evalues all the * and + operators in order from back to front, disregarding order of operations. This scrambles all the operator-operand relationships and gives the wrong result. Essentially, B ends up multiplying the rest of C through J.

I am just thankful that A, B, and H were all zero while E was non-zero, so that this function evaulating to zero raised a red flag to my customer. So now I have to either fix the example or restrict the expression syntax.

That's the thing when you use built-in shipping examples. You sort of just assume that they work.

Wednesday, August 6, 2008

Documentation

Everyone knows that LabVIEW is self-documenting (wink, wink).

There's really no such thing as "self-documenting". When you write code and think it makes perfect obvious sense, you're delusional. There needs to be documentation with the code for it to be as readable as possible. In LabVIEW, this includes VI Info and liberal use of free labels on the diagram.

I guess in a way, this makes LabVIEW partially self-documenting. If you use the tools available to you, it's easy to make your VIs easier to understand. And it doesn't take that much more time to do than leaving your code undocumented. Beyond that, it will save you and your successor countless hours of figuring out "what does this code do?"

I sheepishly admit that in my first days of LabVIEW programming, I thought it would be easier to leave the documenting to the end of the project. After all, code changes so much throughout development, to document it right when you write it would be a waste of time.

This foolish attitude changed drastically and dramatically the first time my first boss made me go back through my whole project at the end and add VI Info to all my VIs. Even though this was only about a hundred VIs, it was painful and mind-numbingly boring. Imagine this on a large scale thousand-VI project! I am glad to have learned that lesson the hard way, but not too hard.

Monday, July 28, 2008

Evolution of Programming

Today I was working for an old customer, on code that was written a long time ago. For a point of reference, the code was sized to fit into an 800x600 resolution. When's the last time you saw a monitor that incapable?

Now they have a modern 4294967296x4294967296 monitor like everyone else, and it gives me a lot more room to make a mess. But for the most part I stick within the original framework.

But what strikes me most when I work on this code is the way it was written. It is in the good old state machine architecture, pre-event structure style, with an array of booleans driving a case structure putting a string on a shift register to select the next state and there are a dozen shift registers carrying all sorts of crap all over the place. All neatly packed into 480000 tiny little pixels.

The thing is that I used the shift registers religiously, like if there's any data in the program at all, it must be on a shift register. Of course, half of them are used in maybe one other state, and the mass of shift registers serves to confuse the issue more than clarify or assist.

It's always like this, it seems, when you look at old code. At least for me. Whenever I look back at something I did, sometimes even a few weeks ago, I often can see a better way to do it. I think this is a tick mark in the column for design and prototyping a concept with a first draft of code with the intention of rewriting it once you've finished. You can't do it all the time, but often times a little time and distance brings clarity. And clarity brings better code.