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
- EX057 — Capital Yes. What does the script do to
Ina@Example.organd to the tickYes, and is that row emailed?Show marking criteria
Rubric: 3 = the address is trimmed and lowercased; the tick staysYes; the row is not emailed because onlyyescounts;; 2 = the address is cleaned and the row is not emailed;; 1 = one of those;; 0 = none. - EX058 — Regular who ticked no. May
eli@example.orgbe emailed because Eli is a regular, and what is Eli offered instead?Show marking criteria
Rubric: 3 = no; Eli may sign the new sheet in person; the refusal is dated in the notebook;; 2 = no, without the sheet;; 1 = yes;; 0 = none.
Exercises
- EX039 — Lab rows. How many rows does the synthetic list have?
Show marking criteria
Rubric: 3 = twelve;; 2 = partly correct;; 1 = wrong;; 0 = none. - EX040 — Blank emails. How many rows have a blank email?
Show marking criteria
Rubric: 3 = two;; 2 = partly correct;; 1 = wrong;; 0 = none. - EX041 — Malformed count. How many addresses are malformed?
Show marking criteria
Rubric: 3 = one;; 2 = partly correct;; 1 = wrong;; 0 = none. - EX042 — Duplicate rows. How many duplicate rows does the script find?
Show marking criteria
Rubric: 3 = two;; 2 = partly correct;; 1 = wrong;; 0 = none. - EX043 — Emailable total. How many unique valid addresses have a yes tick?
Show marking criteria
Rubric: 3 = five;; 2 = partly correct;; 1 = wrong;; 0 = none. - EX044 — Normalising steps. What does the script do before checking each address?
Show marking criteria
Rubric: 3 = trims spaces and lowercases;; 2 = both;; 1 = one;; 0 = none. - EX045 — Blank tick decision. Are rows with a blank tick emailed?
Show marking criteria
Rubric: 3 = no;; 2 = partly correct;; 1 = yes;; 0 = none. - EX046 — Other customers. How will other customers join the newsletter?
Show marking criteria
Rubric: 3 = by signing the new sheet in person;; 2 = partly correct;; 1 = vague;; 0 = none. - EX047 — Plan actions. How many actions are in the one-month plan?
Show marking criteria
Rubric: 3 = five;; 2 = partly correct;; 1 = wrong;; 0 = none. - EX048 — New sheet features. What does the new sheet include?
Show marking criteria
Rubric: 3 = a clear consent box and the date;; 2 = both;; 1 = one;; 0 = none. - EX049 — Late action. Which action slipped?
Show marking criteria
Rubric: 3 = the staff meeting explanation;; 2 = partly correct;; 1 = other;; 0 = none. - EX050 — Next topic. What does Ms. Fischer suggest next?
Show marking criteria
Rubric: 3 = privacy and data protection;; 2 = partly correct;; 1 = other;; 0 = none.