This is the report of 40 yr old male , analyse each thing and give simple and elaborated explaintion of each and everything

Reading File
Reading File
Running Command

cd /home/daytona/workspace/attachments/0ceddced-9d83-4f01-b851-ba5e25c41d4e/ && …

Running Command

python3 -c " from pypdf import PdfReader reader = PdfReader('/home/daytona/works…

Running Command

python3 -c " import subprocess result = subprocess.run(['pdftoppm', '-r', '200',…

Running Command

python3 -c " import pytesseract from PIL import Image import os pages = sorted(…

Running Command

python3 -c " from PIL import Image import os img = Image.open('/tmp/rahul_page-0…

Reading File
Reading File
Running Command

python3 -c " from PIL import Image import os # Resize to smaller for viewing im…

Running Command

python3 -c " from PIL import Image import numpy as np # Check pixel values on p…

Running Command

python3 -c " import pytesseract from PIL import Image, ImageEnhance, ImageFilter…

Running Command

python3 -c " from PIL import Image import numpy as np # Crop to middle portion …

Reading File
Running Command

python3 -c " from PIL import Image import numpy as np import os for pg_num in r…

Reading File
Reading File
Reading File
I now have all the essential data. I can see this is a complete TMT (Treadmill Stress Test) report. Pages 3-10 are ECG traces from different stages. I have all the information I need from pages 1 and 2. Let me now provide a thorough, simple explanation.

TMT (Treadmill Stress Test) Report - Rahul Chavhan, 41 Years Male

Hospital: Platina Heart Hospital, Nagpur | Date: May 23, 2026 | Cardiologist: Dr. Pramod Mundra, MD, DM (Cardiology)

🧍 Patient Details

FieldValue
NameMr. Rahul Chavhan
Age / Sex41 years / Male
Height161 cm
Weight58 kg
AddressWadi, Nagpur
What this means: At 58 kg and 161 cm, his BMI is approximately 22.4 - which is in the normal/healthy range (18.5-24.9). He is not overweight.

πŸƒ What Is This Test? (TMT / Stress Test)

A Treadmill Test (TMT) - also called a Cardiac Stress Test - checks how your heart behaves when it is under physical stress. You walk/run on a treadmill while your heart's electrical activity (ECG) and blood pressure are continuously monitored. The speed and incline increase in stages.
Why it's done: To detect if there is any blockage or reduced blood supply to the heart that only shows up during exertion (not at rest).

πŸ“‹ Test Setup

FieldValueExplanation
ProtocolModified BruceA standard, widely-used treadmill exercise protocol. "Modified" means it starts more gently - suitable for patients who may not be very fit or have risk factors.
Object of TestIHD ScreeningIHD = Ischaemic Heart Disease (blockage in heart arteries). The test was done to screen/check if Rahul has any such blockage.
Brief HistoryIHD ScreeningConfirms this was a preventive/screening test, not because of existing symptoms.

⚠️ Risk Factors

Listed: Male, Hypertension, Age
Simple Explanation:
  • Male sex: Men have a higher risk of heart disease than pre-menopausal women.
  • Hypertension: High blood pressure (which he seems to have - confirmed by his BP readings during the test). High BP damages artery walls over time and is a major risk factor for heart attacks.
  • Age: At 41, he is entering the age window where cardiac risk starts increasing.

🏁 Exercise Stages - Step by Step Data (Page 2 Table)

The test ran through several stages, increasing in speed and effort:
StageTimeSpeedGradeHeart Rate (bpm)BP (mmHg)METsST Level
Pre-Test0:200 km/h0%73120/801.000.52
Supine0:050077120/801.000.52
Standing0:060076120/801.000.42
Hyperventilation0:070075120/801.000.29
Wait for Exercise0:080077120/801.00--
Exercise Stage 13:002.7 km/h0%88120/802.280.68
Exercise Stage 23:002.7 km/h5%91140/803.440.77
Exercise Stage 33:002.7 km/h10%100150/804.60-0.03
Exercise Stage 43:004.0 km/h12%111160/807.01-0.29
Peak Exercise0:015.5 km/h14%111160/8010.21-0.29
Recovery 11:000097160/801.000.29
Recovery 33:000077160/801.000.48

