Home / GCSE · Edexcel / Computer Science / Problem solving with programming

CPX21Writing, Testing and Refining Programs

Edexcel 1CP2 · 6.1.1

Decomposition and abstraction in program design

Before typing any code, break the problem down (decomposition) and decide what to leave out (abstraction).

  • Decomposition: split the problem into smaller parts: inputs, each calculation or check, outputs. Each part often becomes a subprogram.
  • Abstraction: keep only the detail the program needs. A booking program needs ages and seat numbers, not names or hair colour.
  • Abstraction in code: a subprogram hides how it works. The main program just calls boxesNeeded (area) and trusts the answer.
  • Abstraction in data: name a constant for each fixed value (CAPACITY = 40) and choose a structure that models the problem (a 2D list of records).
  • Plan with a structure chart or a short list of steps. Then write the main program as a few calls, and fill in each subprogram.
  • A good plan for a long question: (1) list the inputs and outputs the question asks for; (2) list the data you're given; (3) decide the subprograms; (4) decide the loops and checks; (5) code one part at a time, running it as you go.

Decomposing a reading-log program: the main program calls one subprogram per task.

Exam tipOn the long questions, Solution design Level 3 says the problem has been “decomposed clearly into component parts” and the logic is “clear and appropriate”. Planning first is how you get there.
Decomposition
Breaking a problem down into smaller parts that are easier to understand, solve and test.
Abstraction
Removing or hiding unnecessary detail, for example by using a subprogram to hide how a task is done.
Edexcel 1CP2 · 6.1.2

Reading and refining code: Paper 2's question types

Apart from the last question, Paper 2 gives you code to read and improve. Pearson uses eight question types.

  • Instructions in the files start with # =====>. Do exactly what each says, at that point in the file.
  • Don't rewrite, delete or move the given code unless you're told to. Examiners mark the changes they asked for.
  • Save in the COMPLETED CODING folder with the exact name given, such as Q03FINISHED.py. Examiners run the files you save.
  • Use the constants and variables the file gives you. Typing the number instead of the constant loses the mark.
  • Your IDE must show line numbers, because questions refer to the original line numbers.
TypeWhat you do
Name the partFind identifiers or line numbers (a constant, a local variable, a selection line) and type them into a comment table
Fix the errorsCorrect syntax, runtime and logic errors in the given code
Complete the codeFinish given lines and add new ones; comments describe the logic
Choose the linesAt each point, remove the # from the one correct line of four and leave the others commented out
Parsons problemPut jumbled lines into the right order without changing their indentation
Comment-first codingWrite the code each comment describes
Implement a flowchartTurn a flowchart into Python
OpenDesign and write the whole program, with little or no starting code
Exam tipEvery examiner report says the same: run your code, with the test data in the question, before you move on. Many logic errors would have been obvious from one run.
Refine
Improve an existing program: fix errors, add features, or make it clearer or more efficient.
Parsons problem
A task where given lines of code must be put into the correct order.
Edexcel 1CP2 · 6.1.3

Converting a flowchart into Python

  • Work through the flowchart from Start, turning each symbol into code.
  • Process (rectangle) → an assignment or calculation. Input/output (parallelogram) → input or print. Decision (diamond) → an if or a loop condition. Pre-defined subprogram (rectangle with double sides) → a subprogram call.
  • A decision whose arrow goes back up the chart is a loop: write a while loop. If it only branches forward, it's an if.
  • When the loop's decision comes before the steps it repeats, the condition goes straight into the while. Check which exit (Yes or No) carries on looping.
  • If the flowchart says “stop when count is greater than 5”, the while needs the opposite: while (count <= 5):.
  • Two arrows joining after an if mean the code carries on after the if/else block, unindented.
  • Use the constants named on the flowchart. Don't swap them for numbers.

Each flowchart symbol and the Python it usually becomes.

Worked exampleA flowchart: Start → set total to 0 → input a number → decision “number ≠ −1?”. Yes: add number to total, then go back to the input. No: output total → Stop. Write it in Python.
  1. The arrow from “add to total” goes back up to the input, so this is a loop. The Yes exit carries on looping, so number != -1 is the while condition.
  2. The input appears once before the loop and again at the end of the loop body, so the loop condition always checks a new number.
    total = 0
    number = int (input ("Number (-1 to stop): "))
    while (number != -1):
        total = total + number
        number = int (input ("Number (-1 to stop): "))
    print ("Total:", total)
  3. Inputs 4, 7, −1 give Total: 11.
