VIEW THIS AS

Auto mode follows the Route Engine until you choose a viewpoint.

YOU ARE HERE

ROUTE CHECK

CONNECTED TO

WHAT NEXT

Use the canonical route for this room, or HELP if you are unsure.

Ministry of Education V3.0 Reference 342 | Computing Manual Algorithms: Search, Accumulate, Extract and Split

Student holds a blue notebook and raises a fist while standing in a bright corridor.

Did you know that a program can give the wrong maximum value even if every comparison it makes is mathematically correct? A common beginner’s mistake is starting the ‘largest so far’ variable at zero. That works for positive lists, but for [−8, −3, −11] it incorrectly returns zero, a number which does not even appear in the list. Algorithm design is about specifying the problem, choosing an invariant that stays true during the loop, handling unusual inputs and testing the result—not merely typing Python quickly.

This independent Ministry of Education V3.0 reference teaches 2027 G3 Computing K349 Algorithm Design, focusing on manual list algorithms: finding minimum and maximum without min()/max(), calculating total and mean without sum(), searching positions in lists and strings without index()/find(), extracting items meeting a condition, splitting a string by a delimiter without split(), and developing solutions incrementally. It includes traceable code, twenty-six original worked cases, a twelve-stage Specify–Trace–Test protocol, an eduKate three-pupil workshop and independent challenges.

The sample records, names and identifiers below are fictional educational data. No real student grades or passwords are needed. The code deliberately shows explicit loops, because the syllabus tests understanding of the underlying algorithms; using a built-in function may be good practice in professional software but may fail to meet a school question that explicitly prohibits it.

A 50-second learning route

  • State what the algorithm should return: first position, all positions, smallest value, mean, extracted items or text fields.
  • Choose the proper starting state: for maximum/minimum initialise from a real first item, or define an empty-list policy.
  • Make one pass through the data and update only when the specified condition is met.
  • Trace each iteration by hand and predict the final output before running the code.
  • Test normal, boundary and error cases, then solve a new variant without relying on the previous data.

1. The Difference Between Writing Code and Designing an Algorithm

An algorithm is a finite, precise series of steps to solve a problem under stated inputs. It can be described by natural language, a flowchart or code. A computer executes the chosen instructions, not the developer’s intention. If a student writes an incorrect initial condition, Python faithfully produces a result based on that mistake. Algorithmic literacy therefore begins with a clear contract: what counts as valid input, what output is required, and what should happen at special boundaries.

2. Exact 2027 G3 Computing K349 Requirements

The official 2027 G3 Computing K349 syllabus, Module 2.5 Algorithm Design, especially 2.5.1, explicitly requires algorithms for finding minima and maxima without min()/max(), sum and average without sum(), searching item or character positions without index()/find(), extracting items based on criteria, and splitting strings by a delimiter without split(). It also requires modular and incremental development, manual small-instance reasoning and adapting familiar algorithms to new problems. The syllabus does not list bubble sort, merge sort or binary search as compulsory named algorithms in these outcomes; they should not be imposed as mandatory topics simply because they appear in other computing courses.

3. Every Search Question Has a Hidden Contract

If a list contains the target twice, does the question ask for the first occurrence, the last occurrence, all indices or simply whether the target exists? These are distinct algorithms even though they all compare items against the same target. For a list [4,7,4], a first-index search for 4 returns 0, while an all-index search returns [0,2]. A student must specify zero-based indexing and missing-item behaviour.

4. Minimum and Maximum Require Real Initial Values

For a nonempty numeric list, initialise the candidate from the first element. Then compare each later item and replace the candidate when a more extreme value appears. This creates a useful invariant: after processing the first k values, the candidate equals the maximum or minimum of those k values. For an empty list there is no first element, so the function must reject it or return an explicitly documented special result.

5. Totals and Means Are Accumulations

To calculate a list’s total without sum(), start an accumulator at zero and add each value exactly once. For the mean, count how many numeric items were included and divide total by count after completing the scan. A nonempty-input condition is required before division. Unlike maximum, starting a total at zero is correct for negative numbers because zero is the addition identity, not an assumed candidate from the dataset.

6. Searching Characters Is Similar to Searching List Items

Python strings have indexed characters. A manual search can loop over positions and compare each character with a target. The algorithm must decide whether to return the first position or collect all. The built-in .find() method is convenient in ordinary code, but a ‘without find’ syllabus question requires the explicit comparison sequence.