Explaining Each Column:

Heart Rate (HR) in bpm: How fast his heart was beating. At rest it was 73 bpm (very normal). At peak exercise it reached 111 bpm.
  • His Maximum Predicted Heart Rate = 220 - age = 220 - 41 = 179 bpm
  • He achieved 112 bpm = 62.57% of 179 bpm
  • Ideally, for a conclusive negative test you want to reach 85% of maximum (about 152 bpm). He did not reach 85% because the test was stopped early due to lower limb pain (not heart symptoms), but the cardiologist still interpreted it as negative.
Blood Pressure (BP): Started at 120/80 (perfectly normal). Rose to 160/80 at peak exercise.
  • A rise in BP during exercise is completely expected and normal.
  • His resting BP of 120/80 is at the upper border of normal / early Stage 1 hypertension.
METs (Metabolic Equivalents): A measure of how much energy/effort is being expended.
  • 1 MET = sitting quietly at rest
  • He reached 10.21 METs at peak exercise - this is a good functional capacity. Anything above 10 METs is generally considered excellent cardiac fitness.
ST Level (mm): This is the most important measurement in a stress test. The ST segment on the ECG represents blood flow to the heart muscle.
  • ST depression β‰₯ 1 mm during exercise = sign of possible ischemia (inadequate blood supply to heart)
  • His ST changes were very minor: small positive values at rest (normal variant), small negative values (-0.29 mm) at peak - well below the 1 mm threshold for concern

πŸ›‘ Why Was the Test Stopped?

Reason for Termination: LOWER LIMB PAIN
He stopped because his legs got tired/painful - NOT because of chest pain, breathlessness, or any heart-related symptom. This is a non-cardiac reason for stopping, which is a reassuring finding.

πŸ“Š Key Summary Numbers

ParameterValueWhat It Means
Total Exercise Time12 minutes 1 secondVery good duration - shows he has decent physical endurance
Max Heart Rate112 bpm (62.57% of 179 bpm)Did not reach target 85%, but test still valid as negative
Max Workload10.21 METsExcellent - above 10 METs = good heart reserve
Max BP160/80 mmHgNormal exercise response
Distance Covered0.61 km--
Double Product17,920Heart Rate Γ— Systolic BP at peak = 111 Γ— 160 = 17,760 (close match). This number reflects peak cardiac work. Values > 25,000 would be excellent; his is moderate-good.

πŸ«€ ECG Findings - The Heart Tracings (Pages 3-10)

Pages 3 onwards show the actual ECG recordings at different stages.

Pre-Test ECG (Page 3 - Linked Median Report)

  • Stage: Pre-Test | HR: 73 bpm | BP: 120/80 | METs: 1.00
  • Shows the heart's electrical pattern before any exercise.

Exercise Stage 1 ECG (Page 4)

  • HR: 88 bpm | BP: 120/80 | METs: 3.44 | Speed: 2.7 km/h
  • Heart rate appropriately rising. No concerning ST changes.
The subsequent pages (Pages 5-10) show ECG traces at each subsequent stage of exercise - they represent the continuous monitoring throughout the test.
Key ECG Finding noted on the report: "NSR, LVH"
  • NSR = Normal Sinus Rhythm - The heart's natural pacemaker (sinus node) is in control. The heartbeat is regular and originates from the correct place. This is the ideal, normal finding.
  • LVH = Left Ventricular Hypertrophy - The left ventricle (the main pumping chamber) is slightly thickened/enlarged. This is NOT a heart attack finding. It is commonly seen in people with hypertension - when the heart has to pump against high blood pressure for years, its walls thicken, just like a bicep muscle grows with regular exercise. It confirms he likely has had hypertension for some time.

