Problems Don’t Float

Software developers have access to helpful debugging tools that let us step through the logic of our code and discover lines of code that might be misbehaving or causing problems. If our code is generating an error, the debugger will tell us which line of code is at fault. If we know our data, we know what results to expect and we can work through the code to diagnose problems if we don’t get the expected results.

Diagnosing problems during software development is relatively easy. The real challenge comes when your software is in operation and the end user has an issue–users report the effects of a problem and we, as developers, have to diagnose the root of the problem from the user’s description.

In the health care industry, they often remind doctors to cure the disease, not the symptoms. The same should apply to software developers; it’s very easy to get mislead by symptoms. My favorite “explanation” from an end user is “It worked before and now it’s not working.” This vague statement always sends developers down a path of investigating what changed between when the software worked and when it didn’t. Often, this investigation turns out to be a waste of time.

Let me give you some real life examples of being led down the wrong path thanks to the wrong focus:

My friend, a staff engineer for Delphi, had to diagnose a problem with overheating vehicles. The company’s customer service staff analyzed all the issues reported and came to the conclusion that most of the cars reporting the overheating problem were yellow in color. The engineering department was misled down the path of studying whether paint color had an effect on the temperature of a vehicle’s engine. Later, they discovered that the overheating was caused when the vehicle’s engines idled for too many hours during the day. Many of the cars that reported the problem were cabs in New York City. Since most of the cabs spend a fair amount of time idling while waiting for passengers and most NYC cabs are yellow, the customer service team’s analysis of the situation was accurate (many cars with overheating issues were the same color) but it didn’t get to the root of the problem (idling time).

I once wrote an application for processing reversal of payment transactions. After the application was in use for a while I received complaints that it didn’t work when processing reversals that resulted from bounced checks. I knew I’d tested for this scenario, so I was upset to learn that something was going wrong in its “real life” use. I found out later that a new staff member had been assigned to process the bounced check reversals. This new employee wasn’t properly trained and was mistakenly entering check numbers in the account number column, and vice versa. The problem wasn’t with bounced checks; it was user error. But I wasted a lot of time researching the bounced check stuff before we discovered the real issue.

This leads me to a line one of my Operational Analysis professors used to use: “Problems don’t float, only their effects come to the surface.” Don’t get misled by how a problem is described to you, instead do your own investigation; build your own understanding. Don’t just skim the surface; you have to dive deep if you want to find the root cause of a problem.

Here are few basic steps I’ve always found helpful when diving deep:

1. Collect examples of where the application malfunctioned and make sure you don’t limit the examples based on how the problem was defined to you. Do some analysis of your own to see which data sets produced the wrong results.

2. Compare the data to the source document to eliminate any data entry issues. Don’t assume anything. I remember one application where data fields were mislabeled during a configuration step, causing the wrong data to appear in the wrong columns.

3. Make sure that business requirements haven’t changed. Try not to offend the user reporting the problem, but make sure the output they expected matches the business requirements you followed to build the application. I remember an instance where a payroll auditor held back hundreds of paychecks, declaring that salary calculations were wrong. Many hours were wasted verifying the software used to process the calculations, only to discover that the payroll auditor hadn’t been informed that pay raises had gone into effect.

4. Work through the application using the data from the examples you collected. Make sure each step of the way that the output matches the business requirements. Again don’t assume anything, work through each and every step. Not only will this help you diagnose the problem reported, you might discover some other malfunction that was overlooked during development time.

And finally, remember that once you do uncover the root of the problem, you congratulate the end user for discovering that special “hidden feature” in your application!

Maintain Your Software Like It’s Your Home

Are you interested in software that runs on a magic PC somewhere in “the cloud,” never has to be bothered with, and always works smoothly? Sure you are, but if you think such a thing sounds too good to be true, you’re right. Keeping an application performing well throughout its life is much like maintaining your own house–it’s necessary and valuable.