7. Extraction Changes Selection, Not Ordering Automatically

A filter that selects values meeting a criterion should usually preserve the original order unless the problem says otherwise. Selecting positive values from [0, −4, 6, 2, −1] gives [6,2]; it does not require sorting or replacing negative values with zero. A criterion such as greater-than-or-equal to 10 also differs from strictly greater than 10 at the boundary.

8. Manual String Splitting Demands Boundary Decisions

A delimiter such as a comma marks field boundaries. A manual split scans each character, accumulates the current field, appends the field when it meets the delimiter, and appends the final field after the loop. Two consecutive delimiters can produce an empty field, and a trailing delimiter can do the same. Whether to retain empty fields depends on the declared specification.

9. Eight Rooms of Algorithmic Reasoning

Room one defines valid input and output. Room two handles empty or missing cases. Room three chooses an initial state. Room four states the loop’s invariant. Room five selects the comparison and update. Room six traces at least one pass by hand. Room seven tests duplicates and boundaries. Room eight transfers the logic to unfamiliar data without using a forbidden convenience method.

10. Twelve-Stage Specify–Trace–Test Protocol

Stage 1 — Write the input contract

Specify list of numbers, character sequence or delimited text. For minimum and mean, decide what the algorithm should do if the input is empty.

Stage 2 — Write the expected output contract

Should the function return a numeric result, an index, a list of indices, a filtered list or a list of text fields? Do not postpone this choice until the code is half written.

Stage 3 — Solve a three-item case by hand

Use values such as [−8,−3,−11]. Identify the largest or matching positions manually and record the comparisons needed.

Stage 4 — Choose safe initial variables

For a maximum, use values[0] after checking nonempty input. For a total, use zero. For a search collecting all matches, start an empty output list.

Stage 5 — Decide the exact iteration range

For a max where first item is the initial candidate, compare items from index one. For a search that might match at index zero, inspect the whole list.

Stage 6 — Write the update condition

Use greater-than for a new maximum, less-than for minimum and equality for an exact match. A misplaced equals sign can change duplicate or boundary behaviour.

Stage 7 — Trace the invariant

At each loop step, explain what the candidate or output list represents. This gives a correctness reason rather than only a final number.

Stage 8 — Handle special cases deliberately

Empty list, all-negative list, repeated targets, target absent, delimiter at start and end, and no delimiter all deserve individual checks.

Stage 9 — Implement with permitted Python features

Use variables, for/while, conditions, strings and lists from the syllabus. Follow a question’s restriction against min, max, sum, index, find or split.

Stage 10 — Compare predicted and observed results

Compute the expected answer before executing. If they differ, use a trace table or selected print statements to locate the earliest state that diverged.

Stage 11 — Explain efficiency at a suitable level

One full pass inspects up to n values in a list of length n; describing that work is reasonable, but advanced complexity theory is not required by the named Module 2.5 outcomes.

Stage 12 — Adapt the algorithm to another task

Change largest to smallest, first match to all matches, or comma to pipe delimiter. The student should explain precisely which lines and invariants change.

11. Original Fictional Dataset: The Equipment Return Log

Consider a fictional equipment room recording items returned each day: [−2, −7, −1, −4] could represent signed corrections to a running balance, rather than actual negative counts of children. If a function is asked for the highest value, it should return −1; a zero initial candidate would be wrong. A different list [12, 9, 12, 7, 12] provides three occurrences of the target 12 at indices 0, 2 and 4, showing why a first-match algorithm differs from an all-match algorithm.

The original text record ‘A01,B03,,C02,’ includes two empty fields under a literal comma-splitting contract, one between consecutive commas and one after the trailing comma. The expected output is [‘A01′,’B03′,”,’C02’,”]. This is a deliberately constructed input so pupils can test their own manual splitter without disclosing personal information.

12. Five Working Python Algorithm Cores

Maximum of a Nonempty List

def manual_max(values):
    if len(values) == 0:
        return None
    best = values[0]
    for item in values[1:]:
        if item > best:
            best = item
    return best

print(manual_max([-8, -3, -11]))  # -3

The invariant is that best is the greatest value already inspected. Beginning at values[0] protects all-negative lists; returning None for empty input is a deliberate teaching contract, not a compulsory choice for every problem.

Manual Total and Mean

