KS3National Curriculum Y9.3 32 min read 10 question quiz 17 exam marks

Python Programming

Subroutines, 2D lists, file handling, dictionaries and structured programs. Everything you need so that GCSE programming feels like continuing rather than starting.

Structuring a program

Subroutines

A subroutine is a named block of code you can call whenever you need it.

Python
def get_valid_mark(prompt):
    # Keep asking until the user enters a mark between 0 and 100
    while True:
        entry = input(prompt)
        if entry.isdigit() and 0 <= int(entry) <= 100:
            return int(entry)
        print("Please enter a whole number between 0 and 100.")

def grade_for(mark):
    if mark >= 70:
        return "Distinction"
    elif mark >= 50:
        return "Pass"
    else:
        return "Fail"

mark = get_valid_mark("Enter the mark: ")
print("Grade:", grade_for(mark))

Notice how the main program at the bottom reads almost like English. That is what good structure buys you.

  • A function returns a value using return
  • A procedure just does something and returns nothing

Local and global variables

A local variable exists only inside the subroutine that created it. A global variable exists everywhere.

Local is almost always better, because nothing else in the program can change it by accident.

Python
def add_tax(amount):
    tax = amount * 0.2      # local, disappears when the function ends
    return amount + tax
Local and global variables as the rooms of a houseScope shown as a house. The whole program is the house, and the variable score equals 10, declared in the hallway, is global: every room, which is to say every function, can read it. Each function is a room with its own local variables on the wall: bonus has extra equals 5 and reset has temp equals 0. A local variable exists only inside its own room and is gone when the function ends. The code on the right defines bonus, which prints score plus extra, giving 15, and then tries to print extra from outside, which fails with a NameError because extra is not visible out there. In the picture a person standing outside the house asks for extra and is refused.The program: global scopescore = 10global: every function can read itbonus()extra = 5local: only inthis roomreset()temp = 0local: only inthis roomprint(extra)NameErrorthe room's variables are not visible from outsidescope.py1score = 10          # global23def bonus():4    extra = 5       # local5    print(score + extra)67bonus()             # 158print(extra)        # erroroutput15NameError: name 'extra' is not defineda function can read a global variablea local variable dies when the function ends123
  1. The program is the house. A variable made in the hallway is global, and any function can read it.
  2. Each function is a room. Variables made inside it are local and live only in that room.
  3. Outside code cannot see a room's local variables: asking for one gives a NameError.
Make variables local by default. Reach for a global only when many functions truly share it.

Lists, 2D lists and dictionaries

Working with lists

Python
scores = [45, 78, 12, 90, 33]

print(sum(scores), max(scores), min(scores), len(scores))
print(sorted(scores))          # a sorted copy
scores.sort()                  # sorts in place
scores.append(60)
scores.insert(0, 5)            # insert at the start
scores.remove(12)              # remove the value 12
print(scores.index(90))        # position of 90
print(90 in scores)            # True or False

2D lists

A 2D list is a list of lists, forming a grid.

Python
board = [["X", "O", "X"],
         ["O", "X", "O"],
         ["X", "O", "X"]]

print(board[1][2])       # row 1, column 2, which is "O"

for row in board:
    for cell in row:
        print(cell, end=" ")
    print()
Row first, then column

board[1][2] means row 1, column 2. Getting these round the wrong way is one of the most common errors, and on a non square grid it causes a crash.

Dictionaries

A dictionary stores pairs of keys and values, which is far more readable than remembering that index 3 was the score.

Python
student = {"name": "Aisha", "year": 9, "score": 82}

print(student["name"])          # Aisha
student["score"] = 90           # change a value
student["house"] = "Blue"       # add a new pair

for key in student:
    print(key, "=", student[key])