In an previous post, I discussed the Software Life Cycle and made some basic comparisons between the preparation needed to build a house and the preparation needed to build software. The parallels don’t end there; a lot of similarities can also be seen in the maintenance of, and care for, both a house and a software system. Unfortunately, once your new home or application is built, you don’t get a free pass to kick back with your feet up and a nice cold beverage in hand. Using the house/software comparison, below I’ve listed a few areas where maintenance is important in both places:

Regular care

Lawnmower

  • Regular care at your house will include mowing the lawn, raking the leaves, staining the deck, painting the fence, landscaping, etc. All those things we love to keep busy with! We do them for a reason–to keep our homes looking nice and increase it’s value.
  • Likewise, you should regularly be evaluating how to maintain an aesthetically pleasing and user-friendly experience to keep engagement with your software at its peak. In most cases losing engagement will mean losing value in some way. “Regular maintenance” here can mean generating fresh content regularly, updating the layout of your site, adding accessibility features, or implementing new software standards, where appropriate, to keep your application looking and feeling new.

Upgrades

Roofer

  • Eventually, and hopefully not before you’re good and ready, your house is going to need a new roof, a refinished driveway, an updated heating/air conditioning system, etc. These are bigger projects and occur less frequently than the weekly, monthly, or yearly tasks mentioned above but these can easily be considered even more important to the general upkeep and maintained value of your home.
  • Your software should be getting upgrades too, as regularly as possible. Regular maintenance times for things like hardware upgrades, software patching, and security updates are a must. Beyond that, you should consider moving your software to the latest versions of code frameworks and database management tools. Staying on old versions of these things, much like failing to replace an old roof, increases susceptibility to leaks. And the longer you wait, the more likely your path to upgrading will be even more painful, more stressful, and more costly.

Additions

Blueprint

  • You want to move your laundry room from your first floor into the basement and then remove a wall to expand your dining room? Great…Maybe. Any good contractor will tell you how these changes will affect your house (what if that dining room wall is a load-bearing wall?) and that you’ll need to take these changes into consideration when you think about continued upkeep for your home.
  • Most of your software will have additions after your initial launch, too. This isn’t a bad thing…Much like the laundry room situation above, you won’t always think of everything in your first go-round. How new additions will fit and interact with the rest of your software, and how to most effectively make these additions, should be an important part of maintaining your software. You’ll want to analyze whether new features will cause other parts of your system to have issues, much like how removing a wall from a house may affect its structural integrity. Once your software is live, always consider how system processes interact and what adding a new feature will mean for the people already productively using the software.

Clutter

Clutter

  • When you use your basement as a one big storage closet, continuously piling things down there without a periodic clean out, it leads to a huge mess. What happens when you have an emergency and a plumber or HVAC expert needs to get down there and fix something?
  • Even if you haven’t thought about it yet, at some point you’re going to have to clean up your software the same way you would your basement. Today, it’s a brand new system using bleeding-edge technology and state-of-the-art hardware. But as your amazing software ages, all of the data you’re compiling is going to, eventually, become difficult for the system to manage. Do you really need to hang on to a record set of 10,000 emails logged from 1995 anymore? Probably not… So maybe it’s time to archive anything that’s clutter, helping your application breath a little easier. This clean up will help troubleshooting and day-to-day activities go more smoothly, too.

I could keep making house/software upkeep comparisons all day but I think my point has been made: we frequently overlook the maintenance portion of software development but, much like ignoring home maintenance, it’s a bad idea. Take this to heart; regularly scheduled maintenance is incredibly valuable in keeping your software functioning at its best and understanding why and how you need to care for your software will make dealing with it easier in the long run.

K.I.S.S.

Nope, I’m not talking about extravagant costumes, black and white face paint, and fire breathing.

I’m here to discuss the old adage “Keep it simple, stupid” and how it applies to software development.

