John Wolnisty April, 12

Top 10 Programmer Secrets

Plus, the one thing you should NEVER do

In programming, there’s a lot you just learn from mistakes- errr, I mean experience. As a gift to all my young Padawans, I put together a list of my best programming secrets as well as a few things to avoid.

I’ll admit, 99% of these are my own opinion, but I’ve been doing this a lot longer than most so listen up! These tips are geared toward C# programmers, but the principles can apply to any language.

 

1.    Don’t do anything that makes your phone ring after 5 p.m.

This is your prime directive. Memorize it, frame it, tattoo it on your arm… whatever you have to do. In practice, this means:

  • Don’t roll out changes at the end of the day, on a Friday, or before you go on vacation.
  • Don’t rollout anything you haven’t tested.
  • Don’t go in with the attitude, “If something breaks, I can fix it easily.”
    A.   You can’t.
    B.   It will break at the least convenient time.
    C.   Murphy was an optimist.

 

2.     Organize your code.

This is your secondary directive. Use helpful comments and name variables to help the poor slob reading your code 2 years from now to quickly understand what is going on. That poor slob just might be you. And trust me, 2 years later, the brain cells that wrote that code are long gone.

  • Be consistent. In .Net, Java, or any development environment for that matter, there are 15 ways to accomplish a task. Pick one and use it everywhere. This applies to:
    • Variable, function & object naming
    • Code layout (braces, indents and white space usage)
  • Be clever… But not more clever than you have to be. It's really cool to replace 100 lines of nonsense with 5 elegant lines of algorithmic bliss, but not if mere mortals need to read a large book to understand it.
  • However, don’t “Code for Dummies.” Confidently assume the reader has a journeyman knowledge of the language.

 

3.     Use comments to your advantage.

 

  • Don’t explain code in codespeak. Assume the reader knows how to code in the language you are using. Comments like this are useless:

    firingTime *= 1000;         // multiply by 1000

    Comment at the application level not the code level.

    firingTime *= 1000;         // Convert seconds to milliseconds

    Anyone can see a value is multiplied by 1000, but the comment explains why.
  • Use block comments over line comments. Usually, when code changes, the end of line comment doesn't change with it. Again, explain what is going on in the real world.

    /*

* System returns the values with the units-per-volt already calculated

* we only need to convert the units from kPa to PSI,

* and the time to whole milliseconds rather than fractions of a second.

*/

 

  • Avoid Excessive Comments. A small block above a function is usually all that’s needed, but longer comments may be warranted if the code is particularly tricky.
    • Use the “///” feature of Visual Studio to generate a comment block at the head of a routine.
    • Always document side effects that the reader needs to be aware of.

 

4.     Pick an ORM style and stick with it.

ORM Frameworks are great, but there are multiple ways to accomplish things in it and it can be confusing. I chose the functional programming approach rather than the "psuedo-SQL" approach. For example:

 

UNIT_COMMITTED uc = ctx.UNIT_COMMITTED.FirstOrDefault(u =>       

u.SEQUENCE_NUMBER == CurrentUnit.SequenceNumber);

 

Instead of

 

UNIT_COMMITTED uc = from u in ctx.UNIT_COMMITTED

where u.SEQUENCE_NUMBER == CurrentUnit.SequenceNumber

select u;

 

5.     Use LINQ to reduce useless steps.

Use functional programming to eliminate intermediate steps where it makes sense. Double check places where you use a foreach loop to see if it can be replaced with a LINQ extension. Here’s a before and after using LINQ:

Query with a loop

 

var uc = from u in ctx.UNIT_COMMITTED

where u.SEQUENCE_NUMBER == CurrentUnit.SequenceNumber

select u;

List<string> unitsForTest = new List<string>();

foreach (UNIT_COMMITTED unit in uc) {

if (unit.UNIT_STATUS == "PRELOG")

unitsForTest.Add(unit.SERIAL_NUMBER);

}

 

Functional approach 

 

List<string>     unitsForTest = ctx.UNIT_COMMITTED.Where(u =>

u.SEQUENCE_NUMBER == CurrentUnit.SequenceNumber

&& u.UNIT_STATUS == "PRELOG")

.OrderBy(u => u.SERIAL_NUMBER)

.Select(u => u.SERIAL_NUMBER)

.ToList();

 

This has the advantage of eliminating all that boilerplate code, plus the List is returned sorted. Organizing your code functionally may take some getting used to, but it pays off in the long run. You’ll have less bugs and it will be easier to modify down the road.

 

6.     Manage and understand technical debt.

Stop saying, “Oh I’ll fix that later,” or “I’ll get to it next release.” I can’t count the times I’ve seen quick and dirty code labeled “temporary” still in use years later. This is bad technical debt.

However, there are times you may have to use some ugly code to get the job done. This is reasonable debt. Let’s look at an example.

Say you have a project that requires a data validation step that has about 6 sanity checks on the results. Being a sharp programmer, you know that the best method is to design a rules engine for validation. It would be flexible, extensible and awesome! BUT doing that that will greatly exceed time and budget. So, you quickly write some code that does the job but stays within budget.

In cases like this, leave a comment block that states:

  • You realize this code is ugly.
  • An explanation for why it is that way.
  • How you would have made it better if given more time.

 

7.     Avoid gold plating.

Gold plating means adding features no one asked for just to make the product “shiny”. We all do it at times. Regardless of how useful it is, if you add it, you have to support it. This can be a fine line to tread.

 

8.     Consider using decimal.

In the C# world, the decimal data type is often overlooked in favor of a float or double. Many times, what you really want is a number that has 4 digits after the decimal point. Use a decimal type!

A float/double is an approximation of a value, while decimal is exact. (Decimal 5.0275 always stays 5.0275. You won't suddenly find it as 5.0274999999999.) This applies to your database as well. Don’t use a real when what you really want is a numeric(18,4). Use the correct data type to do the job.

 

9.     Don’t overuse “var.”

Using var is often lazy, with a few exceptions. Admittedly, it’s about readability rather than correctness. However, if you use a declared type now, when you read your code again in 2 years, you won’t have to wonder what the variable is.

 

10. Don’t spend too much time trying to understand bad code.

When you get the task of re-writing hopelessly bad code, stay focused and use a strategic approach.

  • First, get the actual desired operational narrative from the customer. After all, you were hired to replace an application, not rewrite it.
  • Then, learn how the existing app is used from the people that actually use it. They often tell a different story.
  • Look at the old source code only AFTER you understand what needs to be done operationally.
  • Ask tons of questions to avoid wasting hours looking at code that is no longer used.
  • Finally, use the old code as a reference not a blueprint.

 

That’s all, folks! I hope you found this list useful. If you’re feeling generous, leave a comment below about something you learned the hard way so we can all benefit!

John Wolnisty

Mr. Wolnisty joined Vertech in December 2010 and is a Solutions Architect. John has over 32 years experience programming using a variety of platforms, tools and environments including .NET and SQL. His industry knowledge includes process control, manufacturing, warehousing and distribution, real-time payment processing and eCommerce. He also has an extensive background in systems administration, network and database design. He is a Certified Wonderware System Platform Developer and an Inductive Automation Ignition Developer.

COMMENTS

SUBSCRIBE TO OUR BLOG

Sign up to get the latest from Vertech delivered right to your inbox.