$extens("include.py") include("import os", []) def csv_report(path: str = "~/extella-demo-data/orders.csv", group_by: str = "region", value: str = "amount", top: int = 5, filter_column: str = "", filter_value: str = "") -> dict: # A report over a CSV file that lives on the device this program runs on. # Groups the rows by one column, sums a numeric column, returns the top groups. import csv, hashlib, os, platform, socket, time started = time.time() full = os.path.expanduser(path) if not os.path.isfile(full): return {"status": "error", "reason": "no such file on this device: " + path} raw = open(full, "rb").read() rows = list(csv.DictReader(raw.decode("utf-8", "replace").splitlines())) columns = list(rows[0].keys()) if rows else [] for name in (group_by, value): if name not in columns: return {"status": "error", "reason": "no column " + str(name) + " in the file", "columns": columns} if filter_column and filter_column not in columns: return {"status": "error", "reason": "no column " + str(filter_column) + " in the file", "columns": columns} totals, counts, used, skipped = {}, {}, 0, 0 for row in rows: if filter_column and not str(row.get(filter_column, "")).startswith(str(filter_value)): continue try: number = float(row[value]) except (TypeError, ValueError): skipped += 1 continue key = row[group_by] totals[key] = totals.get(key, 0.0) + number counts[key] = counts.get(key, 0) + 1 used += 1 grand = sum(totals.values()) limit = max(1, min(int(top), 50)) ordered = sorted(totals.items(), key=lambda item: -item[1])[:limit] table = [{"group": key, "total": round(total, 2), "rows": counts[key], "share": round(100.0 * total / grand, 1) if grand else 0.0} for key, total in ordered] return {"status": "success", "table": table, "group_by": group_by, "value": value, "filter": (filter_column + "=" + str(filter_value) + "*") if filter_column else "", "rows_in_file": len(rows), "rows_used": used, "rows_skipped": skipped, "groups": len(totals), "grand_total": round(grand, 2), "file": path, "file_sha256": hashlib.sha256(raw).hexdigest(), "host": socket.gethostname(), "os": platform.system() + " " + platform.machine(), "seconds_on_device": round(time.time() - started, 3)}