βœ… Final Impression (The Doctor's Reading)

PhaseFinding
Pre-TestNSR (Normal Sinus Rhythm) + LVH (Left Ventricular Hypertrophy)
Peak ExerciseNO SIGNIFICANT ST-T CHANGES
RecoveryUNEVENTFUL
What "No significant ST-T changes" means: During peak physical effort, the heart's blood supply remained adequate. No signs of ischemia (blockage) were detected.
What "Uneventful recovery" means: After the exercise stopped, the heart returned to its baseline normally without any abnormal rhythms, extra beats, or BP problems.

πŸ† CONCLUSION (The Most Important Line)

"TMT IS NEGATIVE FOR INDUCIBLE ISCHAEMIA AT 12:02 MINUTES OF EXERCISE IN MODIFIED BRUCE PROTOCOL."
In plain language: The treadmill stress test is NEGATIVE - meaning no evidence of blocked or reduced blood supply to the heart was found during exercise. Rahul does NOT appear to have significant coronary artery disease at this time.

πŸ“ Overall Summary for Rahul

FindingStatusWhat To Do
Heart blockage (IHD)❌ Not detected - Negative TMTGood news - no major blockages found
Heart rhythmβœ… Normal (NSR)No action needed
LVH (thickened heart wall)⚠️ PresentLikely due to hypertension - needs BP control
Blood Pressure at rest⚠️ 120/80 (borderline)Monitor, lifestyle changes
Exercise capacityβœ… Good (10.21 METs, 12 min)Maintain regular physical activity
ST changes during exerciseβœ… No significant changesReassuring

πŸ’‘ Key Takeaways in Simple Words

  1. Good news: Your heart stress test came back normal - no blockages detected during exercise.
  2. Watch your blood pressure: The LVH on ECG means high BP has been stressing your heart for some time. Controlling BP is the #1 priority.
  3. Leg pain, not heart pain: The test stopped because your legs got tired, not because your heart struggled - another positive sign.
  4. Good fitness level: Completing 12 minutes and reaching 10+ METs shows decent heart and body fitness.
  5. Follow up regularly: With hypertension as a risk factor, annual cardiac checkups are advisable.
Note: This analysis is for educational understanding only. Please discuss all findings and any concerns directly with Dr. Pramod Mundra or your treating physician, as they have the full clinical context.

Make a lifestyle modification checklist for post-TMT follow-up

Reading File
Asking for Preferences
Reading File
Running Command

mkdir -p /home/daytona/workspace/rahul-tmt && ls /home/daytona/workspace/rahul-t…

Writing File

~/rahul-tmt/generate_checklist.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable
)
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER
from reportlab.platypus import KeepTogether

OUTPUT = "/home/daytona/workspace/rahul-tmt/Rahul_TMT_Lifestyle_Checklist.pdf"

doc = SimpleDocTemplate(
    OUTPUT, pagesize=A4,
    leftMargin=18*mm, rightMargin=18*mm,
    topMargin=16*mm, bottomMargin=16*mm
)

# ── Colour palette ──────────────────────────────────────────────────────────
NAVY    = colors.HexColor("#1A2E4A")
TEAL    = colors.HexColor("#1D7A8C")
MINT    = colors.HexColor("#E6F7F9")
CORAL   = colors.HexColor("#E8503A")
AMBER   = colors.HexColor("#F5A623")
LTGRAY  = colors.HexColor("#F4F6F8")
DGRAY   = colors.HexColor("#4A5568")
WHITE   = colors.white
GREEN   = colors.HexColor("#27AE60")
ORANGE  = colors.HexColor("#E67E22")
RED     = colors.HexColor("#C0392B")

# ── Styles ───────────────────────────────────────────────────────────────────
def style(name, **kw):
    return ParagraphStyle(name, **kw)

title_s   = style("title",   fontSize=22, textColor=WHITE,   fontName="Helvetica-Bold",
                  alignment=TA_CENTER, spaceAfter=2)
sub_s     = style("sub",     fontSize=10, textColor=MINT,    fontName="Helvetica",
                  alignment=TA_CENTER, spaceAfter=2)
patient_s = style("patient", fontSize=9,  textColor=MINT,    fontName="Helvetica",
                  alignment=TA_CENTER)

