Augment Education
    • Question bank
    • Quick fire
    • Worksheets
    • Flashcards
    • Notes
    • Try a quick-fire round
    • All features
    • Business
    • Digital Society
    • Economics
    • Geography
    • Global Politics
    • History
    • Philosophy
    • Psychology
    • Anthropology
    • World Religions
    • Biology
    • Chemistry
    • Physics
    • Computer Science
    • Design Technology
    • ESS
    • SEHS
    • Language and literature
    • Language acquisition
    • Maths AA
    • Maths AI
    • Dance
    • Film
    • Music
    • Theatre
    • Visual Arts
    • Grade calculator
    • Grade boundaries
    • Subject checker
    • Focus timer
    • Exam countdown
    • All free tools
    • IB guide
    • All subjects
  • Blog

Search

Search subjects, the syllabus, glossary terms, the booklets, the IB guide, help and the blog

Log inStart free
augment

Augment Education

IB Diploma revision built around the syllabus.

contact@augment-education.com

Product

  • Features
  • Question bank
  • Quick fire
  • Worksheets
  • Flashcards
  • Notes
  • Subjects
  • What's new

Learn

  • IB guide
  • Booklets, explained
  • Glossary
  • Blog
  • Free tools
  • Grade calculator
  • Subject checker

Company

  • About
  • Help
  • For parents
  • For teachers
  • Comparisons

Subjects

  • English A Lit
  • English A Lang & Lit
  • Chinese A Lit
  • Chinese A Lang & Lit
  • Spanish A Lit
  • Spanish A Lang & Lit
  • English Lit & Perf
  • Spanish Lit & Perf
  • English B
  • Mandarin B
  • Spanish B
  • English ab initio
  • Mandarin ab initio
  • Spanish ab initio
  • Business
  • Digital Society
  • Economics
  • Geography
  • Global Politics
  • History
  • Philosophy
  • Psychology
  • Anthropology
  • World Religions
  • Biology
  • Chemistry
  • Physics
  • Computer Science
  • Design Technology
  • ESS
  • SEHS
  • Maths AA
  • Maths AI
  • Dance
  • Film
  • Music
  • Theatre
  • Visual Arts

Augment Education is developed independently of the International Baccalaureate Organization and is not endorsed by it. “IB” and “International Baccalaureate” are its trademarks.

© 2026 Augment Education. All rights reserved.

  • Privacy
  • Terms
  1. Subjects
  2. Computer Science
  3. Paper 2: reading and writing code

Paper 2: reading and writing code

Read, trace, correct and write Python or Java code by hand for Paper 2, replace prohibited built-in functions with your own loops, and check your answers with a quick trace.

  • IB Computer Science
  • Exam skills
  • SL and HL

24 min readLast reviewed 14 Oct 2026

Two versions of every code question

Paper 2 examines theme B: computational thinking, programming, object-oriented programming and, at HL, abstract data types. Every question that contains code is printed in two equivalent versions, one in Python and one in Java, set in the same context and testing the same skills. You sit the version for the language your school taught, and every code answer you write is in that language. There is no IB pseudocode in this course, so code in the paper is real Python or real Java, and so is yours.

One Paper 2 question focuses on algorithmic thinking with no code to read or write; it has its own page in Exam skills ("The algorithmic thinking question"). Every other question asks you to read code, write code, or both. On earlier IB papers most questions mixed the two: a short program was printed, then the parts asked for its output, a trace, a fault and finally a related function of your own.

Because the two versions match, nothing in a question depends on a feature only one language has. A Python question that uses a list is matched by a Java question that uses an array or an ArrayList, and a Python try/except by a Java try/catch. Your job is to read your own language fluently, including the small differences that change a result.

No specimen paper or markscheme for the 2027 course is public. The guide fixes the structure (two language versions, one no-code question, prohibited built-ins clearly indicated); the question shapes and marking habits that follow come from earlier IB Computer Science papers and are very likely to continue, but treat them as a guide, not as official rules.

Exam tip

Answer in the language of your paper. A correct algorithm written in the other language may still earn credit for its logic, but switching languages mid-answer makes your code ambiguous, and an ambiguous line is not given the benefit of the doubt.