def manual_mean(values):
    if len(values) == 0:
        return None
    total = 0
    count = 0
    for item in values:
        total = total + item
        count = count + 1
    return total / count

print(manual_mean([4, 7, 10]))  # 7.0

Each item is added exactly once, and count tracks the number of inspected items. Separating addition and division makes it easier to identify a loop that accidentally changes count twice.

Search for Every Matching Position

def all_positions(values, target):
    answer = []
    for i in range(len(values)):
        if values[i] == target:
            answer.append(i)
    return answer

print(all_positions([12, 9, 12, 7, 12], 12))  # [0, 2, 4]

The output grows whenever an index matches the target. It does not stop after the first match and it returns an empty list for no matches; this is not the same contract as returning −1 for a failed first-index search.

Extract Values Satisfying a Criterion

def positive_items(values):
    answer = []
    for item in values:
        if item > 0:
            answer.append(item)
    return answer

print(positive_items([0, -4, 6, 2, -1]))  # [6, 2]

The condition is strictly greater than zero; a zero does not qualify. Original order is retained because answer.append(item) follows the input sequence.

Split a String Manually on a Delimiter

def manual_split(text, delimiter):
    if len(delimiter) != 1:
        return None
    fields = []
    current = ""
    for char in text:
        if char == delimiter:
            fields.append(current)
            current = ""
        else:
            current = current + char
    fields.append(current)
    return fields

print(manual_split("A01,B03,,C02,", ","))
# ['A01', 'B03', '', 'C02', '']

The function intentionally requires one delimiter character, retains empty fields, and appends the last field. A full production parser would need a more complex contract for quoted commas or multi-character delimiters; neither is assumed here.

13. Twenty-Six Worked Algorithmic Cases

Worked Example A — A — Maximum with positive values

Scan [2, 7, 4]. Initialise best to 2, update to 7 and retain 7. The maximum is 7. Starting at a real first item gives the same result for positive and negative lists.

Worked Example B — B — Maximum with negatives

For [−8,−3,−11], initialise best=−8, then update to −3 and keep it. A zero initial candidate incorrectly reports a value absent from the input.

Worked Example C — C — Minimum with positive values

Scan [9,5,7], starting best=9. Update to 5, then keep it. The result 5 is the minimum of the actual list, not a default assumption.

Worked Example D — D — Minimum with negatives

For [−4,−12,−6], best starts at −4 and becomes −12. Comparing signed numbers correctly means −12 is smaller than −6.

Worked Example E — E — Single-item list

For [42], manual maximum and minimum both return 42 without further comparisons. This is a valid nonempty boundary case.

Worked Example F — F — Empty-list policy

For [], there is no real minimum or maximum. In the supplied teaching code the function returns None. Another specification might require an error, but the choice must be explicit.

Worked Example G — G — Total including negatives

For [5,−3,2], start total=0, then total becomes 5, 2, 4. Zero is a correct additive identity even though it might be an incorrect starting maximum.

Worked Example H — H — Mean of three values

The list [4,7,10] has total 21 and count 3, so mean 7. Averages must divide by actual item count, not by a guessed capacity.

Worked Example I — I — Mean of an empty input

Dividing total zero by item count zero is undefined. Reject or specially report an empty list before division rather than create a runtime failure without explanation.

Worked Example J — J — First search match

In [8,3,8], the first index of target 8 is 0. A first-match search can return immediately at that point, but such an early return would be wrong for an all-occurrences task.

Worked Example K — K — All search matches

In the same [8,3,8], all matching zero-based indices are [0,2]. The output contract dictates continued scanning after the first hit.

Worked Example L — L — No match

Searching [5,4,3] for 9 yields no matching positions. The all-positions function returns [], while a separate first-index design might return −1.

Worked Example M — M — Target at the last index

For [1,3,5,7], target 7 occurs at index 3. A range ending one step too early will miss it, making this an essential boundary test.

Worked Example N — N — String character search

The string ‘banana’ contains ‘a’ at indices 1,3,5. A manual character scan should return all three if the task asks for every occurrence.

Worked Example O — O — Search is case-sensitive by default

In the string ‘AaA’, an exact comparison against ‘a’ matches only index 1. Convert case deliberately only if the specification requires case-insensitive matching.

Worked Example P — P — Extract positive values

The criterion >0 applied to [0,−4,6,2,−1] produces [6,2]. The zero is excluded because the inequality is strict.

