Donkey

Code Debug: Single Bug Fix

Paste your broken code and the error, and get back a fix plus a plain-English explanation of what went wrong.

What you get: A Markdown report with a one-line diagnosis and confidence level, a plain-English explanation of the root cause, the complete corrected code with changed lines marked, a before/after change table, a step-by-step test checklist, and a ranked fallback list if the bug turns out to be environment-specif Price: $15 flat. Time: usually ready in minutes. Done by AI; you review it, with one free change.

We're not taking orders yet. Join the waitlist and we'll email you once when we open.

Real example

This is an actual result our AI made in a test run, from sample details. Yours is made from your details.

Show the example

Bug Fix Report

1. Diagnosis in one line

Python's CSV reader gives you every value as text, so order['amount'] is a string like "42.50", or "" for a cancelled order. Adding text to the number total fails.

Confidence: High. The error message names the exact types involved, a whole number and a piece of text. That's how csv.DictReader always behaves, and the blank amounts you mentioned are a second problem on the same line.

2. What went wrong (plain English)

Your script reads orders.csv, adds up the amount column and divides the total by the number of orders to get the average.

The problem is on line 14: total += order['amount']. csv.DictReader doesn't guess what kind of data is in each column. Everything comes back as text. So the first time through the loop, Python is asked to do 0 + "42.50". It won't add a number to text, so it stops with unsupported operand type(s) for +=: 'int' and 'str'. In that message, int is your starting total = 0 and str is the text from the CSV.

Converting the text to a number fixes that part. But your cancelled orders have a blank amount, and turning a blank into a number causes its own crash (a ValueError). So the fix also has to skip blank rows.

My assumption: cancelled orders shouldn't count toward the average at all. They're left out of the total and out of the number you divide by. If you divided by every row, including cancelled ones, the average would come out too low.

3. Fixed code

import csv

def load_orders(path):
    orders = []
    with open(path, newline='') as f:
        reader = csv.DictReader(f)
        for row in reader:
            orders.append(row)
    return orders

def average_order_value(orders):
    total = 0
    count = 0  # FIXED: count only orders that actually have an amount
    for order in orders:
        amount = (order['amount'] or '').strip()  # FIXED: get the text value (or '' if missing) and trim spaces
        if amount == '':  # FIXED: skip cancelled orders with a blank amount
            continue  # FIXED
        total += float(amount)  # FIXED: convert text like "42.50" into a number before adding
        count += 1  # FIXED: this row counts toward the average
    return total / count  # FIXED: divide by real (non-blank) orders, not every row

if __name__ == '__main__':
    orders = load_orders('orders.csv')
    print('Average order value:', round(average_order_value(orders), 2))

4. What changed

Location (line/function) Before After Why
average_order_value, new line after total = 0 (none) count = 0 Keeps track of how many orders have a real amount.
average_order_value, start of loop (none) amount = (order['amount'] or '').strip() Gets the amount as clean text. or '' covers a row so short that the field is missing entirely.
average_order_value, in loop (none) if amount == '': continue Skips cancelled orders with blank amounts, so they don't crash the conversion or distort the average.
average_order_value, line 14 total += order['amount'] total += float(amount) Turns the text into a decimal number so it can be added. This was the line that crashed.
average_order_value, in loop (none) count += 1 Counts this order toward the average.
average_order_value, return return total / len(orders) return total / count Divides by real orders only, so cancelled rows don't pull the average down.

5. How to test it

  • Save a copy of your script, put the fixed average_order_value function in it, and run python3 report.py in Terminal from your shop folder.
  • Quick check with known numbers: make a file test.csv containing the three lines amount, 40, 45, then a blank row for a cancelled order (, if there are other columns, or just an empty line if amount is the only one). Point the script at test.csv and you should see Average order value: 42.5, because (40 + 45) ÷ 2.
  • Run it on your real orders.csv and compare the result with Shopify's own average order value for the same date range. It should be close, though Shopify may treat refunds or taxes differently.
  • Edge case: put a space in one blank amount cell (" "). It should still be skipped without crashing.
  • Edge case: try a CSV where every amount is blank. You'll get a ZeroDivisionError. That's expected for now; see Section 7.

6. If it still doesn't work

  1. Amounts contain symbols or commas ($42.50 or 1,250.00) and the script crashes with ValueError: could not convert string to float. To check, add print(repr(amount)) just above the float(amount) line and look at the last value printed before the crash. If you see symbols, remove them first, for example amount.replace('$', '').replace(',', '').
  2. KeyError: 'amount' means the column header doesn't exactly match amount. Real Shopify exports often call it Total or Subtotal, and sometimes the file starts with a hidden character (a "BOM") stuck to the first header. To check, add print(list(orders[0].keys())) after load_orders. If the first name starts with '\ufeff', change the open(...) line to open(path, newline='', encoding='utf-8-sig').
  3. The number looks wrong but there's no crash. You might be averaging the wrong column, or your export might list one row per item, not per order. Shopify order exports can repeat an order across several rows, and the extra rows often have a blank total. To check, open the CSV in Numbers or Excel and see whether the same order number appears on more than one row.

To pin it down, it would help to have the first 3–5 lines of orders.csv (with customer details removed) and the full error text if a new one appears.

7. Other things I noticed (optional)

  • If the file is empty or every order is cancelled, count stays at 0 and dividing by it crashes. You could add if count == 0: return 0 just before the retu

Questions

How does the code debug: single bug fix work?

You answer a few questions, pay $15, and an AI worker does the job. The result appears on your private page, usually within minutes.

Can I get changes?

Yes. Every job includes one free change request: tell the donkey what to fix and it redoes the job with your notes.

Is it really done by AI?

Yes, fully. No human writes it. AI can make mistakes, so please review the result before you rely on it.

What happens to my information?

It is used only to do your job, is never used to train AI models, and is deleted after 30 days.

What if it fails?

Failed jobs are retried once, then refunded automatically.

Need something different?

Can't find it? Describe anything.

Our AI checks it's something we can do safely, then shows you exactly what you'll get and a flat price. Nothing is charged until you order.

More in Tech & code