Reading code: the differences that change a result

Most of what you read in a Paper 2 program is ordinary sequence, selection and iteration (subtopic B2.3, Programming constructs). The places where students misread code are the few where Python and Java behave differently, or where both behave differently from everyday maths. The table lists the ones that most often change an answer.

Idea

Python

Java

What to watch

Dividing two integers

7 / 2 gives 3.5; 7 // 2 gives 3

7 / 2 gives 3 when both are int

Java integer division silently drops the fraction; with negatives the two differ (-7 // 2 is -4 in Python, -7 / 2 is -3 in Java)

Remainder

7 % 2 gives 1

7 % 2 gives 1

used to test even or odd; the same for positive numbers, but -7 % 2 is 1 in Python and -1 in Java

Length

len(items), len(text)

items.length (array), list.size() (ArrayList), text.length() (String)

three different spellings in Java

Comparing strings

a == b compares the text

a.equals(b) compares the text; == compares references

a Java == on strings can be false for equal text

Counted loop

for i in range(1, 5) gives 1, 2, 3, 4

for (int i = 1; i < 5; i++) gives 1, 2, 3, 4

the end value is excluded in both

Multi-way selection

elif

else if

same logic, different keyword

Blocks

indentation

braces { }

in Python the indentation is the structure

Scope

a variable made inside a loop still exists after it

a variable declared inside a block disappears at its }

matters when a later line uses the variable

Common mistake

Reading Java total / count as an exact average when both variables are int. The result is truncated, so a total of 17 over 4 items gives 4, not 4.25. The Java code needs a cast, (double) total / count, to keep the fraction. Python's / always gives a floating-point result, so the same line in a Python paper gives 4.25.

The safest way to read any unfamiliar line is to give it real values. Pick the first item of the data, run the line in your head, and write the result down. If a line still seems unclear, check how its result is used two lines later: a variable compared with 0 each pass is probably a counter, and one that keeps the biggest value seen so far is a running maximum.

Writing code by hand

