Avoid floating-point arithmetic if you need exact answers.

Rounding errors will haunt you forever.

When working with computers, one often sees the use of floating-point numbers. One may see an item for sale for 5.36 dollars or an interest rate of 3.475%. However, the way computers store floating-point numbers in memory can introduce small amounts of error in these representations. For example, the computer may store 5.36 as 5.3600000000000003197442.

These differences are tiny, but when an algorithm determines whether to round numbers up or down, those small errors can lead to unexpected results.

Typically, floating-point numbers are acceptable in scientific applications where programmers understand that every measurement is an estimate. But one should not use them in financial applications where users expect payments to be exact.
For financial applications, one should work with integer representations and avoid rounding errors. The Money pattern is an excellent example of a tool that developers should use in these situations.

Don’t confuse being busy with being productive.

You have to stay focused.

Some people make a big deal out of looking busy. They are always doing a lot of things. Often, they put in extra hours. No one can say they don’t put in lots of effort. But while giving the effort is great, what really matters is results.

Unless you’re a consultant, employers are probably not paying you by the hour. Instead, like most of us, you are expected to deliver results. Presenting the appearance of being busy does not deliver working code.

Instead, one should endeavor to avoid distractions. This will allow you to focus on the problem at hand. Also, when working on your code, you should work on only one task at a time. Multi-tasking slows everything down as you have to do a lot of mental context switching. The better programmers don’t multi-task.

By increasing your focus and attention, you can get more done. You may even be able to do it in less time.

It’s an imperfect world.

Sometimes things go wrong, so you need to handle the cases where things don’t go right.

What happens if an API call returns an error? Or doesn’t return at all? What happens if an API returns an unexpected result? Your software needs to handle these cases.

Too many developers just code for the happy path where everything works as expected. It doesn’t occur to them that some of these components that they depend on may fail. They have worked fine for months or even years. Over time, though, components change, dependencies change, libraries change. There are many reasons a failure may occur. When an unexpected failure occurs, the software can’t handle it, leading to system halt, failure, or even data corruption.

Better developers write their code to handle failure more gracefully. Deliver appropriate error messages. Keep the system state intact. Whatever you do, don’t allow the system to fail silently and risk data corruption.

If you plan your system to handle all the kinds of failures it may see, it will be much more resilient.

Simplicity comes from reduction.

Sometimes less is more. This is one of those times.

After a new application has been rushed to production, or as years pass with an established application, the source code acquires a lot of cruft. Unnecessary routines, logical branches that will never get executed, variables that aren’t used, and many other undesirable items accumulate over time.

If you had to delete the code base completely and start over from scratch, would you go about the project in the exact same way? Probably not.

Sometimes the best you can do is to trim the fat. Remove extra lines of code. Eliminate the extra variables. Refactor and simplify the code for a more obvious flow. The more you delete, the less junk there will be to cause problems later.

On the other hand, sometimes too much time is spent trying to salvage bad work. In those cases, you may have to take more drastic measures. Delete the code and start over.

Smile more.

A great attitude maximizes your strengths and offsets your weaknesses.

Never underestimate the power of a positive mental attitude. How you feel will be reflected in the people around you. If you exhibit high energy, it will charge up others.

Also, when you look like you’re feeling great, people will have more confidence in your ability and choices. This may lead to you gaining support and resources. That, in turn, can help drive further success. So smile!

On the other hand, a bad attitude will negatively impact you. No one wants to work with a Grumpy Gus.

It’s up to you.

Send messages.

Message passing leads to greater scalability.

When you’re operating on a monolithic system, some of the development is easier because everything can call a method on a class directly. And probably for most systems, that is fine. But for applications that need to scale to handle large traffic volumes, the monolith starts to have problems. The only way to make it bigger is to run it on a larger server. Did you know at one point eBay ran on the largest Sun Enterprise 10K server available?

Eventually, of course, they had to split it up to an array of servers, just like everyone else who has to scale.

The easiest way to get a network of servers to work together is to leverage message-passing technologies. Using queues or publish/subscribe tools makes this easier. Although you may lose a bit of the real-time feel of the monolith, you gain a path to scalability.

By decoupling systems, each server can focus on its particular job. Inventory management can be one system, cash transactions on another, shipping and logistics on a third. As you break these systems down, you can replace single servers with clusters. A group of servers can scale up as needed.