sec_s     = style("sec",     fontSize=12, textColor=WHITE,   fontName="Helvetica-Bold",
                  alignment=TA_LEFT, leftPadding=4)
item_s    = style("item",    fontSize=9.5,textColor=NAVY,    fontName="Helvetica",
                  leading=14, leftIndent=4)
item_bold = style("item_b",  fontSize=9.5,textColor=NAVY,    fontName="Helvetica-Bold",
                  leading=14, leftIndent=4)
note_s    = style("note",    fontSize=8,  textColor=DGRAY,   fontName="Helvetica-Oblique",
                  leading=12, leftIndent=4)
warn_s    = style("warn",    fontSize=9,  textColor=RED,     fontName="Helvetica-Bold",
                  leading=13, leftIndent=4)
footer_s  = style("footer",  fontSize=7.5,textColor=DGRAY,   fontName="Helvetica-Oblique",
                  alignment=TA_CENTER)

# ── Helpers ──────────────────────────────────────────────────────────────────
def checkbox(text, bold=False):
    st = item_bold if bold else item_s
    return Paragraph(f"<font color='#1D7A8C'>&#9744;</font>  {text}", st)

def bullet(text):
    return Paragraph(f"<font color='#1D7A8C'>&#9654;</font>  {text}", item_s)

def note(text):
    return Paragraph(f"<i>{text}</i>", note_s)

def warning(text):
    return Paragraph(f"&#9888;  {text}", warn_s)

def section_header(label, color=TEAL):
    data = [[Paragraph(label, sec_s)]]
    t = Table(data, colWidths=[174*mm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), color),
        ("TOPPADDING",    (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("LEFTPADDING",   (0,0), (-1,-1), 8),
        ("ROUNDEDCORNERS", [4,4,4,4]),
    ]))
    return t

def two_col_row(left_items, right_items):
    """Render two-column checklist side by side."""
    def col(items):
        paras = [Spacer(1, 2)]
        for it in items:
            paras.append(checkbox(it))
            paras.append(Spacer(1, 3))
        return paras

    data = [[col(left_items), col(right_items)]]
    t = Table(data, colWidths=[85*mm, 85*mm])
    t.setStyle(TableStyle([
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
        ("LEFTPADDING",   (0,0), (-1,-1), 4),
        ("RIGHTPADDING",  (0,0), (-1,-1), 4),
        ("TOPPADDING",    (0,0), (-1,-1), 2),
        ("BOTTOMPADDING", (0,0), (-1,-1), 2),
        ("BACKGROUND",    (0,0), (-1,-1), LTGRAY),
    ]))
    return t

def info_box(items, bg=MINT):
    """Compact info box with bullet points."""
    paras = [Spacer(1,2)]
    for it in items:
        paras.append(bullet(it))
        paras.append(Spacer(1, 2))
    data = [[paras]]
    t = Table(data, colWidths=[174*mm])
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), bg),
        ("TOPPADDING",    (0,0), (-1,-1), 6),
        ("BOTTOMPADDING", (0,0), (-1,-1), 6),
        ("LEFTPADDING",   (0,0), (-1,-1), 8),
        ("RIGHTPADDING",  (0,0), (-1,-1), 8),
        ("BOX",           (0,0), (-1,-1), 0.5, TEAL),
    ]))
    return t

# ── Cover Banner ─────────────────────────────────────────────────────────────
def banner():
    data = [[
        Paragraph("POST-TMT LIFESTYLE MODIFICATION CHECKLIST", title_s),
        Paragraph("Personalised for Cardiac Risk Management", sub_s),
        Paragraph("Patient: Mr. Rahul Chavhan  |  Age: 41 yrs / Male  |  Date: May 23, 2026", patient_s),
        Paragraph("Platina Heart Hospital, Nagpur  |  Dr. Pramod Mundra, MD, DM (Cardiology)", patient_s),
    ]]
    t = Table(data, colWidths=[174*mm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), NAVY),
        ("TOPPADDING",    (0,0), (-1,-1), 12),
        ("BOTTOMPADDING", (0,0), (-1,-1), 12),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
        ("RIGHTPADDING",  (0,0), (-1,-1), 10),
    ]))
    return t

