Over the years, one lesson I have learned is that troubleshooting progresses a lot faster with a plan… whether we’re fixing code or clocks or e-learning modules.
I first published this article in my old iOS blog in March 2016. However, it contains insights that are just as applicable to e-learning development, so I felt it was appropriate for this blog also.
Disclaimer: This post is not an advertisement, nor is it intended to endorse any product or corporation.
Often, problem-solving skills are seen as instinctual -either you have it, or you don't, or something only developed in specific careers or situations - like coding, or engineering. This article attempts to debunk those myths by demonstrating how taking a structured, step-by-step approach to solving a practical problem (such as fixing a broken kitchen clock), can help identify and develop transferable problem-solving skills.
What Do Clocks & Code Have in Common?
Very little… unless there’s a mysterious problem that needs to be investigated. Then, fixing your average kitchen clock is very similar to debugging a section of code…
We switched to daylight savings time last week, so I performed my usual routine with my kitchen clock: I pulled the minute hand backward until the hour hand jumped back to the previous hour. Several hours later, it became obvious that the clock was broken in some way. It hadn't stopped --it has a swinging pendulum that was still swinging, yet it was displaying the wrong time!
At this point I should explain that I'm emotionally attached to this clock. Aesthetically, it’s 100% my style — 1950’s retro chic. It’s replaceable, but I try to live an eco-friendly lifestyle — like fixing things rather than replacing them with something new. So naturally, I started thinking about fixing it. Which got me thinking about problem-solving in general.
When I'm debugging, I feel under pressure to come up with an instant solution even though I know time usually reveals the quick answer to not necessarily be the most sustainable, scalable, or appropriate solution to a problem. Sometimes the real solution takes a little thought, and may even turn out to be much simpler than we realize. Developing the correct solution involves consciously and systematically thinking and working through a problem -- something that is very difficult under pressure unless we already have a system in place.
Well, I felt this situation presented an excellent opportunity to identify my own system for problem-solving. So, I decided that as I tried to fix the clock, I would consciously follow a similar process to that which I use to debug code, and note the steps. This is the result.
STEP 1: Clearly define the problem in words, removing all ambiguity.
"Sit in a quiet space... and just think about the problem."
I find I can do this if I sit in a quiet space, with no distractions and just think about the problem. To stay focused, I ask myself questions like: "what changed?" and "what precisely IS the problem"?
- WHAT CHANGED? In this case, the problem occurred just after I moved the minute hand backwards to synch the clock to daylight savings time.
- WHAT IS THE PROBLEM? To answer this question, I decided to check the time sporadically over the next couple of hours, comparing the time on the clock to the actual time.Here's what I observed:
|Actual Time||Kitchen Clock|
According to the evidence, the clock was slowly moving backward!
Look for the Obvious Solution First
In the case of my clock, after I'd made the change I needed (i.e. moving the minute hand backwards), the clock stopped working properly. So, it would be obvious to anyone reading this article, that that action caused the problem. Therefore, my obvious solution would be to look for something mechanical that had been put out of alignment, and could be easily fixed.
Remember though, that I still wanted the time to reflect daylight savings time, so simply trying to get the clock back to it's original state was not really an option.
In this single factor, the kitchen clock problem closely mirrors the type of problems we encounter when coding. We make a change which we need to have, then something breaks. However, we still need the change. How do we find a solution that enables the new code to work without breaking the existing code?
If we're lucky the obvious solution can be as simple as adding or removing a comma or a semi-colon. It's very helpful if the code crashes because then we can add breakpoints, find out specifically where the crash occurred, then look to implement an obvious solution at that location.
If there isn't crash, having a clear definition of the problem really helps. In fact, the investigation you carried out in order to arrive at an unambiguous definition will usually yield some ideas as to what some of the obvious solutions might be.
In the case of my clock, I felt the obvious solution would be to remove the back cover and see if anything stood out as being out of place. Unfortunately when I did that, I found the clock mechanism screened off behind a black partition that was glued into place. To me, that was a warning sign: don't go in here. If there had been screws, I would have unscrewed them, but glue usually means the manufacturers do not want anyone messing with their stuff. So, the obvious solution wasn't going to work in this case (unless I wanted to risk totally ruining the clock, which I didn't).
Avoid Reinventing the Wheel
If there's a [reference] source, use it.
For my clock, the correct source would be the manufacturer's guide -- which obviously, I no longer have. However the manufacturer was kind enough to imprint their website URL onto the back of their product, so I went to their website where it turned out they had a Doctor Kit-Cat section.
Would you believe it? I actually found my answer there... but only because I knew what the problem was -- being able to define the actual problem in a specific manner is SO important. When I'm iOS programming, I have two sources I frequently rely on:
I'm re-educating myself to check the reference documentation first, particularly since it has greatly improved since Swift was released. However, if I cannot translate what I find in the reference docs into a practical solution, I Google, then follow the search results which link to solutions on StackOverflow (since there's generally more than one answer, plus discussion and arguments that present optional solutions that I can consider and determine which seems to most closely match my situation).
Here again, is where being able to clearly define the problem helps. I find that if I state the problem correctly, 90% of the time, I'll locate the correct solution. Usually, if I'm having a problem, someone else has had it before. Although I have an account on StackOverflow, I've never had to post a problem yet. Note: I also follow a number of iOS programming blogs; Usually to learn something new --they're not my go-to sources while troubleshooting a problem.
Follow the Instructions
"Advice really only works if you follow it."
Let's face it: advice really only works if you follow it. I'm not advocating that all advice is good advice, but at this point, I have a clear idea of the problem, so I've selected the advice that I think will best help to solve it. Having selected some advice, I follow it for two main reasons:
- To eliminate a probable cause
- So I know the exact steps I have already taken
So, predictably I followed the manufacturer's advice, and I was thrilled to find that my wonderful clock now works. How superb! It's terrific when that happens, isn't it? But what if the advice does not fix the problem?
Solve Or Switch
"I now have sufficient information to decide whether it's worth continuing down my current path, or taking a different approach."
At this point, I usually feel quite sublime --even if my first solution didn't work. I feel in control because I have a much better understanding of the problem --I now have sufficient information to decide whether it's worth continuing down my current path, or taking a different approach.
If I'm going to continue along the same path, I return to Apple's reference docs, read carefully and patiently work from first principles. I've surprised myself by being able to solve a number of problems this way.
Sometimes I've been able to locate a better implementation, or I've found out that I'm simply trying to do something that shouldn't be executed in the manner I'm attempting. Then, I abandon my current path and forge a new one.
"Thinking a problem through removes the fear of failure by distilling it into a set of tasks that are possible to complete."
By following this technique I find that no matter how things work out, I have taken a thought journey that feels much better than flailing around in utter confusion and either hitting the mark by accident, or missing it totally without learning anything. This process is empowering
Thinking a problem through removes the fear of failure by distilling it into a set of tasks that are possible to complete. But one solution doesn't fit everyone. Take some time to study yourself and find out what the best approach might be for you. As you've seen, you don't even have to be coding when you do this. You can always start by trying to fix the kitchen clock...
Kit-Cat® (Kit-Cat Clocks) is registered trademark of the California Clock Company.