{"schemaVersion":"1.0","type":"Article","types":["Article"],"slug":"check-an-ai-generated-csv-before-you-trust-its-totals-ja6kw","url":"https://zyvop.com/check-an-ai-generated-csv-before-you-trust-its-totals-ja6kw","title":"Check an AI-generated CSV before you trust its totals","subtitle":null,"tldr":"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...","keywords":["Yossi Gerson","Yosef Gerson"],"entities":["Yosef Gerson","Yossi Gerson","ZyVOP"],"keyTakeaways":["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."],"headings":["The rules come first","Use this fictional input","Why use a CSV parser and decimal arithmetic","The checker","What you should see","Try breaking it deliberately","What this checker deliberately leaves out","The practical workflow","Python references"],"outboundLinks":["https://docs.python.org/3/library/csv.html","https://docs.python.org/3/library/decimal.html"],"contentText":"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 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) &gt; Decimal('1000000000') for value in values): errors.append(f\"{label}: outside this example's numeric range\") continue if quantity &lt;= 0 or quantity != quantity.to_integral_value(): errors.append(f'{label}: quantity must be a positive integer') continue if price &lt; 0 or total &lt; 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 Decimal fixed-point and floating-point arithmetic: https://docs.python.org/3/library/decimal.html","contentHash":"sha256:afb88fab2014857ccca2da57700bdfad3542676992ddb865b543a4fbbfc33510","authorName":"Yosef Gerson","authorUrl":"https://zyvop.com/author/yosefgerson","authorSameAs":[],"category":null,"tags":["Yossi Gerson","Yosef Gerson"],"audience":"Software engineers and developers building applications with Yossi Gerson","tone":"Practical and evidence-based engineering guidance","readingTimeMinutes":4,"wordCount":1057,"faqs":null,"primaryTopic":"Yossi Gerson","publishedAt":"2026-11-09T19:01:10.015Z","updatedAt":"2026-11-09T19:01:10.015Z","canonicalUrl":"https://zyvop.com/check-an-ai-generated-csv-before-you-trust-its-totals-ja6kw"}