Skip to main content

Make sense of a messy table

Inspect a messy synthetic spreadsheet, spot missing rows and unit traps, and check whether the summary matches the numbers.

1. Scenario

Pick a work role starter with synthetic material, or switch to Bring your own.

Weekly pastry waste sheet with a missing Friday delivery

Small Business · Synthetic material

You want to see how many croissants went unsold per day, and Friday's row has a blank delivery count.

day,delivered_croissants,sold_croissants,unsold_recorded
Mon,40,36,4
Tue,40,38,2
Wed,40,35,5
Thu,40,37,3
Fri,,39,0

2. Work area

Edit the briefs or setup below before you run.

Only the header row, inferred column types, and at most 20 sample rows leave your device. The analysis function runs in your browser on all rows.

5 columns · 24 total rows · 20 sample rows leave device

Answer and chart

Example. No model ran.

Sourdough Loaves sold the most volume at 73 crates across 24 orders, and 6 invoices are currently marked unpaid.

Inline SVG chartSourdough Loaves73Croissants40Cinnamon Buns25Rye Loaves24
Steps in plain words
  1. 1. Sum crates ordered for each product line across all 24 wholesale orders.
  2. 2. Count how many orders have invoice_status equal to unpaid.
  3. 3. List the unpaid orders so the shop owner can check the 6 rows before chasing payment.
Inspect the analyze(rows) code that ran in your browser
function analyze(rows) {
  const byProduct = {};
  let unpaidCount = 0;

  for (const row of rows) {
    const prod = String(row.product || "Other");
    const crates = Number(row.crates) || 0;
    if (!byProduct[prod]) {
      byProduct[prod] = { product: prod, orders: 0, totalCrates: 0 };
    }
    byProduct[prod].orders += 1;
    byProduct[prod].totalCrates += crates;
    if (String(row.invoice_status) === "unpaid") {
      unpaidCount += 1;
    }
  }

  const table = Object.values(byProduct).sort((a, b) => b.totalCrates - a.totalCrates);
  const chart = table.map((p) => ({ label: p.product, value: p.totalCrates }));
  const top = table[0] || { product: "None", totalCrates: 0 };

  return {
    answer: top.product + " sold the most volume at " + top.totalCrates + " crates across " + rows.length + " orders, and " + unpaidCount + " invoices are currently marked unpaid.",
    table,
    chart,
    checkOne: {
      label: "Orders with unpaid invoices",
      figure: unpaidCount,
      column: "invoice_status",
      equals: "unpaid",
      mode: "count"
    }
  };
}

Check one number by hand

Reported: 6 · Rows found: 6

Orders with unpaid invoices: Filter where invoice_status equals unpaid. Below are all 6 matching rows from the 24-row spreadsheet so you can count or sum them yourself.

1. order_id: OR-502 · product: Croissants · customer: Station Espresso · crates: 6 · invoice_status: unpaid
2. order_id: OR-505 · product: Cinnamon Buns · customer: Corner Cafe · crates: 5 · invoice_status: unpaid
3. order_id: OR-508 · product: Rye Loaves · customer: Station Espresso · crates: 5 · invoice_status: unpaid
4. order_id: OR-512 · product: Sourdough Loaves · customer: Station Espresso · crates: 9 · invoice_status: unpaid
5. order_id: OR-516 · product: Croissants · customer: Harbour Deli · crates: 6 · invoice_status: unpaid
6. order_id: OR-519 · product: Cinnamon Buns · customer: Park Kiosk · crates: 4 · invoice_status: unpaid

3. Run

Nothing leaves your browser until you press Run.

Sends only the column header and at most twenty sample rows when you press run. to job data_code (claude-sonnet-5-5, effort medium). Raw text is processed in memory and not stored.

4. Inspect

See what left the browser, which model ran, and the receipt.

Example. No model ran. · source: offline
What left the browser

Nothing sent yet. When you run, only headers and at most 20 sample rows leave this device.

What stayed on device

All 24 rows stay in your browser and run inside the sandboxed Web Worker.

Model and job

data_code · claude-sonnet-5-5 (effort medium, max 1600 tokens). Haiku reads the schema and sample rows to propose checks you can verify against the full table.

Runs and source

0 runs used · source: offline · Example. No model ran.

5. Judge

Did the summary flag Friday's blank `delivered_croissants` value instead of treating Friday's 0 as verified?

80%

50 is a coin flip. 99 is certain. Honest confidence scores best.

6. Debrief and Keep

What to check next time, the matching lesson, and keeping this setup as a recipe.

What to check next time

Blank cells often turn into zeros in downstream summaries. Separating the four complete days (Mon to Thu = 14 unsold) from Friday's missing delivery cell keeps your ordering math accurate.

Keep as a recipe

Save the stronger brief and scenario setup to your device so you can reuse or adapt it in Keep.

Open Keep