Prompt Playground

This page runs your prompt against a live model. Pick a goal, edit the prompt, then hit Run prompt and the page sends it to the model and shows the answer below. One goal asks the model to draw a chart, which the page renders beside a known-good reference chart so you can compare. There is also a floating tutor pill for follow-up questions. The Plan the whole task section at the bottom works differently, since those prompts are meant for the AI tool you already use and do not run on this page.

The Prompt Library gives you patterns for driving analysis with AI. This is where you practice them. Below is a small customer table. Pick an analysis goal, watch the matching prompt pattern fill in, edit it to make it your own, and run it against this data. When you are ready to hand an AI a whole assignment rather than one question, go to Plan the whole task.

The data: 20 customers

A synthetic accounts-receivable extract. Revenue is right-skewed, two accounts are far larger than the rest, and there are two segments. This is the table every prompt below runs against.

customer_idsegmentrevenue ($)days_to_payregion
Shaded rows are the two outliers, the accounts far larger than the rest.

1. Pick an analysis goal

Each goal is one of the five moves from the Prompt Library. Click one and its prompt pattern fills the box below, already adapted to this table's columns.

2. Edit the prompt

Why this prompt works. Pick a goal above to see the pattern and why it earns a good answer.
The good edits: make it more specific, name the exact column, state what the data looks like, and ask the AI to show its reasoning. The note above tells you what this pattern is going for.

3. Run it

Run prompt sends your prompt straight to the model, which gets the 20 rows along with it, and shows the answer below. If you would rather use your own AI in another tab, Copy prompt gives you the text plus the data to paste in. Either way, compare what you get back to the model answer.

Copied
Model answer
Show what a strong answer looks like

Pick a goal first. This reveal shows the kind of answer a strong version of that prompt should pull back, so you can compare it to what you got. It is a yardstick, not a substitute for running your own.

The moves, at a glance

The first five cards are the five categories from the Prompt Library page, each pre-filled with a worked version pointed at this table. The sixth, Chart it, asks the model to draw a chart of the same data so you can compare it to the reference chart the page already knows is right.

A prompt earns a good answer when it is specific, hands the AI the shape of the data, asks for reasoning rather than just a number, and, for a claim, makes the AI argue against you. Never paste a number, or a chart, back into a slide without checking it yourself.

Plan the whole task

Everything above works on one question at a time. A homework assignment is different, because it is a set of instructions, a template to fill, and a group of numbers that all have to tie to each other.

If you paste the whole assignment into an AI and ask for the answer, you will usually get a confident answer that nobody has checked. It can look finished and still be wrong in a way that is hard to find, such as a duplicate row counted twice or a void that was never excluded.

If you instead ask the AI to plan first, build in steps, and prove each step against an independent check, you get work you can walk someone through and defend. The independent check is the part that matters most. It works like a control in an audit, where a number is accepted because a separate test that recomputes it from the source agrees, not because it looks reasonable.

A note on the word script. In these prompts, script means whatever tool you are doing the work in. Right now that is SQL and Excel formulas. From Week 7 it can also mean Python. Tell the AI which tool you are using and it will write the steps in that tool, so none of this needs code you have not learned yet.

These prompts do not run on this page. Fill in the [brackets], copy the prompt, and paste it into the AI tool you already use, where you can keep the whole assignment in one conversation.

The patterns

Open a pattern to see the prompt. The first one is the anchor, and the rest are the pieces it is built from, in roughly the order you would use them on a real assignment.

  • Plan the steps
  • Trace the requirements
  • Test the assumptions
  • Build with checkpoints
  • Verify two ways
  • Grade and defend
Copied

A worked example, end to end

This homework, the company and its data are illustrative, made up for this example. The numbers are internally consistent, so every check below ties to every other one.

This is the anchor pattern filled in for an assignment shaped like Lab 3 and Homework 3, where you fill an aging workbook in Excel and then tie it out in SQL.

Homework (illustrative): AR aging tie-out for Juniper Ridge Supply Co.
  1. Use invoices.csv (invoice_id, customer_id, invoice_date, amount, status) and customers.csv (customer_id, segment, terms_days). Age everything as of March 31, 2026.
  2. Age every open invoice by days past due against the customer's net terms. The due date is the invoice date plus terms_days. An open invoice still within its terms is Not due.
  3. Exclude void and paid invoices.
  4. Fill the Summary sheet of ar_aging_template.xlsx: total open AR (B4), open invoice count (B5), open AR and invoice count for Not due, 1-30, 31-60, 61-90 and 90+ days past due (B8:C12), and the share of open AR more than 60 days past due (B14).
  5. Tie your workbook out in SQL. Reproduce total open AR and every bucket total to the cent.
  6. Write two sentences for the controller on where the collection risk sits.

The filled-in prompt

I have been assigned this homework. Here are the full instructions, copied exactly:

