◇ OpenCyber Academy
Bachelor's · Chapter 8 · English

Chapter 8 — Programming II

Open, free learning for anyone who wants to protect people and technology. No account is required to read this text or its worked answers.

Chapter 8 — Programming II

Lesson map

Lesson 08 published. Map, example, EX022.

flowchart TD
  N0["Learning outcomes"]
  N1["8.1 Functions for measures"]
  N2["8.2 Reading CSV files"]
  N3["Lab — Reporting rates per branch from a CSV file"]
  N4["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4
  N4 --> EX["Worked example"]
  EX --> Q["Exercise EX022"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["8.1 Functions for measures"]
  N2["8.2 Reading CSV files"]
  N3["Lab — Reporting rates per branch from a CSV file"]
  N4["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX022"]
[Learning outcomes]
    |
    v
[8.1 Functions for measures]
    |
    v
[8.2 Reading CSV files]
    |
    v
[Lab — Reporting rates per branch from a CSV file]
    |
    v
[Synthesis]
    |
    v
[Worked example] --> [Exercise EX022]

Learning outcomes

You will (1) write functions to compute behaviour measures; (2) read data from CSV files; (3) handle errors and document code.

8.1 Functions for measures

Nadia restructures her code into functions. One function computes the reporting rate for a branch, another the share of reports that are genuine. Functions make code reusable and testable, since each can be checked on its own. She gives them clear names and short descriptions of what they take and return. She learns that computing a rate requires guarding against division by zero, because a new branch might have no staff records yet. Small decisions like this prevent errors that could mislead managers reading the results.

8.2 Reading CSV files

Ashcombe's IT team provides a synthetic export of reports as a comma-separated values file. Nadia uses Python's csv module, which handles quoted fields and commas inside text correctly, unlike simple splitting. She reads each row into a dictionary keyed by column name, so the code remains correct even if columns are reordered. She computes reporting rates per branch and the overall share of genuine threats. The lab prints rates for each branch, and she notices that rates vary widely between similar branches.

Lab — Reporting rates per branch from a CSV file

# Reporting rates per branch from a CSV (synthetic).
import csv, io
data = "branch,staff,reports,genuine\nCentral,30,14,3\nRiverside,24,10,4\nHill,15,6,1\nMarket,14,5,1\nOakfield,10,4,2\nMill,8,3,0\nQuay,5,3,1\nElm,6,2,0\nAbbey,8,1,0\nNew,,0,0\n"
def rate(r, s): return 100 * r / s if s else None
skipped = 0; rows = []
for row in csv.DictReader(io.StringIO(data)):
    if not row["staff"]: skipped += 1; continue
    rows.append((row["branch"], rate(int(row["reports"]), int(row["staff"]))))
for b, r in sorted(rows, key=lambda x: -x[1]): print(f"{b}: {r:.0f} per 100 staff")
print("skipped rows:", skipped)

Run with python3 lab_csv.py. Verified output:

Quay: 60 per 100 staff
Central: 47 per 100 staff
Riverside: 42 per 100 staff
Hill: 40 per 100 staff
Oakfield: 40 per 100 staff
Mill: 38 per 100 staff
Market: 36 per 100 staff
Elm: 33 per 100 staff
Abbey: 12 per 100 staff
skipped rows: 1

8.3 Errors and documentation

Nadia adds error handling: rows with missing staff counts are logged and skipped, and the script reports how many rows it skipped so nothing is hidden. She writes a short readme explaining the input format, the measures and their limits. Documentation matters because others may reuse her script, and a measure without a definition can be misread. Dr Prescott reminds her that good code tells readers what it assumes, which is part of honest analysis as much as good engineering. She keeps it short.

Worked example

Nadia writes measure functions with zero guards, reads a CSV with the csv module and documents assumptions and skipped rows.

Synthetic case. Data are synthetic.

Errors and limits

Skipped rows may bias results. Rates for small branches are unstable.

Exercises

Synthesis

Functions, proper CSV reading and documented assumptions make measures trustworthy.

Continue studying — chapter 08 of 40

← Chapter 07 (draft) · Course chapter index · Chapter 09 (draft) →