# ── TMT Result Summary Strip ──────────────────────────────────────────────────
def result_strip():
    boxes = [
        ("TMT RESULT", "NEGATIVE βœ“", GREEN),
        ("MAX METs", "10.21 (Excellent)", GREEN),
        ("MAX HR", "112 bpm (62.6%)", AMBER),
        ("BP at Rest", "120/80 mmHg", AMBER),
        ("LVH Found", "YES - Monitor", ORANGE),
        ("IHD Detected", "None", GREEN),
    ]
    header_row = [Paragraph(f"<font color='white'><b>{h}</b></font>",
                             style(f"rs_h_{i}", fontSize=8, textColor=WHITE,
                                   fontName="Helvetica-Bold", alignment=TA_CENTER))
                  for i, (h, _, _) in enumerate(boxes)]
    val_row    = [Paragraph(f"<b>{v}</b>",
                             style(f"rs_v_{i}", fontSize=8.5, textColor=c,
                                   fontName="Helvetica-Bold", alignment=TA_CENTER))
                  for i, (_, v, c) in enumerate(boxes)]

    t = Table([header_row, val_row], colWidths=[29*mm]*6)
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,0), NAVY),
        ("BACKGROUND",    (0,1), (-1,1), LTGRAY),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("ALIGN",         (0,0), (-1,-1), "CENTER"),
        ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
        ("BOX",           (0,0), (-1,-1), 0.8, TEAL),
        ("INNERGRID",     (0,0), (-1,-1), 0.4, colors.HexColor("#BDC3C7")),
    ]))
    return t

# ── Build Story ───────────────────────────────────────────────────────────────
story = []

story.append(banner())
story.append(Spacer(1, 5*mm))
story.append(result_strip())
story.append(Spacer(1, 4*mm))

# ── 1. Blood Pressure Management ─────────────────────────────────────────────
story.append(section_header("1.  BLOOD PRESSURE MANAGEMENT   (Priority #1)"))
story.append(Spacer(1, 2))
story.append(two_col_row(
    [
        "Check BP every morning before eating/medication",
        "Keep a written BP log (date, time, reading)",
        "Target BP: below 130/80 mmHg",
        "Take BP medicines at same time daily",
        "Never skip antihypertensive dose",
    ],
    [
        "Reduce salt: max 5 g (1 teaspoon) per day",
        "Avoid pickles, papads, processed/packaged food",
        "Limit soy sauce, ketchup, namkeen snacks",
        "Show BP diary to doctor at every visit",
        "Inform doctor if BP > 160/100 on 2 readings",
    ]
))
story.append(Spacer(1, 1))
story.append(note("Why: LVH (Left Ventricular Hypertrophy) found on ECG means your heart wall is already thickening due to high BP. Controlling BP prevents further thickening and reduces stroke/heart attack risk."))
story.append(Spacer(1, 4))

# ── 2. Exercise & Physical Activity ──────────────────────────────────────────
story.append(section_header("2.  EXERCISE & PHYSICAL ACTIVITY"))
story.append(Spacer(1, 2))
story.append(two_col_row(
    [
        "Walk briskly 30-45 min, 5 days per week",
        "Start slow (15 min) and increase gradually",
        "Warm up 5 min before and cool down 5 min after",
        "Aim to reach mild-to-moderate breathlessness",
        "Cycling or swimming are excellent alternatives",
        "Do light stretching / yoga 10 min daily",
    ],
    [
        "Avoid sudden intense exercise without warm-up",
        "Stop if chest pain, severe breathlessness, or dizziness",
        "Avoid exercise immediately after heavy meals",
        "Exercise in cool environment (avoid midday heat)",
        "Wear comfortable, supportive footwear",
        "Build up to 150 min moderate exercise/week",
    ]
))
story.append(Spacer(1, 1))
story.append(note("Why: Your TMT showed 10.21 METs - excellent fitness. Maintaining this with regular aerobic exercise keeps cardiac function strong. Leg pain stopped your test (not heart) - strengthening leg muscles will improve endurance."))
story.append(Spacer(1, 4))