As a Project Manager, I spend a lot of time meeting with clients to review requirements for their software and work with them to turn those requirements into a full system. As I work with my clients to navigate the treacherous waters of system design, we inevitably end up with a “feature” that we all agree is on the borderline of “Necessary” and “Nice to have.” This is especially hard to determine in a business system that users will be working with every day.

This is when things get interesting! Let’s take a look at what questions to ask yourself:

Why do you want this feature?

You can tell a lot about how important this feature really is by the initial reaction of a client when you ask this question. If it takes a few minutes of fumbling to eek out a satisfactory answer, you can most likely scrap the feature.

Is it worth it?

To answer this one, we’ll ask a few follow up questions, too:

  • How often will this feature be used?
  • Is there a manual workaround that can be used instead of this feature?
  • Who will use this feature (and how many of these users are there)?
  • How much work will be created for a user is this feature is left off?

Now do a little quick math and, magically, we can determine if it’s financially worth adding this feature. Here is an example:

Add this monthly report that aggregates data for X, Y and Z. 
  • Feature will be used monthly
  • User can perform this process manually
  • 1 administrative user will use the report
  • If this feature isn’t implemented, the administrative user will need to run 3 reports and aggregate the data themselves. This process will take approx. 20 minutes.

Answer: If building the report adds 8 hours to the system build, it will pay for itself in 2 years.

Does this feature add complexity to other areas of the system?

I’ll let you in on a little secret, the answer to this question is always YES.

No mater how much you want this fancy new feature, it will make your system more complex. We often try to convince ourselves that a feature is so simple that it won’t add complexity, but there are a couple of points that always hold true:

  • This feature will need to be tested after every update.
  • The users of this feature will need training.
  • This feature will need to be documented in the help system (and maintained).
  • This feature will need to be discussed when future changes to the system are designed/implemented.

So, let’s return to our seemingly simple example report and apply these issues to the “complexity” question:

  • Will this report need to be tested? Yes
  • Will the users need training? Yes
  • Will we need to add help documentation? Yes
  • Will this report need to be updated if we make changes to report X, Y or Z? Yes

There’s no doubt about it–every time you want to add a feature, you’re choosing to make the system more complex.

Before you commit to a feature, ask yourself if it’s a system requirement and make sure you really understand, and accept, the increase in time, complexity, and cost that including the feature will entail. If the answer is “yes,” then let’s build it. But if there’s any doubt, remember, it’s never a bad idea to K.I.S.S.

Wait…What Was I Doing?

Oh, that’s right, I was trying to work on this blog post. Over the past week or so I’ve been trying to sit down to write this post only to be distracted time and again by that annoying thing called “work.” I had multiple ideas, most of which died before I even started typing. That’s when I finally realized what I should write about–focus.

Focus is something I’ve struggled my whole life with. So what do I mean when I say focus? This isn’t about “Oh, I don’t feel like working so I’m going to play Minecraft for two hours at work today, instead.” though that certainly is a lack of focus. I’m talking about those valid, work-related distractions that actually make you accomplish less; about trying to keep everyone happy and all of your tasks moving forward rather than completing the task you’re working on.

Work the Task at Hand

Of course, that’s problem number one–trying to get everything done at once. What happens when you have 20 tasks you’re trying to complete, a client calls with an issue, and two people stop in your office to ask you to help them with a problem while you’re on the phone? You could start drinking heavily at work. Or you could pull out all of your hair in frustration (where do you think all my hair went?). But neither of those helps with the problem at hand: your brain is being pulled in so many different directions that none of the things you’re trying to accomplish are going to get done in anywhere near a reasonable amount of time. More likely than not, some things what get done at all.

