Business decisions
Use ChatGPT to Check a Sales Forecast's Assumptions Before Sharing It
Summary
Cihan's view: Upload a structured forecast CSV, define acceptable ranges before asking for a conclusion, and require ChatGPT to keep missing inputs visible. Check the calculations against the source before sharing the forecast. A review table can expose weak assumptions, but it cannot decide whether a sales target is realistic or approve a business commitment.
A forecast can look precise while hiding a blank conversion rate or an impossible deal value. ChatGPT can help you find those inputs, provided you define the rules before you ask for a summary.
This guide uses a fictional forecast and an illustrative result. It does not claim a ChatGPT run or a forecast about a real business.
The reader, artifact and decision
This is for an operator preparing a monthly pipeline forecast. The artifact is a review table showing each row’s assumptions, flags and calculated revenue. The decision is whether the file is ready for human review, or needs corrections first.
Evidence label: documentation-based and illustrative. OpenAI’s data analysis documentation says ChatGPT can analyze CSV files, run Python-backed calculations for some tasks, and show tables. OpenAI also says to review generated code, outputs and assumptions before relying on the result. The data and output below are fictional.
Before you start
You need ChatGPT with file upload and data analysis available for your account or workspace. Availability varies by model, plan and settings. Use an approved environment and fictional data while learning. Python 3 is optional if you want to run the independent calculation check below.
Save this as forecast-sample.csv:
month,channel,leads,conversion_rate,average_deal_value
Jan,Email,120,0.10,5000
Feb,Partner,80,0.15,4500
Mar,Referral,50,0.08,6000
Apr,Event,200,0.05,3500
May,Outbound,60,,4000
Jun,Inbound,40,0.10,-1000
The file has six rows. May has a missing conversion rate. June has a negative average deal value. Those are deliberate review cases.
Three steps
1. Upload the file and set the rules
Attach forecast-sample.csv to a new ChatGPT conversation. Paste this prompt:
Analyze only the attached forecast-sample.csv.
First report the column names, row count, duplicate months, missing values,
and non-numeric values. Do not silently repair, drop, or replace any value.
Calculate projected_revenue as leads * conversion_rate * average_deal_value.
Require all three numeric assumptions to be finite numbers, leads to be
nonnegative, conversion_rate to be between 0 and 1, and average_deal_value
to be greater than 0. Flag duplicate months and exclude any flagged row
from the total while keeping it in the review table.
Return:
1. A review table with month, channel, each original assumption, projected_revenue,
and any flag.
2. The accepted-row total and the rows excluded from that total.
3. The calculation steps or Python code used.
4. A short note saying whether the file is ready for human review.
Do not invent a conversion rate, average deal value, target, probability,
customer, or explanation for a flagged row. Keep missing values visible.
The prompt defines the acceptance rules before the model writes a conclusion. If data analysis is unavailable, use a spreadsheet or another approved method and keep the same rules.
2. Review the complete illustrative output
This is an editor-written target based on the fictional CSV, not captured ChatGPT output. Keep all six rows and every original assumption visible. (blank) marks the source’s empty cell; it is not a zero or a replacement rate.
| Month | Channel | Leads | Conversion rate | Average deal value | Projected revenue | Flag |
|---|---|---|---|---|---|---|
| Jan | 120 | 0.10 | 5000 | 60,000.00 | NONE | |
| Feb | Partner | 80 | 0.15 | 4500 | 54,000.00 | NONE |
| Mar | Referral | 50 | 0.08 | 6000 | 24,000.00 | NONE |
| Apr | Event | 200 | 0.05 | 3500 | 35,000.00 | NONE |
| May | Outbound | 60 | (blank) | 4000 | NOT CALCULATED | MISSING conversion_rate |
| Jun | Inbound | 40 | 0.10 | -1000 | NOT CALCULATED | INVALID average_deal_value |
The audit summary should say:
- Columns: month, channel, leads, conversion_rate, average_deal_value.
- Source rows: 6. Duplicate months: none.
- Missing numeric inputs: May / conversion_rate, one blank cell.
- Nonnumeric, nonblank values in the three numeric columns: none. June’s negative number is numeric but invalid under the rule.
- Accepted rows: Jan, Feb, Mar and Apr. Excluded rows: May (missing conversion_rate) and Jun (average_deal_value is not greater than zero).
- Calculation steps: Jan is 120 x 0.10 x 5000 = 60,000; Feb is 80 x 0.15 x 4500 = 54,000; Mar is 50 x 0.08 x 6000 = 24,000; Apr is 200 x 0.05 x 3500 = 35,000. Add only those four results: 60,000 + 54,000 + 24,000 + 35,000 = 173,000.
The accepted-row total is 173,000, not a complete six-month forecast. The review artifact is ready for a human to inspect, but the missing and invalid inputs need correction before the forecast is shared as a business commitment. No currency or forecast realism is inferred from this CSV.
For a reproducible method, save this as check_forecast.py beside forecast-sample.csv and run python check_forecast.py. It uses only Python’s standard library. It preserves original cell strings in the review and reports missing, nonnumeric and duplicate values before returning the accepted-row total.
import csv
import json
from collections import Counter
from decimal import Decimal, InvalidOperation
with open("forecast-sample.csv", newline="", encoding="utf-8") as file:
reader = csv.DictReader(file)
columns = reader.fieldnames
rows = list(reader)
numeric_columns = ["leads", "conversion_rate", "average_deal_value"]
counts = Counter(row["month"] for row in rows)
duplicates = sorted(month for month, count in counts.items() if count > 1)
missing = []
nonnumeric = []
review = []
accepted_total = Decimal("0")
for row in rows:
flags = []
numbers = {}
for column in numeric_columns:
raw = row[column].strip()
if raw == "":
missing.append({"month": row["month"], "column": column})
flags.append("MISSING " + column)
numbers[column] = None
continue
try:
value = Decimal(raw)
if not value.is_finite():
raise InvalidOperation
numbers[column] = value
except InvalidOperation:
nonnumeric.append({"month": row["month"], "column": column})
flags.append("NONNUMERIC " + column)
numbers[column] = None
if numbers["leads"] is not None and numbers["leads"] < 0:
flags.append("INVALID leads")
rate = numbers["conversion_rate"]
if rate is not None and not Decimal("0") <= rate <= Decimal("1"):
flags.append("INVALID conversion_rate")
deal = numbers["average_deal_value"]
if deal is not None and deal <= 0:
flags.append("INVALID average_deal_value")
if row["month"] in duplicates:
flags.append("DUPLICATE month")
revenue = None
if not flags:
revenue = numbers["leads"] * rate * deal
accepted_total += revenue
review.append({
**row,
"projected_revenue": format(revenue, ".2f") if revenue is not None else "NOT CALCULATED",
"flag": "; ".join(flags) if flags else "NONE",
})
print(json.dumps({
"columns": columns,
"row_count": len(rows),
"duplicate_months": duplicates,
"missing_values": missing,
"nonnumeric_values": nonnumeric,
"review": review,
"excluded_rows": [row["month"] for row in review if row["flag"] != "NONE"],
"accepted_row_total": format(accepted_total, ".2f"),
}, indent=2))
Running this code yourself is a local calculation check, not evidence that ChatGPT ran it. If ChatGPT says it used code, inspect the actual analysis details and compare the method and rows with the source. A model’s prose assertion that it calculated the result is not execution proof.
3. Apply the decision check
The file is ready for human review only when:
- All six source rows appear in the review table.
- May remains visible with a missing-value flag.
- June remains visible with an invalid-value flag.
- No value was invented for either row.
- The accepted-row total is 173,000.
- The note calls the rows review flags and does not present the forecast as a commitment.
If any check fails, fix the input or prompt and run the review again. Do not share a polished total while its assumptions are still unclear.
Troubleshooting
- A blank value becomes zero: restate that missing values must remain visible and excluded from the total.
- Every row receives a total: ask for an accepted-row rule and a separate excluded-row list.
- The result looks complete but the row count is wrong: ask for the original row count and compare it with the review table before reading the summary.
Limits and privacy
ChatGPT’s documentation says file and feature availability varies, and that the analysis environment cannot make external web requests or API calls. Review the generated method and output. Do not upload confidential forecasts unless your organization’s approved policy allows it.
Next step
Use this same review pattern for a budget, hiring plan or launch pipeline, changing the acceptance rules to fit the file. For a weekly practical workflow, join The Weekly Verdict.