You write Paper 2 code on paper or in a plain answer box, with no editor to indent, colour or check it. The examiner reads it once, line by line, and can credit a feature only if it is clear exactly what each line does. Layout earns no marks of its own, but unclear indentation or a missing brace can make a correct loop impossible to credit.

  • Indentation. In Python, indentation decides which lines are inside a loop or an if, so it must be unmistakable. Indent each level by a clear, consistent step (about the width of four letters). In Java, put each { at the end of the line that opens the block and each } on its own line, lined up with the start of that line, and indent the body as well.

  • Names. Use the names the question gives for the function, its parameters and any variables it mentions. For your own variables, choose names that say what they hold (count, largest, total_hours), not x or temp2.

  • Headers. Write the full header: def count_rises(temps): in Python, public static int countRises(int[] temps) in Java, with the return type and parameter types the question implies.

  • Comments. A short comment helps only where the purpose of a line is not obvious (# start at 1: day 0 has no day before it). Never use a comment instead of code.

  • Corrections. Cross out a wrong line with a single line and write the replacement next to it. Do not squeeze extra lines between existing ones; draw an arrow to where an added line belongs.

  • Do only what is asked. A question that says "construct a function that returns…" does not want input statements or a menu around it. Writing a whole program costs time and adds lines that can contradict your answer.

Exam tip

Read the verb in the question: "returns" needs a return statement, while "outputs", "prints" or "displays" needs print or System.out.println. A function that prints the right value when the question asks for it to be returned loses the mark for the return.

How code answers are marked

On earlier IB Computer Science papers, code answers were marked on features of the algorithm, not on the program as a whole. A markscheme for a construct question lists the separate things a correct answer must do, and each earns a mark wherever it appears in your code: a correct header with the right parameters, correct initialisation before a loop, a loop with the right bounds, the right condition, the right update or accumulation, and the right return or output. The annotated answer to a five-mark question shows how the marks are spread.

Python function count_rises with five annotations: one mark for the header with a parameter, one for setting the counter to 0 first, one for the loop from index 1 to the end, one for comparing with the day before and adding 1, one for returning after the loop. Total 5.Python function count_rises with five annotations: one mark for the header with a parameter, one for setting the counter to 0 first, one for the loop from index 1 to the end, one for comparing with the day before and adding 1, one for returning after the loop. Total 5.
Each mark belongs to one feature, so an answer with a wrong loop bound can still earn the other four marks.

A partly correct answer therefore still scores. If you cannot finish a function, write the parts you can (the header, the initialisation, the loop), because each is credited on its own. The same feature-by-feature reading explains what is and is not penalised.

Usually not penalised

Usually penalised

A missing colon or semicolon

A loop bound that misses the first or last element

Print instead of print, or a small spelling slip in a keyword

> where the task needs >=

A different but correct approach (a while loop instead of a for loop)

A counter or total reset inside the loop

Extra brackets that do not change the meaning

return inside the loop when every element must be checked

Using a different variable name consistently

Using a built-in function the question prohibits

A markscheme gives one model answer, but any code that does the same job is credited, while a wrong index, two dependent lines in the wrong order or a variable that was never given a value loses the mark for that feature. Where one part of a question uses your answer to an earlier part, a wrong earlier value used correctly later can still earn the later marks (error carried forward).

Tip

Improve your notes: Take three construct questions you have answered in class and mark them yourself against a feature list: header, initialisation, loop bounds, condition, update, return. Write the missing feature next to each answer that lost a mark, then list your two most frequent missing features at the top of your revision notes.

Question types and model answers

Code questions on earlier papers came in a small number of shapes. The command term tells you which shape you are facing (command terms are explained in full on their own Exam skills page): state and identify want a short answer with no reasons, trace wants a full record of the values, explain wants a reason, and construct wants working code.

State the output and identify parts of a program

The function mystery processes a list of whole numbers.

Python
def mystery(values):
    result = 0
    for v in values:
        if v % 2 == 0:
            result = result + v
        else:
            result = result - 1
    return result


print(mystery([4, 7, 10, 3]))
Java version
Java
public class Mystery {
    public static int mystery(int[] values) {
        int result = 0;
        for (int v : values) {
            if (v % 2 == 0) {
                result = result + v;
            } else {
                result = result - 1;
            }
        }
        return result;
    }

    public static void main(String[] args) {
        int[] data = {4, 7, 10, 3};
        System.out.println(mystery(data));
    }
}

Worked example

(a) Identify the parameter of mystery. [1]

(b) Identify one variable in mystery that is used as an accumulator. [1]

(c) State the output of the program. [2]

Show the model answer

(a) values. [1] (The list [4, 7, 10, 3] in the call is the argument, not the parameter.)

(b) result. [1] It is given a starting value before the loop and changed by every pass.

(c) Work through each element, keeping result up to date:

v

v % 2 == 0

result

0

4

True

4

7

False

3

10

True

13

3

False

12

Output: 12 [2]. Award [1] for a correct working that reaches 13 after the third element, [1] for the final value 12.

A "state" answer needs only the value, but a short working (here the four values of result) protects your method marks if the final value is wrong. An "identify" answer must name exactly one item from the code, written exactly as it appears; a description ("the list") does not earn the mark.

Trace

To trace code is to follow it line by line and record every change to its variables (tracing). The record is a trace table: one column per variable, in the order the variables appear, an optional column for a condition, and a column for output; a new row each time a value changes or each time the loop runs. The program digits counts and adds up the digits of a number using the remainder and integer division.

Python
n = 4071
total = 0
count = 0
while n > 0:
    digit = n % 10
    total = total + digit
    count = count + 1
    n = n // 10
print(count, total)
Java version
Java
public class Digits {
    public static void main(String[] args) {
        int n = 4071;
        int total = 0;
        int count = 0;
        while (n > 0) {
            int digit = n % 10;
            total = total + digit;
            count = count + 1;
            n = n / 10;
        }
        System.out.println(count + " " + total);
    }
}

In Java, n / 10 divides two int values, so it already drops the fraction; Python needs // to do the same. Both versions give the same trace.

Worked example

Trace the program digits, using a trace table with columns n, n > 0, digit, total, count and output. [4]

Show the model answer

n

n > 0

digit

total

count

Output

4071

0

0

4071

True

1

1

1

407

True

7

8

2

40

True

0

8

3

4

True

4

12

4

0

False

4 12

Each row shows one pass: digit is the last digit of n at the start of the pass, and n shrinks by one digit at the end of it. The zero digit still counts, which is why count reaches 4 while total does not change in the third pass.

Award [1] for each of:

  • the initial values 4071, 0, 0;

  • digit taking the values 1, 7, 0, 4 in that order;

  • total and count correct after every pass;

  • the loop ending when n is 0, and the output 4 12.

Exam tip

Follow the order of the lines exactly. In digits, n changes at the end of each pass, so the n > 0 check that ends the loop happens after the fourth pass. Updating n too early, or recording a value the program never prints, are the commonest ways to lose trace marks.

Find and correct errors

A program with a fault is printed and you must identify the faulty line, explain what goes wrong and correct it. The faults are usually logic errors: the code runs but gives the wrong answer. The function count_passes should return how many marks are at or above the pass mark.

Python
def count_passes(marks, pass_mark):
    for m in marks:
        count = 0
        if m > pass_mark:
            count = count + 1
    return count


print(count_passes([55, 40, 70, 50], 50))
Java version
Java
public class Passes {
    public static int countPasses(int[] marks, int passMark) {
        int count = 0;
        for (int m : marks) {
            count = 0;
            if (m > passMark) {
                count = count + 1;
            }
        }
        return count;
    }

    public static void main(String[] args) {
        int[] marks = {55, 40, 70, 50};
        System.out.println(countPasses(marks, 50));
    }
}

The program prints 0, although three of the four marks (55, 70 and 50) are at or above 50.

Worked example

The function count_passes (countPasses in Java) contains two errors. Identify each error, explain its effect and construct the corrected function. [6]

Show the model answer

Error 1: the counter is set to 0 inside the loop, so it is reset on every pass. [1] The function returns only the result for the last mark (0 or 1), not the total. [1]

Error 2: the condition uses > instead of >=. [1] A mark equal to the pass mark (50) is not counted, although the task says "at or above". [1]

Corrected function:

Python
def count_passes(marks, pass_mark):
    count = 0
    for m in marks:
        if m >= pass_mark:
            count = count + 1
    return count

Java:

Java
public static int countPasses(int[] marks, int passMark) {
    int count = 0;
    for (int m : marks) {
        if (m >= passMark) {
            count = count + 1;
        }
    }
    return count;
}

Award [1] for the counter initialised once before the loop and [1] for >= in the condition. With the data [55, 40, 70, 50] and pass mark 50, the corrected function returns 3.

A good test for any "find the error" question is a value exactly on the boundary. The mark of 50 exposes the > error at once, so when the question gives data, check first whether any value is boundary data.

Construct a function or method

Construct questions ask you to write code that does a stated job, usually a single function (Python) or method (Java) with given parameters. They usually carry the most marks in a question and are marked feature by feature.

Worked example

A weather app stores each day's maximum temperature, in order, in a list temps (Java: an int array). Construct a function count_rises(temps) (Java: countRises(int[] temps)) that returns the number of days on which the temperature was higher than on the day before. [5]

Show the model answer
Python
def count_rises(temps):
    rises = 0
    for i in range(1, len(temps)):
        if temps[i] > temps[i - 1]:
            rises = rises + 1
    return rises

Java:

Java
public static int countRises(int[] temps) {
    int rises = 0;
    for (int i = 1; i < temps.length; i++) {
        if (temps[i] > temps[i - 1]) {
            rises = rises + 1;
        }
    }
    return rises;
}

Award [1] for each of:

  • a correct header with one parameter (Java: int return type);

  • a counter set to 0 before the loop;

  • a loop from index 1 to the last index;

  • comparing temps[i] with temps[i - 1] and adding 1 when it is greater;

  • returning the counter after the loop.

Check: for [14, 17, 16, 19, 21, 21] the rises are 14→17, 16→19 and 19→21, so the function returns 3. For a single day, [9], the loop never runs and it returns 0.

The loop starts at index 1 because the first day has no day before it. Starting at 0 would compare temps[0] with temps[-1], which in Python is silently the last element and in Java throws an ArrayIndexOutOfBoundsException. The fault is the same off-by-one in both languages, but only the Java version stops with an error.

Exception handling

Exception handling questions ask you to keep a program running when something goes wrong: text where a number was expected, a missing file, a division by zero. Python uses try and except; Java uses try and catch; both can add finally. The function read_tickets keeps asking until the user types a whole number of at least 1.

Python
def read_tickets():
    while True:
        text = input("Number of tickets: ")
        try:
            tickets = int(text)
            if tickets >= 1:
                return tickets
            print("Enter at least 1")
        except ValueError:
            print("Enter a whole number")


print("Booked", read_tickets())
Java version
Java
import java.util.Scanner;

public class Tickets {
    public static int readTickets(Scanner input) {
        while (true) {
            System.out.print("Number of tickets: ");
            String text = input.nextLine();
            try {
                int tickets = Integer.parseInt(text);
                if (tickets >= 1) {
                    return tickets;
                }
                System.out.println("Enter at least 1");
            } catch (NumberFormatException e) {
                System.out.println("Enter a whole number");
            }
        }
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("Booked " + readTickets(input));
    }
}

With the inputs two, 0 and 3, both versions produce the same run:

Plain text
Number of tickets: two
Enter a whole number
Number of tickets: 0
Enter at least 1
Number of tickets: 3
Booked 3

Worked example

Explain how read_tickets (readTickets in Java) handles the input two, and state why a separate check is still needed for the input 0. [3]

Show the model answer
  • Converting two with int() / Integer.parseInt() raises a ValueError / NumberFormatException; [1]

  • control jumps to the except / catch block, which prints a message instead of the program crashing, and the while loop asks again; [1]

  • 0 is a valid whole number, so no exception is raised, but it is outside the allowed range, so the if check (tickets >= 1) is needed to reject it. [1]

Name the specific exception when you write a handler (ValueError, FileNotFoundError, NumberFormatException, IOException). A bare except: or catch (Exception e) works, but it also hides faults you did not expect, and an "explain" answer about it is weaker because it cannot say which error is being handled.

File processing

File questions ask you to read a text file line by line, process each line, and often write results to another file. A common shape is a file of records, one per line, with fields separated by commas. The function copy_passes reads lines such as Amira,72 and writes the names of students at or above the pass mark to a new file, returning how many it wrote.

Python
def copy_passes(in_name, out_name, pass_mark):
    written = 0
    try:
        source = open(in_name, "r")
        target = open(out_name, "w")
        for line in source:
            parts = line.strip().split(",")
            name = parts[0]
            score = int(parts[1])
            if score >= pass_mark:
                target.write(name + "\n")
                written = written + 1
        source.close()
        target.close()
    except FileNotFoundError:
        print("File not found:", in_name)
    return written


print(copy_passes("scores.txt", "passed.txt", 50))
Java version
Java
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Passed {
    public static int copyPasses(String inName, String outName, int passMark) {
        int written = 0;
        try {
            BufferedReader source = new BufferedReader(new FileReader(inName));
            FileWriter target = new FileWriter(outName);
            String line = source.readLine();
            while (line != null) {
                String[] parts = line.split(",");
                String name = parts[0];
                int score = Integer.parseInt(parts[1]);
                if (score >= passMark) {
                    target.write(name + "\n");
                    written = written + 1;
                }
                line = source.readLine();
            }
            source.close();
            target.close();
        } catch (FileNotFoundException e) {
            System.out.println("File not found: " + inName);
        } catch (IOException e) {
            System.out.println("Could not read or write a file");
        }
        return written;
    }

    public static void main(String[] args) {
        System.out.println(copyPasses("scores.txt", "passed.txt", 50));
    }
}

With a scores.txt holding Amira,72, Ben,45, Chen,50 and Dara,38, the program prints 2 and passed.txt contains Amira and Chen. Called with a file name that does not exist, it prints File not found: missing.txt and returns 0.

The marking points for a file question follow the life of the file: open it in the right mode ("r", "w" or "a"; in Java new FileWriter(name, true) appends), read every line with a loop that stops at the end of the file, split and convert each line, process it, write with an explicit "\n", and close both files. Java's FileReader and FileWriter throw checked exceptions, so Java code must catch IOException or declare it with throws; Python code has no such rule but should still handle FileNotFoundError when the question mentions a missing file.

Common mistake

Forgetting that "w" mode empties the file before writing. A program that opens a results file with "w" inside a loop keeps only the last line written. Open the output file once, before the loop, or use "a" mode when the task says to add to an existing file.

Classes, objects and comparing algorithms

Two more shapes recur. Object-oriented questions (subtopic B3.1) give a description or a UML class diagram and ask you to construct a class: private attributes, a constructor that sets them from its parameters, accessor and mutator methods, and sometimes a method that uses the attributes. Marks go to each attribute, the constructor's assignments, each method's header and its return. Algorithm questions (subtopic B2.4) ask you to compare linear and binary search, or bubble and selection sort, in Big O terms and in practice; a full answer names the complexity of each, says what it means for large inputs, and adds a condition such as "binary search needs the data to be sorted first".

Prohibited built-in functions

Python has many built-in functions that do common jobs in one call. Their use is encouraged in your internal assessment, but some Paper 2 questions prohibit specific ones so that you have to show the algorithm yourself. Each question that does this says so clearly.

Definition

Built-in function: a function supplied ready-made by a programming language or its standard library, which a program can call without writing its algorithm.

Python's len, max, min, sum and sorted are built-in functions; a question that prohibits one expects the same result from a loop you write yourself.

Recognising the instruction

The guide says only that such questions will be clearly indicated. Expect wording such as "Do not use the built-in functions max or min", "You must not use any built-in sort function" or "without using len", and underline it as soon as you read it. Check which part or parts it covers, and read every later part for a restriction of its own.

A prohibition also covers anything that does the same job in disguise. If sort is prohibited, sorted(items) and items.sort() both break the rule. If max is prohibited, sorting the list and taking the last element breaks it too, because the question wants your own comparison loop. The guide names only Python built-ins, and the Java version of a question states its own restrictions. Treat the library methods that do the same jobs (Arrays.sort, Collections.sort, Collections.max, an ArrayList's contains and indexOf) the same way.

Prohibited

Hand-written replacement

The idea

len

count the items with a loop

counter starts at 0, add 1 per item

max, min

keep the best value seen so far

start with the first item, compare each other item

sum

running total

accumulator starts at 0, add each item

in, index, count

linear search

compare each item with the target, return its position or −1

sort, sorted

bubble sort or selection sort

repeated comparisons and swaps

reverse

swap from both ends towards the middle

two indexes moving inwards

pop

an array-based stack with a top index

read stack[top], then decrease top

Hand-written replacements

The first set of replacements makes one pass through the data. The same five-line patterns appear inside many larger answers, so learn them by heart.

Python
def length(items):
    count = 0
    for item in items:
        count = count + 1
    return count


def largest(items):
    best = items[0]
    for item in items:
        if item > best:
            best = item
    return best


def total(items):
    running = 0
    for item in items:
        running = running + item
    return running


def find(items, target):
    i = 0
    for item in items:
        if item == target:
            return i
        i = i + 1
    return -1


def count_of(items, target):
    count = 0
    for item in items:
        if item == target:
            count = count + 1
    return count


data = [12, 5, 31, 8, 5]
print(length(data), largest(data), total(data))
print(find(data, 8), find(data, 99), count_of(data, 5))
Java version
Java
import java.util.ArrayList;

public class ByHand {
    public static int length(ArrayList<Integer> items) {
        int count = 0;
        for (int item : items) {
            count = count + 1;
        }
        return count;
    }

    public static int largest(int[] items) {
        int best = items[0];
        for (int item : items) {
            if (item > best) {
                best = item;
            }
        }
        return best;
    }

    public static int total(int[] items) {
        int running = 0;
        for (int item : items) {
            running = running + item;
        }
        return running;
    }

    public static int find(int[] items, int target) {
        for (int i = 0; i < items.length; i++) {
            if (items[i] == target) {
                return i;
            }
        }
        return -1;
    }

    public static int countOf(int[] items, int target) {
        int count = 0;
        for (int item : items) {
            if (item == target) {
                count = count + 1;
            }
        }
        return count;
    }

    public static void main(String[] args) {
        int[] data = {12, 5, 31, 8, 5};
        ArrayList<Integer> list = new ArrayList<Integer>();
        for (int x : data) {
            list.add(x);
        }
        System.out.println(length(list) + " " + largest(data) + " " + total(data));
        System.out.println(find(data, 8) + " " + find(data, 99) + " " + countOf(data, 5));
    }
}
Plain text
5 31 61
3 -1 2

The Python find keeps its own index i so that it needs no len; when len is allowed, for i in range(len(items)) is just as good. The return i inside the loop is correct here because the task is to stop at the first match, while every other function returns after the loop because it must see every item.

Common mistake

Writing for i in range(len(items)) in an answer that prohibits len. The loop header itself calls the prohibited function, so the mark for the loop is lost even though the rest of the code is correct. Loop over the items directly (for item in items) and keep your own counter if you need positions.

The second set rearranges the data. Sorting and reversing work in place, changing the list they are given, and the stack keeps a top index instead of calling pop.

Python
def bubble_sort(items):
    n = len(items)
    swapped = True
    while swapped:
        swapped = False
        for i in range(n - 1):
            if items[i] > items[i + 1]:
                temp = items[i]
                items[i] = items[i + 1]
                items[i + 1] = temp
                swapped = True
        n = n - 1


def reverse(items):
    left = 0
    right = len(items) - 1
    while left < right:
        temp = items[left]
        items[left] = items[right]
        items[right] = temp
        left = left + 1
        right = right - 1


stack = [0] * 5
top = -1


def push(value):
    global top
    top = top + 1
    stack[top] = value


def pop():
    global top
    value = stack[top]
    top = top - 1
    return value


data = [12, 5, 31, 8, 5]
bubble_sort(data)
print(data)
reverse(data)
print(data)
push(4)
push(9)
print(pop(), pop(), top)
Java version
Java
import java.util.Arrays;

public class ByHand2 {
    static int[] stack = new int[5];
    static int top = -1;

    public static void bubbleSort(int[] items) {
        int n = items.length;
        boolean swapped = true;
        while (swapped) {
            swapped = false;
            for (int i = 0; i < n - 1; i++) {
                if (items[i] > items[i + 1]) {
                    int temp = items[i];
                    items[i] = items[i + 1];
                    items[i + 1] = temp;
                    swapped = true;
                }
            }
            n = n - 1;
        }
    }

    public static void reverse(int[] items) {
        int left = 0;
        int right = items.length - 1;
        while (left < right) {
            int temp = items[left];
            items[left] = items[right];
            items[right] = temp;
            left = left + 1;
            right = right - 1;
        }
    }

    public static void push(int value) {
        top = top + 1;
        stack[top] = value;
    }

    public static int pop() {
        int value = stack[top];
        top = top - 1;
        return value;
    }

    public static void main(String[] args) {
        int[] data = {12, 5, 31, 8, 5};
        bubbleSort(data);
        System.out.println(Arrays.toString(data));
        reverse(data);
        System.out.println(Arrays.toString(data));
        push(4);
        push(9);
        int first = pop();
        int second = pop();
        System.out.println(first + " " + second + " " + top);
    }
}
Plain text
[5, 5, 8, 12, 31]
[31, 12, 8, 5, 5]
9 4 -1

The Java listing uses Arrays.toString only to display the result; it plays no part in the algorithms. The swap needs a temporary variable in both languages: writing items[i] = items[i + 1] first would overwrite the value before it is copied. If len is prohibited as well, the Python bubble_sort and reverse can get the length from the hand-written length function instead.

Exam tip

When a built-in is prohibited, the marks are for the algorithm the built-in hides. Write the replacement inside your function (or as a short helper function you also write), and keep it plain: initialise, loop, compare, update, return. A clever one-line trick that avoids the named function but uses another built-in to do the same job gains nothing.

Checking your own code with a quick trace

Before you move on from a construct answer, trace it with a tiny input. It takes a minute and catches most logic errors, because a wrong initial value, a missed element or a misplaced return shows up after two or three rows. Choose the input deliberately:

  1. A small normal case with three or four items, where you can work out the right answer in your head.

  2. A case that tests the edges: the answer is the first item, the last item, or a value on a boundary (exactly the pass mark).

  3. An awkward case if the task allows one: a single item, no matching items, or (where the question allows it) an empty list.

Then trace your code, not the code you meant to write, writing each variable's value as it changes, and compare the result with the answer you expected. The function smallest was written as an answer to "construct a function that returns the smallest value in a non-empty list, without using min".

Python
def smallest(values):
    low = 0
    for i in range(1, len(values)):
        if values[i] < low:
            low = values[i]
    return low
Java version
Java
public static int smallest(int[] values) {
    int low = 0;
    for (int i = 1; i < values.length; i++) {
        if (values[i] < low) {
            low = values[i];
        }
    }
    return low;
}

Worked example

Trace smallest with the input [5, 8, 3], then identify the error and construct a correction. [4]

Show the model answer

i

values[i]

values[i] < low

low

0

1

8

False

0

2

3

False

0

The function returns 0, a value that is not even in the list; the right answer is 3. [1]

The error is the initial value: low starts at 0, which is smaller than every positive value, so no element can ever replace it. [1] Start from the first element instead, which the loop from index 1 already expects:

Python
def smallest(values):
    low = values[0]
    for i in range(1, len(values)):
        if values[i] < low:
            low = values[i]
    return low

Java:

Java
public static int smallest(int[] values) {
    int low = values[0];
    for (int i = 1; i < values.length; i++) {
        if (values[i] < low) {
            low = values[i];
        }
    }
    return low;
}

Award [1] for low = values[0] and [1] for keeping the loop from index 1 (or from 0) with the < comparison. Re-tracing with [5, 8, 3] now gives 5, 5, 3 and returns 3; with [2, 8, 3] (smallest first) it returns 2.

If the trace shows the loop running one time too many or too few, check the end value of range or the < versus <= in the Java loop condition first, because most off-by-one errors come from one of those two places.

Tip

A useful habit for every construct answer is to write your test input and expected result in the margin before you write the code ("[5, 8, 3] → 3"). Writing the expected answer first stops you from accepting whatever your code happens to produce.

Checklist

  • To do:

    I know which language version of Paper 2 I will sit, and I write every code answer in it.

  • To do:

    I can read the Python and Java spellings of length, integer division, string comparison and loops without slowing down.

  • To do:

    I can predict when Java integer division drops a fraction.

  • To do:

    I write hand-written code with clear indentation, full headers and the names the question gives.

  • To do:

    I check whether the question says "returns" or "outputs" and answer with return or a print accordingly.

  • To do:

    I know code is marked by features: header, initialisation, loop bounds, condition, update, return.

  • To do:

    I can state the output of a short program and identify a parameter, argument, local variable, counter or accumulator in it.

  • To do:

    I can trace a loop in a trace table, one row per pass, with output written exactly as printed.

  • To do:

    I can find and correct a reset accumulator, a wrong comparison and an off-by-one loop bound.

  • To do:

    I can write exception handling for invalid input and a missing file in my language.

  • To do:

    I can read a text file line by line, split each line, and write results to another file.

  • To do:

    I underline any prohibited built-in function and know the hand-written replacement for len, max, min, sum, searching, sorting, reversing and pop.

  • To do:

    I check every construct answer with a quick trace on a small normal case and an edge case.

Keep your place

In Augment the notes remember where you stopped and which pages you have finished.

Open in Augment

More IB Computer Science notes

  • The pre-released case studyThe page before this.
  • The algorithmic thinking questionThe next page.
  • Computer Science assessmentEach Computer Science paper, the internal assessment and grade boundaries.
  • IB Computer ScienceThe Computer Science syllabus, how it is assessed and every notes page.

Carry on with Computer Science in Augment

With a free account, Augment remembers where you stopped in the notes and which questions you have marked.

Start free