You’re just one person, kids. Don’t try to work those 20 tasks at the same time. Every time you shift gears to pay attention to something new you waste time and effort mentally “putting down” one task and “picking up” the next. And, because you didn’t complete the first task the same happens when you go back to it. Where did you leave off? Were you working on a script to check data when you put it down? Maybe you should re-read through the task notes again. Instead of doing these mental gymnastics, focus on one thing and work it to completion (or a blocking point). Yes, your other tasks will have to be lonely for a while but, in the end, you’ll finish your 20 tasks in far less time, and with better results, if you don’t shift mental gears 10 times a day.

Manage Expectations–Not Everything is a Fire

When your client calls don’t let them distract you from this rule. I know it’s hard; this is the trap I fall into more than any other because my clients are mostly support-related, so I’m on the phone with them regularly. It’s just in my nature to keep them happy and productive so when they call my gut reaction is to drop what I’m doing, regardless of the size of the issue, and help them through whatever they need. But I need to remember not to be afraid to have a quick chat, take some notes, ask them put in a support ticket, and tell them “Hey, I’m in the middle of something right now and, as long as Milton hasn’t set the building on fire, I’m going to finish it up and then move over to your issue. I should have an answer to you by X”. That last part is important–make sure your client knows you’re not blowing them off, set a reasonable timeframe for getting back to them, and then get back to them within that timeframe.

This same rule applies for co-workers. Don’t be afraid to say “Hey, I’m working on something right now, but I’ll come grab you in about 15 minutes.” 15 minutes later you’ll be one task lighter, have a sense of accomplishment, and be in a much better mental spot to help with your co-worker’s problems.

Lists Aren’t Just for Santa Claus

An important tool to help you manage all of this is your task list–make sure you have one. If you have something you need to accomplish, make sure you write it down and keep your list in the order you want/need to complete your tasks. Writing everything down will keep you from dropping the ball. Granted, this advice is coming from someone who can’t remember what he had for dinner on Monday, but it applies to everyone–even the most organized of us will have a problem staying on top of everything they want to accomplish without a list.

Even with a list, there’s nothing more overwhelming than looking at a sheet of paper or computer screen full of “to-dos” and knowing there’s no way you’ll be able to tackle them all. This is where keeping them in order becomes important. When a new task comes in, prioritize it right away and rearrange your list if necessary, placing things in the proper order. Then, as you’re working your task list for the day all you have to do is work your way down your list, completing each task (!) and moving onto the next. This process doesn’t have to be rocket science; you can use a small notebook that you keep with you at all times or one of any of a hundred digital options now available. Just make sure that, if you go with a digital choice, it’s safely stored so you when you drop your phone in a sink you don’t lose your tasks for the week (I’m not talking from experience at all, here). I’m a nerd, so I use Google Tasks so they’re synced on my laptop, phone, and tablet.

Consider breaking your task lists up into smaller chunks if that makes them more mentally manageable; it may help you survive the overwhelming nature of a longer list.

The best part about having a task list of any kind is looking back and saying “Hey, look what I accomplished today!” That’s a great feeling.

Disappear…Like a Ninja

Don’t be afraid to drop off the grid for a little while. One of the most effective focus methods is shutting down your email for an hour or two while you work. Some people have set timeframe during which they respond to email: a block in the morning and one in the afternoon where the only thing they work on is email. I haven’t taken this approach yet, but I can definitely see its value. Close your door, if you have one, or put on headphones and disconnect from the world if you’re working on a difficult task. In extreme cases, ask to be moved to a separate office space if you think it will help. Trust me, if there’s a real emergency, someone will find you but, if not, you’ll be able to focus on the task at hand with greater ease.

A Break From it All

Finally, remember to take some mental breaks during the day and get away from your desk for a few minutes. I’m fond of taking walks during lunchtime; it’s great exercise and healthy, from a mental standpoint, to see that ball of fire in the sky. Even if you just walk across the hall to make a new cup of coffee, your brain will disconnect between tasks and you’ll feel ready to attack the next thing in your list when you get back to your desk.

For now though, I’ve got to go. My phone is ringing and I haven’t touched my email yet this morning.