Download this file as Markdown to fill in
By the end of this module you should hold a short record of one piece of work you generated, checked, corrected, and can defend. That record is your evidence pack.
It is one to two pages. It is not an essay, and it is not a programming assignment. Its purpose is to make visible the thing the module is actually about: the distance between "I generated this" and "I understand and can defend this".
The pack is yours and stays yours. It is a private formative self-check. You are not asked to submit it, it is not marked, and nobody collects it. Export it, print it, or show it to someone only if you decide to.
Two routes, one pack
There are two ways to fill this in, and they produce evidence of equal standing.
- Table-based verification. You compare generated values against a reference table — one you derived by hand and one published in the module — and record what matched and what did not. No code is run at any point.
- Automated verification. You run
course/lab/check.pyagainst a Python file and record what the checker reported.
Both routes verify the same claim by an independent method, which is what verification means. Both are worked through below, in full, so you can see what each looks like when it is done properly. Pick the one that suits how you work.
If you would rather not install or run Python but want a runnable checkpoint
record, the browser self-check at build/site/selfcheck.html produces one; the Python
route produces the same record with
python3 selfcheck.py progress --evidence.
The template
Copy everything between the rules into a new file and fill it in.
Evidence pack
Name: Date: Context: academic (course or module) / professional (role and organisation) / self-study Route used: table-based verification / automated verification Task: (one line — what you asked for)
1. Original prompt
Paste the prompt exactly as you sent it, including anything you got wrong or left out. Do not tidy it up. The gaps in this prompt are the evidence.
2. Generated output
Paste what came back, or the relevant part of it. If it was code, include it as code. If it was a table of values, include the table. If it carried claims about history or sources, include those too — they are part of the output and part of what needs checking.
3. Verification result
State what you checked it against, by what method, and what happened. Name your reference. "It looked right" is not a result; "B1 disagreed with the value I derived in Unit 3" is.
- Checked against:
- Method:
- Result:
4. Discrepancy notes
For each disagreement: what the output said, what the reference said, and — as
far as you can tell — what kind of error it was. Use the failure-mode codes the
checker reports where one applies (b1-sign, odd-terms, ada-indexing,
off-by-one, not-fraction, raises, import-error, no-function); most are
discussed in course/misconceptions.md.
If nothing disagreed, say so, and say what you checked that could have disagreed. A check that could not have failed has not told you anything.
| index or claim | output said | reference said | code / kind of error |
|---|---|---|---|
5. Revised prompt
Paste your second prompt. Then, in one or two lines per clause, say which clause you added and which discrepancy above it was meant to remove. Every clause should be traceable to something that actually went wrong.
| clause added | discrepancy it addresses |
|---|---|
6. Final result
The corrected output, and the verification you ran on it. Same standard as section 3: name the reference and the method.
- Checked against:
- Method:
- Result:
7. AI-use disclosure
Two or three sentences. What you used AI for, at what stage, and what you did with the output afterwards. Factual and specific. This is a statement about how the work was made.
8. Correctness defence
Exactly two sentences. Why the final result is correct, citing the checks you ran or the reasoning you followed. This is a statement about why the work is right, and it must not rest on the authority of the tool.
Worked illustration A — table-based verification
A completed pack, no code run at any point.
Route used: table-based verification
Task: Get a table of the Bernoulli numbers B0 to B8 to use in a report.
1. Original prompt
Give me a table of the first few Bernoulli numbers.
2. Generated output
B0 = 1
B1 = 1/6
B2 = -1/30
B3 = 1/42
B4 = -1/30
B5 = 5/66
B6 = -691/2730
B7 = 7/6
These are the values Ada Lovelace computed in Note G of her 1843 notes,
where she calculated B7 using the Analytical Engine.
3. Verification result
- Checked against: the value of
B4I derived by hand from the recurrence in Unit 3, and the module's published table incourse/lab/README.md. - Method: wrote both sequences side by side and compared index by index.
- Result: disagrees from
B1onwards, apart from a coincidental match atB4. My hand derivation givesB4 = -1/30; the output files-1/30atB2as well as atB4.
4. Discrepancy notes
| index or claim | output said | reference said | code / kind of error |
|---|---|---|---|
| B1 | 1/6 | -1/2 | ada-indexing — the modern B2, filed as B1 |
| B3 | 1/42 | 0 | odd-terms — odd terms are not zero |
| B4 | -1/30 | -1/30 | agrees, but coincidentally: the modern B8 also equals -1/30 |
| B1..B7 as a block | the non-zero values in order | modern B2, B4, B6, ... | ada-indexing — only non-zero terms numbered |
| "she calculated B7" | Note G computes B7 | Note G computes Ada's B7, the modern B8 | index confusion in prose, unsourced |
| "using the Analytical Engine" | the engine ran the computation | the engine was never built (Unit 1) | unsourced historical claim |
The whole table is the consecutive renumbering: every value in it is a genuine
Bernoulli number, filed under the scheme that numbers only the non-zero terms —
B1 holds the modern B2, B2 the modern B4, and so on — and none is filed
under its modern index. Even the apparent agreement at B4 is a coincidence of
the mathematics: the modern B8 happens to equal the modern B4. The
historical sentence is a separate claim which the correct-looking arithmetic
gave me no reason to trust, and the exemplar verifier catches it at the first
source check: the output says the computation was run "using the Analytical
Engine", but the engine was never built (Unit 1) — see
course/misconceptions.md §6.
5. Revised prompt
List the Bernoulli numbers B0 to B8 using modern indexing, where every
index is numbered including the odd ones that are zero. Use the first
Bernoulli convention, B1 = -1/2. Give each value as an exact fraction,
not a decimal. Do not include any historical commentary.
| clause added | discrepancy it addresses |
|---|---|
| "modern indexing ... including the odd ones that are zero" | ada-indexing, odd-terms |
| "first Bernoulli convention, B1 = -1/2" | b1-sign |
| "exact fraction, not a decimal" | pre-empts not-fraction |
| "no historical commentary" | the unsourced Note G claim |
6. Final result
B0 = 1 B5 = 0
B1 = -1/2 B6 = 1/42
B2 = 1/6 B7 = 0
B3 = 0 B8 = -1/30
B4 = -1/30
- Checked against: my hand-derived
B4, and the module's published table incourse/lab/README.md, which itself agrees with 22 values transcribed from published tables. - Method: index-by-index comparison of all nine values, twice, second time reading the reference first.
- Result: all nine agree. The odd terms
B3,B5,B7are now zero, which is the property I had specifically failed on before.
7. AI-use disclosure
I used an AI assistant to produce a table of Bernoulli numbers
B0toB8. The first output used a different sign convention and Lovelace's 19th-century indexing, which I found by comparing it against a value I had derived by hand and against the module's published table. I re-prompted with the convention and indexing stated explicitly and verified the second table the same way.
8. Correctness defence
Every value in the final table matches the module's published reference table index by index, and
B4 = -1/30matches the value I derived independently from the recurrence before generating anything. The convention is stated — first Bernoulli numbers,B1 = -1/2— so the comparison is between two tables that are answering the same question.
Worked illustration B — automated verification
The same task, checked by running the code.
Route used: automated verification
Task: Get a Python function bernoulli(n) for use in the Unit 5 exercise.
1. Original prompt
Write me a Python function to compute Bernoulli numbers.
2. Generated output
from fractions import Fraction
from math import comb
def bernoulli(n: int) -> Fraction:
values = [Fraction(0)] * (n + 1)
for m in range(n + 1):
values[m] = Fraction(1)
for k in range(m):
values[m] -= Fraction(comb(m, k) * values[k], m - k + 1)
return values[n]
I read the file before running it: it imports only fractions and math, and
does nothing to the filesystem, the network, or the shell.
3. Verification result
- Checked against:
course/lab/reference_bernoulli.py, the module's test oracle. - Method: pasted the function into
exercises/ex04_bernoulli.pyand ranpython3 check.py exercises/ex04_bernoulli.py, comparing indices 0 to 30. - Result: FAIL, two findings.
FAIL - 2 problem(s) found.
[divergence] First divergence at n=1: expected -1/2, got 1/2.
[b1-sign] B1 has the wrong sign for this module's convention.
4. Discrepancy notes
| index or claim | output said | reference said | code / kind of error |
|---|---|---|---|
| B1 | 1/2 | -1/2 | b1-sign |
| B0, B2..B30 | — | — | agree exactly |
One index out of 31. The routine is correct under the second Bernoulli
convention; the specification I gave never said which convention I wanted, so
this is a specification failure rather than an arithmetic one. Worth noting that
the failure was found at n=1, the second value tested — a spot check starting
at B2 would have missed it entirely.
5. Revised prompt
Write a Python function with this interface:
bernoulli(n: int) -> fractions.Fraction
Defined for every n >= 0; first-Bernoulli convention B1 = -1/2; exact
Fraction returns only, never float; returns Fraction(0) for odd n > 1.
| clause added | discrepancy it addresses |
|---|---|
| "first-Bernoulli convention B1 = -1/2" | b1-sign — the one that actually failed |
| "exact Fraction ... never float" | pre-empts not-fraction |
| "defined for every n >= 0" | pre-empts raises at the boundaries |
| "returns Fraction(0) for odd n > 1" | pre-empts odd-terms and ada-indexing |
The interface contract is the module's fixed specification, the same wording
check.py enforces. Only the first clause fixed a
bug I had; the other three are clauses I now know to include because I read the
failure modes in course/misconceptions.md.
6. Final result
from fractions import Fraction
from math import comb
def bernoulli(n: int) -> Fraction:
if n < 0:
raise ValueError("n must be >= 0")
if n > 1 and n % 2 == 1:
return Fraction(0)
values = [Fraction(0)] * (n + 1)
for m in range(n + 1):
values[m] = Fraction(1)
for k in range(m):
values[m] -= Fraction(comb(m, k) * values[k], m - k + 1)
if n == 1:
return -values[n]
return values[n]
- Checked against: the same oracle.
- Method:
python3 check.py exercises/ex04_bernoulli.py --verbose, thenpython3 selfcheck.py run cp05-bernoulli; on the table route, completecp05-table-evidenceand retain the compared rows. - Result: PASS.
PASS - agrees with the oracle for every n from 0 to 30,
returns exact Fractions, and odd terms above B1 are zero.
(Indices compared: 0 to 30)
I also derived B4 = -1/30 by hand in Unit 3, before any of this, and the
function returns that value.
7. AI-use disclosure
I used an AI assistant to write a Python function computing the Bernoulli numbers. The first version used the second Bernoulli convention, which the lab's differential checker identified at
n = 1. I re-prompted with the module's interface contract stated in full, read the result, and re-ran the checker.
8. Correctness defence
The function agrees with the lab's test oracle for every index from 0 to 30, returns exact
Fractionvalues, and returns zero at every odd index aboveB1; the oracle itself agrees with 22 values transcribed from published tables and uses a different algorithm from this implementation.B4 = -1/30also matches the value I derived by hand from the recurrence before generating any code, so the comparison does not depend on the oracle alone.
Completion criteria
Your evidence pack is complete when all of the following are true. They apply equally to both routes.
- [ ] All eight sections are filled in.
- [ ] The original prompt is the one you actually sent, not a tidied version.
- [ ] The generated output is included as it arrived, including any claims about history or sources.
- [ ] The verification section names a specific reference and a specific method, not an impression.
- [ ] At least one discrepancy is recorded, or — if the first attempt genuinely passed — you have stated what you checked that could have failed.
- [ ] Each discrepancy is labelled with a failure-mode code where one applies.
- [ ] Every clause added to the revised prompt is traceable to a specific discrepancy.
- [ ] The final result has been verified by the same method as the first, and the result is recorded.
- [ ] The disclosure says how the work was made, in your own words.
- [ ] The defence is two sentences, cites checks or reasoning, and does not cite the tool's confidence, the tool's name, or the fact that it "looked right".
- [ ] You can answer, out loud, which convention your result uses and why it matters.
Optionally attach your self-check record — python3 selfcheck.py progress
--evidence, or the summary from build/site/selfcheck.html. It shows which
checkpoints you passed. It is not evidence that you can defend them, which is
what sections 7 and 8 are for.
Instructor note
What this pack is for, and why it is not collected.
It is not collected. The pack is a private formative self-check. It is not submitted, not marked, and not reviewed by default, and no part of the module asks a learner to hand it over. If a learner chooses to export it or show it to someone — in a tutorial, in peer discussion, or in a portfolio of their own — that is their decision.
What it is for. The pack makes the learner's own verification process visible to them. The valuable content is sections 4 and 5 — the discrepancies found and the clauses added — because those are where checking either happened or did not. A pack whose first attempt passed and whose defence is thin says more than a pack with a working function.
Read the process, not the artefact. If a learner does ask you to look at a pack, respond to whether verification occurred and whether the defence is evidence-based. Whether the final code runs, and how good the code is, are not the point. A learner who generated broken code, found the bug, named the failure mode, fixed the specification and defended the result has met every objective in this module. A learner who generated correct code first time and wrote "the AI got it right" has met none of them, and the pack should be able to show that difference to the learner themselves.
Both routes count equally. A table-based pack and an automated pack are evidence of the same competence. Nothing in the module should reward running Python, and no cohort communication should describe the table-based route as a fallback or as being for anyone in particular. Worked illustration A is included in full, at the same length as B, for this reason.
Why the stakes are zero by design. The module asks learners to record their mistakes in writing. That only produces an honest record if there is nothing to lose by writing one down, which is why the pack is private and uncollected rather than submitted for feedback or for a mark. Attaching a mark to the artefact would produce packs in which nothing ever went wrong, and the module would have taught the opposite of its subject.
Common weak spots, worth naming in teaching. A defence that names the tool
rather than the checks. A revised prompt with clauses that do not correspond to
any recorded discrepancy — usually copied from the Unit 6 material rather than
derived. "It looked correct" appearing in section 3. A discrepancy table with no
entries and no statement of what was checked. Each maps to an entry in
course/misconceptions.md, so a discussion can point at a specific unit and
checkpoint rather than at a learner.
Cross-references. The disclosure wording, the two-sentence defence, and the assembly of this pack are Unit 8. The interface contract quoted in illustration B is the module's fixed specification. Rules about permitted AI use in assessed work are set by the learner's own institution or course; this module does not set them and does not state them.