# ── 3. Diet & Nutrition ───────────────────────────────────────────────────────
story.append(section_header("3.  DIET & NUTRITION", color=colors.HexColor("#1A6B4A")))
story.append(Spacer(1, 2))

# Eat / Avoid table
eat_items = [
    ("INCLUDE MORE", "#27AE60",
     ["Fresh fruits: apple, guava, pomegranate, citrus",
      "Vegetables: leafy greens, tomato, brinjal, lauki",
      "Whole grains: jowar, bajra, brown rice, oats",
      "Lean protein: dal, sprouts, tofu, fish (2x/week)",
      "Low-fat dairy: buttermilk, skimmed milk, curd",
      "Nuts (small handful): walnuts, almonds, flaxseeds",
      "Olive/mustard oil - 3-4 tsp/day only"]),
    ("REDUCE / AVOID", "#C0392B",
     ["Fried foods: vada, puri, bhajia, samosa",
      "Refined carbs: white bread, maida products",
      "Red meat: mutton, beef, processed meat",
      "Full-fat dairy: cream, paneer, ghee (limit)",
      "Sugary drinks: cola, packaged juices, energy drinks",
      "Alcohol: limit to 1 drink/day maximum",
      "Trans fats: vanaspati, dalda, bakery biscuits"]),
]

col_data = []
for title, col_hex, items in eat_items:
    col = [Paragraph(f"<b><font color='{col_hex}'>{title}</font></b>",
                     style("et", fontSize=9, fontName="Helvetica-Bold", alignment=TA_CENTER))]
    for it in items:
        col.append(Paragraph(f"  {'+ ' if col_hex=='#27AE60' else '- '}{it}", item_s))
    col_data.append(col)

t = Table([col_data], colWidths=[85*mm, 85*mm])
t.setStyle(TableStyle([
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ("TOPPADDING",    (0,0), (-1,-1), 6),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("BACKGROUND",    (0,0), (0,0), colors.HexColor("#EAFAF1")),
    ("BACKGROUND",    (1,0), (1,0), colors.HexColor("#FDEDEC")),
    ("BOX",           (0,0), (0,0), 0.5, GREEN),
    ("BOX",           (1,0), (1,0), 0.5, RED),
]))
story.append(t)
story.append(Spacer(1, 1))
story.append(note("Why: A heart-healthy DASH/Mediterranean-style diet lowers BP, reduces LDL cholesterol, and prevents plaque buildup in coronary arteries. Your weight (58 kg) is healthy - focus on quality, not restriction."))
story.append(Spacer(1, 4))

# ── 4. Stress & Sleep ─────────────────────────────────────────────────────────
story.append(section_header("4.  STRESS MANAGEMENT & SLEEP", color=colors.HexColor("#5B2C8D")))
story.append(Spacer(1, 2))
story.append(two_col_row(
    [
        "Sleep 7-8 hours every night (fixed schedule)",
        "Avoid screens 1 hour before bedtime",
        "Practice deep breathing: 10 min daily",
        "Pranayama or meditation: 15 min morning",
        "Spend time outdoors / in nature daily",
    ],
    [
        "Identify and reduce key work/home stressors",
        "Take short breaks every 1-2 hours at work",
        "Avoid arguments and emotional outbursts",
        "Talk to family/friends - social support matters",
        "If anxiety persists, discuss with your doctor",
    ]
))
story.append(Spacer(1, 1))
story.append(note("Why: Chronic stress raises cortisol, spikes BP, and increases risk of arrhythmias. Poor sleep worsens hypertension. Both are modifiable risk factors for heart disease."))
story.append(Spacer(1, 4))

# ── 5. Smoking & Substances ───────────────────────────────────────────────────
story.append(section_header("5.  SMOKING, TOBACCO & ALCOHOL", color=colors.HexColor("#7D3C0F")))
story.append(Spacer(1, 2))
story.append(info_box([
    "If you smoke - QUIT immediately. Smoking doubles the risk of heart attack even with a negative TMT.",
    "If you use tobacco (gutka, paan, khaini) - stop completely. Nicotine raises BP and causes artery spasm.",
    "Alcohol: if consumed, limit to 1 small drink (30 ml spirit / 150 ml wine) per day - no binge drinking.",
    "Avoid second-hand smoke environments (smoky rooms, vehicles).",
    "If quitting is difficult, ask your doctor about nicotine replacement therapy.",
], bg=colors.HexColor("#FEF9E7")))
story.append(Spacer(1, 4))

