quill: add csv_summary.py artifact with sample and verifier

This commit is contained in:
quill committed 2026-11-01 21:51:57 +00:00
1 parent 8ea25bf50f
commit 558f259da9
3 files changed
+91

No files matched your search

+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env python3
"""csv_summary.py — Read a CSV from stdin or a file argument and emit JSON summary statistics."""
import sys
import json
import csv
from collections import defaultdict
from statistics import mean, median
def summarize_csv(path=None):
fh = open(path, newline='') if path else sys.stdin
reader = csv.DictReader(fh)
rows = list(reader)
fh.close() if path else None
if not rows:
return {"rows": 0, "columns": [], "numeric": {}}
columns = reader.fieldnames or []
numeric = {}
for col in columns:
values = []
for row in rows:
try:
values.append(float(row[col]))
except (ValueError, TypeError):
pass
if values:
numeric[col] = {
"count": len(values),
"sum": round(sum(values), 4),
"mean": round(mean(values), 4),
"median": round(median(values), 4),
"min": round(min(values), 4),
"max": round(max(values), 4),
}
return {
"rows": len(rows),
"columns": columns,
"numeric": numeric,
}
def main():
path = sys.argv[1] if len(sys.argv) > 1 else None
result = summarize_csv(path)
json.dump(result, sys.stdout, indent=2)
sys.stdout.write("\n")
if __name__ == "__main__":
main()
+6
View File
@@ -0,0 +1,6 @@
name,age,salary,active
Alice,30,50000,true
Bob,25,45000,false
Charlie,35,70000,true
Diana,28,52000,true
Eve,32,48000,false
1 name age salary active
2 Alice 30 50000 true
3 Bob 25 45000 false
4 Charlie 35 70000 true
5 Diana 28 52000 true
6 Eve 32 48000 false
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/env python3
"""verify_summary.py — Assert csv_summary.py output matches expected values."""
import sys
import json
expected_rows = 5
expected_columns = ["name", "age", "salary", "active"]
expected_age = {
"count": 5,
"sum": 150.0,
"mean": 30.0,
"median": 30.0,
"min": 25.0,
"max": 35.0,
}
expected_salary = {
"count": 5,
"sum": 265000.0,
"mean": 53000.0,
"median": 50000.0,
"min": 45000.0,
"max": 70000.0,
}
data = json.load(sys.stdin)
assert data["rows"] == expected_rows, f"rows: {data['rows']}"
assert data["columns"] == expected_columns, f"columns: {data['columns']}"
age = data["numeric"]["age"]
for k, v in expected_age.items():
assert age[k] == v, f"age.{k}: {age[k]} != {v}"
sal = data["numeric"]["salary"]
for k, v in expected_salary.items():
assert sal[k] == v, f"salary.{k}: {sal[k]} != {v}"
print("VERIFIED")