Evidence: Excel
What we asked for, and what we handed over. Every answer the tools gave is kept exactly as it came back — listed below, one file each, unedited.
Brief
Excel — the brief, the fixture and the scoring
Sent as one message with orders-q2.xlsx attached through each tool’s own file upload, on the free tier, in a fresh chat (Claude: incognito). Nine tools, same file, same day. If a tool cannot take an .xlsx, the sheet is pasted as CSV text and that is noted.
I run a small online shop in Portugal. Attached is my order export for April to June 2026 - it’s messy. Please:
- Tell me what’s wrong with the data and fix it. Give me the cleaned sheet back as an .xlsx.
- Revenue per month and per category, and the product with the most units sold.
- List the duplicate orders and any order where Total doesn’t match Qty × Unit Price.
- One Excel formula I can paste to get revenue per month from the cleaned sheet, which keeps working when I add rows.
Keep it short.
The fixture
orders-q2.xlsx, one sheet “Orders”, 124 rows: 120 orders plus 4 exact duplicates. Built by make_fixture.py (seeded, reproducible); the exact answers are in ground-truth.txt. Eight faults are planted:
| Fault | Rows | What a careful reader does |
|---|---|---|
| Exact duplicate orders | 4 | drops them |
| Total ≠ Qty × Unit Price | 5 | flags them; revenue uses Qty × Unit Price |
| Qty blank | 3 | derives Qty from Total ÷ Unit Price |
| Region blank | 2 | flags, cannot be derived |
| Category blank | 8 | fills from the product name |
| Unit Price as text, “€12,50” | 18 | converts to a number |
| Product name case and spacing variants | 18 | normalises to one spelling per product |
Dates in three formats: real dates, dd/mm/yyyy text, Apr 5, 2026 text |
30 + 12 | parses all as dates; the shop is in Portugal so 03/04/2026 is 3 April |
The date trap has a clear tell: reading dd/mm as mm/dd produces orders in July to December and 20 invalid dates. ground-truth.txt also lists the totals a tool gets if it sums the Total column as-is, or deduplicates but keeps the wrong totals.
Scoring
- Faults found - how many of the eight fault classes the tool names, of 8.
- File - an .xlsx comes back, opens, and is actually cleaned: 120 rows, real dates, numeric prices, one spelling per product, categories filled. Checked with openpyxl.
- Months - revenue for April, May, June within €0.01 of the truth, of 3. A stated different basis (for example “sum of the Total column as given”) is recorded but not counted as right, because the brief asks for the cleaned data.
- Categories - of 3. Top product - Vinho Verde 750ml, 42 units, right or wrong.
- Duplicates - of 4, with any false positives noted. Mismatches - of 5.
- Formula - works on the cleaned sheet, and keeps working when rows are appended (whole-column or Table references, not a fixed range). Judged by reading it and, where the logic is not obvious, re-implementing it.
- Invented facts - anything stated about the shop, the customers or the numbers that the file does not support.
- Time to answer, whether the free tier refused or truncated, and whether the answer is in English.
README
Fixtures for the Excel test
orders-q2.xlsx- the messy order export sent to every tool. Synthetic: a fictional Portuguese food-and-homeware shop, invented customer names, no real people or businesses. Built bymake_fixture.py.make_fixture.py- generates the workbook and prints the ground truth; seeded so it reproduces exactly.ground-truth.txt- the right answers, plus the alternates a tool produces if it skips a cleaning step.brief.md- the message sent, the fault list and the scoring rules.check_returned.py- opens a returned workbook and compares it with the ground truth (row count, duplicate IDs, date and price types, product spellings, blanks, monthly totals).returned/- the cleaned workbooks the tools sent back, named by tool. Claude, Grok, Copilot and Perplexity returned one; the others did not.
Cleanup afterwards: Copilot’s composer said a copy of the upload goes to the personal OneDrive (“При отправке с устройства копия будет отправлена в OneDrive (личный)”) - delete orders-q2.xlsx there. Nothing else persists: one upload per tool, no memory instructions, no automations.
What we gave them
- fixtures/orders-q2.xlsxxlsx11 KB
What came back
How we marked it
- fixtures/check_returned.pypy3 KB
- fixtures/ground-truth.txttxt1 KB
- fixtures/make_fixture.pypy5 KB
Also kept
- The test (2026-09)The test, written up
- fixtures/returned/claude.xlsxxlsx16 KB
- fixtures/returned/copilot.xlsxxlsx13 KB
- fixtures/returned/grok.xlsxxlsx11 KB
- fixtures/returned/perplexity.xlsxxlsx13 KB
- results-2026-09.yamlyaml5 KB