Lists, 2D lists and dictionariesThree ways to store more than one value. A list holds values in order, reached by position, so for scores equals forty five, seventy eight, twelve, ninety and thirty three, scores index zero is forty five, scores index three is ninety, and len of scores is five. Because counting starts at zero, five values occupy indexes zero to four and asking for index five raises an IndexError. A 2D list is a list of lists forming a grid, so a noughts and crosses board is three rows of three, and board index one index two means row one then column two, which is O; getting row and column the wrong way round is the most common error in the topic. A dictionary stores pairs of keys and values, so student holds name Aisha, year nine and score eighty two, reached by name rather than by position, and a new pair such as house Blue can simply be added. Use a list for a set of values you will sort or total, a 2D list for a grid, and a dictionary whenever a position number would otherwise need a comment explaining it.Three ways to hold more than one value45[0]78[1]12[2]90[3]33[4]scores = [45, 78, 12, 90, 33]scores[0] is 45 scores[3] is 90 len(scores) is 5Order is kept, duplicates are allowed, and you can add to or remove from either end.sum, max, min, len, sorted, append, insert, remove, index45[0]78[1]12[2]90[3]33[4]scores = [45, 78, 12, 90, 33][3]The fourth value lives at index 3scores[5] does not exist: five values occupy indexes 0 to 4.IndexError means you asked for a position that is not there.board = [["X","O","X"], ["O","X","O"], ["X","O","X"]]row 0XOXrow 1OXOrow 2XOXcol 0col 1col 2board[1][2] is "O": row first, then columnSwapping them round is the most common error in the whole topic.student = {"name": "Aisha", "year": 9, "score": 82}name"Aisha"year9score82KEYVALUEstudent["name"] gives "Aisha"student["house"] = "Blue" adds a new pairstudent["score"] says what it means. scores[2] does not.A set of scores you will sort and totallistA noughts and crosses board, or a seating plan2D listOne person's name, year and score togetherdictionaryAnything where you would otherwise write a commentdictionaryA dictionary costs you nothing and makes the code readable six months later.
If you find yourself writing a comment to remember what index 3 was, you wanted a dictionary.
A dictionary is a cabinet of labelled drawersA Python dictionary drawn as a filing cabinet. Each drawer has a label, which is the key, and holds one value: the drawer labelled name holds Asha, the drawer labelled age holds 15, and the drawer labelled form, added by the second line of code, holds 10B. To find a value you ask for it by key, so student with the key age gives 15, and the test form in student is True because a drawer with that label exists. A fourth drawer labelled club is shown dashed because it has not been added: asking for a key that is not there is an error. A list is found by position, scores at index 2, but a dictionary is found by key, student at key age, and the order of the drawers does not matter.dict.py1student = {"name": "Asha", "age": 15}2student["form"] = "10B"3print(student["age"])4print("form" in student)output15TrueList or dictionary?listfind by positionscores[2]dictionaryfind by keystudent["age"]a key is a label you choose, so the order does not mattername"Asha"age15form"10B"clubnot here123
  1. Each drawer has a key for a label and one value inside it.
  2. Assigning to a new key adds a drawer, here form: "10B".
  3. Ask for a value by its key, and in tests whether a key exists.
Use a list when position matters and a dictionary when a name does.

Files and building a real program

Reading and writing files

