import csv from datetime import datetime, timedelta from collections import defaultdict import statistics # Load CGM data cgm = [] with open('/home/ben/downloads/Blood Glucose-2026-02-19-2026-03-17.csv') as f: reader = csv.DictReader(f) for row in reader: dt = datetime.strptime(row['Date/Time'], '%Y-%m-%d %H:%M:%S') bg = int(row['Blood Glucose (mg/dL)']) cgm.append((dt, bg)) cgm.sort(key=lambda x: x[0]) daily = defaultdict(list) for dt, bg in cgm: daily[dt.strftime('%Y-%m-%d')].append((dt, bg)) # Pre-Lent (Feb 19-23) vs Early Lent (Feb 24 - Mar 2) vs Mid Lent (Mar 3-9) vs Late Lent (Mar 10-17) periods = { 'Pre-Lent (Feb 19-23)': ('2026-02-19', '2026-02-23'), 'Early Lent OMAD (Feb 24 - Mar 2)': ('2026-02-24', '2026-03-02'), 'Mid Lent (Mar 3-9)': ('2026-03-03', '2026-03-09'), 'Late Lent (Mar 10-17)': ('2026-03-10', '2026-03-17'), } print("="*80) print("PERIOD COMPARISON") print("="*80) for name, (start, end) in periods.items(): readings = [] for date_str in sorted(daily.keys()): if start <= date_str <= end: readings.extend([bg for dt, bg in daily[date_str]]) if not readings: continue mean = statistics.mean(readings) tir = sum(1 for bg in readings if 70 <= bg <= 140) / len(readings) * 100 above_140 = sum(1 for bg in readings if bg > 140) / len(readings) * 100 above_160 = sum(1 for bg in readings if bg > 160) / len(readings) * 100 cv = (statistics.stdev(readings) / mean) * 100 # Overnight only (4-6am) overnight = [] for date_str in sorted(daily.keys()): if start <= date_str <= end: overnight.extend([bg for dt, bg in daily[date_str] if 4 <= dt.hour < 6]) on_mean = statistics.mean(overnight) if overnight else 0 print(f"\n{name}:") print(f" Mean: {mean:.0f}, CV: {cv:.1f}%, TIR: {tir:.0f}%") print(f" >140: {above_140:.1f}%, >160: {above_160:.1f}%") print(f" Min: {min(readings)}, Max: {max(readings)}") print(f" Overnight (4-6am): {on_mean:.0f}") print(f" Readings: {len(readings)}") # Reactive hypoglycemia frequency print("\n\n" + "="*80) print("REACTIVE HYPOGLYCEMIA ANALYSIS") print("="*80) # Find all drops below 90 that follow a meal spike reactive_events = [] for date_str in sorted(daily.keys()): day_data = sorted(daily[date_str], key=lambda x: x[0]) for i, (dt, bg) in enumerate(day_data): if bg < 90: # Check if there was a reading >130 in the prior 4 hours prior_high = max( (bg2 for dt2, bg2 in day_data if timedelta(0) < (dt - dt2) < timedelta(hours=4)), default=0 ) if prior_high > 125: reactive_events.append((dt, bg, prior_high)) print(f"\nTotal reactive drops (<90 after >125 spike): {len(reactive_events)}") for dt, low, high in reactive_events: print(f" {dt.strftime('%b %d %H:%M')}: dropped to {low} (prior high: {high})") # Look at fasting duration vs pre-meal glucose correlation print("\n\n" + "="*80) print("FASTING DURATION vs PRE-MEAL GLUCOSE") print("="*80) fasting_data = [ (21.9, 103), (19.2, 115), (17.0, 112), (14.6, 126), (18.6, 115), (19.4, 103), (14.3, 120), (10.8, 115), (11.8, 115), (18.7, 108), (13.6, 110), (14.3, 101), (18.8, 98), ] # Simple correlation n = len(fasting_data) sum_x = sum(h for h, g in fasting_data) sum_y = sum(g for h, g in fasting_data) sum_xy = sum(h * g for h, g in fasting_data) sum_x2 = sum(h ** 2 for h, g in fasting_data) sum_y2 = sum(g ** 2 for h, g in fasting_data) r = (n * sum_xy - sum_x * sum_y) / ((n * sum_x2 - sum_x**2) * (n * sum_y2 - sum_y**2)) ** 0.5 print(f"\nCorrelation (fast hours vs pre-meal BG): r = {r:.3f}") print("(negative = longer fasts → lower pre-meal glucose)") for h, g in sorted(fasting_data, key=lambda x: x[0]): print(f" {h:.1f}h fast → {g} mg/dL pre-meal") # Best and worst days analysis print("\n\n" + "="*80) print("WHAT MAKES A GOOD vs BAD DAY") print("="*80) good_days = ['2026-02-28', '2026-03-05', '2026-03-06', '2026-03-14', '2026-03-15', '2026-03-16'] bad_days = ['2026-02-19', '2026-03-07', '2026-02-23', '2026-02-24'] print("\nGood days (mean <115):") for d in good_days: readings = [bg for dt, bg in daily.get(d, [])] if readings: print(f" {d}: mean {statistics.mean(readings):.0f}, max {max(readings)}") print("\nBad days (mean >125 or max >180):") for d in bad_days: readings = [bg for dt, bg in daily.get(d, [])] if readings: print(f" {d}: mean {statistics.mean(readings):.0f}, max {max(readings)}")