Exam tipExaminers said students who followed the flowchart step by step earned very good marks. Students who wrote their own version of the logic often lost the marks for the parts they left out.
Edexcel 1CP2 · 6.1.3

Converting written descriptions and comments into Python

  • Pearson's “pseudocode” isn't a special language. It's an informal written description in plain English.
  • In a comment-first question, each # =====> comment describes the code to write underneath it. Write that code directly below the comment.
  • Read the whole description first, then underline the clues: “as a real number” means float; “repeat until” means a while loop with the opposite condition; “for each” means a for loop; “to two decimal places” means {:.2f}.
  • “Until” and “while” are opposites. “Repeat until the total reaches 100” is while (total < 100):.
  • Keep the comments in your finished file. They help the examiner see which code answers which instruction.
Worked exampleTurn these comments into code.
# =====> Ask for the number of guests, as an integer
# =====> Work out the tables needed, at TABLE_SIZE guests a table,
#        rounding up
# =====> Display the number of tables
  1. “As an integer” → int (input (…)). “Rounding up” → math.ceil, which needs import math at the top. “TABLE_SIZE” → use the constant.
    import math
    
    TABLE_SIZE = 8
    
    guests = 0
    tables = 0
    
    # =====> Ask for the number of guests, as an integer
    guests = int (input ("How many guests? "))
    
    # =====> Work out the tables needed, at TABLE_SIZE guests a table,
    #        rounding up
    tables = math.ceil (guests / TABLE_SIZE)
    
    # =====> Display the number of tables
    print ("Tables needed:", tables)
  2. Test: 30 guests → 4 tables; 32 → 4; 33 → 5.
Pseudocode (Pearson)
An informal written description of a program in imprecise English, with no strict syntax.
Comment-first coding
A Paper 2 task where the logic is given as comments and you write the code for each one.
Edexcel 1CP2 · 6.1.4

Making programs easy to read and maintain

The spec names five techniques: layout, indentation, comments, meaningful identifiers and white space.

  • Layout: group related statements in Pearson's sections: Import libraries, Constants, Global variables, Subprograms, Main program, each under a banner comment.
  • Indentation: Python needs it to mark blocks. Keep it consistent (4 spaces) so the structure is clear.
  • Comments: explain the logic of blocks (an if/elif/else, a loop, a subprogram), not every line. A comment that repeats the code adds clutter.
  • Meaningful identifiers: trayCounts, not x. Pearson uses camelCase for variables and subprograms, and CAPITALS for constants. Avoid single letters.
  • White space: blank lines between blocks; spaces around operators and before brackets (total = total + price, print ("Hi")). Don't double-space every line.
  • Use constants for fixed values, so a change is made in one place.
  • Break long lines inside brackets, and indent the next line so it lines up clearly.
  • Before and after:
    x=[3,14,8]
    for i in x:
        print(i,"trays hold",i*12,"eggs")
    # -------------------------------------------------------------------
    # Constants
    # -------------------------------------------------------------------
    EGGS_PER_TRAY = 12
    
    # -------------------------------------------------------------------
    # Global variables
    # -------------------------------------------------------------------
    trayCounts = [3, 14, 8]
    
    # -------------------------------------------------------------------
    # Main program
    # -------------------------------------------------------------------
    # Show how many eggs each delivery of trays holds
    for trays in trayCounts:
        print (trays, "trays hold", trays * EGGS_PER_TRAY, "eggs")

Pearson's layout for a code file: every statement goes in its section.

Exam tipExaminers are “knowledgeable third parties” who can read Python without a comment on every line. In one year, an answer with a comment on every line was described as very difficult to read.
Meaningful identifier
A name that says what a variable, constant or subprogram holds or does in the problem, such as seatsLeft.
White space
Blank lines and spaces used to separate blocks and parts of a line so code is easier to read.
Edexcel 1CP2 · 6.1.5

Syntax and runtime errors: reading Python's messages

  • A syntax error breaks the rules (grammar) of the language, so the program can't be translated at all. Your IDE usually highlights it before it runs.
  • A runtime error happens while the program runs, when it is asked to do something impossible. The program crashes.
  • Python's message names the error and gives a line number. Go to that line first; the real mistake is sometimes on the line just above (a missing bracket or quote).
  • Fix errors one at a time, from the top, and run again after each fix: one mistake can cause several messages.
