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.
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.
def add_tax(amount):
tax = amount * 0.2 # local, disappears when the function ends
return amount + tax- The program is the house. A variable made in the hallway is global, and any function can read it.
- Each function is a room. Variables made inside it are local and live only in that room.
- Outside code cannot see a room's local variables: asking for one gives a NameError.
Lists, 2D lists and dictionaries
Working with lists
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 False2D lists
A 2D list is a list of lists, forming a grid.
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()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.
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])Step 1 of 5 A list is values in order, reached by their position number.
- Each drawer has a key for a label and one value inside it.
- Assigning to a new key adds a drawer, here form: "10B".
- Ask for a value by its key, and in tests whether a key exists.
Files and building a real program
Reading and writing files
# 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.
If you need to add a record without losing what is there, use "a" for append.
Putting it together
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.
- r reads. The file is only looked at, and it must already exist.
- w writes. Everything already in the file is erased first.
- a appends. New lines go on the end and the old ones are kept.
- with closes the file for you, and \n ends a line.
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.
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
- 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.
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
grid = [[1,2,3],[4,5,6]], what does grid[1][0] give?scores.append(50) do?student["name"] do if student is a dictionary?line.strip().split(",") do?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.
- LCode can be reused rather than written out several times
- LEach subroutine can be tested separately, making errors easier to find
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.
- 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
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.
- 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
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.
board = [["X","O"],["O","X"],["X","X"]]. State what board[2][0] contains and explain how a 2D list is accessed.3 marks- Lboard[2][0] contains X
- LThe first index gives the row
- LThe second index gives the column or position within that row
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.
- 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
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.