50 year old woman with diabtetes on meds viliga -M also on levothyroxine 75 mcg hasfamily history of diabetes in father and father passed away due to lung cancer and mother has rheumatoid arthritis patient has long standing history or
Long standing history of varicose veins and now her lower legs on the back inner and oiter side have turned pigmented has constant itchying urge also feels numbing on sitting crosslegged and then getting up after 20-30 mins has also had dry cough since 2 weeks what all do you think this woman need to undergo checking for as part or screening routine and spefcific tobher
| Test | Reason |
|---|---|
| Duplex Venous Ultrasound (bilateral lower limb) | Gold standard - maps superficial and deep venous reflux, identifies incompetent perforators, rules out DVT |
| ABI (Ankle-Brachial Index) | Must rule out arterial disease before compression therapy, especially in diabetics |
| Skin biopsy (if diagnosis uncertain) | Rule out contact dermatitis, vasculitis, or diabetic dermopathy |
| D-Dimer + Doppler | If acute DVT component cannot be excluded |
| Test | Reason |
|---|---|
| 10-g monofilament test (Semmes-Weinstein) | Detects LOPS - mandatory annual test |
| 128 Hz tuning fork at base of great toe | Vibration sensation screening |
| Ankle reflexes | Reduced/absent in peripheral neuropathy |
| Nerve Conduction Studies (NCS) / EMG | If clinical examination is ambiguous - quantifies neuropathy |
| HbA1c | Glycemic control drives neuropathy progression |
| Pinprick sensation testing | Small fiber neuropathy |
| Orthostatic blood pressure | Autonomic neuropathy - screen at diagnosis of T2DM |
| Test | Frequency | Reason |
|---|---|---|
| HbA1c | Every 3-6 months | Glycemic control target |
| Fasting glucose / SMBG log | Ongoing | Day-to-day monitoring |
| Urine Albumin-to-Creatinine Ratio (UACR) | Annual | Early diabetic nephropathy |
| Serum Creatinine + eGFR | Annual | Renal function; also required for metformin dosing |
| Lipid profile (LDL, HDL, TG, Total Chol) | Annual | Cardiovascular risk - high in diabetics |
| Retinal examination (fundoscopy/slit lamp) | Annual | Diabetic retinopathy |
| Foot examination | Annual (every visit ideally) | Ulcer risk, LOPS |
| Blood pressure | Every visit | Target <130/80 in diabetics |
| ECG | Annual (or as indicated) | Silent ischemia common in diabetic women |
| Dental exam | Biannual | Periodontal disease more frequent in DM |
| Test | Reason |
|---|---|
| Chest X-ray | First-line for cough + lung cancer family history |
| Low-dose CT chest (LDCT) | If smoking history ≥10 pack-years or clinical suspicion |
| TSH + Free T4 | Check levothyroxine adequacy; hypothyroidism can cause dry cough/hoarseness |
| Spirometry / PFTs | Rule out obstructive/restrictive lung disease |
| Review Vildagliptin | If cough began after medication start/dose change - consider switch to SGLT2i or GLP-1 agonist |
| GERD workup | Diabetic gastroparesis predisposes to GERD-induced cough |
| ENT referral | If UACS (upper airway cough syndrome) or postnasal drip |
| Test | Frequency |
|---|---|
| TSH | Every 6-12 months once stable |
| Free T4 | If TSH is abnormal |
| Anti-TPO antibodies | If not previously done (confirms Hashimoto's etiology) |
| Thyroid ultrasound | If goiter or nodule detected |
| Test | Reason |
|---|---|
| Rheumatoid Factor (RF) + Anti-CCP antibodies | Early RA screening - most specific marker |
| ANA (Antinuclear Antibody) | Screening for broader autoimmune disease (SLE, Sjogren's) |
| ESR + CRP | Systemic inflammation marker |
| Schirmer's test / dry eye and dry mouth symptoms | Rule out Sjogren's syndrome (commonly comorbid with Hashimoto's + RA family history) |
| Screening | Recommendation |
|---|---|
| Mammography | Annual or biennial from age 40-50 (varies by guideline) |
| Pap smear + HPV co-test | Every 5 years (if previous normal) |
| Colonoscopy | From age 45 (ACS) - due for first if never done |
| Low-dose CT chest | If smoking history - father's lung cancer adds context |
| DEXA scan (bone density) | Perimenopausal women with hypothyroidism (levothyroxine at supraphysiologic dose suppresses bone density) |
| Test | Reason |
|---|---|
| Fasting lipid profile | Dyslipidemia in DM + hypothyroidism |
| ECG | Baseline; silent ischemia |
| ECHO or stress test | If chest symptoms or multiple risk factors |
| Carotid intima-media thickness (CIMT) or coronary calcium score | 10-year cardiovascular risk stratification in high-risk women |
| Framingham / ASCVD risk score calculation | Guides statin initiation |
Clinical note: This patient has overlapping metabolic, venous, autoimmune, and medication-related issues. A methodical systems review with the above panel will avoid missing any of the key diagnoses.
Create a tracking table for annual diabetes screening dates 42/43 maybe for autoimmune itself father didnt have smoking history nor does she early menarche early menopause
ls /home/daytona/workspace/ 2>/dev/null || echo "workspace not found"
Diagnosed with thyroiditis when she was taking diabtets meds from her diabetologist diabetes screening dates 42/43 maybe for autoimmune itself father didnt have smoking history nor does she early menarche early menopause
mkdir -p /home/daytona/workspace/patient-tracker && ls /home/daytona/workspace/patient-tracker/
~/patient-tracker/build_tracker.py
import openpyxl
from openpyxl.styles import (
Font, PatternFill, Alignment, Border, Side, GradientFill
)
from openpyxl.utils import get_column_letter
from openpyxl.styles.numbers import FORMAT_DATE_DDMMYY
from datetime import date
wb = openpyxl.Workbook()
# ── colour palette ──────────────────────────────────────────────────────────
C_HEADER_DARK = "1F3864" # deep navy
C_HEADER_MID = "2E75B6" # mid blue
C_SECTION_DM = "D6E4F0" # light blue – Diabetes
C_SECTION_TH = "E8F5E9" # light green – Thyroid / Autoimmune
C_SECTION_VEN = "FFF3E0" # light amber – Venous / Vascular
C_SECTION_GYN = "FCE4EC" # light pink – Gynaecology / Hormonal
C_SECTION_CAN = "F3E5F5" # light lavender – Cancer screening
C_SECTION_CV = "FFEBEE" # light red – Cardiovascular
C_SECTION_MED = "E8EAF6" # light indigo – Medication review
C_WHITE = "FFFFFF"
C_DONE = "C8E6C9" # tick-green
C_DUE = "FFF9C4" # amber-yellow
C_OVERDUE = "FFCDD2" # soft red
C_TEXT_DARK = "1A1A2E"
C_ACCENT = "FF6F00" # orange for alerts
def mk_fill(hex_col):
return PatternFill("solid", fgColor=hex_col)
def mk_font(bold=False, size=10, color=C_TEXT_DARK, italic=False):
return Font(name="Arial", bold=bold, size=size, color=color, italic=italic)
def mk_border(style="thin"):
s = Side(style=style, color="BDBDBD")
return Border(left=s, right=s, top=s, bottom=s)
def mk_align(h="center", v="center", wrap=True):
return Alignment(horizontal=h, vertical=v, wrap_text=wrap)
# ═══════════════════════════════════════════════════════════════════════════
# SHEET 1 – PATIENT SUMMARY
# ═══════════════════════════════════════════════════════════════════════════
ws_sum = wb.active
ws_sum.title = "Patient Summary"
ws_sum.sheet_view.showGridLines = False
# Title banner
ws_sum.merge_cells("A1:H1")
ws_sum["A1"] = "PATIENT HEALTH TRACKING RECORD"
ws_sum["A1"].font = mk_font(bold=True, size=16, color=C_WHITE)
ws_sum["A1"].fill = mk_fill(C_HEADER_DARK)
ws_sum["A1"].alignment = mk_align()
ws_sum.merge_cells("A2:H2")
ws_sum["A2"] = "Confidential – Clinical Screening & Follow-up Tracker"
ws_sum["A2"].font = mk_font(italic=True, size=10, color="BDBDBD")
ws_sum["A2"].fill = mk_fill(C_HEADER_DARK)
ws_sum["A2"].alignment = mk_align()
ws_sum.row_dimensions[1].height = 30
ws_sum.row_dimensions[2].height = 18
# ── Profile block ────────────────────────────────────────────────────────
profile = [
("Age", "50 years"),
("Sex", "Female"),
("Diabetes Dx", "Type 2 DM – approx age 42-43"),
("Thyroid Dx", "Autoimmune Thyroiditis (Hashimoto's) – diagnosed ~age 42-43 during DM workup"),
("Current Meds", "Vildagliptin-M (Vildagliptin + Metformin) | Levothyroxine 75 mcg"),
("Menstrual Hx", "Early Menarche | Early Menopause (~50 or before) – prolonged estrogen window THEN abrupt loss"),
("Family Hx", "Father: Type 2 DM (no smoking) | Mother: Rheumatoid Arthritis"),
("Venous Hx", "Long-standing Varicose Veins → CVI with hemosiderin pigmentation & stasis dermatitis"),
("Current Complaint", "Leg pigmentation (inner/outer/posterior), itching, positional numbness, dry cough 2 weeks"),
]
ws_sum.merge_cells("A4:B4")
ws_sum["A4"] = "PATIENT PROFILE"
ws_sum["A4"].font = mk_font(bold=True, size=11, color=C_WHITE)
ws_sum["A4"].fill = mk_fill(C_HEADER_MID)
ws_sum["A4"].alignment = mk_align()
ws_sum.merge_cells("C4:H4")
ws_sum["C4"] = ""
ws_sum["C4"].fill = mk_fill(C_HEADER_MID)
for i, (label, value) in enumerate(profile, start=5):
r = i
ws_sum[f"A{r}"] = label
ws_sum[f"A{r}"].font = mk_font(bold=True, size=10)
ws_sum[f"A{r}"].fill = mk_fill("EBF5FB")
ws_sum[f"A{r}"].alignment = mk_align(h="left")
ws_sum[f"A{r}"].border = mk_border()
ws_sum.merge_cells(f"B{r}:H{r}")
ws_sum[f"B{r}"] = value
ws_sum[f"B{r}"].font = mk_font(size=10)
ws_sum[f"B{r}"].fill = mk_fill(C_WHITE)
ws_sum[f"B{r}"].alignment = mk_align(h="left")
ws_sum[f"B{r}"].border = mk_border()
ws_sum.row_dimensions[r].height = 28
# Key risk flags
flag_row = len(profile) + 6
ws_sum.merge_cells(f"A{flag_row}:H{flag_row}")
ws_sum[f"A{flag_row}"] = "⚠ KEY RISK FLAGS FOR THIS PATIENT"
ws_sum[f"A{flag_row}"].font = mk_font(bold=True, size=11, color=C_WHITE)
ws_sum[f"A{flag_row}"].fill = mk_fill(C_ACCENT)
ws_sum[f"A{flag_row}"].alignment = mk_align()
ws_sum.row_dimensions[flag_row].height = 22
flags = [
("1", "BREAST CANCER RISK ELEVATED",
"Early menarche + early menopause = prolonged estrogen exposure window. Park's Preventive Medicine: '40+ years menstruation doubles breast cancer risk.' Annual mammography mandatory."),
("2", "OVARIAN / ENDOMETRIAL CANCER RISK",
"Early menarche is a risk factor for ovarian cancer (Schwartz Surgery). Early menopause adds pelvic atrophy. Pelvic ultrasound + CA-125 baseline warranted."),
("3", "CARDIOVASCULAR RISK – EARLY MENOPAUSE",
"Harrison's 22E: early menopause associated with 1.5x CVD/stroke risk. Combined with DM + autoimmune disease = high cardiac risk. Statin therapy + ECG + ECHO review."),
("4", "AUTOIMMUNE CLUSTER RISK",
"Hashimoto's thyroiditis confirmed + mother with RA = autoimmune diathesis. Screen for RA (Anti-CCP), Sjogren's (ANA, Schirmer's), Celiac (anti-tTG IgA), Vitiligo, Pernicious anaemia."),
("5", "DRY COUGH – VILDAGLIPTIN OR THYROID",
"DPP-4 inhibitors cause cough via bradykinin pathway. Also check levothyroxine adequacy (TSH). Father had lung cancer (non-smoker) – LDCT chest if suspicious."),
("6", "DIABETIC NEUROPATHY vs POSITIONAL COMPRESSION",
"Numbness on cross-legged sitting may be early LOPS from DPN OR peroneal entrapment (worsened in diabetics). Monofilament + NCS mandatory."),
("7", "OSTEOPOROSIS RISK – EARLY MENOPAUSE + LEVOTHYROXINE",
"Early menopause = estrogen withdrawal → bone loss. Levothyroxine at suppressive doses further accelerates bone loss. DEXA scan urgently required."),
]
for row_off, (num, title, detail) in enumerate(flags, start=flag_row+1):
r = row_off
ws_sum[f"A{r}"] = num
ws_sum[f"A{r}"].font = mk_font(bold=True, size=10, color=C_WHITE)
ws_sum[f"A{r}"].fill = mk_fill("E53935")
ws_sum[f"A{r}"].alignment = mk_align()
ws_sum[f"A{r}"].border = mk_border()
ws_sum[f"B{r}"] = title
ws_sum[f"B{r}"].font = mk_font(bold=True, size=10)
ws_sum[f"B{r}"].fill = mk_fill("FFEBEE")
ws_sum[f"B{r}"].alignment = mk_align(h="left")
ws_sum[f"B{r}"].border = mk_border()
ws_sum.merge_cells(f"C{r}:H{r}")
ws_sum[f"C{r}"] = detail
ws_sum[f"C{r}"].font = mk_font(size=9, italic=True)
ws_sum[f"C{r}"].fill = mk_fill(C_WHITE)
ws_sum[f"C{r}"].alignment = mk_align(h="left")
ws_sum[f"C{r}"].border = mk_border()
ws_sum.row_dimensions[r].height = 42
# Column widths
ws_sum.column_dimensions["A"].width = 6
ws_sum.column_dimensions["B"].width = 28
for col in ["C","D","E","F","G","H"]:
ws_sum.column_dimensions[col].width = 18
# ═══════════════════════════════════════════════════════════════════════════
# SHEET 2 – ANNUAL SCREENING TRACKER
# ═══════════════════════════════════════════════════════════════════════════
ws = wb.create_sheet("Annual Screening Tracker")
ws.sheet_view.showGridLines = False
# Title
ws.merge_cells("A1:L1")
ws["A1"] = "ANNUAL DIABETES & MULTISYSTEM SCREENING TRACKER"
ws["A1"].font = mk_font(bold=True, size=14, color=C_WHITE)
ws["A1"].fill = mk_fill(C_HEADER_DARK)
ws["A1"].alignment = mk_align()
ws.row_dimensions[1].height = 28
ws.merge_cells("A2:L2")
ws["A2"] = "Patient: 50F | T2DM (dx ~42-43) | Hashimoto's Thyroiditis | Varicose Veins / CVI | Early Menarche & Early Menopause | Mother: RA"
ws["A2"].font = mk_font(italic=True, size=9, color="CCCCCC")
ws["A2"].fill = mk_fill(C_HEADER_DARK)
ws["A2"].alignment = mk_align()
ws.row_dimensions[2].height = 16
# Column headers
headers = [
"Category", "Investigation / Screening", "Why Specific to This Patient",
"Frequency", "Last Done (Date)", "Next Due (Date)",
"Result / Value", "Normal Range / Target", "Action Required",
"Done By", "Priority", "Notes"
]
ws.row_dimensions[4].height = 36
for col_i, h in enumerate(headers, start=1):
cell = ws.cell(row=4, column=col_i, value=h)
cell.font = mk_font(bold=True, size=10, color=C_WHITE)
cell.fill = mk_fill(C_HEADER_MID)
cell.alignment = mk_align()
cell.border = mk_border()
# ── Data rows ──────────────────────────────────────────────────────────────
# Format: (category, test, why, freq, last, next, result, normal, action, done_by, priority, notes, section_color)
rows = [
# ── DIABETES MONITORING ────────────────────────────────────────────────
("DIABETES\nMONITORING", "HbA1c", "T2DM on Vildagliptin-M; primary glycaemic control marker", "Every 3 months", "", "", "", "< 7.0% (53 mmol/mol)", "Adjust Vildagliptin-M if above target", "Diabetologist", "URGENT", "Dx ~age 42-43; now 50 → ~7-8 yrs of DM", C_SECTION_DM),
("DIABETES\nMONITORING", "Fasting Blood Glucose", "Daily monitoring; detect hypo/hyperglycaemia episodes", "Every visit / at home daily", "", "", "", "70-130 mg/dL (fasting)", "Review medication if persistently high", "Self / GP", "HIGH", "", C_SECTION_DM),
("DIABETES\nMONITORING", "Urine Albumin:Creatinine Ratio (UACR)", "Earliest marker of diabetic nephropathy; 7-8 yrs DM = prime onset window", "Annual", "", "", "", "< 30 mg/g", "Refer nephrology if > 300 (macroalbuminuria)", "GP / Diabetologist", "URGENT", "Metformin requires eGFR check before continuing", C_SECTION_DM),
("DIABETES\nMONITORING", "Serum Creatinine + eGFR", "Metformin must be dose-adjusted/stopped if eGFR < 45", "Annual", "", "", "", "eGFR > 60 mL/min/1.73m²", "Stop metformin if eGFR < 30", "GP", "URGENT", "", C_SECTION_DM),
("DIABETES\nMONITORING", "Lipid Profile (LDL, HDL, TG, Total)", "DM + autoimmune + early menopause = very high CVD risk; statin likely indicated", "Annual", "", "", "", "LDL < 70 mg/dL (high-risk target)", "Initiate/optimise statin; Metformin helps TG", "GP / Cardiologist", "HIGH", "Menopause worsens lipid profile independently", C_SECTION_DM),
("DIABETES\nMONITORING", "Retinal Examination (Fundoscopy)", "Diabetic retinopathy risk; 7-8 yrs DM", "Annual", "", "", "", "No retinopathy", "Ophthalmology referral if any changes", "Ophthalmologist", "HIGH", "Hypothyroidism can also cause ocular changes", C_SECTION_DM),
("DIABETES\nMONITORING", "Foot Examination (Monofilament 10g + 128Hz tuning fork + ankle reflexes)", "Diabetic peripheral neuropathy; also explains positional numbness", "Every visit (formal annual)", "", "", "", "Intact sensation; no LOPS", "Refer podiatry; Nerve Conduction Study if LOPS", "GP / Diabetologist", "URGENT", "Varicose veins + DM = compound foot ulcer risk", C_SECTION_DM),
("DIABETES\nMONITORING", "Orthostatic Blood Pressure", "Autonomic neuropathy screening; ADA recommends at T2DM diagnosis", "Annual", "", "", "", "< 20 mmHg systolic drop on standing", "Refer if symptomatic orthostatic hypotension", "GP", "MODERATE", "", C_SECTION_DM),
("DIABETES\nMONITORING", "Dental Examination", "Periodontal disease more frequent and severe in DM", "Every 6 months", "", "", "", "No periodontitis", "Refer dentist; improved glycaemia helps gums", "Dentist", "MODERATE", "", C_SECTION_DM),
# ── THYROID / AUTOIMMUNE ───────────────────────────────────────────────
("THYROID &\nAUTOIMMUNE", "TSH (Thyroid Stimulating Hormone)", "On Levothyroxine 75 mcg; Hashimoto's diagnosed during DM workup ~42-43", "Every 6 months", "", "", "", "0.5 – 4.0 mIU/L (aim 1-2.5 in treated)", "Adjust levothyroxine dose; over-treatment causes AF + bone loss", "Endocrinologist / GP", "URGENT", "TSH also explains dry cough if undertreated", C_SECTION_TH),
("THYROID &\nAUTOIMMUNE", "Free T4 (FT4)", "Confirm levothyroxine adequacy", "With TSH or if symptoms", "", "", "", "12–22 pmol/L", "Dose adjust; refer endocrinology", "GP", "HIGH", "", C_SECTION_TH),
("THYROID &\nAUTOIMMUNE", "Anti-TPO Antibodies", "Confirms Hashimoto's; titre correlates with activity", "Once (if not done); repeat every 2 yrs", "", "", "", "< 35 IU/mL", "High titres = active autoimmune disease", "Endocrinologist", "HIGH", "Mother has RA → autoimmune diathesis confirmed", C_SECTION_TH),
("THYROID &\nAUTOIMMUNE", "Anti-Thyroglobulin (Anti-Tg) Antibodies", "Hashimoto's can be seronegative for TPO but positive for Tg", "Once", "", "", "", "< 40 IU/mL", "", "Endocrinologist", "MODERATE", "", C_SECTION_TH),
("THYROID &\nAUTOIMMUNE", "Thyroid Ultrasound", "Hashimoto's → nodule surveillance; rule out malignant transformation", "Annual", "", "", "", "No nodule > 1 cm or suspicious echogenicity", "Fine needle aspiration if TIRADS 4/5", "Endocrinologist / Radiologist", "HIGH", "", C_SECTION_TH),
("THYROID &\nAUTOIMMUNE", "Rheumatoid Factor (RF) + Anti-CCP", "Mother has RA; autoimmune clustering; Anti-CCP is most specific", "Annual", "", "", "", "RF < 14 IU/mL; Anti-CCP negative", "Refer rheumatology if positive", "Rheumatologist / GP", "HIGH", "RA + DM + Hypothyroid = triple autoimmune risk", C_SECTION_TH),
("THYROID &\nAUTOIMMUNE", "ANA (Antinuclear Antibody)", "Screen for SLE, mixed CT disease, Sjogren's – all cluster with Hashimoto's", "Every 2 years", "", "", "", "Negative or low titre < 1:80", "If positive, refer rheumatology + sub-type (anti-dsDNA, anti-Ro/La)", "Rheumatologist", "MODERATE", "", C_SECTION_TH),
("THYROID &\nAUTOIMMUNE", "Anti-tTG IgA (Coeliac Screen)", "Coeliac disease clusters with Hashimoto's and T1DM; affects levothyroxine absorption", "Once; repeat if symptoms", "", "", "", "Negative", "GI referral + duodenal biopsy if positive", "Gastroenterologist", "MODERATE", "Malabsorption can cause erratic thyroid control", C_SECTION_TH),
("THYROID &\nAUTOIMMUNE", "Serum B12 + Folate", "Pernicious anaemia clusters with autoimmune thyroiditis; metformin also depletes B12", "Annual", "", "", "", "B12 > 200 pg/mL", "Supplement if low; metformin is key culprit", "GP", "HIGH", "Metformin depletes B12 → worsens neuropathy", C_SECTION_TH),
("THYROID &\nAUTOIMMUNE", "ESR + CRP", "Systemic inflammation marker; baseline for autoimmune monitoring", "Annual or if symptoms", "", "", "", "ESR < 20 mm/hr; CRP < 5 mg/L", "Elevated = active autoimmune flare", "GP", "MODERATE", "", C_SECTION_TH),
# ── VENOUS / VASCULAR ─────────────────────────────────────────────────
("VENOUS &\nVASCULAR", "Bilateral Lower Limb Duplex Venous Ultrasound", "Long-standing varicose veins + hemosiderin pigmentation = advanced CVI; CEAP staging required", "Annual (or sooner if ulcer)", "", "", "", "No DVT; reflux mapped", "Vascular surgery referral; grading directs treatment", "Vascular Surgeon", "URGENT", "Gold standard for venous disease staging (Sabiston Surgery)", C_SECTION_VEN),
("VENOUS &\nVASCULAR", "Ankle-Brachial Index (ABI)", "Diabetic patient: MUST rule out PAD before any compression therapy", "Annual", "", "", "", "ABI 0.9 – 1.3", "ABI < 0.9 = PAD; avoid compression bandaging", "Vascular Surgeon / GP", "URGENT", "DM + venous disease = high PAD risk", C_SECTION_VEN),
("VENOUS &\nVASCULAR", "Nerve Conduction Studies (NCS) / EMG", "Positional numbness: distinguish DPN from peroneal nerve entrapment", "Once baseline; repeat if worsening", "", "", "", "Normal conduction velocities", "Neurology referral if abnormal", "Neurologist", "HIGH", "DM makes nerves more vulnerable to compression injury", C_SECTION_VEN),
("VENOUS &\nVASCULAR", "D-Dimer + Compression Ultrasound (if acute)", "Rule out DVT if sudden unilateral swelling or calf tenderness", "As clinically indicated", "", "", "", "D-Dimer < 500 ng/mL", "Anticoagulate if DVT confirmed", "Emergency / GP", "AS NEEDED", "", C_SECTION_VEN),
# ── CARDIOVASCULAR ────────────────────────────────────────────────────
("CARDIO-\nVASCULAR", "ECG (12-lead)", "DM + early menopause + dyslipidaemia = silent ischaemia risk; Levothyroxine affects rhythm", "Annual", "", "", "", "Normal sinus rhythm; no ischaemic changes", "Cardiology referral if abnormal", "Cardiologist / GP", "HIGH", "Hyperthyroidism from over-treatment causes AF", C_SECTION_CV),
("CARDIO-\nVASCULAR", "Echocardiogram", "Early menopause + RA family history = accelerated atherosclerosis; venous hypertension can stress right heart", "Every 2-3 years or if symptomatic", "", "", "", "Normal LV/RV function; EF > 55%", "Cardiology referral", "Cardiologist", "MODERATE", "Harrison's 22E: early menopause → 1.5x CVD risk", C_SECTION_CV),
("CARDIO-\nVASCULAR", "ASCVD 10-Year Risk Score + Blood Pressure", "Calculate at every visit; multiple risk factors present", "Every visit", "", "", "", "BP < 130/80 mmHg; ASCVD < 7.5%", "Start statin if ASCVD > 7.5%; ACEI/ARB for BP if needed", "GP / Cardiologist", "HIGH", "Avoid ACE inhibitors – she already has dry cough!", C_SECTION_CV),
# ── GYNAECOLOGY / HORMONAL ────────────────────────────────────────────
("GYNAECOLOGY\n& HORMONAL", "Mammography (Digital)", "Early menarche + early menopause = prolonged estrogen exposure → DOUBLED breast cancer risk (Park's Preventive Medicine)", "Annual", "", "", "", "BI-RADS 1 or 2 (normal/benign)", "Core biopsy if BI-RADS 4/5", "Radiologist / Breast Surgeon", "URGENT", "This is her HIGHEST cancer risk given hormonal history", C_SECTION_GYN),
("GYNAECOLOGY\n& HORMONAL", "Pelvic Ultrasound (TVS) + CA-125", "Early menarche = ovarian cancer risk factor (Schwartz Surgery); early menopause = endometrial changes", "Annual pelvic USS; CA-125 if clinical concern", "", "", "", "No adnexal mass; CA-125 < 35 U/mL", "Gynaecology referral if abnormal", "Gynaecologist", "HIGH", "", C_SECTION_GYN),
("GYNAECOLOGY\n& HORMONAL", "Pap Smear + HPV Co-test", "Routine cervical cancer screening; early sexual activity with early menarche may increase exposure window", "Every 5 years (if prior normal + HPV neg)", "", "", "", "Negative for intraepithelial lesion; HPV neg", "Colposcopy if HSIL or HPV positive", "Gynaecologist", "HIGH", "", C_SECTION_GYN),
("GYNAECOLOGY\n& HORMONAL", "FSH + LH + Estradiol", "Confirm menopause status and severity; guide HRT decision (if T2DM allows)", "Once at menopause onset; repeat annually", "", "", "", "FSH > 40 IU/L + Estradiol < 20 pg/mL = menopause", "Discuss HRT risk-benefit (DM + CVD risk may limit options)", "Gynaecologist / Endocrinologist", "HIGH", "HRT may improve glycaemic control and lipids in some women", C_SECTION_GYN),
("GYNAECOLOGY\n& HORMONAL", "DEXA Bone Density Scan", "TRIPLE risk: early menopause (estrogen loss) + Levothyroxine (bone resorption) + DM (bone quality impaired)", "Every 2 years", "", "", "", "T-score > -1.0 (normal)", "Bisphosphonate + Ca2+/Vit D if T-score < -2.5", "Rheumatologist / Endocrinologist", "URGENT", "Levothyroxine at even slightly supraphysiologic dose suppresses bone", C_SECTION_GYN),
("GYNAECOLOGY\n& HORMONAL", "Vitamin D + Calcium", "Menopause + DM = bone loss; also Vit D deficiency worsens insulin resistance", "Annual", "", "", "", "Vit D > 30 ng/mL; Ca 8.5-10.5 mg/dL", "Supplement if deficient", "GP", "HIGH", "", C_SECTION_GYN),
# ── CANCER SCREENING ──────────────────────────────────────────────────
("CANCER\nSCREENING", "Colonoscopy / FIT (Faecal Immunochemical Test)", "T2DM is an independent colorectal cancer risk factor; age 50", "Colonoscopy every 10 yrs (if normal); FIT annually", "", "", "", "No polyps / negative FIT", "Polypectomy if adenoma found", "Gastroenterologist", "HIGH", "DM increases CRC risk ~30%", C_SECTION_CAN),
("CANCER\nSCREENING", "Chest X-Ray", "Dry cough 2 weeks; father had lung cancer (non-smoker); DPP-4 cough must be distinguished", "Now (urgent) + annual if symptoms persist", "", "", "", "Clear lung fields", "CT chest if any opacity; review Vildagliptin", "Radiologist / Pulmonologist", "URGENT", "Father = non-smoker with lung cancer → possible genetic risk (e.g. EGFR mutation familial)", C_SECTION_CAN),
("CANCER\nSCREENING", "Low-Dose CT Chest (LDCT)", "Father died of lung cancer (non-smoker) – possible familial/genetic risk (EGFR, ALK mutations common in non-smoking women)", "Consider baseline now; annual if risk confirmed", "", "", "", "No nodule or mass", "Pulmonology + genetic counselling referral", "Radiologist / Oncologist", "HIGH", "Non-smoker lung adenocarcinoma is common in South Asian women with family history", C_SECTION_CAN),
("CANCER\nSCREENING", "CA-125 + Pelvic USS (Ovarian)", "Early menarche = ovarian cancer risk", "Annual (listed also under Gynaecology)", "", "", "", "CA-125 < 35 U/mL", "", "Gynaecologist", "HIGH", "", C_SECTION_CAN),
# ── MEDICATION REVIEW ─────────────────────────────────────────────────
("MEDICATION\nREVIEW", "Review Vildagliptin for Cough", "DPP-4 inhibitors cause dry cough via bradykinin; she has 2-week dry cough", "Now (urgent)", "", "", "", "No cough = acceptable", "Switch to SGLT2i (empagliflozin) or GLP-1 RA if cough confirms DPP-4 origin", "Diabetologist", "URGENT", "Bonus: SGLT2i reduces CV events + CKD progression; GLP-1 RA aids weight", C_SECTION_MED),
("MEDICATION\nREVIEW", "Metformin + Vitamin B12 Level", "Long-term metformin depletes B12 → worsens peripheral neuropathy (already symptomatic)", "Annual B12 check", "", "", "", "B12 > 200 pg/mL", "Supplement B12 orally or IM", "GP / Diabetologist", "HIGH", "Critical: B12 depletion mimics/worsens DPN", C_SECTION_MED),
("MEDICATION\nREVIEW", "Levothyroxine Dose Review (TSH target)", "Supraphysiologic levothyroxine = bone loss + AF risk. Under-treatment = cough, fatigue, worsened lipids", "Every 6 months TSH", "", "", "", "TSH 1.0–2.5 mIU/L (optimal for Hashimoto's)", "Adjust dose by 12.5-25 mcg increments", "Endocrinologist", "HIGH", "", C_SECTION_MED),
("MEDICATION\nREVIEW", "Statin Therapy Initiation Assessment", "DM + early menopause + dyslipidaemia + autoimmune disease = high ASCVD risk; statin likely indicated", "Now", "", "", "", "LDL < 70 mg/dL (goal)", "Initiate rosuvastatin or atorvastatin", "GP / Cardiologist", "HIGH", "", C_SECTION_MED),
("MEDICATION\nREVIEW", "Aspirin / Antiplatelet Review", "Low-dose aspirin in high ASCVD risk DM patients (individualize)", "Annual review", "", "", "", "Per ASCVD risk score", "Discuss risk vs GI bleed benefit", "Cardiologist / GP", "MODERATE", "", C_SECTION_MED),
]
priority_colors = {
"URGENT": "B71C1C",
"HIGH": "E65100",
"MODERATE": "1565C0",
"AS NEEDED": "388E3C",
}
for row_i, row_data in enumerate(rows, start=5):
r = row_i
cat, test, why, freq, last, nxt, result, normal, action, done_by, priority, notes, sec_color = row_data
ws.row_dimensions[r].height = 45
values = [cat, test, why, freq, last, nxt, result, normal, action, done_by, priority, notes]
for col_i, val in enumerate(values, start=1):
c = ws.cell(row=r, column=col_i, value=val)
c.border = mk_border()
c.alignment = mk_align(h="left")
c.font = mk_font(size=9)
if col_i == 1: # category
c.font = mk_font(bold=True, size=9, color=C_HEADER_DARK)
c.fill = mk_fill(sec_color)
c.alignment = mk_align(h="center")
elif col_i == 2: # test name
c.font = mk_font(bold=True, size=9)
c.fill = mk_fill(C_WHITE)
elif col_i == 11: # priority
pcolor = priority_colors.get(val, "757575")
c.font = mk_font(bold=True, size=9, color=C_WHITE)
c.fill = mk_fill(pcolor)
c.alignment = mk_align()
elif col_i in [5, 6]: # date fields
c.fill = mk_fill(C_DUE)
c.alignment = mk_align()
elif col_i == 7: # result
c.fill = mk_fill("F5F5F5")
else:
c.fill = mk_fill(C_WHITE)
# Column widths
col_widths = [14, 32, 38, 18, 14, 14, 18, 22, 36, 16, 10, 30]
for ci, w in enumerate(col_widths, start=1):
ws.column_dimensions[get_column_letter(ci)].width = w
# Freeze header row
ws.freeze_panes = "A5"
# ═══════════════════════════════════════════════════════════════════════════
# SHEET 3 – TIMELINE CALENDAR (by year / age)
# ═══════════════════════════════════════════════════════════════════════════
ws_cal = wb.create_sheet("Screening Timeline")
ws_cal.sheet_view.showGridLines = False
ws_cal.merge_cells("A1:M1")
ws_cal["A1"] = "SCREENING TIMELINE BY AGE / YEAR"
ws_cal["A1"].font = mk_font(bold=True, size=13, color=C_WHITE)
ws_cal["A1"].fill = mk_fill(C_HEADER_DARK)
ws_cal["A1"].alignment = mk_align()
ws_cal.row_dimensions[1].height = 26
# Year columns
years = list(range(2026, 2032))
ages = list(range(50, 56))
ws_cal.row_dimensions[3].height = 32
ws_cal.row_dimensions[4].height = 20
ws_cal["A3"] = "Test / Screening"
ws_cal["A3"].font = mk_font(bold=True, size=10, color=C_WHITE)
ws_cal["A3"].fill = mk_fill(C_HEADER_MID)
ws_cal["A3"].alignment = mk_align()
ws_cal["A3"].border = mk_border()
ws_cal.column_dimensions["A"].width = 36
ws_cal["B3"] = "Priority"
ws_cal["B3"].font = mk_font(bold=True, size=10, color=C_WHITE)
ws_cal["B3"].fill = mk_fill(C_HEADER_MID)
ws_cal["B3"].alignment = mk_align()
ws_cal["B3"].border = mk_border()
ws_cal.column_dimensions["B"].width = 10
for ci, (yr, ag) in enumerate(zip(years, ages), start=3):
col = get_column_letter(ci)
ws_cal.merge_cells(f"{col}3:{col}4")
ws_cal[f"{col}3"] = f"{yr}\n(Age {ag})"
ws_cal[f"{col}3"].font = mk_font(bold=True, size=10, color=C_WHITE)
ws_cal[f"{col}3"].fill = mk_fill(C_HEADER_MID)
ws_cal[f"{col}3"].alignment = mk_align()
ws_cal[f"{col}3"].border = mk_border()
ws_cal.column_dimensions[col].width = 13
# Tests with schedule (test, priority, yr2026, yr2027, yr2028, yr2029, yr2030, yr2031)
# Legend: A = Annual, 2Y = Every 2 yrs, 3Y = Every 3 yrs, 6M = Every 6 months, NOW = Immediate, --- = Not due
tl_rows = [
("── DIABETES ──────────────────", "", "", "", "", "", "", ""),
("HbA1c", "URGENT", "Q3M", "Q3M", "Q3M", "Q3M", "Q3M", "Q3M"),
("UACR (Urine Albumin:Cr Ratio)", "URGENT", "A", "A", "A", "A", "A", "A"),
("eGFR / Serum Creatinine", "URGENT", "A", "A", "A", "A", "A", "A"),
("Lipid Profile", "HIGH", "A", "A", "A", "A", "A", "A"),
("Retinal Examination", "HIGH", "A", "A", "A", "A", "A", "A"),
("Foot Exam (Monofilament etc.)", "URGENT", "A", "A", "A", "A", "A", "A"),
("Autonomic / Orthostatic BP", "MOD", "A", "A", "A", "A", "A", "A"),
("── THYROID / AUTOIMMUNE ──────", "", "", "", "", "", "", ""),
("TSH + Free T4", "URGENT", "6M", "6M", "6M", "6M", "6M", "6M"),
("Anti-TPO / Anti-Tg Antibodies", "HIGH", "A", "---", "A", "---", "A", "---"),
("Thyroid Ultrasound", "HIGH", "A", "A", "A", "A", "A", "A"),
("RF + Anti-CCP", "HIGH", "A", "A", "A", "A", "A", "A"),
("ANA Screen", "MOD", "A", "---", "A", "---", "A", "---"),
("Anti-tTG IgA (Coeliac)", "MOD", "NOW", "---", "---", "A", "---", "---"),
("Serum B12 + Folate", "HIGH", "A", "A", "A", "A", "A", "A"),
("── VENOUS / VASCULAR ─────────", "", "", "", "", "", "", ""),
("Duplex Venous USS (Bilateral LL)", "URGENT", "NOW", "A", "A", "A", "A", "A"),
("Ankle-Brachial Index (ABI)", "URGENT", "NOW", "A", "A", "A", "A", "A"),
("NCS / EMG (Neuropathy)", "HIGH", "NOW", "---", "A", "---", "A", "---"),
("── CARDIOVASCULAR ────────────", "", "", "", "", "", "", ""),
("ECG (12-lead)", "HIGH", "A", "A", "A", "A", "A", "A"),
("Echocardiogram", "MOD", "NOW", "---", "---", "A", "---", "---"),
("ASCVD Score + BP", "HIGH", "A", "A", "A", "A", "A", "A"),
("── GYNAECOLOGY / HORMONAL ────", "", "", "", "", "", "", ""),
("Mammography", "URGENT", "A", "A", "A", "A", "A", "A"),
("Pelvic USS + CA-125", "HIGH", "A", "A", "A", "A", "A", "A"),
("Pap Smear + HPV Co-test", "HIGH", "NOW", "---", "---", "---", "---", "A"),
("FSH / LH / Estradiol", "HIGH", "A", "A", "A", "A", "A", "A"),
("DEXA Bone Density Scan", "URGENT", "NOW", "---", "A", "---", "A", "---"),
("Vitamin D + Calcium", "HIGH", "A", "A", "A", "A", "A", "A"),
("── CANCER SCREENING ──────────", "", "", "", "", "", "", ""),
("Colonoscopy (baseline)", "HIGH", "NOW", "---", "---", "---", "---", "---"),
("Chest X-Ray", "URGENT", "NOW", "A", "A", "A", "A", "A"),
("Low-Dose CT Chest (LDCT)", "HIGH", "NOW", "---", "A", "---", "A", "---"),
("── MEDICATION REVIEW ─────────", "", "", "", "", "", "", ""),
("Review Vildagliptin (cough)", "URGENT", "NOW", "---", "---", "---", "---", "---"),
("Metformin B12 monitoring", "HIGH", "A", "A", "A", "A", "A", "A"),
("Levothyroxine dose review", "HIGH", "6M", "6M", "6M", "6M", "6M", "6M"),
("Statin initiation assessment", "HIGH", "NOW", "A", "A", "A", "A", "A"),
]
cell_colors = {
"A": "C8E6C9", # green
"Q3M": "B3E5FC", # light blue
"6M": "B2EBF2", # cyan
"2Y": "FFF9C4", # yellow
"NOW": "FFCDD2", # red/urgent
"---": "F5F5F5", # grey
"MOD": "1565C0",
}
section_header_fill = "37474F"
for ri, trow in enumerate(tl_rows, start=5):
r = ri
ws_cal.row_dimensions[r].height = 22
test, priority = trow[0], trow[1]
schedule = trow[2:]
is_section = test.startswith("──")
a_cell = ws_cal.cell(row=r, column=1, value=test)
a_cell.border = mk_border()
if is_section:
a_cell.font = mk_font(bold=True, size=9, color=C_WHITE)
a_cell.fill = mk_fill(section_header_fill)
a_cell.alignment = mk_align(h="left")
ws_cal.merge_cells(f"A{r}:M{r}")
else:
a_cell.font = mk_font(bold=False, size=9)
a_cell.fill = mk_fill(C_WHITE)
a_cell.alignment = mk_align(h="left")
b_cell = ws_cal.cell(row=r, column=2, value=priority)
b_cell.border = mk_border()
if not is_section:
pcolor = priority_colors.get(priority, priority_colors.get("MOD","757575"))
b_cell.font = mk_font(bold=True, size=8, color=C_WHITE)
b_cell.fill = mk_fill(pcolor)
b_cell.alignment = mk_align()
else:
b_cell.fill = mk_fill(section_header_fill)
for sci, sval in enumerate(schedule, start=3):
sc = ws_cal.cell(row=r, column=sci, value=sval if not is_section else "")
sc.border = mk_border()
sc.alignment = mk_align()
if is_section:
sc.fill = mk_fill(section_header_fill)
else:
fc = cell_colors.get(sval, "FFFFFF")
sc.fill = mk_fill(fc)
sc.font = mk_font(bold=(sval not in ["---", ""]), size=9,
color="1A1A2E" if sval not in ["---"] else "9E9E9E")
ws_cal.freeze_panes = "C5"
# Legend
legend_row = len(tl_rows) + 7
ws_cal[f"A{legend_row}"] = "LEGEND:"
ws_cal[f"A{legend_row}"].font = mk_font(bold=True, size=9)
legend_items = [
("B", "NOW", "FFCDD2", "Immediate / Urgent"),
("C", "A", "C8E6C9", "Annual"),
("D", "Q3M", "B3E5FC", "Every 3 months"),
("E", "6M", "B2EBF2", "Every 6 months"),
("F", "---", "F5F5F5", "Not due this year"),
]
for col_l, code, fc, desc in legend_items:
cell_code = ws_cal[f"{col_l}{legend_row}"]
cell_code.value = f"{code} = {desc}"
cell_code.fill = mk_fill(fc)
cell_code.font = mk_font(size=9)
cell_code.border = mk_border()
cell_code.alignment = mk_align(h="left")
# ── Save ────────────────────────────────────────────────────────────────────
out_path = "/home/daytona/workspace/patient-tracker/Diabetes_Multisystem_Screening_Tracker.xlsx"
wb.save(out_path)
print(f"Saved: {out_path}")
cd /home/daytona/workspace/patient-tracker && python build_tracker.py
~/patient-tracker/build_tracker.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/patient-tracker/build_tracker.py'
if False block - that was a leftover from the replace. Let me fix that and also the cell color logic:~/patient-tracker/build_tracker.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/patient-tracker/build_tracker.py'
cd /home/daytona/workspace/patient-tracker && python build_tracker.py
ls /home/daytona/workspace/patient-tracker/ && df -h /home/daytona/workspace/
~/patient-tracker/build_tracker.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/patient-tracker/build_tracker.py'
cd /home/daytona/workspace/patient-tracker && python build_tracker.py
~/patient-tracker/build_tracker.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/patient-tracker/build_tracker.py'
cd /home/daytona/workspace/patient-tracker && python build_tracker.py && ls -lh /home/daytona/workspace/patient-tracker/
Diagnosed with thyroiditis when she was taking diabtets meds from her diabetologist diabetes screening dates 42/43 maybe for autoimmune itself father didnt have smoking history nor does she early menarche early menopause Continuous cough no productive ubtikk now
ls /home/daytona/workspace/ 2>/dev/null && ls /tmp/workspace/ 2>/dev/null && echo "---" && find /home/daytona -name "*.py" 2>/dev/null | head -5
ls /tmp/workspace/ 2>/dev/null || echo "no tmp workspace" ; ls /tmp/ | head -20
ls /tmp/workspace/ && ls /tmp/workspace/patient-tracker/ 2>/dev/null || echo "no patient-tracker folder"
mkdir -p /tmp/workspace/patient-tracker
~/patient-tracker/build_tracker.py
import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.utils import get_column_letter
wb = openpyxl.Workbook()
# ── Palette ─────────────────────────────────────────────────────────────────
C_NAVY = "1F3864"
C_BLUE = "2E75B6"
C_DM = "D6E4F0"
C_TH = "E8F5E9"
C_VEN = "FFF3E0"
C_GYN = "FCE4EC"
C_CAN = "F3E5F5"
C_CV = "FFEBEE"
C_MED = "E8EAF6"
C_WHITE = "FFFFFF"
C_DONE = "C8E6C9"
C_DUE = "FFF9C4"
C_ALERT = "FF6F00"
C_SECTION_HD = "37474F"
PRIORITY_CLR = {
"URGENT": "B71C1C",
"HIGH": "E65100",
"MODERATE": "1565C0",
"AS NEEDED":"388E3C",
}
def fill(h): return PatternFill("solid", fgColor=h)
def font(bold=False, size=10, color="1A1A2E", italic=False):
return Font(name="Arial", bold=bold, size=size, color=color, italic=italic)
def border():
s = Side(style="thin", color="BDBDBD")
return Border(left=s, right=s, top=s, bottom=s)
def align(h="center", v="center", wrap=True):
return Alignment(horizontal=h, vertical=v, wrap_text=wrap)
def hdr_row(ws, row, text, span, bg=C_NAVY, fsize=13):
ws.merge_cells(f"A{row}:{get_column_letter(span)}{row}")
c = ws[f"A{row}"]
c.value = text; c.font = font(bold=True, size=fsize, color="FFFFFF")
c.fill = fill(bg); c.alignment = align(); ws.row_dimensions[row].height = 28
# ═══════════════════════════════════════════════════════════════════════════
# SHEET 1 – PATIENT SUMMARY
# ═══════════════════════════════════════════════════════════════════════════
ws1 = wb.active
ws1.title = "Patient Summary"
ws1.sheet_view.showGridLines = False
hdr_row(ws1, 1, "PATIENT HEALTH SCREENING RECORD", 8, C_NAVY, 15)
hdr_row(ws1, 2, "Confidential – Clinical Tracking & Follow-up", 8, C_NAVY, 9)
ws1.row_dimensions[2].height = 16
# Profile
profile = [
("Age / Sex", "50 years | Female"),
("Diabetes Diagnosis", "Type 2 DM – diagnosed approximately age 42-43"),
("Thyroid Diagnosis", "Autoimmune Thyroiditis (Hashimoto's) – diagnosed DURING diabetes workup at ~age 42-43 by diabetologist (incidental finding on autoimmune screening)"),
("Current Medications","Vildagliptin-M (Vildagliptin 50mg + Metformin) | Levothyroxine 75 mcg OD"),
("Menstrual History", "EARLY MENARCHE (before age 12) → EARLY MENOPAUSE (~age 40-48) = prolonged estrogen exposure THEN abrupt withdrawal"),
("Family History", "Father: Type 2 DM + Lung Cancer (NON-SMOKER – significant, suggests genetic/EGFR-type risk) | Mother: Rheumatoid Arthritis"),
("Venous Disease", "Long-standing varicose veins → NOW: Advanced CVI – hemosiderin skin pigmentation (inner/outer/posterior lower legs), stasis dermatitis with constant itching"),
("Neurological Sx", "Positional numbness (sitting cross-legged, resolves 20-30 min after getting up) – DDx: Diabetic peripheral neuropathy vs peroneal nerve entrapment"),
("Cough", "CONTINUOUS DRY (non-productive) COUGH – ongoing since ≥2 weeks, now persistent. No sputum production to date. HIGH PRIORITY – see Risk Flags below."),
("Smoking History", "NON-SMOKER. Father also NON-SMOKER despite lung cancer death."),
]
ws1.merge_cells("A4:B4"); ws1["A4"] = "PATIENT PROFILE"
ws1["A4"].font = font(bold=True, size=11, color="FFFFFF")
ws1["A4"].fill = fill(C_BLUE); ws1["A4"].alignment = align()
ws1.merge_cells("C4:H4"); ws1["C4"].fill = fill(C_BLUE)
ws1.row_dimensions[4].height = 22
for i,(lbl,val) in enumerate(profile, start=5):
ws1[f"A{i}"] = lbl
ws1[f"A{i}"].font = font(bold=True, size=10)
ws1[f"A{i}"].fill = fill("EBF5FB")
ws1[f"A{i}"].alignment = align(h="left")
ws1[f"A{i}"].border = border()
ws1.merge_cells(f"B{i}:H{i}")
ws1[f"B{i}"] = val
ws1[f"B{i}"].font = font(size=10)
ws1[f"B{i}"].fill = fill(C_WHITE)
ws1[f"B{i}"].alignment = align(h="left")
ws1[f"B{i}"].border = border()
ws1.row_dimensions[i].height = 32
# Risk flags
fr = len(profile) + 6
hdr_row(ws1, fr, "⚠ KEY RISK FLAGS – SPECIFIC TO THIS PATIENT", 8, C_ALERT, 11)
flags = [
("1", "VILDAGLIPTIN (DPP-4i) CAUSING PERSISTENT COUGH – ACT NOW",
"Murray & Nadel's Respiratory Medicine directly names 'sitagliptin, a DPP-4 inhibitor' as a cause of chronic cough via DPP-4 inhibition in mucosa → inflammation → postnasal cough, rhinorrhea, fatigue. Vildagliptin = same class. This is the #1 suspect for her persistent non-productive cough. SWITCH medication urgently. Consider SGLT2i (empagliflozin) – added CV/renal benefit."),
("2", "FATHER: NON-SMOKER LUNG CANCER – GENETIC RISK (EGFR/ALK)",
"Non-smoker lung cancer (especially adenocarcinoma) in a first-degree relative = possible familial EGFR mutation, ALK rearrangement, or ROS1 mutation. Common in South Asian and East Asian women. Persistent cough + this family history = CHEST X-RAY + LOW-DOSE CT CHEST mandatory NOW, even though she is a non-smoker."),
("3", "BREAST CANCER RISK DOUBLED – EARLY MENARCHE",
"Park's Preventive Medicine: '40+ years of menstruation doubles breast cancer risk vs 30 years.' Early menarche + early menopause = maximum lifetime estrogen exposure window then abrupt loss. Annual mammography is MANDATORY and should already have started."),
("4", "EARLY MENOPAUSE → CARDIOVASCULAR + BONE RISK",
"Harrison's 22E: early menopause = 1.5x CVD/stroke risk. Combined with DM + autoimmune disease = markedly elevated cardiac risk. PLUS: Levothyroxine at any borderline-supraphysiologic dose + estrogen withdrawal = ACCELERATED BONE LOSS. DEXA scan urgently required."),
("5", "AUTOIMMUNE CLUSTER – HASHIMOTO'S + RA FAMILY HISTORY",
"Hashimoto's thyroiditis diagnosed ~age 42-43 DURING diabetes workup = autoimmune diathesis confirmed. Mother with RA amplifies this. Screen for: RA (Anti-CCP), Sjogren's (ANA, anti-Ro/La), Coeliac disease (anti-tTG IgA – affects levothyroxine absorption), pernicious anaemia (B12 low also from metformin)."),
("6", "METFORMIN + B12 DEPLETION WORSENING NEUROPATHY",
"Long-term metformin depletes B12. She already has positional numbness suggesting early peripheral neuropathy. Low B12 directly worsens diabetic neuropathy – a reversible contribution often missed. Annual B12 is mandatory."),
("7", "OVARIAN / ENDOMETRIAL CANCER RISK",
"Early menarche = ovarian cancer risk factor (Schwartz Surgery). Pelvic USS + CA-125 baseline warranted. If early menopause occurred before natural cessation, check endometrial lining thickness on TVS."),
]
for off,(num,title,detail) in enumerate(flags, start=fr+1):
r = fr+1+off-1
ws1[f"A{r}"] = num; ws1[f"A{r}"].font = font(bold=True,size=10,color="FFFFFF")
ws1[f"A{r}"].fill = fill("E53935"); ws1[f"A{r}"].alignment = align(); ws1[f"A{r}"].border = border()
ws1[f"B{r}"] = title; ws1[f"B{r}"].font = font(bold=True,size=10)
ws1[f"B{r}"].fill = fill("FFEBEE"); ws1[f"B{r}"].alignment = align(h="left"); ws1[f"B{r}"].border = border()
ws1.merge_cells(f"C{r}:H{r}")
ws1[f"C{r}"] = detail; ws1[f"C{r}"].font = font(size=9,italic=True)
ws1[f"C{r}"].fill = fill(C_WHITE); ws1[f"C{r}"].alignment = align(h="left"); ws1[f"C{r}"].border = border()
ws1.row_dimensions[r].height = 52
ws1.column_dimensions["A"].width = 6
ws1.column_dimensions["B"].width = 30
for col in ["C","D","E","F","G","H"]:
ws1.column_dimensions[col].width = 18
# ═══════════════════════════════════════════════════════════════════════════
# SHEET 2 – SCREENING TRACKER
# ═══════════════════════════════════════════════════════════════════════════
ws2 = wb.create_sheet("Annual Screening Tracker")
ws2.sheet_view.showGridLines = False
hdr_row(ws2, 1, "ANNUAL DIABETES & MULTISYSTEM SCREENING TRACKER", 12, C_NAVY, 13)
hdr_row(ws2, 2,
"50F | T2DM dx ~42-43 | Hashimoto's dx ~42-43 (during DM workup) | CVI + Hemosiderin pigmentation | Early Menarche + Early Menopause | Father: Lung Ca (non-smoker) | Mother: RA | Persistent dry cough",
12, C_NAVY, 9)
ws2.row_dimensions[2].height = 18
# Column headers
hdrs = ["Category","Investigation / Screening","Why Specific to This Patient",
"Frequency","Last Done (Date)","Next Due (Date)",
"Result / Value","Target / Normal Range","Action Required",
"Clinician","Priority","Notes / Evidence"]
ws2.row_dimensions[4].height = 38
for ci,h in enumerate(hdrs,1):
c = ws2.cell(row=4,column=ci,value=h)
c.font = font(bold=True,size=10,color="FFFFFF")
c.fill = fill(C_BLUE); c.alignment = align(); c.border = border()
# Data rows
# (cat, test, why, freq, last, next, result, target, action, clinician, priority, notes, color)
rows = [
# DIABETES
("DIABETES\nMONITORING","HbA1c",
"T2DM on Vildagliptin-M; primary glycaemic control marker; DM dx ~7-8 yrs ago",
"Every 3 months","","","","< 7.0% (53 mmol/mol)",
"Adjust Vildagliptin-M or switch to SGLT2i if cough confirms DPP-4 cause",
"Diabetologist","URGENT","DM diagnosed ~age 42-43; now 50 = ~7-8 yrs",C_DM),
("DIABETES\nMONITORING","Fasting Blood Glucose / SMBG Log",
"Daily monitoring; hypoglycaemia detection especially if medication switched",
"Daily self-monitoring","","","","70–130 mg/dL fasting",
"Review if persistent high; watch for hypo if SGLT2i started",
"Self / GP","HIGH","",C_DM),
("DIABETES\nMONITORING","Urine Albumin:Creatinine Ratio (UACR)",
"Earliest diabetic nephropathy marker; 7-8 yrs of DM = prime onset window",
"Annual","","","","< 30 mg/g",
"Refer nephrology if >300 (macroalbuminuria); start ACEI/ARB (but NOTE – she has cough, avoid ACEi)",
"GP / Diabetologist","URGENT","ARB preferred over ACEi given her cough",C_DM),
("DIABETES\nMONITORING","Serum Creatinine + eGFR",
"Metformin dosing requires eGFR monitoring; must stop if eGFR < 30",
"Annual","","","","eGFR > 60 mL/min/1.73m²",
"Stop/reduce metformin if eGFR <45; SGLT2i also requires eGFR check",
"GP","URGENT","SGLT2i requires eGFR ≥45 to start",C_DM),
("DIABETES\nMONITORING","Fasting Lipid Profile (LDL, HDL, TG, Total Chol)",
"DM + autoimmune + early menopause = very high CVD risk; menopause worsens lipid profile",
"Annual","","","","LDL < 70 mg/dL (high-risk DM target)",
"Initiate statin (rosuvastatin/atorvastatin); metformin helps TG",
"GP / Cardiologist","HIGH","Hypothyroidism also raises LDL – treat thyroid first then reassess lipids",C_DM),
("DIABETES\nMONITORING","Retinal Examination (Fundoscopy / OCT)",
"Diabetic retinopathy risk after 7-8 yrs DM; hypothyroidism adds ocular changes",
"Annual","","","","No diabetic retinopathy",
"Ophthalmology referral if any grade of retinopathy",
"Ophthalmologist","HIGH","",C_DM),
("DIABETES\nMONITORING","Foot Examination (10g Monofilament + 128Hz Tuning Fork + Ankle Reflexes + Pedal Pulses)",
"Annual LOPS screening mandatory (ADA); positional numbness may indicate early DPN; DM + CVI = compound ulcer risk",
"Every visit (formal annual)","","","","Intact sensation; no LOPS; palpable pulses",
"Refer podiatry if LOPS; NCS/EMG if clinical neuropathy confirmed",
"GP / Diabetologist","URGENT","Harrison's 22E: ADA recommends annual DPN screen from T2DM diagnosis",C_DM),
("DIABETES\nMONITORING","Orthostatic Blood Pressure",
"Autonomic neuropathy screening; ADA recommends at time of T2DM diagnosis",
"Annual","","","","< 20 mmHg systolic drop on standing",
"Refer if symptomatic; rule out medication contribution",
"GP","MODERATE","",C_DM),
("DIABETES\nMONITORING","Dental Examination",
"Periodontal disease more frequent and severe in DM",
"Every 6 months","","","","No periodontitis",
"Refer dentist; improved glycaemic control helps",
"Dentist","MODERATE","",C_DM),
# THYROID / AUTOIMMUNE
("THYROID &\nAUTOIMMUNE","TSH (Thyroid Stimulating Hormone)",
"On Levothyroxine 75 mcg; Hashimoto's found incidentally during diabetes workup at ~age 42-43. Persistent dry cough may be from undertreated hypothyroidism.",
"Every 6 months","","","","0.5–4.0 mIU/L (aim 1.0–2.5 in treated Hashimoto's)",
"Adjust levothyroxine; over-treatment → AF + bone loss; under-treatment → cough, fatigue, worsened lipids",
"Endocrinologist / GP","URGENT","TSH must be checked NOW alongside cough investigation",C_TH),
("THYROID &\nAUTOIMMUNE","Free T4 (FT4)",
"Confirm levothyroxine adequacy",
"With TSH / if symptomatic","","","","12–22 pmol/L",
"Dose adjust by 12.5–25 mcg increments",
"GP / Endocrinologist","HIGH","",C_TH),
("THYROID &\nAUTOIMMUNE","Anti-TPO + Anti-Thyroglobulin Antibodies",
"Confirms Hashimoto's; monitors autoimmune activity; high titres = active disease",
"Once if not done; repeat every 2 years","","","","Anti-TPO < 35 IU/mL; Anti-Tg < 40 IU/mL",
"High titres = active autoimmune inflammation",
"Endocrinologist","HIGH","Hashimoto's confirmed when diagnosed ~age 42-43",C_TH),
("THYROID &\nAUTOIMMUNE","Thyroid Ultrasound",
"Hashimoto's → nodule surveillance; rule out malignant transformation",
"Annual","","","","No nodule >1cm or suspicious echogenicity",
"FNAC if TIRADS 4/5 nodule",
"Radiologist / Endocrinologist","HIGH","",C_TH),
("THYROID &\nAUTOIMMUNE","Rheumatoid Factor (RF) + Anti-CCP Antibodies",
"Mother has RA; autoimmune clustering with Hashimoto's; Anti-CCP is most specific marker for RA",
"Annual","","","","RF < 14 IU/mL; Anti-CCP negative",
"Refer rheumatology if positive",
"Rheumatologist / GP","HIGH","RA + DM + Hashimoto's = triple autoimmune cluster",C_TH),
("THYROID &\nAUTOIMMUNE","ANA (Antinuclear Antibody) Screen",
"Screen for SLE, Sjogren's, mixed connective tissue disease – all cluster with Hashimoto's",
"Every 2 years","","","","Negative or titre < 1:80",
"If positive: subtype (anti-dsDNA, anti-Ro/La, anti-Sm); refer rheumatology",
"Rheumatologist","MODERATE","",C_TH),
("THYROID &\nAUTOIMMUNE","Anti-tTG IgA (Coeliac Disease Screen)",
"Coeliac disease clusters with Hashimoto's; causes malabsorption of levothyroxine → erratic TSH control",
"Once; repeat if GI symptoms","","","","Negative",
"GI referral + duodenal biopsy if positive; gluten-free diet",
"Gastroenterologist","MODERATE","Unexplained TSH fluctuation = check this",C_TH),
("THYROID &\nAUTOIMMUNE","Serum B12 + Folate",
"DUAL risk: (1) Pernicious anaemia clusters with Hashimoto's; (2) Metformin depletes B12 → worsens peripheral neuropathy",
"Annual","","","","B12 > 200 pg/mL",
"Oral or IM B12 supplementation; STOP metformin contribution if severe",
"GP","HIGH","Critical: low B12 worsens DPN – a reversible cause",C_TH),
("THYROID &\nAUTOIMMUNE","ESR + CRP (Inflammatory Markers)",
"Baseline for autoimmune disease monitoring; elevated = active flare",
"Annual / if symptomatic","","","","ESR < 20 mm/hr; CRP < 5 mg/L",
"Elevated = investigate active autoimmune flare",
"GP","MODERATE","",C_TH),
# COUGH / RESPIRATORY
("COUGH &\nRESPIRATORY","IMMEDIATE: Stop / Review Vildagliptin",
"Murray & Nadel's Respiratory Medicine explicitly names DPP-4 inhibitors (sitagliptin/vildagliptin class) as cause of chronic non-productive cough via DPP-4 inhibition in mucosa → inflammation, postnasal drip, fatigue. Most likely cause of her persistent cough.",
"NOW – urgent medication review","","","","Cough resolves within 4–8 weeks of stopping",
"Switch to empagliflozin (SGLT2i) – added CV + renal benefit; or GLP-1 RA. Re-evaluate cough at 8 weeks.",
"Diabetologist","URGENT","Murray & Nadel's Textbook of Respiratory Medicine 2-vol, p.394",C_CAN),
("COUGH &\nRESPIRATORY","Chest X-Ray (PA + Lateral)",
"Persistent non-productive cough + father died of lung cancer (NON-SMOKER = possible familial EGFR genetic risk). Fishman's Pulmonary Diseases: 'chest radiograph warranted at beginning of evaluation of chronic cough to assess for serious causes'.",
"NOW – urgently","","","","Clear lung fields; no mass/opacity/effusion",
"Urgent LDCT chest + pulmonology referral if any abnormality",
"Radiologist / Pulmonologist","URGENT","Fishman's Pulmonary Diseases & Disorders, p.442",C_CAN),
("COUGH &\nRESPIRATORY","Low-Dose CT Chest (LDCT)",
"Father = non-smoker with lung cancer → possible familial genetic cancer risk (EGFR mutations, ALK rearrangements common in non-smoking South Asian/East Asian women). She is also a non-smoker – LDCT not for smoking screening but for FAMILY HISTORY RISK.",
"Now as baseline; annual if risk confirmed","","","","No pulmonary nodule or mass",
"Pulmonology + oncogenetic counselling referral if any finding",
"Radiologist / Oncologist","HIGH","Non-smoker lung adenocarcinoma ≠ smoking-related; driven by molecular alterations",C_CAN),
("COUGH &\nRESPIRATORY","Spirometry / PFTs (Pulmonary Function Tests)",
"Rule out obstructive (asthma, COPD) or restrictive (interstitial lung disease) causes of chronic cough",
"Once baseline","","","","FEV1/FVC > 0.70; FVC > 80% predicted",
"Bronchodilator reversibility test if obstruction found",
"Pulmonologist","HIGH","",C_CAN),
("COUGH &\nRESPIRATORY","GERD Evaluation (PPI Trial / pH Manometry if needed)",
"Diabetic gastroparesis predisposes to GERD; GERD is a top 3 cause of chronic cough (Fishman's). Her DM duration increases gastroparesis risk.",
"Clinical trial of PPI for 8 weeks","","","","Cough resolves on PPI",
"If no response to PPI: 24-hr pH manometry; GI referral",
"GP / Gastroenterologist","HIGH","GERD can be silent – no heartburn in up to 40%",C_CAN),
("COUGH &\nRESPIRATORY","Upper Airway Cough Syndrome (UACS) / ENT Review",
"Postnasal drip is most common cause of chronic cough (Fishman's). DPP-4 inhibitor also directly causes rhinorrhea and postnasal cough.",
"ENT review if cough persists after medication switch","","","","No postnasal drip / sinusitis",
"Antihistamine + nasal steroid trial; sinus CT if needed",
"ENT Specialist","MODERATE","",C_CAN),
# VENOUS / VASCULAR
("VENOUS &\nVASCULAR","Bilateral Lower Limb Duplex Venous Ultrasound",
"Long-standing varicose veins + hemosiderin pigmentation (inner/outer/posterior lower legs) + stasis dermatitis = Advanced CVI. Sabiston Surgery: 'hyperpigmentation in distal calf secondary to hemosiderin deposition'. CEAP staging required.",
"NOW (urgent); then annual","","","","No DVT; reflux pattern mapped; CEAP stage documented",
"Vascular surgery referral; grading directs treatment (compression, ablation, surgery)",
"Vascular Surgeon","URGENT","Sabiston Textbook of Surgery, p.2404",C_VEN),
("VENOUS &\nVASCULAR","Ankle-Brachial Index (ABI)",
"DM patient: MUST rule out PAD before prescribing compression therapy. ABI is mandatory pre-compression.",
"Annual","","","","ABI 0.9–1.3 (normal)",
"ABI < 0.9 = PAD – STOP compression; vascular surgery referral",
"Vascular Surgeon / GP","URGENT","DM + CVI = high PAD coexistence risk",C_VEN),
("VENOUS &\nVASCULAR","Nerve Conduction Studies (NCS) / EMG",
"Positional numbness on cross-legged sitting: must differentiate DPN (diabetic peripheral neuropathy) from peroneal nerve entrapment (DM makes nerves more susceptible to compression injury)",
"Once as baseline; repeat if worsening","","","","Normal conduction velocities and latencies",
"Neurology referral if abnormal; podiatry for foot care",
"Neurologist","HIGH","",C_VEN),
# CARDIOVASCULAR
("CARDIO-\nVASCULAR","ECG (12-lead)",
"DM + early menopause + autoimmune disease = silent cardiac ischaemia; Levothyroxine over-treatment → AF",
"Annual","","","","Normal sinus rhythm; no ischaemic changes",
"Cardiology referral; adjust levothyroxine if rhythm abnormality",
"Cardiologist / GP","HIGH","",C_CV),
("CARDIO-\nVASCULAR","Echocardiogram",
"Early menopause + RA family Hx + DM = accelerated atherosclerosis; CVI can stress right heart",
"Every 2-3 years or if symptomatic","","","","EF > 55%; no valvular or wall motion abnormality",
"Cardiology referral",
"Cardiologist","MODERATE","Harrison's 22E: early menopause → 1.5x CVD risk",C_CV),
("CARDIO-\nVASCULAR","ASCVD 10-Year Risk Score + BP at Every Visit",
"Multiple CV risk factors: DM + early menopause + dyslipidaemia + autoimmune. Note: AVOID ACE inhibitors (she has cough) – use ARB for BP if needed",
"Every visit","","","","BP < 130/80 mmHg; ASCVD < 7.5%",
"Start statin if ASCVD >7.5%; use ARB not ACEi for BP control",
"GP / Cardiologist","HIGH","ACEi contraindicated – she already has persistent cough",C_CV),
# GYNAECOLOGY / HORMONAL
("GYNAECOLOGY\n& HORMONAL","Mammography (Digital / 3D Tomosynthesis)",
"Early menarche + early menopause = maximum lifetime estrogen exposure. Park's Preventive Medicine: '40+ years of menstruation DOUBLES breast cancer risk vs 30 years'. This is her HIGHEST individual cancer risk.",
"Annual","","","","BI-RADS 1 or 2",
"Core biopsy if BI-RADS 4/5; breast surgeon referral",
"Radiologist / Breast Surgeon","URGENT","Park's Textbook Preventive Medicine",C_GYN),
("GYNAECOLOGY\n& HORMONAL","Pelvic Ultrasound (TVS) + CA-125",
"Early menarche = ovarian cancer risk factor (Schwartz Surgery). Early menopause → monitor endometrial thickness.",
"Annual","","","","No adnexal mass; CA-125 < 35 U/mL; endometrial < 4mm post-menopause",
"Gynaecology referral if abnormal",
"Gynaecologist","HIGH","",C_GYN),
("GYNAECOLOGY\n& HORMONAL","Pap Smear + HPV Co-test",
"Routine cervical cancer screening; early menarche may extend exposure window",
"Every 5 years (if prior normal + HPV neg)","","","","NILM; HPV negative",
"Colposcopy if HSIL or HPV 16/18 positive",
"Gynaecologist","HIGH","",C_GYN),
("GYNAECOLOGY\n& HORMONAL","FSH + LH + Estradiol",
"Confirm menopause status and severity; guide HRT discussion (complex given DM + CVD risk)",
"Once at menopause; then annually","","","","FSH > 40 IU/L; Estradiol < 20 pg/mL = confirmed menopause",
"Discuss HRT risk-benefit: DM + CVD may limit choices; non-hormonal options available",
"Gynaecologist / Endocrinologist","HIGH","",C_GYN),
("GYNAECOLOGY\n& HORMONAL","DEXA Bone Density Scan",
"TRIPLE bone loss risk: (1) Early menopause = estrogen withdrawal; (2) Levothyroxine at borderline-supraphysiologic dose → bone resorption; (3) DM impairs bone quality",
"Every 2 years","","","","T-score > -1.0 (normal)",
"Bisphosphonate + Ca2+ + Vit D if T-score ≤ -2.5 (osteoporosis)",
"Endocrinologist / Rheumatologist","URGENT","All three risk factors converge in this patient",C_GYN),
("GYNAECOLOGY\n& HORMONAL","Vitamin D + Serum Calcium",
"Menopause + DM = bone loss; Vit D deficiency worsens insulin resistance",
"Annual","","","","Vit D 25-OH > 30 ng/mL; Ca 8.5–10.5 mg/dL",
"Supplement cholecalciferol + calcium carbonate if deficient",
"GP","HIGH","",C_GYN),
# CANCER SCREENING
("CANCER\nSCREENING","Colonoscopy / FIT Test",
"T2DM independently increases colorectal cancer risk ~30%; age 50 = standard screening threshold",
"Colonoscopy every 10 yrs if normal; FIT annually","","","","No polyps; FIT negative",
"Polypectomy if adenoma; surveillance colonoscopy schedule",
"Gastroenterologist","HIGH","",C_CAN),
# MEDICATION REVIEW
("MEDICATION\nREVIEW","URGENT: Switch Vildagliptin → SGLT2i or GLP-1 RA",
"DPP-4 inhibitor class (Vildagliptin) causes persistent non-productive cough. She has had continuous cough. Murray & Nadel's: DPP-4 inhibition in mucosa causes inflammation → rhinorrhea, postnasal cough. Empagliflozin (SGLT2i) better: reduces CV events, CKD progression, HbA1c, weight.",
"NOW","","","","Cough should resolve within 4-8 weeks",
"Discuss empagliflozin; check eGFR first (needs ≥45). GLP-1 RA alternative if eGFR low.",
"Diabetologist","URGENT","Murray & Nadel's Respiratory Medicine; Fishman's Pulmonary Diseases",C_MED),
("MEDICATION\nREVIEW","Metformin B12 Monitoring",
"Long-term metformin depletes B12 → worsens peripheral neuropathy (she already has positional numbness). Reversible if caught early.",
"Annual B12 check","","","","B12 > 200 pg/mL",
"Oral B12 1000 mcg OD or IM hydroxocobalamin quarterly",
"GP / Diabetologist","HIGH","This is a reversible cause of neuropathy – do not miss",C_MED),
("MEDICATION\nREVIEW","Levothyroxine 75 mcg – TSH-guided Dose Review",
"Cough may partly reflect undertreated hypothyroidism (mucous membrane changes). Also: supraphysiologic dosing causes bone loss and AF.",
"Every 6 months (TSH)","","","","TSH 1.0–2.5 mIU/L",
"Adjust dose ±12.5 mcg increments based on TSH",
"Endocrinologist","HIGH","",C_MED),
("MEDICATION\nREVIEW","Statin Initiation Assessment",
"DM + early menopause + dyslipidaemia + autoimmune disease = high ASCVD risk. Hypothyroidism raises LDL – check TSH optimised before or alongside statin start.",
"Now","","","","LDL < 70 mg/dL (high-risk DM target)",
"Rosuvastatin or atorvastatin; monitor LFTs + CK at 3 months",
"GP / Cardiologist","HIGH","Optimise thyroid first – hypothyroidism raises LDL independently",C_MED),
("MEDICATION\nREVIEW","NOTE: AVOID ACE Inhibitors",
"ACE inhibitors cause dry cough (bradykinin mechanism). She ALREADY has persistent cough. If antihypertensive or renoprotective therapy needed → use ARB (telmisartan, losartan, olmesartan) NOT ACEi.",
"Ongoing prescribing alert","","","","No ACE inhibitor prescribed",
"Use ARB class for BP / nephroprotection",
"All prescribing clinicians","URGENT","Document ACEi contraindication in notes",C_MED),
]
for ri, rd in enumerate(rows, start=5):
r = ri
cat,test,why,freq,last,nxt,result,target,action,clinician,priority,notes,sec_color = rd
ws2.row_dimensions[r].height = 50
vals = [cat,test,why,freq,last,nxt,result,target,action,clinician,priority,notes]
for ci,v in enumerate(vals,1):
c = ws2.cell(row=r,column=ci,value=v)
c.border = border(); c.alignment = align(h="left"); c.font = font(size=9)
if ci == 1:
c.font = font(bold=True,size=9,color=C_NAVY)
c.fill = fill(sec_color); c.alignment = align(h="center")
elif ci == 2:
c.font = font(bold=True,size=9); c.fill = fill(C_WHITE)
elif ci == 11:
pc = PRIORITY_CLR.get(v,"757575")
c.font = font(bold=True,size=9,color="FFFFFF")
c.fill = fill(pc); c.alignment = align()
elif ci in (5,6):
c.fill = fill(C_DUE); c.alignment = align()
elif ci == 7:
c.fill = fill("F5F5F5")
else:
c.fill = fill(C_WHITE)
col_widths = [14,32,42,18,14,14,18,24,38,16,10,30]
for ci,w in enumerate(col_widths,1):
ws2.column_dimensions[get_column_letter(ci)].width = w
ws2.freeze_panes = "A5"
# ═══════════════════════════════════════════════════════════════════════════
# SHEET 3 – SCREENING TIMELINE
# ═══════════════════════════════════════════════════════════════════════════
ws3 = wb.create_sheet("Screening Timeline")
ws3.sheet_view.showGridLines = False
hdr_row(ws3, 1, "SCREENING SCHEDULE BY YEAR (2026-2031)", 9, C_NAVY, 13)
hdr_row(ws3, 2, "Patient age 50 → 55 | All dates fillable | Colour guide: see Legend below", 9, C_NAVY, 9)
ws3.row_dimensions[2].height = 16
years = [2026,2027,2028,2029,2030,2031]
ages = [50,51,52,53,54,55]
ws3["A3"] = "Test / Screening"
ws3["A3"].font = font(bold=True,size=10,color="FFFFFF"); ws3["A3"].fill = fill(C_BLUE)
ws3["A3"].alignment = align(); ws3["A3"].border = border()
ws3.column_dimensions["A"].width = 38
ws3["B3"] = "Priority"
ws3["B3"].font = font(bold=True,size=10,color="FFFFFF"); ws3["B3"].fill = fill(C_BLUE)
ws3["B3"].alignment = align(); ws3["B3"].border = border()
ws3.column_dimensions["B"].width = 10
for ci,(yr,ag) in enumerate(zip(years,ages),start=3):
col = get_column_letter(ci)
ws3.merge_cells(f"{col}3:{col}4")
c = ws3[f"{col}3"]
c.value = f"{yr}\n(Age {ag})"
c.font = font(bold=True,size=10,color="FFFFFF"); c.fill = fill(C_BLUE)
c.alignment = align(); c.border = border()
ws3.column_dimensions[col].width = 13
ws3.row_dimensions[3].height = 30; ws3.row_dimensions[4].height = 4
CELL_CLR = {
"NOW":"FFCDD2","A":"C8E6C9","Q3M":"B3E5FC","6M":"B2EBF2",
"2Y":"FFF9C4","---":"F5F5F5","DONE":"C8E6C9",
}
tl = [
# header rows start with ──
("── DIABETES ──────────────────────────────", "", "", "", "", "", "", ""),
("HbA1c", "URGENT","Q3M", "Q3M", "Q3M", "Q3M", "Q3M", "Q3M"),
("UACR (Urine Albumin:Creatinine Ratio)", "URGENT","A", "A", "A", "A", "A", "A"),
("eGFR / Serum Creatinine", "URGENT","A", "A", "A", "A", "A", "A"),
("Fasting Lipid Profile", "HIGH", "A", "A", "A", "A", "A", "A"),
("Retinal Examination", "HIGH", "A", "A", "A", "A", "A", "A"),
("Foot Exam (Monofilament + reflexes)", "URGENT","A", "A", "A", "A", "A", "A"),
("Orthostatic Blood Pressure", "MOD", "A", "A", "A", "A", "A", "A"),
("── THYROID / AUTOIMMUNE ─────────────────", "", "", "", "", "", "", ""),
("TSH + Free T4", "URGENT","6M", "6M", "6M", "6M", "6M", "6M"),
("Anti-TPO + Anti-Tg Antibodies", "HIGH", "A", "---", "A", "---", "A", "---"),
("Thyroid Ultrasound", "HIGH", "A", "A", "A", "A", "A", "A"),
("RF + Anti-CCP (RA screen)", "HIGH", "A", "A", "A", "A", "A", "A"),
("ANA Screen", "MOD", "A", "---", "A", "---", "A", "---"),
("Anti-tTG IgA (Coeliac screen)", "MOD", "NOW", "---", "---", "A", "---", "---"),
("Serum B12 + Folate", "HIGH", "A", "A", "A", "A", "A", "A"),
("ESR + CRP", "MOD", "A", "A", "A", "A", "A", "A"),
("── COUGH / RESPIRATORY ──────────────────", "", "", "", "", "", "", ""),
("STOP Vildagliptin / Switch medication", "URGENT","NOW", "---", "---", "---", "---", "---"),
("Chest X-Ray", "URGENT","NOW", "A", "A", "A", "A", "A"),
("Low-Dose CT Chest (LDCT)", "HIGH", "NOW", "---", "A", "---", "A", "---"),
("Spirometry / PFTs", "HIGH", "NOW", "---", "---", "A", "---", "---"),
("PPI Trial (GERD cough)", "HIGH", "NOW", "---", "---", "---", "---", "---"),
("ENT Review (UACS / postnasal drip)", "MOD", "A", "A", "A", "A", "A", "A"),
("── VENOUS / VASCULAR ────────────────────", "", "", "", "", "", "", ""),
("Duplex Venous USS – Bilateral Lower Limb", "URGENT","NOW", "A", "A", "A", "A", "A"),
("Ankle-Brachial Index (ABI)", "URGENT","NOW", "A", "A", "A", "A", "A"),
("NCS / EMG (Neuropathy workup)", "HIGH", "NOW", "---", "A", "---", "A", "---"),
("── CARDIOVASCULAR ───────────────────────", "", "", "", "", "", "", ""),
("ECG (12-lead)", "HIGH", "A", "A", "A", "A", "A", "A"),
("Echocardiogram", "MOD", "NOW", "---", "---", "A", "---", "---"),
("ASCVD Score + Blood Pressure", "HIGH", "A", "A", "A", "A", "A", "A"),
("── GYNAECOLOGY / HORMONAL ──────────────", "", "", "", "", "", "", ""),
("Mammography (Annual – HIGH RISK)", "URGENT","A", "A", "A", "A", "A", "A"),
("Pelvic USS + CA-125", "HIGH", "A", "A", "A", "A", "A", "A"),
("Pap Smear + HPV Co-test", "HIGH", "NOW", "---", "---", "---", "---", "A"),
("FSH + LH + Estradiol", "HIGH", "A", "A", "A", "A", "A", "A"),
("DEXA Bone Density Scan", "URGENT","NOW", "---", "A", "---", "A", "---"),
("Vitamin D + Calcium", "HIGH", "A", "A", "A", "A", "A", "A"),
("── CANCER SCREENING ─────────────────────", "", "", "", "", "", "", ""),
("Colonoscopy (baseline at 50)", "HIGH", "NOW", "---", "---", "---", "---", "---"),
("── MEDICATION REVIEW ────────────────────", "", "", "", "", "", "", ""),
("Switch Vildagliptin (DPP-4i cough)", "URGENT","NOW", "---", "---", "---", "---", "---"),
("Metformin B12 monitoring", "HIGH", "A", "A", "A", "A", "A", "A"),
("Levothyroxine dose review (TSH)", "HIGH", "6M", "6M", "6M", "6M", "6M", "6M"),
("Statin initiation", "HIGH", "NOW", "A", "A", "A", "A", "A"),
("ALERT: NO ACE Inhibitors (cough)", "URGENT","NOW", "A", "A", "A", "A", "A"),
]
for ri, trow in enumerate(tl, start=5):
r = ri
ws3.row_dimensions[r].height = 22
test_nm = trow[0]; priority = trow[1]; schedule = trow[2:]
is_sec = test_nm.startswith("──")
a = ws3.cell(row=r,column=1,value=test_nm)
a.border = border()
if is_sec:
a.font = font(bold=True,size=9,color="FFFFFF")
a.fill = fill(C_SECTION_HD); a.alignment = align(h="left")
ws3.merge_cells(f"A{r}:I{r}")
else:
a.font = font(size=9); a.fill = fill(C_WHITE); a.alignment = align(h="left")
if not is_sec:
b = ws3.cell(row=r,column=2,value=priority)
b.border = border(); b.alignment = align()
pc = PRIORITY_CLR.get(priority,"1565C0")
b.font = font(bold=True,size=8,color="FFFFFF"); b.fill = fill(pc)
for sci,sv in enumerate(schedule,start=3):
sc = ws3.cell(row=r,column=sci,value=sv)
sc.border = border(); sc.alignment = align()
fc = CELL_CLR.get(sv,"FFFFFF")
sc.fill = fill(fc)
sc.font = font(bold=(sv not in ["---",""]),size=9,
color="1A1A2E" if sv != "---" else "9E9E9E")
ws3.freeze_panes = "C5"
# Legend
lr = len(tl)+7
ws3[f"A{lr}"] = "LEGEND:"
ws3[f"A{lr}"].font = font(bold=True,size=9)
for li,(col_l,code,fc,desc) in enumerate([
("B","NOW","FFCDD2","Immediate / Urgent action"),
("C","A","C8E6C9","Annual"),
("D","Q3M","B3E5FC","Every 3 months"),
("E","6M","B2EBF2","Every 6 months"),
("F","---","F5F5F5","Not due this year"),
],0):
c = ws3.cell(row=lr,column=li+2,value=f"{code} = {desc}")
c.fill = fill(fc); c.font = font(size=9); c.border = border(); c.alignment = align(h="left")
# Save
import shutil, os
tmp = "/tmp/Diabetes_Screening_Tracker_v2.xlsx"
dest = "/tmp/workspace/patient-tracker/Diabetes_Screening_Tracker_v2.xlsx"
wb.save(tmp)
os.system(f"cp '{tmp}' '{dest}'")
print(f"Saved: {dest}")
cd /tmp/workspace/patient-tracker && python build_tracker.py && ls -lh /tmp/workspace/patient-tracker/
Diabetes Screening Tracker v2
Spreadsheet · XLSX
"Hashimoto's Thyroiditis diagnosed DURING diabetes workup at ~age 42-43 by diabetologist (incidental finding on autoimmune screening)"
"Father died of lung cancer as a NON-SMOKER → possible familial EGFR mutation, ALK rearrangement, or ROS1 mutation - common in South Asian women. Persistent cough + this family history = CHEST X-RAY + LDCT chest MANDATORY NOW"
| Sheet | Contents |
|---|---|
| Patient Summary | Full clinical profile + 7 colour-coded risk flags |
| Annual Screening Tracker | 40+ investigations with: reason, frequency, date columns, targets, actions, priority badges |
| Screening Timeline | Year-by-year schedule (2026-2031, age 50-55) with colour coding |