Worked Example Q — Q — Extract at least a threshold

With threshold 10, values [10,9,11] produce [10,11] for condition >=10. A boundary value of 10 distinguishes this from >10.

Worked Example R — R — Preserve order when filtering

From [4,8,2,10], keeping even numbers yields the same order [4,8,2,10]. Filtering alone does not sort, even though the list appears untidy.

Worked Example S — S — Extract characters

From ‘A2B3′, keeping only digit characters under a stated digit criterion yields ’23’. Building the new string one accepted character at a time avoids relying on .split() or indexing helpers.

Worked Example T — T — Delimiter at the start

Splitting ‘,A’ on commas with empty fields preserved gives [”, ‘A’]. Omitting the initial empty field changes the chosen contract.

Worked Example U — U — Delimiter at the end

Splitting ‘A,’ produces [‘A’,”]; forgetting the final fields.append(current) drops the trailing empty field.

Worked Example V — V — Two delimiters together

Splitting ‘A,,B’ gives [‘A’,”,’B’]. The empty middle field is a deliberate consequence of consecutive separators.

Worked Example W — W — No delimiter

Splitting ‘ABC’ on comma produces [‘ABC’], a one-element list. The absence of a delimiter is not an error under the declared contract.

Worked Example X — X — Counting repeated matches

The list [12,9,12,7,12] has three matches at [0,2,4]. The index list’s length is three, which can be counted without confusing count with location.

Worked Example Y — Y — Trace a loop’s invariants

A running sum should equal the total of items processed so far. After reading first two values [3,−1], it should be 2. Any trace row showing 4 identifies an earlier wrong update.

Worked Example Z — Z — A modular redesign

A fictional tool must return all temperatures above 30. Reuse the filtered-items approach with the criterion >30, test 30 as a boundary, and preserve original observation order.

14. Why One-By-One Search Is Not the Same as Binary Search

Linear search inspects elements in sequence until a match or the end. The K349 algorithm outcome explicitly requires this kind of manual item or character search, without index() or find(). Binary search relies on a sorted sequence and additional interval logic; it may be an interesting enrichment topic but is not named as a compulsory algorithm in the 2027 Module 2.5.1 listing. Students should meet the actual specification before learning optional alternatives.

15. Two Bad Initialisations and Their Repairs

For maximum, beginning at zero is unsafe because all items may be negative. For minimum, beginning at a huge made-up sentinel is also unnecessary when the real first element is available. Starting from values[0] establishes a candidate that belongs to the dataset. A running total is different: zero is a mathematically valid identity for addition. Teaching the reason for each initial value is more transferable than memorising one template for every algorithm.

16. Trace Tables Are Evidence of Correctness

Make columns for iteration number, item or index read, comparison result and updated candidate or output. Trace a four-item case and explain what remains true after each step. For the max example [−8,−3,−11], start best −8, update at −3 and keep −3 at −11. If a pupil records an incorrect candidate during the trace, that is the first repair node; changing the final answer without fixing the process will not transfer.

17. Why the Manual Split Algorithm Needs a Final Append

Each delimiter causes the accumulated current field to be stored and cleared. The last field has no following delimiter in the ordinary case, so it must be appended after the loop. An end delimiter instead leaves an empty current string which is also appended under the chosen contract. This simple detail is an excellent test of whether a student has truly traced a loop rather than guessed the expected output.

18. Normal, Boundary and Error Cases

  • For a maximum: a mixed-sign list, a single item, all-negative items and empty input.
  • For a search: target first, target last, repeated target, no target and an empty sequence.
  • For a manual split: one delimiter, none, adjacent delimiters, leading/trailing delimiters and an invalid delimiter length.
  • For extraction: item exactly on the comparison threshold, immediately below, immediately above, and no qualifying items.
  • For mean: one numeric item, multiple signed items and empty input before dividing.

19. A Ninety-Minute Three-Pupil Tutorial Route

  • 10 minutes: retrieval of loop variables, index positions and valid-input rules.
  • 15 minutes: manually derive maximum and total using short lists, deliberately including all-negative numbers.
  • 20 minutes: write and trace the maximum, average and all-positions functions without banned convenience calls.
  • 20 minutes: rotate three students through filter, character search and manual splitting cases.
  • 15 minutes: individually solve a fresh no-match or boundary-case problem with a predicted trace and output.
  • 10 minutes: identify the first incorrect state, repair it and explain a changed independent input.

