Why you suck at programming

Man with vacuum cleaner by Justin Horrocks @iStockphoto

Do you know why you suck at programming? Because you don’t understand the process involved in programming.

There are 3 phases in programming

  • understanding the problem
  • formulating a solution
  • converting solution into code

Failing at any one (or more) of those phases, and you end up with wrong implementations, bugs and nasty results. There’s a common syndrome where programmers freeze up, unable to come up with what to do next, and don’t know how to write the code needed. It all comes down to failing at one of the phases.

Generally speaking, programming problems have little to do with technical knowledge, and more with problem understanding and solution formulation.

Understand the problem

If you’re a student, you’re probably looking at an assignment question from your professor. If you’re a professional programmer, you’re probably looking at user requirements. Either way, you’re figuring out the intention of what you’re tasked to do.

This is important because if you don’t understand the problem, you might end up solving the wrong problem or provide an inappropriate solution.

When I was in university, there was this assignment question about pointers. I can’t remember the exact question, but I remember that the question specified that only pointer syntax to be used (and not array syntax). Although my solution was correct, I wasn’t given the full credit because I failed to understand what pointer syntax was.

The problem might require you to call upon your other pieces of knowledge, like math or physics or music or colour representation. If you’re a professional, then this “other pieces of knowledge” will include your business logic, such as how your business works and how your users will interact with your software.

Formulate a solution

Once you understand the problem, you can then go about formulating its solution. There are 2 types of solutions. The first type requires a user interface, or an automation procedure, or a new way of handling data. Basically you need to write code. This is the one you’re probably familiar with. The second type is independent of code, or more specifically, you don’t have to write any code.

For example, the user wants to sum up all the values of a column in an Excel spreadsheet, and put the sum at the end of that column. If you just jump into writing code, you’ll probably call on OleDB functions and Microsoft Office helper functions and DLLs. Your program might work, but that’s not the point. The fact is, you can just educate the user of the summation function in Excel.

Part of your job as a programmer is to know when not to code.

In my case, my team leader goes through the user requirements, and decides if another existing system is capable of handling the requirements. This isn’t laziness, because as a whole, the company strives to minimise duplication of software systems. The user might not know that another existing software can handle his request. That’s why we as programmers have to help do that. (Which is probably why my job title is “systems analyst”…)

Convert solution into code

A solution is usually easier to describe than to code. Ever had those “just need to retrieve data, do some calculations, sort them and then dump them back into the database” moments? There are 2 ways to approach this. The first is to talk out the solution into pseudo code, and then figure out how to replace the pseudo code with real code. The second is to come up with every programming skill you have, and force feed them into the solution.

For example, let’s take finding the maximum number in an array of numbers. The first method’s pseudo code might be

  • have a variable to store maximum number
  • loop through array
  • while looping, compare current element with variable
  • while comparing, if greater than variable, then replace variable value with current value

Note that, it’s “loop through array”, so you’re free to choose any looping mechanism, be it a for loop or while loop or do-while loop.

What if you just learned sorting, and it’s the first (and only) programming skill you could think of to solve the problem? Hey, we could sort the array in ascending order, and then the last element would contain the maximum! Problem solved!

So you follow the second method, force feeding the sorting algorithm to the array, taking note of the last element, and then getting the maximum. It works. It’s just … excessive. There’s a Chinese saying that goes something like, “you don’t need a butcher knife to slaughter chickens”.

There are pros and cons to either method. The important thing is that you’re aware of what they are. Make sure you’re solving the right problem. You could be fixing bugs in that sorting algorithm when it’s not necessary in the first place.

Example: Sum of arithmetic progression

Let’s bring all 3 phases together. Suppose you’re tasked with finding the sum of the following series

1 + 2 + 3 + 4 + 5 + ... + 95 + 96 + 97 + 98 + 99 + 100

In understanding the problem, you’ll have to ask questions. Questions like

  • Is it always an increasing sequence?
  • Does it always increase by 1?
  • Is the number of terms fixed?
  • Does it always start with 1 and end with 100?

You might have found a solution. The point is, is the problem a one-time thing, or is it variable? Maybe the user needed the answer with the question phrased like this. What if the user wanted to increase by 2 the next time? Can you generalise your solution?

Sometimes, the scope of the problem is not given by the user, but is implied. The user expected it, but because you’re so logical and follows strictly to rules, you fail to see the bigger picture (and hence bigger problem).

The solution could be (using the first method of solution approach from above)

  • have a variable to store intermediate sum
  • do a loop, starting with 1, end with 100
  • sum up values in the loop, one iteration at a time

You can probably come up with working code for this, so I’ll leave that to you.

Now what if you’re also a math wiz, and you realise that the series is actually an arithmetic progression? Then using the math formula for arithmetic series (toning some terms down)

S = n(2a + (n-1) d) / 2

where S is the sum
n is the number of terms, which is 100
a is the first term, which is 1
d is the difference between terms, which is 1

Notice there’s a formula, which means it’s easy to translate into a function. And you have an instant generalised function to handle any arithmetic series. This is much better than the looping solution presented before this. But you will only get this better solution if you know the math formula for arithmetic series, which is outside of most programming education.

Alright, fine, maybe during your programming education, you did learn some math. My point is, programming is a tool to solve problems. The solution can come from another place, in this case, the math formula for arithmetic series. You’re a better programmer because you knew math as well.

Now, what if the user really wanted to solve the original problem only once, and only this specific instance? Here’s an ingenious solution, and no coding required. Let me put the series here again for better illustration.

1 + 2 + 3 + 4 + 5 + ... + 95 + 96 + 97 + 98 + 99 + 100

Notice that 1 can be paired with 99 to add up to 100. Notice that 2 can be paired up with 98 to add up to 100. Can you see the pattern? The pairs, (1,99), (2,98), (3,97) … (49, 51) add up to 100 each. And there are 49 such pairs. The only terms without a partner are 50 and 100.

So what do we have? 49(100) + 50 + 100, which is 5050. Compare it with the math formula, where you have 100(2(1) + (100 – 1) 1) / 2 which is 5050. You get the same answer, even without using the formula.

If you really understood the problem, then solutions vary, and sometimes, solutions don’t require code at all. Solve the real problem. And that’s how you can suck less at programming.