Concepts / Techniques for Writing Correct and Robust Programs

Techniques for Writing Correct and Robust Programs

Program correctness is the idea that programs should be free from errors.

  • Programming

Why Running Is Not the Same as Being Correct

A program can run from start to finish and still fail the people who depend on it. It can produce wrong results, or it can fail at the wrong moment. Either way, it has not met the central goal of this chapter. Writing a program that executes is only part of the job. The program also has to be free from errors, and getting there takes deliberate effort.

What do you think happens?

If a program runs without crashing and prints a result, can we conclude that it is correct?

  • Yes, a program that runs without crashing is correct

  • No, a program can run and still produce wrong results

Reveal answer
Answer:

No, a program can run and still produce wrong results

The source is explicit that a program which runs but produces wrong results has not met the goal of being free from errors. Running without crashing and being correct are different things.

Correctness Is Pursued, Not Inherited

Definition

Program correctness is the idea that programs should be free from errors.

Key point

Correct programs do not just happen. A program does not become correct by default, and writing code is not enough on its own. Correctness has to be deliberately pursued.

The phrase correctness does not happen by accident is the core of this topic. A beginner may assume that careful typing alone produces working software. The source rejects that assumption. Errors are avoided through specific choices, and those choices have to be made on purpose.

Following a Program From Idea to Result

It helps to picture the path a program takes. It starts as an idea, becomes a plan, is written as code, and is then checked. At each stage, an error can enter. The source does not describe this path in detail, but it does say that the two stated means of avoiding errors are planning and attention to detail. Planning comes before and during writing code. Attention to detail is applied while the code is being written and reviewed.

  1. 1
    Start with an idea of what the program should do (this is where a misunderstood goal can introduce an error)
  2. 2
    Plan the program before and during writing code (planning is one of the two stated ways errors are avoided)
  3. 3
    Write the code while paying attention to detail (attention to detail applies during writing)
  4. 4
    Review the code while still paying attention to detail (attention to detail also applies during review)
  5. 5
    Check whether the result is actually correct, not just whether the program runs

Planning and Attention to Detail as Error Prevention

The source states that avoiding errors takes planning and attention to detail. These are the two requirements it names, and they work at different points in the process. Planning shapes what will be written before and during the writing of code. Attention to detail is the care taken while the code is being written and reviewed. Neither one alone is presented as sufficient in the source, which is why both are named together.

Key point

Planning looks ahead to what the program needs to do. Attention to detail looks closely at what the program actually says. A plan that is written carefully can still be undermined by a careless line of code, and carefully written code can still be built on a poor plan.

Tracing a Small Program That Runs but Is Wrong

The following small program is an illustration written for this article. Its job is to compute the average of a list of numbers. It runs without any error message, but it contains a mistake that makes its result wrong. Trace it step by step and watch the values change.

Code walkthrough
def average(nums):
    total = sum(nums)
    return total / (len(nums) + 1)

print(average([2, 4, 6]))
  1. 1
    sum([2, 4, 6]) gives 12, so total becomes 12
  2. 2
    len([2, 4, 6]) gives 3, so the divisor is written as 3 + 1, which is 4
  3. 3
    12 divided by 4 gives 3.0
  4. 4
    The correct average is 12 divided by 3, which is 4.0, so the printed result is wrong even though nothing crashed
  • The function adds up the numbers in the list
  • The divisor should be the count of numbers, which is 3 here
  • The divisor is wrongly computed as one more than the count
Output
3.0
Worked example

Finding the Error by Tracing Values

A program prints 3.0 for average([2, 4, 6]). Is this result correct, and where does the error come from?

  1. 1
    Compute the correct answer independently

    The numbers are 2, 4 and 6. Their sum is 12 and there are 3 numbers, so the correct average is 4.0.

  2. 2
    Compare with the program's output

    The program printed 3.0, which does not match 4.0. The program ran, but its result is wrong.

  3. 3
    Trace the value that causes the mismatch

    The sum is correct at 12. The divisor is 4 instead of 3 because of the extra 1 added to len(nums).

  4. 4
    Correct the mistake and check again

    Changing the divisor to len(nums) gives 12 divided by 3, which is 4.0, matching the correct answer.

Result

The result 3.0 is wrong. The error is the divisor, and it was only visible because the result was checked against an independently computed answer.

Techniques That Raise the Odds of Correctness

Beyond planning and attention to detail, the source says that programmers have techniques they can use to increase the likelihood that their programs are correct. The wording is deliberate. These techniques increase likelihood. They do not guarantee correctness, and the source does not claim they do.

The source does not name or describe these techniques in this introduction. Its purpose here is to establish that such techniques exist and what they are for. Their specific content is developed in the material that follows. This article therefore covers only the framing: why techniques are needed and what they aim to achieve.

Key point

Techniques aim to make correct programs more likely. They are not a substitute for planning and attention to detail, and they do not promise a bug-free result.

Mistakes Learners Make About Correctness

  • Common mistake

    Assuming a program is correct because it runs

    What it looks like

    The averaging program above prints 3.0 with no error message.

    Why it fails

    The source says a program that runs but produces wrong results has not met the goal of being free from errors.

    Do this instead

    Check results against an independently known answer.

  • Common mistake

    Believing correctness happens by default

    Why it fails

    The source states that correct programs do not just happen and that correctness has to be deliberately pursued.

    Do this instead

    Plan first, pay attention to detail while writing and reviewing, and use techniques deliberately.

  • Common mistake

    Treating techniques as a guarantee

    Why it fails

    The source says techniques increase the likelihood of correctness but do not guarantee it.

    Do this instead

    Use techniques as aids that raise the odds, while still checking results.

  • Common mistake

    Skipping planning and going straight to code without considering what the program should do

Practice Reasoning About Correctness

EASY

Using the averaging example, suppose a different program computes average([10, 20]) and prints 15.0. Without running any code, explain whether the result is correct, and describe which of the two stated means of avoiding errors (planning or attention to detail) would be most useful for catching a mistake of this kind.

Hints
  • Compute the correct average of 10 and 20 yourself first
  • Consider whether the mistake lies in the plan or in the detail of how the code is written
  • Recall that the source says the result, not the absence of a crash, decides whether the program is correct

Key Takeaways

  • Program correctness means that programs should be free from errors, and a program that runs but gives wrong results does not meet this goal.
  • Correct programs do not just happen; correctness has to be deliberately pursued.
  • The source names planning and attention to detail as the means of avoiding errors, with planning before and during writing and attention to detail while writing and reviewing.
  • Techniques exist that increase the likelihood that programs are correct, but they do not guarantee it, and their specific content is covered in later material.