MessageKindTypical causeExample
SyntaxErrorSyntaxMissing colon, bracket or quote; = instead of ==; => instead of >=if (age > 17)
IndentationErrorSyntaxA block not indented, or indented inconsistentlyA line under for not indented
NameErrorRuntimeA misspelt name, a variable used before it's created, a missing importtotl = total + 1
TypeErrorRuntimeJoining a string and a number with +; wrong number of arguments"Day " + 3
ValueErrorRuntimeConverting text that isn't a numberint ("ten")
IndexErrorRuntimeAn index past the end of a list or stringscores[len (scores)]
AttributeErrorRuntimeA subprogram name the value doesn't havename.uppercase (), turtle.turtle ()
ZeroDivisionErrorRuntimeDividing by zerototal / count when count is 0
Worked exampleThis line causes TypeError: can only concatenate str (not "int") to str. Fix it.
print ("Lap " + lap + " done")
  1. lap is an integer, and + can only join strings to strings.
  2. Convert it: print ("Lap " + str (lap) + " done"). (Commas would also work: print ("Lap", lap, "done").)
Exam tipIn “Fix the errors” questions, the code doesn't have to run for you to earn each fix's mark, but making it run is the only way to check your fixes. Recent Python versions add hints such as “Did you mean: 'total'?”: read them.
Syntax error
An error that breaks the rules (grammar) of the programming language, so the code can't be translated.
Runtime error
An error that happens while the program is running, when it is asked to do something impossible, such as divide by zero. The program crashes.
Edexcel 1CP2 · 6.1.5

Finding logic errors: testing, tracing and the debugger

  • A logic error lets the program run, but it gives the wrong result. Python shows no message, so you find logic errors by testing.
  • Examiners report that logic errors are the fixes students miss most often, every year.
  • Run the program with data where you know the answer. If the output is wrong, work out which part of the code produced it.
  • Trace the code: follow it line by line, writing down each variable's value (a trace table; see Trace tables and errors on Paper 1).
  • Add temporary print lines to show values inside a loop, then remove them when you've found the problem.
  • Use your IDE's debugger: set a breakpoint on a line so the program pauses there, step through one line at a time, and watch the values in the variable inspector.
Common logic errorExampleFix
Wrong relational operator (boundary missed)if (mark > 50): when 50 should passif (mark >= 50):
Loop runs one time too fewfor day in range (1, 7): for 7 daysrange (1, 8) or range (1, DAYS + 1)
Integer division where a real is neededaverage = total // countaverage = total / count
Tests in the wrong orderif (score >= 50): before elif (score >= 80):Test the highest band first
Counter or total reset inside the looptotal = 0 as the loop's first lineSet it once, before the loop
Wrong indentationA print inside the if that should be after itMove it out of the block
Using and instead of or (or the reverse)if ((age < 11) and (age > 18)): is never Trueor
Exam tipWhen a question lists expected outputs, run your code with exactly those inputs and compare every line. A single wrong character in the output can show a logic error.
Logic error
An error that lets the program run but makes it give an incorrect or unexpected result.
Breakpoint
A marker on a line that makes the debugger pause the program there, so values can be inspected.
Variable inspector
A debugger window that shows the current value of each variable as the program runs.
Edexcel 1CP2 · 6.1.6

Test data and test plans

  • Test data is input chosen to check that a program works. Choose it before you run the program, and write down the result you expect.
  • A test plan lists each test: the input, why it was chosen, the expected result and, after running, the actual result.
  • Test a range check at both boundaries and just outside them, plus a typical value. Many logic errors sit at a boundary.
  • Also try data the user might type by mistake: a blank, a word where a number is wanted, a negative number. A program that crashes on these isn't robust.
  • The words normal, boundary and erroneous (invalid) data are useful labels, but Pearson's papers don't ask for them by name.
  • For random programs, run several times and check every value is in range. For programs that write files, run twice and check the file.