# ── 6. Weight & Metabolic ─────────────────────────────────────────────────────
story.append(section_header("6.  WEIGHT & METABOLIC MONITORING"))
story.append(Spacer(1, 2))
story.append(two_col_row(
    [
        "Weigh yourself weekly (same time, same clothes)",
        "Current BMI: 22.4 - maintain in 18.5-24.9 range",
        "Waist circumference: keep below 90 cm (men)",
        "Fasting blood sugar test: every 6 months",
        "Lipid profile (cholesterol): every 6-12 months",
    ],
    [
        "HbA1c test: annually (rule out hidden diabetes)",
        "Kidney function (creatinine, urine): annually",
        "Thyroid (TSH): if fatigue or weight gain noticed",
        "If BMI rises above 25, review diet with doctor",
        "No crash dieting - lose weight gradually if needed",
    ]
))
story.append(Spacer(1, 1))
story.append(note("Why: Your risk factors include hypertension, age, and male sex. Diabetes and high cholesterol are additive risks. Early detection through regular blood tests allows timely treatment."))
story.append(Spacer(1, 4))

# ── 7. Medications & Medical Follow-up ───────────────────────────────────────
story.append(section_header("7.  MEDICATIONS & MEDICAL FOLLOW-UP", color=CORAL))
story.append(Spacer(1, 2))
story.append(two_col_row(
    [
        "Take all prescribed medicines without fail",
        "Never stop BP medicines without doctor advice",
        "Carry a medicine list / prescription at all times",
        "Report side effects immediately to your doctor",
        "Repeat TMT: as advised (typically every 1-2 years)",
    ],
    [
        "Echocardiogram: to assess LVH - ask your doctor",
        "Visit cardiologist every 3-6 months initially",
        "Annual full cardiac check-up thereafter",
        "Emergency: go to hospital if chest pain at rest",
        "Keep emergency contact (hospital) saved in phone",
    ]
))
story.append(Spacer(1, 4))

# ── 8. Warning Signs ─────────────────────────────────────────────────────────
story.append(section_header("8.  WARNING SIGNS - GO TO HOSPITAL IMMEDIATELY", color=CORAL))
story.append(Spacer(1, 2))
warn_data = [
    [warning("Chest pain, pressure, or tightness at rest or during activity"),
     warning("Sudden shortness of breath without exertion")],
    [warning("Pain radiating to left arm, jaw, neck, or back"),
     warning("Palpitations: fast, irregular, or pounding heartbeat")],
    [warning("Sudden dizziness, lightheadedness, or fainting"),
     warning("Severe headache with very high BP (> 180/110)")],
]
wt = Table(warn_data, colWidths=[87*mm, 87*mm])
wt.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), colors.HexColor("#FDEDEC")),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("BOX",           (0,0), (-1,-1), 0.8, RED),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, colors.HexColor("#F1948A")),
]))
story.append(wt)
story.append(Spacer(1, 4))

# ── Daily Habit Tracker ───────────────────────────────────────────────────────
story.append(section_header("9.  DAILY HABIT TRACKER  (Tick each day)", color=colors.HexColor("#2C3E50")))
story.append(Spacer(1, 2))

habits = [
    "Morning BP check + log",
    "30 min brisk walk / exercise",
    "8 glasses of water (2 litres)",
    "Heart-healthy meals (no fried food)",
    "10 min meditation / deep breathing",
    "Medicines taken on time",
    "7-8 hours sleep",
    "No tobacco / alcohol today",
]
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]

header = [Paragraph(f"<b><font color='white'>Habit</font></b>",
                     style("th", fontSize=8, fontName="Helvetica-Bold",
                           textColor=WHITE, alignment=TA_CENTER))]
