OpenCyber Academy
Rapid course · Lesson 4 · English
Course code: OCA-003Lesson 04: OCA-003-A004

Guided lab and action plan

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

Lesson map

Lesson 04 published. Map, example, EX057.

flowchart TD
  N0["Learning outcomes"]
  N1["4.1 The sign-up list"]
  N2["Lab — Checking a synthetic café sign-up list for bla"]
  N3["4.2 What the lab finds"]
  N4["4.3 Deciding who to email"]
  N5["4.4 The action plan"]
  N6["4.5 After the course"]
  N7["Concepts — a row is not a permission"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
  N7 --> EX["Worked example"]
  EX --> Q["Exercise EX057"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["4.1 The sign-up list"]
  N2["Lab — Checking a synthetic café sign-up list for bla"]
  N3["4.2 What the lab finds"]
  N4["4.3 Deciding who to email"]
  N5["4.4 The action plan"]
  N6["4.5 After the course"]
  N7["Concepts — a row is not a permission"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX057"]
[Learning outcomes]
    |
    v
[4.1 The sign-up list]
    |
    v
[Lab — Checking a synthetic café sign-up list for bla]
    |
    v
[4.2 What the lab finds]
    |
    v
[4.3 Deciding who to email]
    |
    v
[4.4 The action plan]
    |
    v
[4.5 After the course]
    |
    v
[Concepts — a row is not a permission]
    |
    v
[Worked example] --> [Exercise EX057]

Learning outcomes

You will (1) check a synthetic sign-up list with a short script; (2) decide who may receive the newsletter; (3) write a one-month action plan.

4.1 The sign-up list

Copperleaf's newsletter list was typed from paper sheets by different staff. Some rows have blank emails, some have the same address typed twice with different capitals or spaces and some have no tick in the consent box. Kwame wants to know how many addresses the café may actually email. Ms. Fischer helps him write a short Python script using only the standard library, run on a synthetic list of twelve rows that copies these problems without using any real customer details. Kwame runs it.

Lab — Checking a synthetic café sign-up list for blanks, malformed addresses, duplicates and consent ticks

"""Check a synthetic cafe newsletter sign-up list: blanks, duplicates and consent ticks (stdlib only)."""
rows = [("ana@example.org", "yes"), ("Ana@Example.org ", "yes"), ("", "yes"), ("ben@example.org", ""),
        ("cai@example.org", "yes"), ("dee@example", "yes"), ("eli@example.org", "no"), ("fay@example.org", "yes"),
        ("cai@example.org", "yes"), ("gus@example.org", "yes"), ("", ""), ("hal@example.org", "yes")]
clean = [(e.strip().lower(), c) for e, c in rows]
blank = sum(1 for e, _ in clean if not e)
bad = sum(1 for e, _ in clean if e and ("@" not in e or "." not in e.split("@")[-1]))
seen, dup = set(), 0
for e, _ in clean:
    if e and e in seen: dup += 1
    seen.add(e)
ok = {e for e, c in clean if e and c == "yes" and "." in e.split("@")[-1]}
print(f"rows {len(rows)}; blank email {blank}; malformed {bad}; duplicates {dup}")
print(f"unique valid addresses with a yes tick: {len(ok)}")

Run with python3 lab_signups.py. Verified output:

rows 12; blank email 2; malformed 1; duplicates 2
unique valid addresses with a yes tick: 5

4.2 What the lab finds

The script trims spaces and lowercases each address before checking it. Of twelve rows, two have a blank email, one address is malformed because it has no proper ending after the at sign and two rows are duplicates of addresses already listed. After removing problems, only five unique, valid addresses have a yes tick in the consent box. Kwame is surprised: twelve rows on paper become five people the café can confidently email. He shows the result to Mrs. Adeyemi, who had expected a much larger list.

4.3 Deciding who to email

Ms. Fischer explains that marketing emails need the customer's consent, and the café must be able to show it. Rows with a blank tick or a no tick are not emailed. The malformed address cannot be used anyway. Kwame and Mrs. Adeyemi decide to email the five confirmed addresses and to ask other customers in person to sign the new sheet if they want the newsletter. He records the decision and the date in the notebook. Mrs. Adeyemi agrees with the decision.

4.4 The action plan

Kwame writes a one-month plan with five actions: replace the sign-up sheet with the shorter version including a clear consent box and the date; run the lab check each month on the typed list; delete the forgotten spreadsheet; finish switching to the paid messaging app; and explain the rules at the next staff meeting. Each action has a person and a date. Mrs. Adeyemi approves it, and Kwame pins it beside the rules. He keeps the plan short so that it can actually be finished in a month.

4.5 After the course

At the end of the month, Kwame reviews progress. Four actions are done; the staff meeting moved to the following week. He reflects that small, clear decisions changed more than he expected, and that checking data with a short script made the problem visible to everyone. Ms. Fischer suggests he continue with privacy and data protection, since customer and staff details are central to the café. The next course in this area does exactly that. Kwame thanks Ms. Fischer and enrols the following month.

Worked example

Kwame checks twelve synthetic sign-up rows, finding two blanks, one malformed address and two duplicates, leaving five unique valid addresses with consent, decides to email only those and completes four of five actions in his one-month plan.

Synthetic case. The list is synthetic; outputs come from lab_signups.py; the GDPR is real. This is not legal advice.

Errors and limits

Counting rows instead of unique, valid, consented addresses overstates who may be emailed.

Concepts — a row is not a permission

The script does not ask how many lines are on the paper. It asks which addresses are unique, valid and ticked yes after the address is trimmed and lowercased. The tick itself is not lowercased. Yes is not yes.

Lesson table; scroll horizontally to read all columns →

Lab result on 12 synthetic rows Count May that row be emailed?
Blank email 2 No. There is no address
Malformed address 1 No. dee@example has no proper ending after @
Duplicate rows 2 The repeat is not a second person
Unique valid address with tick yes 5 Yes. This is the only send list
Tick blank or no, including eli@example.org Not in the 5 No. Consent was not given

Twelve rows became five people. Emailing the other seven because they appear on the paper overstates the list. That is the error in this chapter.

Data — the five actions and the one that slipped

Lesson table; scroll horizontally to read all columns →

Action Person Done when Kwame reviewed the month?
Short sheet with a clear consent box and the date Kwame Yes
Run this check each month on the typed list Kwame Yes
Delete the forgotten spreadsheet after the check Kwame Yes
Finish the paid messaging app Mrs. Adeyemi and Kwame Yes
Explain the rules at the staff meeting Kwame No. The meeting moved to the next week

The plan stays five actions. A slipped date is written down. It is not deleted from the plan to make the month look finished.

Decision flow — may this address receive the newsletter?

flowchart TD
  A["One typed row"] --> B["Trim spaces and lowercase the address. Do not change the tick"]
  B --> C{"Is the address blank or malformed?"}
  C -->|Yes| D["Do not email"]
  C -->|No| E{"Is this address already in the send list?"}
  E -->|Yes| F["Duplicate. Do not count a second person"]
  E -->|No| G{"Is the tick exactly yes?"}
  G -->|No| H["Do not email. Ask the person to sign the new sheet"]
  G -->|Yes| I["Include this one address"]
  I --> J["Record the decision and the date in the notebook"]
  H --> J

Worked example — a capital Yes and a regular who ticked no

A row reads Ina@Example.org with the tick Yes. Ina's typed capitals become a usable address, yet the consent box is stored exactly as written. The send rule accepts only yes, so the exact-match test leaves her outside the five. Kwame does not "fix" the tick in the script to raise the count. He asks Ina to sign the new sheet. The same week Mrs. Adeyemi wants to email eli@example.org, a regular who ticked no. Kwame refuses. A regular is not a substitute for the tick. Eli can join by signing the new sheet in person. Both decisions go in the notebook with the date.

Synthetic case. Ina's row and the request to email Eli are invented. The tick rule is the one in lab_signups.py. This is not legal advice.

Apply

Exercises

Worked answers

EX039. Twelve.

EX040. Two blank emails.

EX041. One malformed address.

EX042. Two duplicate rows.

EX043. Five.

EX044. It trims spaces and converts to lowercase.

EX045. No; blank ticks are not treated as consent.

EX046. By signing the new sheet in person if they wish.

EX047. Five actions.

EX048. A clear consent box and the date.

EX049. Explaining the rules at the staff meeting, moved a week.

EX050. Privacy and data protection.

EX057. The script trims and lowercases the address. The tick stays Yes. The row is not emailed, because only an exact yes counts.

EX058. No. Eli may sign the new sheet in person. The refusal is dated in the notebook.