20. eduKate Depth–Load–Transfer Diagnostic

Depth: Can the learner explain why max starts from the first element but sum starts from zero? Load: Can they manage loop indices, repeated matches, delimiter boundaries and validation without mixing output contracts? Transfer: Can they change a first-position search into an all-position search for an unfamiliar string? The Clementi three-pupil small-group standard guides diagnosis, repair, practice and independent proof.

21. Misconception Ledger

  • Initialising maximum at zero works for all lists: false when all numbers are negative.
  • A found item always means stop: false when the contract requests every match.
  • An index and an item value are interchangeable: false; a list position and stored entry are distinct.
  • Filtering automatically sorts: false; iteration preserves order unless separate sorting is specified.
  • A manual split may omit its final field: false under the specified retain-all-fields contract.
  • Passing one ordinary input is proof of correctness: false; special cases and input validity remain untested.

22. Parent and Tutor Progress Questions

Ask the pupil to state the expected return before writing code; ask what the candidate represents after each iteration; ask which banned method the question excludes; and ask how the function behaves with no data. A student who can explain one new test without being told the answer shows more genuine understanding than one who types an earlier memorised Python block correctly.

23. Frequently Asked Questions

Why not use Python’s max() or min()?

The 2027 K349 algorithm-design outcome explicitly asks students to know how to obtain extrema without those built-ins in specified tasks.

Should maximum start at zero?

Not generally. Initialise from the first actual item of a nonempty list so negative-only data are handled.

What about an empty list?

A maximum or mean is undefined for an empty list; decide whether to return a documented special value or reject the input.

Does the syllabus require bubble sort?

The named K349 Module 2.5.1 outcomes focus on extrema, totals, searching, extraction and splitting; bubble sort is not listed as a compulsory named algorithm there.

How do I find every repeated match?

Scan every index and append positions which match the target; do not return after the first match.

Why is Python indexing important?

Python uses zero-based list and string indexing in these examples; the first position is 0, not 1.

Can the search return −1 on failure?

Yes, for an explicitly specified first-index contract; an all-indices contract can reasonably return an empty list instead.

Why append after the splitting loop?

The final field otherwise disappears when no delimiter follows it.

Is filtering the same as sorting?

No. Filtering selects items by a criterion, usually preserving their original order.

What is the best proof of learning?

An independently written and traced solution for a new set of input, boundary and error conditions.

24. Independent Depth and Transfer Practice

Practice 1 — All-negative maximum

Write a maximum algorithm for [−11,−4,−9] without max(); show candidate updates and result −4.

Practice 2 — Manual mean

Use an explicit accumulator and count to find the mean of [−2,4,7,3], which is 3, without sum().

Practice 3 — First vs every occurrence

Search [5,3,5,5] for 5; design first match 0 and all indices [0,2,3], then explain why the loops differ.

Practice 4 — Find characters

Scan ‘assessment’ for ‘s’ and return every zero-based index. Check that repeated letters are not lost.

Practice 5 — Extract at a boundary

From [9,10,11,0] keep values at least 10. Explain why 10 qualifies but 9 does not.

Practice 6 — Manual delimiter split

For ‘A,,B,’ and comma delimiter, expect [‘A’,”,’B’,”]; explain each append action.

Practice 7 — Empty policy

Decide an explicit safe result for calculating a mean of [], justify it and show that division by zero does not occur.

Practice 8 — Independent transfer problem

Design a function returning all days with rainfall above a chosen nonnegative threshold. Define type validation, ordering, equality and the empty-result behaviour before coding.

25. Closing Principle

Good algorithm design begins before code: define the input and result, choose an invariant, initialise safely, scan deliberately, and test the boundaries. Small loops can reveal the whole reasoning structure of a useful program. Independent understanding is evident when a pupil can modify one of these algorithms for a new problem without leaning on a copied worked example.

Helpful Reading and Official Sources

Read Reference 325 — Python Functions, Reference 310 — Strings, Lists and Files, Reference 203 — Computational Thinking, the MOE V3.0 library and the Clementi teaching standard. Confirm the examined algorithms in 2027 G3 Computing K349, Module 2.5, page 8. For pedagogical consultation questions, use eduKate’s main enquiry route without assuming any particular course has available places.

Reference Navigation

Previous: Reference 341 · MOE V3.0 Library.