Check an AI-generated CSV before you trust its totals A tutorial by Yosef Gerson presents a standard-library Python script, check_table.py, that validates AI-generated CSV tables without contacting any AI service, checking column headers, field counts, numeric finiteness, a one-billion value ceiling, positive-integer quantities, cent precision and each line total against quantity times unit price. In the fictional sample table, the checker flags the folder record because four folders at $1.25 each cost $5.00, not the stated $6.00. The piece argues that separating the language task of turning notes into rows from repeatable software checks catches arithmetic errors a table can hide. By Yosef Gerson A table can look orderly and still contain a wrong total. If an AI helps turn notes into rows, separate the language task from checks that software can repeat exactly. This tutorial builds a small local Python checker for a fictional shopping table. It checks the columns, the shape of each record, the permitted kinds of numbers and the multiplication behind each line total. It does not contact an AI service, send data anywhere or alter a file. The rules come first For this exercise, each record describes an item sold in whole units. Quantity must be a positive integer. Unit price and line total must be nonnegative amounts that fit cent precision. Values larger than one billion are outside this deliberately bounded example. No tax, discounts, returns or delivery charges are included. Those assumptions matter. A rule requiring whole quantities would be wrong for items sold by weight. A rule rejecting negative totals would be wrong for a table that intentionally includes refunds. Write the rules for your actual data before adapting the code. Use this fictional input item,quantity,unit price,line total Notebook,3,2.40,7.20 Folder,4,1.25,6.00 Pen,2,0.90,1.80 The folder record is deliberately wrong. Four folders at $1.25 each cost $5.00, not $6.00. The other two records are arithmetically consistent. Why use a CSV parser and decimal arithmetic Splitting every line at each comma is fragile because CSV can contain quoted fields with commas. Python's csv module handles that structure. Decimal constructs decimal numbers from their text representation, avoiding the familiar binary floating-point representation issue for values such as 0.1. This example still needs explicit validation: Decimal can represent NaN and infinity, which are not acceptable prices here. The checker Save the following as check table.py. It uses only Python's standard library. Run it with Python 3 using: python3 check table.py python import csv from decimal import Decimal, InvalidOperation from io import StringIO COLUMNS = 'item', 'quantity', 'unit price', 'line total' def check table text : reader = csv.DictReader StringIO text if reader.fieldnames = COLUMNS: return 'Header must be: ' + ','.join COLUMNS errors = row count = 0 for number, row in enumerate reader, start=2 : row count += 1 label = f'Record {number}' if None in row or any value is None for value in row.values : errors.append f'{label}: wrong number of fields' continue if not row 'item' .strip : errors.append f'{label}: item is blank' try: quantity = Decimal row 'quantity' price = Decimal row 'unit price' total = Decimal row 'line total' except InvalidOperation: errors.append f'{label}: invalid number' continue values = quantity, price, total if not all value.is finite for value in values : errors.append f'{label}: non-finite number' continue if any abs value Decimal '1000000000' for value in values : errors.append f"{label}: outside this example's numeric range" continue if quantity <= 0 or quantity = quantity.to integral value : errors.append f'{label}: quantity must be a positive integer' continue if price < 0 or total < 0: errors.append f'{label}: negative money value' continue if any value = value.quantize Decimal '0.01' for value in price, total : errors.append f'{label}: money must have cent precision' continue expected = quantity price if total = expected: errors.append f'{label}: expected {expected:.2f}, got {total:.2f}' if row count == 0: errors.append 'No data records' return errors if name == ' main ': example = '''item,quantity,unit price,line total Notebook,3,2.40,7.20 Folder,4,1.25,6.00 Pen,2,0.90,1.80 ''' problems = check table example print '\n'.join problems if problems else 'Checks passed' What you should see Record 3: expected 5.00, got 6.00 The record number includes the header as record 1. It is not necessarily a physical line number: a quoted CSV field may itself contain a newline. Change Folder's line total to 5.00 and run it again. For that corrected sample, the output is Checks passed. A successful run means the implemented checks found no problem; it does not establish that the products, quantities or prices are true. Try breaking it deliberately Make one change at a time, restoring the input after each test: - Replace a price with NaN. Expect a non-finite number warning. - Change a quantity to 1.5. Expect the positive-integer rule to fail. - Remove a field from a row. Expect a wrong-number-of-fields warning. - Change a price to 0.905. Expect the cent-precision rule to fail. - Remove every data record. Expect No data records. These cases help distinguish a checker that detects faults from one that merely prints a reassuring message. The supplied code was exercised against eight small cases, including valid input, incorrect multiplication, missing fields, fractional quantity, sub-cent prices, NaN, an empty table and an out-of-range number. That is a limited test set, not a production certification. What this checker deliberately leaves out It does not know whether a source document listed two pens or twenty. It does not detect duplicate purchases, omitted records, inconsistent item names or a plausible but fabricated price. A wrong input can still produce a perfectly correct multiplication result. It also does not implement an invoice system, tax rules or spreadsheet-formula sanitization. A text field beginning with a spreadsheet formula character needs separate handling if you later export it to software that evaluates formulas. This code does not export or open spreadsheets. Malformed CSV syntax, very large files and arbitrary hostile inputs need more defensive handling than this teaching example provides. Use a separate source review alongside the code. Match records to the original source, check missing and duplicated entries, and make sure the rules fit the data. Keep sensitive records out of online tools unless you understand and have authorized their handling. The practical workflow Keep the original source and the generated table separately. Run checks on a copy. Review every reported problem against the source rather than silently replacing a value because a formula suggests another answer. Then preserve the corrected version with a short note of what changed. If the table needs a new rule, add that rule and a small failing example together. You can then show both that the problem is caught and that a valid row still passes. Prepared with AI assistance. The data is fictional. The code and worked example were tested locally; the limitations above are part of the example. Python references CSV file reading and writing: https://docs.python.org/3/library/csv.html https://docs.python.org/3/library/csv.html Decimal fixed-point and floating-point arithmetic: https://docs.python.org/3/library/decimal.html https://docs.python.org/3/library/decimal.html