The membership script nobody can hand over
A small charity's membership script was written by a volunteer who has since left. It renews memberships, emails reminders and updates a spreadsheet on a shared drive. The only documentation is a README saying 'run main.py' and 40 lines of commented-out old code. The script works for eleven months of the year, but every February the renewal run stops partway through and someone restarts it by hand. There is no test data, no record of which Python version is installed, and one backup from 2019. A new part-time administrator with basic coding skills has two days to make the February run reliable and to leave the system in a state someone else can pick up.
1. With two days available, state what documentation you would produce first and what you would deliberately not do, justifying the priority.
Read the worked answer
Produce first: an expanded README plus a pinned dependency list. The next person's first question is not 'what does line 62 do' but 'how do I run this, and where does the data live?'. Minimum useful content:
- the exact command to run, and what 'success' looks like (how many reminders sent, what the log ends with);
- the Python version actually installed and any packages, pinned in a requirements file - currently nobody can rebuild the environment;
- where inputs and outputs live: shared-drive path, spreadsheet name, the email account used and who owns its credentials;
- a one-line 'known issues' entry describing the February failure.
Deliberately not do: do not comment every line. Comments that restate the code double the reading effort and rot fastest. Comment only where the code is surprising - a date rule, a workaround, a magic number.
Also delete the 40 lines of commented-out old code. It is competing with the working code for the reader's attention, and if the charity has any version control at all, it already exists there.
2. Describe how you would investigate the February failure within the time available, and how you would create the test data the system currently lacks.
Read the worked answer
Reproduce before explaining. 'Fails in February' generates hypotheses; it is not a diagnosis.
Cheap checks first:
- Read the log around where it stops and identify the last record processed - its data is the prime suspect.
- Look for date handling: a format mismatch (
%d/%m/%yvs%m/%d/%y), a renewal date of 29 February, or a 'days until renewal' calculation that behaves differently in a 28-day month. - Check data-shape problems: a member record missing a renewal date, or an extra column added to the spreadsheet in January.
- Check external causes that happen to coincide: an expired email credential, a spreadsheet locked by another user.
Creating test data: copy the spreadsheet, keep the structure, and replace real members with about 20 fake records. Deliberately include the awkward ones - a 29 February renewal, a missing date, a blank email address, a name with an apostrophe. Anonymise: the test copy must contain no real personal data, both for privacy and so it can be committed alongside the script.
Interpretation: if it fails on the fake data you have a safe reproduction and a fix you can verify. If it does not fail, the difference between the real and fake data is the clue - which is itself progress.
3. The February fix works. Explain where the fix should be recorded and why each location serves a different reader, and what should be committed so the next person is not in the same position.
Read the worked answer
Three places, three readers.
- Commit message / changelog - for the next developer. Say why, not what: 'renewal run aborted on 29 Feb because no matching renewal date exists in non-leap years; treat as 28 Feb'. Dated, one entry per change. Once people leave, this is the only durable history.
- A comment at the fix site - for whoever edits that function next. Explain the decision that looks arbitrary; the code already shows the mechanics.
- README 'known issues' / run book - for the administrator on a bad morning. State the symptom they will see and the manual workaround, so recovery does not require reading code.
What to commit alongside the script:
- the 20-record test data set with its expected outcome, so 'what does a good run look like' is answerable without the original author;
- the pinned requirements file and recorded Python version;
- an automated backup or at least a dated export, since a single 2019 backup is not a backup.
And make failure loud: the script should raise a clear error with the offending record rather than stopping silently partway, so the next February is diagnosed in minutes rather than rediscovered.