"How to Solve It" is an excellent book by the mathematician George Polya in which he lays out the mental process of problem solving. He describes problem solving as a skill which can be learnt and taught. Polya gives a set of practices and guiding questions which he has found effective in solving problems and teaching students how to solve problems. I will summarize the book and follow with some observations about how it relates to Software Development.
- Understanding the problem
- Making connections to create a plan
- Executing the plan
- Reviewing and discussing the solution
1. Understand the Problem
The first phase is to understand the problem. What is the unknown, data, condition?
Draw a figure, introduce notation.
Is it possible to satisfy the condition?
a) getting acquainted, and
b) working for better understanding.
The point being that it takes effort to examine the problem from multiple angles, and achieve a strong definition of what the goal is.
You should only start working on the next phase when you have a clear understanding of the problem that sticks in your mind without effort.
2. Making a Plan
There is an excellent book called "Where do good ideas come from?" by Steven Johnson which explores the source of ideas at an individual and macro scale. Johnson identifies a strong network effect which he illustrates by discussing coral reefs which support a teaming diversity of life unlike the swathes of empty ocean, dense cities like New York having a tendency to produce intellectual breakthroughs, and the internet opening up a stampede of innovation. It is interesting to see how similarly these two authors talk about ideas, but from very different starting points; Johnson searching for innovation in the large, and Polya coming from a formal mathematical problem solving perspective.
You can cultivate an innovative environment by:
- Reading widely.
- Taking an interest in varying subjects.
- Spending time thinking.
- Exploring combinations of existing concepts to make new ones.
- Making a memory map of important thoughts and ideas for later use (there are software solutions to assist with this, I find keeping a journal works).
Good ideas occur in a fertile environment. Good mental habits are required:
- Concentration upon the purpose - you want an idea related to your problem, so keep it clearly in your mind.
- Create work for your background mind - your brain does amazing work while you are sleeping, you want it working on the right problem, and the way to do that is to consciously think about the problem you want to solve while awake.
- Interest is required to do this, so look for ways to re-frame the problem as something interesting, and follow your curiosity.
- Sometimes we get lucky.
Thomas Jefferson said "The harder I work the luckier I get."
Be deserving of luck by exploiting opportunities.
Louis Pasteur said "Chance favors the prepared mind."
3. Execute the Plan
Polya recommends some strategies and guiding questions such as:
- Could you use this idea?
- Can you restate the problem?
- Try to solve a related problem
- Did you use all the data?
- Did you use the whole condition?
- Construct an interesting example
With a plan in place, execution requires patience and diligence. Check each step methodically before completing this phase.
When interviewing candidates I ask "Where do most bugs come from?" By far the most common response is "Lack of attention to detail". Most people are aware of this, it takes self discipline to carry out the plan and check each step.
4. Review and Discuss the Solution
- Can you check the results?
- Can you check the logic?
- Can you derive the result differently?
- Can you see it at a glance?
- Can you use the result or method for some other problem?
- Make new connections
- Test by dimension.
- Use all relevant data.
- Variation of the data.
- Make a concrete interpretation
In this room, if you know the dimensions, can you calculate the diagonal from one corner here to there?
First we have to understanding the problem:
- What is the unknown?
- What are the data?
- Draw a diagram. Introduce suitable notation.
- What shall we denote the unknown as?
- What shall we denote length, width, height?
- What is the condition linking a, b, c, x?
- Is it a reasonable problem? Is the condition sufficient to determine the unknown?
Now let's devise a plan:
- Do you know a related problem?
- Look at the unknown! Do you know a problem having the same unknown?
- Well what is the unknown?
- Do you know a problem with a similar unknown?
- A problem whose unknown is the length of a line?
- The length of a diagonal?
- Find a side of a right triangle.
- Good! Here is a related problem. Can you use it?
- Could you introduce some auxiliary element in order to use it?
- The problem you remembered was about triangles, are there any triangles in your figure?
- Could you find the diagonal if it were the side of a triangle?
It was a good idea to draw that triangle, how do you calculate the unknown?
Does everyone see that?
O.K. I see you have a plan.
Let's carry out the plan:
Introduce suitable notation for the intermediate leg
x2 = y2 + c2
y2 = a2 + b2
x2 = a2 + b2 + c2
x = root (a+b+c)
Check each step carefully!
Now it is time to looking back and review the solution:
- Can you check the result?
- Is the expression symmetric?
- If the height decreases, and vanishes what happens?
- If the height increases, the diagonal increases. Does your formula show this?
- If the shape expands in the same proportions, does the diagonal also increase in proportion?
- Does it matter if you use feet or meters?
- Can you use the method for some other problem?
- Say we put a flag on the roof of a building with cables holding it in place from each corner, how long are the cables?
OK great. The questions Polya recommends are not problem specific, and the methodology works. Let's talk about software development.
In the context of SCRUM:
You will have already noticed many similarities with generic problem solving and software development iterations. The big difference is that typically these stages are split up among different team members. This yields some efficiency, but taken to the extreme can limit the benefits you accumulate from being involved in the complete set of problem solving phases. You want to be involved at some level in each phase to be able to grow your network of idea connections. When dividing up work it is in your best interests, and your teams, to avoid completely isolating yourself to one phase of the process. At the same time you do want to take advantage of the fact that certain team members are specialized.
Being an ace problem solver is a valuable skill. Translating those problem solving skills to a team environment is crucial to ongoing success.
Recognize that code complete is not done, there is more work required to complete a story, and it requires time. Discuss with QA what effect the implementation may have on the software. Follow up with your coworkers to make sure that your story goes through all phases of the cycle.
For defects, fill out the resolution field. You can often find bugs just by describing what you did because it forces you to review your solution. You are sometimes reminded of cases that you forgot to check. The additional explanation yields far better release notes for our customers.
Do a quick self code review of your changeset. Some changes turn out to be unnecessary and wrong after you find the real problem.
If the last thing you tested works, don't stop immediately, you may overlook the other aspects of the problem.
Recognize that team members have differing responsibilities but that you are all collaborating to solve real world problems and provide value to your customers. Each phase and each iteration must be cohesive to succeed.
Where good ideas come from - Steven Johnson
Hammock driven development - Rich Hickey
The Scrum Guide - Ken Schwaber, Jeff Sutherland