for d in days:
    header.append(Paragraph(f"<b><font color='white'>{d}</font></b>",
                              style(f"td_{d}", fontSize=8, fontName="Helvetica-Bold",
                                    textColor=WHITE, alignment=TA_CENTER)))

rows = [header]
for h in habits:
    row = [Paragraph(h, style("hb", fontSize=8, fontName="Helvetica", textColor=NAVY))]
    for _ in days:
        row.append(Paragraph("&#9744;", style("cb", fontSize=10, textColor=TEAL,
                                               alignment=TA_CENTER)))
    rows.append(row)

tracker = Table(rows, colWidths=[70*mm] + [15*mm]*7)
tracker.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), NAVY),
    ("BACKGROUND",    (0,1), (-1,1), LTGRAY),
    ("BACKGROUND",    (0,2), (-1,2), WHITE),
    ("BACKGROUND",    (0,3), (-1,3), LTGRAY),
    ("BACKGROUND",    (0,4), (-1,4), WHITE),
    ("BACKGROUND",    (0,5), (-1,5), LTGRAY),
    ("BACKGROUND",    (0,6), (-1,6), WHITE),
    ("BACKGROUND",    (0,7), (-1,7), LTGRAY),
    ("BACKGROUND",    (0,8), (-1,8), WHITE),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (0,-1), 6),
    ("ALIGN",         (1,0), (-1,-1), "CENTER"),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ("BOX",           (0,0), (-1,-1), 0.8, TEAL),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, colors.HexColor("#BDC3C7")),
]))
story.append(tracker)
story.append(Spacer(1, 6))

# ── Footer ───────────────────────────────────────────────────────────────────
story.append(HRFlowable(width="100%", thickness=0.5, color=TEAL))
story.append(Spacer(1, 3))
story.append(Paragraph(
    "This checklist is personalised based on Rahul Chavhan's TMT report (May 23, 2026). "
    "It is an educational guide and does not replace medical advice. "
    "Always follow your cardiologist's specific instructions.  |  "
    "Platina Heart Hospital, Nagpur  |  Dr. Pramod Mundra, MD, DM (Cardiology)",
    footer_s))

# ── Build ─────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF saved to: {OUTPUT}")
Running Command

python3 /home/daytona/workspace/rahul-tmt/generate_checklist.py 2>&1

Running Command

ls -lh /home/daytona/workspace/rahul-tmt/Rahul_TMT_Lifestyle_Checklist.pdf

Running Command

python3 -c " from pypdf import PdfReader r = PdfReader('/home/daytona/workspace/…

Running Command

pdftoppm -r 150 /home/daytona/workspace/rahul-tmt/Rahul_TMT_Lifestyle_Checklist.…

Reading File
The PDF looks clean and professional. Here's your checklist:

Your personalised post-TMT lifestyle checklist is ready:

Rahul TMT Lifestyle Checklist

PDF Document Β· PDF


The 3-page PDF covers everything specific to Rahul's report findings:
What's inside:
  1. TMT Result Summary Strip - quick-glance colour-coded snapshot (Negative TMT, 10.21 METs, LVH alert, BP)
  2. Blood Pressure Management (Priority #1) - because LVH is confirmed, with salt targets and BP logging instructions
  3. Exercise & Physical Activity - tailored around his good fitness base (10.21 METs) and the leg-pain issue
  4. Diet & Nutrition - two-column Include vs. Avoid food guide with Indian food examples
  5. Stress Management & Sleep - pranayama, screen habits, social support
  6. Smoking, Tobacco & Alcohol - with context for Indian habits (gutka, paan, khaini)
  7. Weight & Metabolic Monitoring - blood test schedule (lipids, sugar, thyroid, kidney)
  8. Medications & Follow-up - echocardiogram for LVH, repeat TMT timing, emergency plan
  9. Warning Signs - red-flag symptoms requiring immediate hospital visit
  10. Daily Habit Tracker - printable weekly tick-box table for all 8 daily habits
This is a shared conversation. Sign in to Orris to start your own chat.