Test dataReasonExpected resultActual result
14Typical value inside the range 11–18AcceptedAccepted
11Lower boundaryAcceptedAccepted
18Upper boundaryAcceptedRejected ✗
10Just below the rangeError message, asked againError message, asked again
19Just above the rangeError message, asked againError message, asked again
abcNot a numberError message, asked againProgram crashed (ValueError) ✗
Worked exampleIn the test plan above, two tests failed. What do they tell the programmer?
  1. 18 was rejected: the upper check probably uses age >= 18 (or age < 18) where it should allow 18. That is a logic error at the boundary.
  2. “abc” crashed the program: it converts the input with int () before checking it, so the program isn't robust to that input.
Exam tipPaper 2 mark schemes print the test data examiners will use, and the question often gives it too. Use it. Code that crashes on “anticipated or provided input” is Level 1 for Functionality.
Test data
Inputs chosen to check that a program works correctly, each with an expected result.
Test plan
A table of tests: the data, the reason for it, the expected result and the actual result.
Robust
Able to cope with unexpected or wrong input without crashing or giving wrong results.
Edexcel 1CP2 · 6.1.6

Fitness for purpose and efficiency

  • A program is fit for purpose if it does everything the requirements ask, gives accurate output and copes with the input it will meet. Check it against each requirement, using logical reasoning and test data.
  • The spec measures efficiency in three ways: the number of compares, the number of passes through a loop, and the use of memory.
  • Stop early: when a search finds what it wants, stop looking. Use a while loop with a Boolean flag, not break.
  • One pass: work out a total, the highest value and a count in the same loop instead of three loops.
  • Memory: don't copy data into a second list you don't need, and don't read a whole file into a list if you can process it line by line.
  • One entry, one exit: each loop and subprogram has one way in and one way out. That makes the code easier to follow and debug. break and exit () aren't in the PLS.
  • Stopping early with a flag:
    def firstOver (pValues, pLimit):
        position = -1
        index = 0
        found = False
        while ((index < len (pValues)) and (not found)):
            if (pValues[index] > pLimit):
                position = index
                found = True
            index = index + 1
        return (position)
    
    print (firstOver ([12, 18, 25, 31, 9], 20))
  • This displays 2. It compares 3 values instead of all 5.
Worked exampleA loop checks every item of a 200-item list for a target. The target is at index 9. How many compares does it make with and without an early exit?
  1. Without an early exit: every item is compared, so 200 compares.
  2. With an early exit: indexes 0 to 9 are compared, then it stops, so 10 compares.
200 compares v 10 compares.
Exam tipOn the open questions, examiners look for an early exit from searches, no repeated passes over the data and no duplicate copies of it. A break works, but a while loop with a flag gives one clear exit test.
Fitness for purpose
How well a program meets all its requirements, accurately and robustly.
Efficiency
How few resources a program uses: measured by the number of compares, the number of passes through a loop and the use of memory.
Edexcel 1CP2 · 6.1.1–6.1.6

How the long questions are marked: the three levels

Paper 2's longer questions give points for each required feature, plus up to three levels-marked strands of 3 marks each. The last question always has all three.

  • Level 1 (1 mark) and Level 2 (2 marks) are “little” and “some” or “most” of the same things.
  • The points marks need each feature in the right place. The levels judge the whole program, so a partly working program still earns level marks.
  • Attempt every question: examiners reported marks for loops and selection even in programs that didn't fully work.
  • Don't add validation the question doesn't ask for: it earns nothing. Do add the validation it does ask for, such as rejecting a blank input.
StrandWhat Level 3 looks like (Pearson's descriptors, shortened)How to get there
Solution designThe problem is “decomposed clearly into component parts”; the logic is clear and appropriate; the choice of variables, data structures and constructs is appropriatePlan first. Use subprograms with parameters and return values, suitable loops, one pass, early exits, constants
Good programming practicesLayout is effective in separating sections; meaningful variable names and subprogram interfaces; effective comments explain blocks; good use of white spacePearson's sections, camelCase names, a comment per block, blank lines between blocks
Functionality (when the code is run)Fully meets the requirements; output is accurate, informative and suitable for the user; responds predictably to anticipated input; robustTest with the given data and with boundaries; clear messages; no crashes on expected input
Exam tipWith about 25–30 minutes for the last question, spend the first few minutes planning: inputs, outputs, data, subprograms. Then build and run it one part at a time, so you always have something that works.
Solution design
The Paper 2 levels strand for how well the problem has been decomposed and how appropriate the logic, data structures and constructs are.
Functionality
The Paper 2 levels strand for how well the program works when run: requirements met, accurate output, predictable and robust.