Message passing is a powerful tool and definitely one you should learn more about.

Look forward.

How we got here is not as important as where we are going.

You can’t change the past, but you can improve the future. Too many people obsess over the past. They want to document everything that happened, create an official record. The problem is, you can’t change the past. It’s already happened. At best, you can color the recorded history, so that when other people look at it, their opinion may be slanted the way you prefer. This borders on being dishonest or misleading, which is not a good thing. And most of that energy is wasted, as few people are interested in the history. What really matters is where things are headed in the future.

Determining blame can be a waste of time. Instead, develop a plan to move forward. If people are focused on blame, they aren’t working towards making things better. They aren’t moving in the right direction. People who pick up the dropped ball and carry it forward are the real heroes.

Now, one agile practice is to pause and reflect upon the past. Having retrospective meetings are only good if they lead to future change. If you find the retrospectives become just another ceremony and don’t result in changes, then they aren’t doing any good. To avoid wasting precious time in yet another meeting, ensure that each retrospective results in changes to processes.

Look to the future. That’s where we’re headed. Preparing for a better future is infinitely more productive than whining about the past.

Increase visibility.

Shine a light into the darkness.

If the last 10% of the project takes another 90% of the time, that’s bad.

If weeks go by without visible progress, that’s bad.

What you need is a lot more openness. A lot more transparency. People should be able to see, at a glance, the current status easily.

Unit tests provide evidence of robustness, correctness, low coupling, high cohesion. If you’re practicing Test Driven Development, you will have lots of unit tests. Your test suite will be able to tell the story.

Kanban shows work in progress. There is nothing like having a highly visible Kanban board to constantly remind people what the current status of the project is.

Incremental development increases the visibility of progress by increasing the frequency of development evidence. The more frequently you deliver, the more often the business can stand up and take notice. Working software is real evidence of forward progress, and it increases trust.

Nothing is permanent.

Expect things to change, for they will.

I’ve lived in many cities, and a couple of times even owned property. Ended up moving each time though. I’ve had several different jobs throughout my career, and each time, for various reasons, it became necessary to find better employment. I’ve even had the world’s best cat, but time caught up with him. Heck, I’ve even seen the iconic New York City skyline destroyed and rebuilt. The point is, nothing lasts forever. Things change.

This is particularly the case with business requirements. Sometimes this is because it is rare for the exact requirements to be fully understood, even by the business people themselves. More often though, the rapidly changing needs of the marketplace and the incoming stream of new information leads to changes in needs. As products make their way to the public, the feedback starts to roll in, and this leads to more changes in requirements.

Don’t fight it. Embrace it.

Write your code so it can more easily respond to change. One of the biggest things you can do here is separate concerns. For example, in an order processing system, if you have one method that computes shipping, taxes, and fees when totaling up an order, then it will have many reasons to change in the future. If shipping, taxes, and fees were handled by separate methods, then each method has only one reason to change. The smaller your methods are, the less there is to change when the requirements change.

Also, keep each piece of logic in only one place. When that logic has to change in the future, you should only have to update it in one place. Otherwise, you risk bugs where logic is updated for some parts but not for others.

Generally, when writing software, keep in mind that almost any requirement can change. Nothing is set in stone. Think about how the next developer will need to modify your code in the future.

Be user-friendly.

Make interfaces easy to use correctly and hard to use incorrectly.

When people are using your interfaces, whether it is a graphical user interface or an API, you should strive to make it very easy to use. Further, it should be obvious how to use it properly.

Strive to make each field as obvious as possible. Choose your names and labels carefully. Imagine a field named “amount”. Is this an amount in dollars? A quantity of items ordered? The number of ounces of product? It could mean a lot of things. As a result, with this field, it would be easy for the user to misuse the interface. This is a bad design.

In visual interfaces, it is important to use controls that match the field type. Booleans work well with checkboxes, with the checked state matching the true condition. Phone numbers should limit the controls to numeric input, which is particularly helpful when your customer is using a mobile device. Limit text choices with a dropdown instead of validating after entry.

Techniques like these make it hard for the user to enter the wrong kind of data. This increases your chances that your system will be used correctly.

The same holds for APIs. With expressive names and restrictive rules, you can avoid problems where the wrong kind of data is submitted with any given parameter.