Homework: AR aging tie-out for Juniper Ridge Supply Co.
1. Use invoices.csv (invoice_id, customer_id, invoice_date, amount, status) and customers.csv (customer_id, segment, terms_days). Age everything as of March 31, 2026.
2. Age every open invoice by days past due against the customer's net terms. The due date is the invoice date plus terms_days. An open invoice still within its terms is Not due.
3. Exclude void and paid invoices.
4. Fill the Summary sheet of ar_aging_template.xlsx: total open AR (B4), open invoice count (B5), open AR and invoice count for Not due, 1-30, 31-60, 61-90 and 90+ days past due (B8:C12), and the share of open AR more than 60 days past due (B14).
5. Tie your workbook out in SQL. Reproduce total open AR and every bucket total to the cent.
6. Write two sentences for the controller on where the collection risk sits.

I need to populate the Summary sheet of ar_aging_template.xlsx. The data is in invoices.csv and customers.csv.

Please generate a script that can complete the homework as assigned. I am using Excel formulas for the workbook and SQLite for the tie-out, and I do not know Python yet. Before you write anything, give me a numbered plan with the input, the output and a checkpoint for each step, and list anything in the instructions that is ambiguous.

Then set up a separate model where I can independently verify the results. Reload the raw CSVs and my filled Summary sheet into a SQLite database, and write queries that test each assumption the plan makes: row counts, duplicate invoice IDs, invoices whose customer is missing from customers.csv, status values, bucket edges, and totals that should tie. For each check, tell me what result means the work is right and what result means it is wrong.

The verification has to recompute every number from the raw data. Do not check the workbook by rereading it.
Copied
Show what a strong response looks like

A strong response plans before it builds, names what it is unsure of, and hands you checks that recompute the numbers from the raw files. Compare the shape of what your AI gives you to this, not the exact wording.

1. Questions to settle before starting

  • As-of date. The instructions fix it at March 31, 2026, so the work uses that date rather than today's date, which would change every bucket each time it runs.
  • Missing customers. If an invoice's customer is not in customers.csv, there are no terms to age it against. The plan defaults to 30 days, flags the invoice, and tests whether the choice moves it to a different bucket.
  • Bucket edges. The plan reads 1-30 as 1 through 30 days past due, so 31 is the first day of 31-60 and 91 is the first day of 90+. Worth confirming with your instructor if the spec is not explicit.

2. The plan

StepInputOutputCheckpoint
1. Load and profileinvoices.csv, customers.csvTwo SQLite tables241 invoice rows and 30 customers, status is only Open, Paid or Void
2. CleaninvoicesOne row per open invoice114 open invoices, down from 115 open rows once one exact duplicate is removed
3. Attach terms and ageOpen invoices, customersdays_past_due for each invoiceNo blank due dates, and the one invoice without a customer is flagged
4. Bucket and summarizeAged invoicesFive bucket totals and countsThe buckets add back to total open AR
5. Fill the workbookA cleaned invoice sheetSummary sheet B4:C12 and B14, as SUMIFS and COUNTIFS formulasEvery cell filled with a formula, not a typed value
6. Verify independentlyRaw CSVs plus the saved Summary sheetA difference tableThe difference query returns zero rows
7. Write the noteVerified numbersTwo sentencesEvery number in the note is one the difference query checked

3. The assumption register

AssumptionHow it is testedWhat it found, and what changes
invoice_id is uniqueCheck BIt is not. INV-10002 appears twice as an exact copy, so one copy is dropped before anything is summed.
Every invoice has a customer recordCheck CINV-10058 ($880.61, customer K031) has none. On 30-day terms it is 28 days past due, and on 45-day terms it would be 13, so it lands in 1-30 either way and the bucket does not depend on the guess.
Status is spelled exactly Open, Paid or VoidCheck AHolds. If it did not, a variant such as "open " would silently drop out of the open total.
Amounts are positive, with no credit memosCheck DHolds. A negative amount would need a rule for netting it against the customer's balance.
Every invoice_date is a real dateCheck DHolds, with dates from 2025-11-01 to 2026-03-31. A date stored as text in another format would age wrong without an error.
Bucket edges are read correctlyCheck FFive invoices sit on an edge, two at 31 days and one each at 60, 90 and 91, and each is spot-checked by hand.

4. The verification model, in SQLite

Import the two CSVs as tables named invoices and customers, for example with File, Import, Table from CSV in DB Browser for SQLite. None of these queries read the workbook until check G, which is what makes them an independent check.

A. Every raw row is accounted for

SELECT status, COUNT(*) AS n, ROUND(SUM(amount), 2) AS total
FROM invoices
GROUP BY status
ORDER BY status;

Open 115 rows, $289,477.74. Paid 106 rows, $356,351.36. Void 20 rows, $46,843.89. The three add to 241, which matches the number of data rows in invoices.csv, and no other status appears.

B. No invoice is counted twice

SELECT invoice_id, COUNT(*) AS copies
FROM invoices
GROUP BY invoice_id
HAVING COUNT(*) > 1;

One row back: INV-10002, 2 copies. Zero rows would mean the IDs are unique. This one is an exact duplicate of an open $1,918.32 invoice.

C. Every invoice matches a customer