Python
# Write, which erases anything already in the file
with open("scores.txt", "w") as file:
    file.write("Aisha,82
")
    file.write("Ben,64
")

# Append, which adds without deleting
with open("scores.txt", "a") as file:
    file.write("Chloe,91
")

# Read
with open("scores.txt", "r") as file:
    for line in file:
        name, score = line.strip().split(",")
        print(name, "scored", score)

Using with open(...) closes the file automatically, even if something goes wrong.

Write mode erases the file

If you need to add a record without losing what is there, use "a" for append.

Putting it together

Python
def load_scores(filename):
    scores = {}
    try:
        with open(filename, "r") as file:
            for line in file:
                name, value = line.strip().split(",")
                scores[name] = int(value)
    except FileNotFoundError:
        print("No score file yet, starting fresh.")
    return scores

def save_scores(filename, scores):
    with open(filename, "w") as file:
        for name in scores:
            file.write(name + "," + str(scores[name]) + "
")

def show_top(scores):
    if len(scores) == 0:
        print("No scores recorded.")
        return
    best = max(scores, key=scores.get)
    print("Top score:", best, "with", scores[best])

scores = load_scores("scores.txt")
scores["Dev"] = 77
show_top(scores)
save_scores("scores.txt", scores)

This program has four clear jobs, each in its own subroutine, and it handles the case where the file does not exist yet. That is the difference between code that works on your machine and code that works.

Reading, writing and appending to a text fileThree ways to open a text file, one card each. Opening with mode r reads the file: the program looks at the lines, nothing in the file changes, and it is an error if the file does not exist. Opening with mode w writes: it creates the file if it is missing, but if it exists everything in it is erased first, so a file that held two lines ends up holding only the new line. Opening with mode a appends: the new line is added to the end and the old lines are kept. The code below uses the with statement, which closes the file automatically, and writes the line Tia comma 51 followed by a newline character. Always close a file, because unwritten data may stay in a buffer and never reach the disk."r" readbeforeAsha,42Tom,37"w" writebeforeAsha,42Tom,37"a" appendbeforeAsha,42Tom,37programreads each linethe file is not changederror if it does not existTia,51erases what was therecreates the file if missingAsha,42Tom,37Tia,51adds to the endkeeps what was theresave.py1with open("scores.txt", "a") as f:2    f.write("Tia,51\n")with closes the file for you\n starts a new linea is safer than w for addingalways close a file, or the last lines may never reach the disk1234
  1. r reads. The file is only looked at, and it must already exist.
  2. w writes. Everything already in the file is erased first.
  3. a appends. New lines go on the end and the old ones are kept.
  4. with closes the file for you, and \n ends a line.
If you mean to add to a file, open it with a. Opening it with w by mistake wipes it.

Key terms you must be able to define

Subroutine
A named block of code that performs a task and can be called from anywhere in a program.
Function
A subroutine that returns a value.
Procedure
A subroutine that performs a task without returning a value.
Parameter
A value passed into a subroutine so it can do its work.
Local variable
A variable that exists only inside the subroutine where it was created.
Global variable
A variable available throughout the whole program.
2D list
A list of lists, forming a grid accessed by row and column.
Dictionary
A data structure storing pairs of keys and values.
Append mode
Opening a file so new data is added to the end without erasing existing content.

Flashcards

Say the definition out loud before you flip the card. Retrieving it from memory is what builds recall, reading it again is not.

DefineSubroutine
AnswerA named block of code that performs a task and can be called from anywhere in a program.
DefineFunction
AnswerA subroutine that returns a value.
DefineProcedure
AnswerA subroutine that performs a task without returning a value.
DefineParameter
AnswerA value passed into a subroutine so it can do its work.
DefineLocal variable
AnswerA variable that exists only inside the subroutine where it was created.
DefineGlobal variable
AnswerA variable available throughout the whole program.
Define2D list
AnswerA list of lists, forming a grid accessed by row and column.
DefineDictionary
AnswerA data structure storing pairs of keys and values.

Reach the top grade on this topic

The top level in Year 9 Python is about writing programs that survive contact with a real user.

Break the program into subroutines before you start typing. If you can name four jobs the program has to do, you have four subroutines and the code almost writes itself.

Handle the awkward cases. What if the file does not exist? What if the list is empty? What if the user types letters? A program that only works when everything goes right is not finished.

Comment why, not what. count = count + 1 # add one to count is useless. # skip the header row is worth having.

  • Write a program using at least three subroutines with parameters and return values
  • Read from and write to a file, choosing the correct mode
  • Use a 2D list to represent a grid and loop through it correctly
  • Validate every piece of input before the program uses it

Mistakes that cost marks here

Avoid these
  • Opening a file in write mode when the existing data needs keeping.
  • Getting row and column the wrong way round in a 2D list.
  • Forgetting to use return, so the function calculates an answer and throws it away.
  • Assuming a file exists, so the program crashes the first time it is run.
  • Writing one long program with no subroutines, which becomes impossible to debug.
Fun fact

Reading someone else's code is a genuine skill and it is harder than writing your own. Professional programmers spend far more time reading than writing, which is exactly why clear names and comments matter so much.

Knowledge check

0 of 10 answered
1What is the difference between a function and a procedure?
2In grid = [[1,2,3],[4,5,6]], what does grid[1][0] give?
3Which file mode adds to a file without erasing what is already there?
4What does a dictionary store?
5Why are local variables usually preferred to global ones?
6What does scores.append(50) do?
7What does student["name"] do if student is a dictionary?
8Why should a program be split into subroutines?
9What does line.strip().split(",") do?
10What happens if a program opens a file that does not exist in read mode?
Score 0 / 10

Exam-style questions

Five written questions in the style of the real paper. Write a full answer, then let the marker check it against the mark scheme.

17 marks
1State two reasons why a programmer would use subroutines.2 marks
State

Mark scheme0 / 2
  • LCode can be reused rather than written out several times
  • LEach subroutine can be tested separately, making errors easier to find
Model answer

Subroutines let the same code be written once and then called wherever it is needed, so it does not have to be repeated and any change only has to be made in one place. They also make a program much easier to develop and test, because each subroutine does one clearly defined job and can be tested on its own until it is known to work.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
2Write a Python function that takes a list of numbers as a parameter and returns the average.4 marks
Write

Mark scheme0 / 4
  • LDefines a function with a parameter
  • LCalculates the total of the list
  • LDivides by the number of items
  • LUses return to send the answer back
Model answer

def average(numbers): total = sum(numbers) return total / len(numbers) The function takes the list as a parameter called numbers. The built in sum function adds every value in the list, and dividing that total by len(numbers), which gives how many items there are, produces the mean. The return statement sends the answer back to the code that called the function, so it can be printed or stored.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
3Explain the difference between opening a file in write mode and in append mode, and state when each should be used.3 marks
Explain

Mark scheme0 / 3
  • LWrite mode erases the existing contents of the file
  • LAppend mode adds to the end without deleting existing data
  • LUse write to start a new file and append to add a record to existing data
Model answer

Opening a file in write mode erases everything already in it before anything new is written, so all previous content is lost. Opening in append mode leaves the existing content untouched and adds anything written to the end of the file. Write mode should be used when the file is being created from scratch or when the whole contents are being replaced, for example saving a complete set of records back to disk. Append mode should be used when a single new record is being added to data that must be kept, such as adding one new high score to an existing list.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
4A program uses board = [["X","O"],["O","X"],["X","X"]]. State what board[2][0] contains and explain how a 2D list is accessed.3 marks
State

Mark scheme0 / 3
  • Lboard[2][0] contains X
  • LThe first index gives the row
  • LThe second index gives the column or position within that row
Model answer

board[2][0] contains "X". A 2D list is a list whose items are themselves lists, so it behaves like a grid. The first index selects which inner list, which corresponds to the row, and the second index selects a position within that inner list, which corresponds to the column. Here index 2 selects the third row, which is ["X","X"], and index 0 selects the first item in it, which is "X". Because both indexes start at 0, care is needed not to swap them round.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
5Write a program that asks the user for a name and a score, then adds them to a file called scores.txt without deleting the existing contents.5 marks
Write

Mark scheme0 / 5
  • LAsks for the name
  • LAsks for the score
  • LOpens the file in append mode
  • LWrites the name and score to the file
  • LCloses the file, or uses with open
Model answer

name = input("Enter the name: ") score = input("Enter the score: ") with open("scores.txt", "a") as file: file.write(name + "," + score + "\n") print("Score saved.") The file is opened in append mode, which is essential here because write mode would delete every score already stored. The name and score are written on one line separated by a comma so they can be split apart when the file is read back, and the newline character puts each record on its own line. Using with open means the file is closed automatically once the block finishes, even if an error occurs.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
Machine mark 0 / 17