SELECT i.invoice_id, i.customer_id, i.amount, i.status
FROM invoices i
LEFT JOIN customers c ON c.customer_id = i.customer_id
WHERE c.customer_id IS NULL;

One row back: INV-10058, K031, $880.61, Open. This is a customer in one table and not the other, and an inner join would have dropped it from the total without any warning.

D. Amounts and dates are usable

SELECT
  SUM(CASE WHEN amount IS NULL OR amount <= 0 THEN 1 ELSE 0 END) AS bad_amounts,
  SUM(CASE WHEN julianday(invoice_date) IS NULL THEN 1 ELSE 0 END) AS bad_dates,
  MIN(invoice_date) AS first_date,
  MAX(invoice_date) AS last_date
FROM invoices;

0 bad amounts, 0 bad dates, first 2025-11-01, last 2026-03-31. Nothing is dated after the as-of date.

E. Rebuild the aging from the raw data

CREATE VIEW open_aged AS
SELECT *,
  CASE
    WHEN days_past_due <= 0  THEN 'Not due'
    WHEN days_past_due <= 30 THEN '1-30'
    WHEN days_past_due <= 60 THEN '31-60'
    WHEN days_past_due <= 90 THEN '61-90'
    ELSE '90+'
  END AS bucket
FROM (
  SELECT DISTINCT i.invoice_id, i.customer_id, i.invoice_date, i.amount,
    CAST(julianday('2026-03-31')
       - julianday(i.invoice_date, '+' || COALESCE(c.terms_days, 30) || ' days')
       AS INTEGER) AS days_past_due
  FROM invoices i
  LEFT JOIN customers c ON c.customer_id = i.customer_id
  WHERE i.status = 'Open'
);

SELECT bucket, COUNT(*) AS n, ROUND(SUM(amount), 2) AS total
FROM open_aged
GROUP BY bucket;

Not due 27, $83,174.21. 1-30 23, $46,353.83. 31-60 31, $74,364.19. 61-90 18, $46,539.40. 90+ 15, $37,127.79. Together that is 114 invoices and $287,559.42, which is the open total from check A less the $1,918.32 duplicate. The LEFT JOIN keeps INV-10058, and DISTINCT drops the second copy of INV-10002.

F. The bucket edges

SELECT invoice_id, days_past_due, bucket
FROM open_aged
WHERE days_past_due IN (0, 1, 30, 31, 60, 61, 90, 91)
ORDER BY days_past_due;

Five rows: two at 31 days in 31-60, one at 60 in 31-60, one at 90 in 61-90, and one at 91 in 90+. These are the rows an off-by-one mistake would move, so compare each to the workbook by hand.

G. Reload the workbook and compare

Save the Summary sheet as summary.csv with two columns, label and value, and import it as a table named template_out. Then recompute the same labels in SQL and list every one that disagrees.

CREATE TABLE sql_out AS
SELECT 'Total open AR' AS label, ROUND(SUM(amount), 2) AS value FROM open_aged
UNION ALL
SELECT 'Open invoice count', COUNT(*) FROM open_aged
UNION ALL
SELECT 'AR ' || bucket, ROUND(SUM(amount), 2) FROM open_aged GROUP BY bucket
UNION ALL
SELECT 'Count ' || bucket, COUNT(*) FROM open_aged GROUP BY bucket
UNION ALL
SELECT 'Share over 60 days (%)',
  ROUND(100.0 * SUM(CASE WHEN days_past_due > 60 THEN amount ELSE 0 END) / SUM(amount), 1)
FROM open_aged;

SELECT s.label, t.value AS workbook, s.value AS recomputed,
  ROUND(t.value - s.value, 2) AS difference
FROM sql_out s
LEFT JOIN template_out t ON t.label = s.label
WHERE t.value IS NULL OR ABS(t.value - s.value) > 0.005;

On the first pass this returned five rows, which is the check doing its job.

labelworkbookrecomputeddifference
Total open AR289,477.74287,559.421,918.32
Open invoice count1151141
AR 31-6076,282.5174,364.191,918.32
Count 31-6032311
Share over 60 days (%)28.929.1-0.2

Every dollar difference is $1,918.32, which is INV-10002 from check B. The workbook's SUMIFS counted the duplicate twice, and it sits in 31-60 because it is 39 days past due. The share moved too, even though the duplicate is not over 60 days, because it inflated the total underneath the ratio. Removing the duplicate row in the workbook and saving the Summary sheet again brings the difference query to zero rows.

Second pass: zero rows. SQL and the workbook are two separate methods, and they now agree on every label, so the numbers can go in the note.

5. The note to the controller

Open AR is $287,559.42 across 114 invoices as of March 31, 2026, and 29.1 percent of it, $83,667.19, is more than 60 days past due. One open invoice for $880.61 (customer K031) has no customer record and was aged on 30-day terms, so the billing team should confirm that customer before the next aging runs.

Notice what the response did not do. It did not report a total until the duplicate and the missing customer had been found, and it did not trust the workbook because the workbook looked right. The workbook was accepted when a separate method, built from the raw files, agreed with it.