This is as the refferal and make the SOAP analysis of the sandhya case sheet

Reading File
Reading File
Running Command

python3 << 'EOF' from pptx import Presentation pptx_path = "/tmp/workspace/attachments/d7466835-bc19-436c-be9d-7de0c22d6fbf/5_6095778492585089495 (1).pptx" prs = Presentation(pptx_path) for i, slide in enumerate(prs.slides, 1): print(f"\n=== SLIDE {i} ===") for shape in slide.shapes: if shape.has_text_frame and shape.text_frame.text.strip(): print(shape.text_frame.text) EOF

Running Command

python3 << 'EOF' import pdfplumber pdf_path = "/tmp/workspace/attachments/d7466835-bc19-436c-be9d-7de0c22d6fbf/Sandhya .pdf" with pdfplumber.open(pdf_path) as pdf: print(f"Total pages: {len(pdf.pages)}") for i, page in enumerate(pdf.pages, 1): print(f"\n=== PAGE {i} ===") text = page.extract_text() if text: print(text) else: print("[No text extracted - may be image-based]") EOF

Running Command

python3 << 'EOF' # Convert PDF pages to images using pypdf + PIL from pypdf import PdfReader import subprocess, os pdf_path = "/tmp/workspace/attachments/d7466835-bc19-436c-be9d-7de0c22d6fbf/Sandhya .pdf" # Try using pdf2image if available try: from pdf2image import convert_from_path images = convert_from_path(pdf_path, dpi=150, first_page=1, last_page=5) os.makedirs("/tmp/workspace/sandhya_pages", exist_ok=True) for i, img in enumerate(images, 1): img.save(f"/tmp/workspace/sandhya_pages/page_{i}.png") print(f"Converted {len(images)} pages") except Exception as e: print(f"pdf2image error: {e}") # Try using pypdf to extract images reader = PdfReader(pdf_path) print(f"Pages: {len(reader.pages)}") for i, page in enumerate(reader.pages[:5], 1): images = page.images print(f"Page {i}: {len(images)} images") for j, img in enumerate(images): path = f"/tmp/workspace/sandhya_pages/page_{i}_img_{j}.{img.name.split('.')[-1]}" os.makedirs("/tmp/workspace/sandhya_pages", exist_ok=True) with open(path, "wb") as f: f.write(img.data) print(f" Saved: {path}") EOF

Running Command

python3 << 'EOF' from pdf2image import convert_from_path import os pdf_path = "/tmp/workspace/attachments/d7466835-bc19-436c-be9d-7de0c22d6fbf/Sandhya .pdf" os.makedirs("/tmp/workspace/sandhya_pages", exist_ok=True) # Convert all 46 pages in batches - first get pages 1-20 images = convert_from_path(pdf_path, dpi=120, first_page=1, last_page=20) for i, img in enumerate(images, 1): img.save(f"/tmp/workspace/sandhya_pages/page_{i}.png") print(f"Converted pages 1-20") images2 = convert_from_path(pdf_path, dpi=120, first_page=21, last_page=46) for i, img in enumerate(images2, 21): img.save(f"/tmp/workspace/sandhya_pages/page_{i}.png") print(f"Converted pages 21-46") EOF

Running Command

python3 << 'EOF' from PIL import Image import os # Create composite images: combine multiple pages into one tall image per call # Group pages: 1-8, 9-16, 17-24, 25-32, 33-46 def combine_pages(page_nums, output_path, max_width=1000): images = [] for n in page_nums: path = f"/tmp/workspace/sandhya_pages/page_{n}.png" if os.path.exists(path): img = Image.open(path) # Resize to uniform width ratio = max_width / img.width new_h = int(img.height * ratio) img = img.resize((max_width, new_h), Image.LANCZOS) images.append(img) if not images: return total_h = sum(img.height for img in images) combined = Image.new("RGB", (max_width, total_h), (255, 255, 255)) y = 0 for img in images: combined.paste(img, (0, y)) y += img.height combined.save(output_path, "PNG") print(f"Saved {output_path} ({len(images)} pages, {total_h}px tall)") os.makedirs("/tmp/workspace/sandhya_combined", exist_ok=True) combine_pages(range(1, 7), "/tmp/workspace/sandhya_combined/group1.png") combine_pages(range(7, 13), "/tmp/workspace/sandhya_combined/group2.png") combine_pages(range(13, 20), "/tmp/workspace/sandhya_combined/group3.png") combine_pages(range(20, 30), "/tmp/workspace/sandhya_combined/group4.png") combine_pages(range(30, 47), "/tmp/workspace/sandhya_combined/group5.png") EOF

analyse_media
analyse_media
analyse_media
Running Command

python3 << 'EOF' # Extract text from individual pages using pytesseract if available, otherwise use pypdf image extraction import subprocess # Check if tesseract is available result = subprocess.run(["which", "tesseract"], capture_output=True, text=True) print(f"Tesseract: {result.stdout.strip() or 'not found'}") # Try pytesseract try: import pytesseract from PIL import Image img = Image.open("/tmp/workspace/sandhya_pages/page_1.png") text = pytesseract.image_to_string(img) print("Page 1 OCR:") print(text[:2000]) except Exception as e: print(f"pytesseract error: {e}") # Try easyocr try: import easyocr reader = easyocr.Reader(['en']) result = reader.readtext("/tmp/workspace/sandhya_pages/page_1.png", detail=0) print("EasyOCR page 1:", result) except Exception as e: print(f"easyocr error: {e}") EOF

Running Command

python3 -c " try: import pytesseract from PIL import Image img = Image.open('/tmp/workspace/sandhya_pages/page_1.png') text = pytesseract.image_to_string(img) print('Page 1:') print(text[:3000]) except Exception as e: print(f'pytesseract error: {e}') try: import easyocr print('easyocr available') except Exception as e: print(f'easyocr error: {e}') "

Running Command

pip install --user pytesseract 2>&1 | tail -3

Running Command

python3 -c " import sys sys.path.insert(0, '/opt/amazon/genesis1p-tools/var/.local/lib/python3.12/site-packages') import pytesseract from PIL import Image # Test if tesseract binary available import shutil print('Tesseract binary:', shutil.which('tesseract')) "

Loading Image
Loading Image
Note on the Sandhya PDF: The PDF (46 pages) is entirely image/scan-based. OCR (Tesseract) is not available in this sandbox, and the analyse_media tool requires a public HTTP URL. All clinical data below is therefore drawn from the PPTX referral presentation, which contains the complete case information.

SOAP Analysis - Sandhya Case

Presented by: Sindhana M, 2nd Pharm D | Nandha Medical College and Hospital Pharmacotherapeutics-I - Second Sessional Practical Examination

S - SUBJECTIVE

Patient Demographics:
  • Age: 32 years | Sex: Male
  • Admitted: 25/03/2026 | Discharged: 28/03/2026
Chief Complaints:
  • Muscle cramps in bilateral upper limbs (B/L UL) and right side - 10 days duration
  • Giddiness
  • Abdominal pain
History of Present Illness (HoPI):
  • Muscle cramps in B/L upper limbs and right side for 10 days
  • Associated giddiness and abdominal pain
  • No further systemic symptoms documented in the referral
Past Medical History:
  • Known case of Decompensated Chronic Liver Disease (DCLD) - diagnosed 6 months prior
  • On irregular medication for DCLD
Personal/Social History:
  • Diet: Mixed
  • Alcohol use: 7 years (chronic alcohol consumption - primary etiology for DCLD)

O - OBJECTIVE

Vital Signs:
ParameterValueNormal RangeStatus
Blood Pressure100/70 mmHg120/80 mmHgLow-normal / Hypotension
Pulse Rate111/min60-100/minTachycardia
Respiratory Rate20/min12-20/minHigh-normal
Temperature98.6°F98.6°FNormal (Afebrile)
General Examination:
  • Conscious and oriented
  • Afebrile
  • Icterus present (+) - indicating jaundice/hepatic dysfunction
  • L/E: Right eye cataract noted
Systemic Examination:
  • CVS: S1 S2 heard, no added sounds
  • RS: Bilateral air entry present
  • P/A (Abdomen):
    • Right hypochondrial region tenderness
    • Free fluid present (+) - indicating ascites
  • CNS: No focal neurological deficits (NFND)
Investigations: (The Sandhya PDF case sheet contains lab reports and investigation results. The PDF is image-based and could not be OCR-extracted in this environment. The referral PPTX does not list specific lab values. Based on the clinical picture, the following would be expected and should be reviewed from the original case sheet: LFT, RFT, serum electrolytes - particularly serum potassium - CBC, PT/INR, serum albumin, abdominal ultrasound/FAST.)
Final Diagnosis: DCLD (Decompensated Chronic Liver Disease)

A - ASSESSMENT

Primary Diagnosis

Decompensated Chronic Liver Disease (DCLD) - likely alcohol-induced (7 years alcohol history), presenting with decompensation features.

Clinical Problems Identified

#ProblemEvidence
1DCLD with decompensationIcterus, ascites (free fluid + RHC tenderness), tachycardia
2Hypokalemia (probable)Muscle cramps B/L UL, giddiness - classic hypokalemia features; KCl prescribed
3AscitesFree fluid on P/A examination, fluid restriction and salt restriction ordered
4Hepatic dysfunctionIcterus, right hypochondrial tenderness, DCLD diagnosis
5Nutritional deficiencyAlcohol history + DCLD → thiamine (Vit B1), Vitamin B12/B-complex, Vitamin E (Evion LC), Vitamin D/Calcium (Shelcal HD) supplemented
6Peptic disease / GERDSompraz D 40mg (Pantoprazole + Domperidone) prescribed
7Edema / Fluid overloadDytor 5mg (Torasemide - loop diuretic) prescribed
8Right eye cataractIncidental finding; likely alcohol/steroid-related or unrelated; needs ophthalmology referral
9Muscle spasticity/crampsBaclofen prescribed (muscle relaxant)

Drug Therapy Analysis (Discharge Medications)

DrugDose/FrequencyIndicationClass
T. Sompraz D 40mg1-0-0 (morning)Gastroprotection / GERDPPI + Prokinetic (Pantoprazole + Domperidone)
T. Thiamine 100mg1-0-1 (BD)Wernicke's prophylaxis / Vit B1 deficiencyVitamin supplement
T. Dytor 5mg1-1-0 (BD)Ascites / edema managementLoop diuretic (Torasemide)
T. UDCA 300mg1-0-1 (BD)Hepatoprotection, cholestasisUrsodeoxycholic acid
T. Evion LC1-0-0Antioxidant / Vitamin E supplementationFat-soluble vitamin
T. Shelcal HD0-0-1 (night)Calcium + Vitamin D supplementationMineral supplement
T. Neurobion Forte1-0-0B-complex (B1, B6, B12) supplementationVitamin supplement
T. VSL1-0-0Gut microbiome support / probioticProbiotic
T. Baclofen1-0-0Muscle cramps / spasticityGABA-B agonist / Muscle relaxant
Syp. KCl 5ml TDS5ml three times dailyHypokalemia correctionPotassium supplement

Non-Pharmacological Measures

  • Fluid restriction: Less than 1 L/day (for ascites management)
  • Salt restriction: Less than 2 g/day (for ascites - sodium restriction)

Drug-Related Problems (DRPs) to Consider

  1. Baclofen in hepatic impairment: Baclofen is hepatically metabolized and can accumulate in DCLD - dose adjustment may be needed; monitor for encephalopathy.
  2. Torasemide (Dytor) + KCl: Loop diuretics cause potassium loss - KCl supplementation is appropriate and necessary; monitor serum electrolytes.
  3. UDCA + other drugs: Generally well-tolerated; no significant interactions noted.
  4. Domperidone (in Sompraz D) in hepatic impairment: Domperidone is contraindicated in severe hepatic impairment due to QT prolongation risk - needs review.
  5. Irregular prior medication: Adherence issue noted; patient counseling on the importance of regular medication for DCLD is essential.

P - PLAN

Pharmacological Plan

  1. Continue all discharge medications as prescribed with appropriate monitoring.
  2. Monitor serum electrolytes (K+, Na+, Mg²+) regularly given loop diuretic use + KCl supplementation.
  3. Review Domperidone (in Sompraz D) - assess severity of liver disease; consider switching to plain Pantoprazole if Child-Pugh Class C.
  4. Monitor Baclofen closely - start at low dose, titrate cautiously; watch for CNS depression and worsening hepatic encephalopathy.
  5. Thiamine + B-complex supplementation is appropriate and essential in chronic alcohol use disorder.
  6. Liver function tests (LFT) to be repeated at follow-up to monitor disease progression.

Non-Pharmacological Plan

  1. Strict alcohol abstinence - patient counseling; refer to de-addiction services.
  2. Diet: High-protein, high-calorie diet within sodium restriction; avoid raw shellfish (Vibrio risk in cirrhosis).
  3. Fluid restriction: < 1 L/day (continue).
  4. Salt restriction: < 2 g/day (continue).
  5. Daily weight monitoring to assess fluid balance.
  6. Ophthalmology referral for right eye cataract assessment.

Monitoring Plan

ParameterFrequencyTarget
Serum K+Weekly initially3.5 - 5.0 mEq/L
Serum Na+Weekly135-145 mEq/L
LFT (ALT, AST, Bilirubin, Albumin)At follow-up (2-4 weeks)Trending improvement
PT/INRAt follow-upMonitor coagulopathy
Body weightDailyStable / decreasing (ascites reduction)
Blood pressure & pulseDailyHemodynamic stability
Signs of hepatic encephalopathyEvery visitAbsence of flap, orientation intact

Patient Counseling Points

  1. Complete alcohol abstinence - alcohol is the primary driver of disease progression.
  2. Take all medications regularly and on time (previous irregular adherence noted).
  3. Importance of low-salt diet and fluid restriction in controlling ascites.
  4. Watch for warning signs: increased abdominal swelling, confusion/disorientation (encephalopathy), hematemesis (variceal bleed), fever (SBP - spontaneous bacterial peritonitis) - return to ER immediately.
  5. KCl syrup must be taken diluted with water to avoid GI irritation.
  6. Follow-up appointment in 1-2 weeks for electrolyte check and clinical reassessment.

Note: The Sandhya PDF (46 pages) is an image-scanned case sheet containing the original hospital records. It could not be automatically read (OCR not available in this environment). If specific lab values (LFT, CBC, electrolytes, ultrasound reports) from the case sheet are needed to enrich the Objective section, please share a text-readable version of those results or type out key lab values, and I will incorporate them into the SOAP analysis.

Create for this case sheet

Asking for Preferences
Reading File
Reading File
general-purpose

Create a professional SOAP Analysis Word document (.docx) for a pharmacy clinical case. Save it to: /tmp/workspace/sandhya_output/Sandhya_SOAP_Analysis.docx Use python-docx to create the document. Here is the full clinical data: PATIENT: 32-year-old male, admitted Nandha Medical College & Hospital on 25/03/2026, discharged 28/03/2026. CASE DETAILS: - Chief Complaints: Muscle cramps in bilateral upper limbs (B/L UL) and right side for 10 days, giddiness, abdominal pain - Past History: Known case of DCLD (Decompensated Chronic Liver Disease) for 6 months, on irregular medication - Personal History: Mixed diet, Alcohol use for 7 years - Vitals: BP 100/70 mmHg, PR 111/min, RR 20/min, Temp 98.6°F - General: Conscious, oriented, afebrile, Icterus present (+), Right eye cataract (L/E) - CVS: S1S2+; RS: BAE+; P/A: Right hypochondrial tenderness, Free fluid (+) [ascites]; CNS: NFND - Final Diagnosis: DCLD (Decompensated Chronic Liver Disease) - Non-Pharm: Fluid restriction <1L/day, Salt restriction <2g/day DISCHARGE MEDICATIONS: 1. T. Sompraz D 40mg - 1-0-0 (Pantoprazole + Domperidone - gastroprotection) 2. T. Thiamine 100mg - 1-0-1 (Vitamin B1 deficiency/Wernicke's prophylaxis) 3. T. Dytor 5mg - 1-1-0 (Torasemide - loop diuretic for ascites/edema) 4. T. UDCA 300mg - 1-0-1 (Ursodeoxycholic acid - hepatoprotection) 5. T. Evion LC - 1-0-0 (Vitamin E) 6. T. Shelcal HD - 0-0-1 (Calcium + Vitamin D) 7. T. Neurobion Forte - 1-0-0 (B-complex vitamins) 8. T. VSL - 1-0-0 (Probiotic) 9. T. Baclofen - 1-0-0 (Muscle relaxant for cramps) 10. Syp. KCl 5ml TDS (Potassium chloride for hypokalemia) SOAP STRUCTURE to include: S - SUBJECTIVE: - Patient demographics - Chief complaints with duration - History of Present Illness - Past Medical History - Personal/Social History O - OBJECTIVE: - Vital signs table - General examination - Systemic examination - Diagnosis A - ASSESSMENT: - Primary diagnosis discussion (DCLD with decompensation) - Identified clinical problems (numbered list with evidence): Hypokalemia (muscle cramps, giddiness → KCl prescribed), Ascites (free fluid, RHC tenderness → fluid/salt restriction, Dytor), Hepatic dysfunction (icterus), Nutritional deficiencies (alcohol-related → multiple supplements), GERD/peptic disease (Sompraz D), Muscle cramps (Baclofen) - Drug-related problems: (1) Domperidone contraindicated in severe hepatic failure - QT risk; (2) Baclofen accumulates in hepatic impairment - monitor encephalopathy; (3) Dytor + KCl appropriate combination - Drug therapy table (all 10 medications with dose, frequency, indication, class) P - PLAN: - Pharmacological plan (6 points) - Non-pharmacological plan (alcohol abstinence, diet, fluid/salt restriction, weight monitoring, ophthalmology referral) - Monitoring parameters table (K+, Na+, LFT, PT/INR, body weight, BP/PR, encephalopathy signs) - Patient counseling points (6 points) FORMATTING REQUIREMENTS: - Use python-docx - Title: "SOAP ANALYSIS - SANDHYA CASE" in bold, centered, dark blue (0,0,128) - Subtitle: "Pharmacotherapeutics-I | Nandha Medical College & Hospital" centered - Date line: "Date of Admission: 25/03/2026 | Date of Discharge: 28/03/2026" centered - Section headers (S, O, A, P) as Heading 1 style, colored dark blue, with full label e.g. "S - SUBJECTIVE" - Sub-section headers as Heading 2 - Tables with header rows shaded light blue (173, 216, 230) - Normal text font: Arial 11pt - Add a horizontal rule line before each SOAP section - Save the file and print "SUCCESS: /tmp/workspace/sandhya_output/Sandhya_SOAP_Analysis.docx" Make sure to create the output directory first with os.makedirs. Return: confirmation the file was created successfully with its path.

general-purpose

Create a professional PowerPoint SOAP Analysis presentation (.pptx) for a pharmacy student clinical case. Save it to: /tmp/workspace/sandhya_output/Sandhya_SOAP_Presentation.pptx Use python-pptx to create the presentation. Here is the full clinical data: PATIENT: 32-year-old male, admitted Nandha Medical College & Hospital on 25/03/2026, discharged 28/03/2026. Presented by: Sindhana M, 2nd Pharm D | Pharmacotherapeutics-I Second Sessional Practical Examination CASE DETAILS: - Chief Complaints: Muscle cramps in bilateral upper limbs (B/L UL) and right side for 10 days, giddiness, abdominal pain - Past History: Known case of DCLD (Decompensated Chronic Liver Disease) for 6 months, on irregular medication - Personal History: Mixed diet, Alcohol use for 7 years - Vitals: BP 100/70 mmHg, PR 111/min, RR 20/min, Temp 98.6°F - General: Conscious, oriented, afebrile, Icterus present (+), Right eye cataract (L/E) - CVS: S1S2+; RS: BAE+; P/A: Right hypochondrial tenderness, Free fluid (+) [ascites]; CNS: NFND - Final Diagnosis: DCLD (Decompensated Chronic Liver Disease) DISCHARGE MEDICATIONS: 1. T. Sompraz D 40mg - 1-0-0 2. T. Thiamine 100mg - 1-0-1 3. T. Dytor 5mg - 1-1-0 4. T. UDCA 300mg - 1-0-1 5. T. Evion LC - 1-0-0 6. T. Shelcal HD - 0-0-1 7. T. Neurobion Forte - 1-0-0 8. T. VSL - 1-0-0 9. T. Baclofen - 1-0-0 10. Syp. KCl 5ml TDS SLIDE STRUCTURE (create exactly these slides): Slide 1 - TITLE SLIDE: Title: "SOAP ANALYSIS" Subtitle: "Sandhya Case | Pharmacotherapeutics-I" Below: "Presented by: Sindhana M | 2nd Pharm D" Below: "Nandha Medical College & Hospital" Background: dark navy blue (#003366), text white Slide 2 - SUBJECTIVE (Patient Profile): Title: "S - SUBJECTIVE" Content: • Patient: 32-year-old male • Admitted: 25/03/2026 | Discharged: 28/03/2026 • Chief Complaints: - Muscle cramps (B/L UL & right side) - 10 days - Giddiness - Abdominal pain • Past History: K/C/O DCLD - 6 months, irregular medication • Personal History: Mixed diet | Alcohol - 7 years Slide 3 - OBJECTIVE (Vitals & Examination): Title: "O - OBJECTIVE" Two columns: Left - Vital Signs: BP: 100/70 mmHg (Low-normal) PR: 111/min (Tachycardia) RR: 20/min (Normal) Temp: 98.6°F (Afebrile) Right - Examination: General: Conscious, Oriented, Icterus (+) CVS: S1S2 heard RS: BAE present P/A: RHC tenderness, Free fluid (+) CNS: NFND L/E: Right eye cataract Slide 4 - DIAGNOSIS: Title: "Final Diagnosis" Large centered text: "DCLD" Below: "Decompensated Chronic Liver Disease" Bullet points: • Alcohol-induced (7 years history) • Presenting with decompensation features • Ascites, Icterus, Tachycardia Slide 5 - ASSESSMENT - Clinical Problems: Title: "A - ASSESSMENT: Clinical Problems" Table with 3 columns: Problem | Evidence | Management Row 1: Hypokalemia | Muscle cramps, Giddiness | Syp. KCl 5ml TDS Row 2: Ascites | Free fluid+, RHC tenderness | Dytor 5mg, Fluid/Salt restriction Row 3: Hepatic dysfunction | Icterus, DCLD | UDCA 300mg Row 4: Nutritional deficiency | Alcohol 7 yrs, DCLD | Thiamine, Neurobion, Shelcal, Evion Row 5: GERD/Peptic disease | Abdominal pain | Sompraz D 40mg Row 6: Muscle cramps | B/L UL cramps | Baclofen Slide 6 - ASSESSMENT - Drug Therapy: Title: "A - ASSESSMENT: Drug Chart" Table with 4 columns: Drug | Dose/Freq | Indication | Class List all 10 medications: Sompraz D 40mg | 1-0-0 | GERD/Gastroprotection | PPI + Prokinetic Thiamine 100mg | 1-0-1 | Vit B1 / Wernicke's | Vitamin Dytor 5mg | 1-1-0 | Ascites/Edema | Loop Diuretic UDCA 300mg | 1-0-1 | Hepatoprotection | Bile acid Evion LC | 1-0-0 | Antioxidant | Vit E Shelcal HD | 0-0-1 | Ca + Vit D | Mineral/Vitamin Neurobion Forte | 1-0-0 | B-complex | Multivitamin VSL | 1-0-0 | Gut flora | Probiotic Baclofen | 1-0-0 | Muscle cramps | Muscle relaxant Syp. KCl 5ml | TDS | Hypokalemia | K+ supplement Slide 7 - ASSESSMENT - Drug Related Problems: Title: "A - ASSESSMENT: Drug Related Problems" Bullet points: • DRP 1: Domperidone (in Sompraz D) - contraindicated in severe hepatic impairment (QT prolongation risk) → Review and consider plain Pantoprazole • DRP 2: Baclofen in DCLD - hepatic metabolism, risk of accumulation → Monitor for encephalopathy, use lowest effective dose • DRP 3: Torasemide (Dytor) causes K+ loss → KCl supplementation appropriate, monitor serum electrolytes • DRP 4: Non-adherence to prior DCLD medication → Patient counseling needed Slide 8 - PLAN - Pharmacological & Non-Pharmacological: Title: "P - PLAN" Left column - Pharmacological: • Continue discharge medications • Monitor serum K+, Na+ weekly • Review Domperidone - consider switch • Titrate Baclofen cautiously • Thiamine/B-complex essential • Repeat LFTs at follow-up Right column - Non-Pharmacological: • Strict alcohol abstinence • High-protein, low-sodium diet • Fluid restriction < 1L/day • Salt restriction < 2g/day • Daily weight monitoring • Ophthalmology referral (cataract) Slide 9 - PLAN - Monitoring: Title: "P - PLAN: Monitoring Parameters" Table with 3 columns: Parameter | Frequency | Target Serum K+ | Weekly | 3.5-5.0 mEq/L Serum Na+ | Weekly | 135-145 mEq/L LFT | At follow-up (2-4 wks) | Trending improvement PT/INR | At follow-up | Monitor coagulopathy Body Weight | Daily | Stable/decreasing BP & PR | Daily | Hemodynamic stability Signs of encephalopathy | Every visit | Absent Slide 10 - PLAN - Patient Counseling: Title: "P - PLAN: Patient Counseling" Bullet points: • Complete alcohol abstinence - primary driver of disease progression • Take all medications regularly (previous non-adherence noted) • Maintain low-salt diet and fluid restriction to control ascites • Warning signs: Increased abdomen swelling, confusion, vomiting blood, fever → ER immediately • KCl syrup: dilute with water before taking • Follow-up: 1-2 weeks for electrolyte check Slide 11 - THANK YOU: Title: "Thank You" Subtitle: "Sindhana M | 2nd Pharm D" "Nandha Medical College & Hospital" "Pharmacotherapeutics-I" DESIGN REQUIREMENTS: - Color scheme: Navy blue (#003366) headers, white/light blue content areas - Title slides: dark background, white text - Content slides: white background, navy header bar - Tables: header row in light blue (#ADD8E6), alternating row shading (#F0F8FF) - Use python-pptx from pptx library - Slide dimensions: standard widescreen (13.33 x 7.5 inches) - Font: Title slides use bold 36pt, section titles 28pt bold, body text 16-18pt - Make it look like a professional medical education presentation Make sure to create the output directory first: os.makedirs("/tmp/workspace/sandhya_output", exist_ok=True) Save to: /tmp/workspace/sandhya_output/Sandhya_SOAP_Presentation.pptx Print "SUCCESS: /path" at the end. Return confirmation the file was created with path.

Reading File
Reading File
Reading File
Writing File

~/create_soap_docx.py

import os
from docx import Document
from docx.shared import Pt, Inches, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
from io import BytesIO

# ── Output path ─────────────────────────────────────────────────────────────
OUT_DIR  = "/tmp/workspace/sandhya_output"
OUT_FILE = os.path.join(OUT_DIR, "Sandhya_SOAP_Analysis.docx")
os.makedirs(OUT_DIR, exist_ok=True)

# ── Colour constants ─────────────────────────────────────────────────────────
DARK_BLUE   = RGBColor(0, 0, 128)
LIGHT_BLUE  = "ADD8E6"   # hex for shade_cell  (173,216,230)
WHITE       = RGBColor(255, 255, 255)
BLACK       = RGBColor(0, 0, 0)

# ── Document setup ───────────────────────────────────────────────────────────
doc = Document()

# Page margins
section = doc.sections[0]
section.page_width  = Inches(8.5)
section.page_height = Inches(11)
section.top_margin    = Inches(1)
section.bottom_margin = Inches(1)
section.left_margin   = Inches(1)
section.right_margin  = Inches(1)

# Normal style → Arial 11
normal = doc.styles["Normal"]
normal.font.name = "Arial"
normal.font.size = Pt(11)

# Heading 1 style → dark blue, bold, 14
h1_style = doc.styles["Heading 1"]
h1_style.font.name  = "Arial"
h1_style.font.size  = Pt(14)
h1_style.font.bold  = True
h1_style.font.color.rgb = DARK_BLUE

# Heading 2 style → dark blue, bold, 12
h2_style = doc.styles["Heading 2"]
h2_style.font.name  = "Arial"
h2_style.font.size  = Pt(12)
h2_style.font.bold  = True
h2_style.font.color.rgb = DARK_BLUE

# ── Helper functions ─────────────────────────────────────────────────────────

def shade_cell(cell, hex_fill):
    """Apply background shading to a table cell."""
    tcPr = cell._tc.get_or_add_tcPr()
    shd  = OxmlElement("w:shd")
    shd.set(qn("w:val"),   "clear")
    shd.set(qn("w:color"), "auto")
    shd.set(qn("w:fill"),  hex_fill)
    tcPr.append(shd)


def add_horizontal_rule(doc):
    """Add a horizontal line (border on a paragraph)."""
    p  = doc.add_paragraph()
    pPr = p._p.get_or_add_pPr()
    pBdr = OxmlElement("w:pBdr")
    bottom = OxmlElement("w:bottom")
    bottom.set(qn("w:val"),   "single")
    bottom.set(qn("w:sz"),    "6")
    bottom.set(qn("w:space"), "1")
    bottom.set(qn("w:color"), "000080")   # dark blue
    pBdr.append(bottom)
    pPr.append(pBdr)
    return p


def add_section_heading(doc, text):
    """Add a horizontal rule then a Heading 1 paragraph."""
    add_horizontal_rule(doc)
    h = doc.add_heading(text, level=1)
    h.alignment = WD_ALIGN_PARAGRAPH.LEFT
    # Ensure colour is set on the run too
    for run in h.runs:
        run.font.color.rgb = DARK_BLUE
    return h


def add_sub_heading(doc, text):
    """Add a Heading 2 paragraph."""
    h = doc.add_heading(text, level=2)
    h.alignment = WD_ALIGN_PARAGRAPH.LEFT
    for run in h.runs:
        run.font.color.rgb = DARK_BLUE
    return h


def body_para(doc, text, bold=False, italic=False):
    """Add a normal body paragraph."""
    p = doc.add_paragraph()
    p.style = doc.styles["Normal"]
    run = p.add_run(text)
    run.bold   = bold
    run.italic = italic
    return p


def bullet(doc, text, level=1):
    """Add a bulleted list item."""
    style = "List Bullet" if level == 1 else f"List Bullet {level}"
    p = doc.add_paragraph(text, style=style)
    return p


def numbered(doc, text, level=1):
    """Add a numbered list item."""
    style = "List Number" if level == 1 else f"List Number {level}"
    p = doc.add_paragraph(text, style=style)
    return p


def add_table_with_headers(doc, headers, rows_data, col_widths=None):
    """
    Create a Table Grid table with shaded header row.
    headers    : list of str
    rows_data  : list of list of str
    col_widths : list of Inches() values (must sum to <=6.5 in)
    """
    n_cols = len(headers)
    table  = doc.add_table(rows=1 + len(rows_data), cols=n_cols)
    table.style     = "Table Grid"
    table.alignment = WD_TABLE_ALIGNMENT.CENTER

    # Default equal widths
    if col_widths is None:
        w = Inches(6.5 / n_cols)
        col_widths = [w] * n_cols

    # Header row
    hdr_cells = table.rows[0].cells
    for i, hdr in enumerate(headers):
        cell = hdr_cells[i]
        cell.width = col_widths[i]
        shade_cell(cell, LIGHT_BLUE)
        p   = cell.paragraphs[0]
        run = p.add_run(hdr)
        run.bold      = True
        run.font.size = Pt(10)
        run.font.name = "Arial"

    # Data rows
    for r_idx, row_data in enumerate(rows_data):
        row_cells = table.rows[r_idx + 1].cells
        for c_idx, val in enumerate(row_data):
            cell = row_cells[c_idx]
            cell.width = col_widths[c_idx]
            p   = cell.paragraphs[0]
            run = p.add_run(str(val))
            run.font.size = Pt(10)
            run.font.name = "Arial"

    return table


# ════════════════════════════════════════════════════════════════════════════
#  TITLE BLOCK
# ════════════════════════════════════════════════════════════════════════════

# Main title
title_p = doc.add_paragraph()
title_p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = title_p.add_run("SOAP ANALYSIS - SANDHYA CASE")
run.bold      = True
run.font.size = Pt(18)
run.font.name = "Arial"
run.font.color.rgb = DARK_BLUE

# Subtitle
sub_p = doc.add_paragraph()
sub_p.alignment = WD_ALIGN_PARAGRAPH.CENTER
sub_run = sub_p.add_run("Pharmacotherapeutics-I | Nandha Medical College & Hospital")
sub_run.font.size   = Pt(12)
sub_run.font.name   = "Arial"
sub_run.font.italic = True

# Date line
date_p = doc.add_paragraph()
date_p.alignment = WD_ALIGN_PARAGRAPH.CENTER
date_run = date_p.add_run("Date of Admission: 25/03/2026  |  Date of Discharge: 28/03/2026")
date_run.font.size = Pt(11)
date_run.font.name = "Arial"

doc.add_paragraph()   # spacer


# ════════════════════════════════════════════════════════════════════════════
#  S – SUBJECTIVE
# ════════════════════════════════════════════════════════════════════════════
add_section_heading(doc, "S - SUBJECTIVE")

add_sub_heading(doc, "Patient Demographics")
add_table_with_headers(
    doc,
    headers=["Parameter", "Details"],
    rows_data=[
        ["Name",         "Sandhya (Case Patient)"],
        ["Age / Sex",    "32 years / Male"],
        ["Hospital",     "Nandha Medical College & Hospital"],
        ["Date of Admission",  "25/03/2026"],
        ["Date of Discharge",  "28/03/2026"],
        ["Duration of Stay",   "3 days"],
    ],
    col_widths=[Inches(2.5), Inches(4.0)]
)

doc.add_paragraph()

add_sub_heading(doc, "Chief Complaints")
bullet(doc, "Muscle cramps in bilateral upper limbs (B/L UL) and right side - 10 days duration")
bullet(doc, "Giddiness")
bullet(doc, "Abdominal pain")

add_sub_heading(doc, "History of Present Illness")
body_para(doc,
    "A 32-year-old male, known case of Decompensated Chronic Liver Disease (DCLD) for the past "
    "6 months, presented with complaints of muscle cramps involving bilateral upper limbs and the "
    "right side of the body for 10 days, associated with giddiness and abdominal pain. The patient "
    "has been on irregular medication for DCLD. Alcohol use history of 7 years is noted as a "
    "significant contributing factor to the liver disease and associated nutritional deficiencies."
)

add_sub_heading(doc, "Past Medical History")
bullet(doc, "Known case of DCLD (Decompensated Chronic Liver Disease) - 6 months")
bullet(doc, "Irregular medication compliance for DCLD")
bullet(doc, "Right eye cataract (L/E - Left Eye, under evaluation)")

add_sub_heading(doc, "Personal / Social History")
bullet(doc, "Diet: Mixed diet")
bullet(doc, "Alcohol use: 7 years (significant risk factor for liver disease and nutritional deficiencies)")
bullet(doc, "Smoking: Not documented")
bullet(doc, "Occupation: Not documented")


# ════════════════════════════════════════════════════════════════════════════
#  O – OBJECTIVE
# ════════════════════════════════════════════════════════════════════════════
add_section_heading(doc, "O - OBJECTIVE")

add_sub_heading(doc, "Vital Signs")
add_table_with_headers(
    doc,
    headers=["Parameter", "Value", "Normal Range", "Interpretation"],
    rows_data=[
        ["Blood Pressure (BP)",   "100/70 mmHg",  "120/80 mmHg",    "Hypotension"],
        ["Pulse Rate (PR)",       "111 /min",      "60-100 /min",    "Tachycardia"],
        ["Respiratory Rate (RR)", "20 /min",       "12-20 /min",     "Normal/Upper limit"],
        ["Temperature",           "98.6 degF",     "97-99 degF",     "Normal (Afebrile)"],
    ],
    col_widths=[Inches(2.0), Inches(1.5), Inches(1.7), Inches(1.3)]
)

doc.add_paragraph()

add_sub_heading(doc, "General Examination")
add_table_with_headers(
    doc,
    headers=["Finding", "Status"],
    rows_data=[
        ["Consciousness",       "Conscious and oriented"],
        ["Fever",               "Afebrile"],
        ["Icterus",             "Present (+) - indicates hepatic involvement"],
        ["Pallor",              "Not documented"],
        ["Cyanosis",            "Not documented"],
        ["Clubbing",            "Not documented"],
        ["Lymphadenopathy",     "Not documented"],
        ["Oedema",              "Not documented"],
        ["Right Eye Cataract",  "Present (L/E - under evaluation)"],
    ],
    col_widths=[Inches(3.0), Inches(3.5)]
)

doc.add_paragraph()

add_sub_heading(doc, "Systemic Examination")
add_table_with_headers(
    doc,
    headers=["System", "Finding"],
    rows_data=[
        ["CVS (Cardiovascular)",      "S1, S2 heard; no murmurs (S1S2+)"],
        ["RS (Respiratory System)",   "Bilateral air entry present (BAE+)"],
        ["P/A (Per Abdomen)",         "Right hypochondrial tenderness; Free fluid present (+) - Ascites"],
        ["CNS (Central Nervous System)", "No focal neurological deficit (NFND)"],
    ],
    col_widths=[Inches(2.5), Inches(4.0)]
)

doc.add_paragraph()

add_sub_heading(doc, "Final Diagnosis")
p = doc.add_paragraph()
p.style = doc.styles["Normal"]
run = p.add_run("Decompensated Chronic Liver Disease (DCLD)")
run.bold          = True
run.font.size     = Pt(11)
run.font.color.rgb = DARK_BLUE


# ════════════════════════════════════════════════════════════════════════════
#  A – ASSESSMENT
# ════════════════════════════════════════════════════════════════════════════
add_section_heading(doc, "A - ASSESSMENT")

add_sub_heading(doc, "Primary Diagnosis Discussion")
body_para(doc,
    "The patient presents with Decompensated Chronic Liver Disease (DCLD), a stage of chronic "
    "liver disease in which the liver is no longer able to compensate for its impaired function. "
    "Decompensation is evidenced by the presence of ascites (free fluid in abdomen), icterus "
    "(jaundice), haemodynamic instability (hypotension, tachycardia), and electrolyte imbalances "
    "(hypokalemia manifesting as muscle cramps and giddiness). Chronic alcohol use for 7 years "
    "is the primary etiological factor, contributing to hepatocellular damage, portal hypertension, "
    "ascites, and multiple nutritional deficiencies."
)

add_sub_heading(doc, "Identified Clinical Problems")

numbered(doc, "Hypokalemia")
p = doc.add_paragraph(style="List Bullet 2")
p.add_run("Evidence: Muscle cramps in B/L upper limbs, giddiness")
p = doc.add_paragraph(style="List Bullet 2")
p.add_run("Management: Syrup KCl 5 mL TDS prescribed for potassium replacement")

numbered(doc, "Ascites / Fluid Overload")
p = doc.add_paragraph(style="List Bullet 2")
p.add_run("Evidence: Free fluid on abdominal examination, right hypochondrial tenderness")
p = doc.add_paragraph(style="List Bullet 2")
p.add_run("Management: T. Dytor 5 mg (Torasemide - loop diuretic); Fluid restriction <1 L/day; Salt restriction <2 g/day")

numbered(doc, "Hepatic Dysfunction with Jaundice")
p = doc.add_paragraph(style="List Bullet 2")
p.add_run("Evidence: Icterus (+), known DCLD for 6 months, elevated bilirubin expected")
p = doc.add_paragraph(style="List Bullet 2")
p.add_run("Management: T. UDCA 300 mg BD (hepatoprotective, improves bile flow)")

numbered(doc, "Alcohol-related Nutritional Deficiencies")
p = doc.add_paragraph(style="List Bullet 2")
p.add_run("Evidence: 7-year alcohol history - Thiamine (B1), B-complex, Vitamin E, Calcium/Vit D deficiencies expected")
p = doc.add_paragraph(style="List Bullet 2")
p.add_run("Management: T. Thiamine 100 mg BD, T. Neurobion Forte OD, T. Evion LC OD, T. Shelcal HD OD")

numbered(doc, "GERD / Gastric Mucosal Protection")
p = doc.add_paragraph(style="List Bullet 2")
p.add_run("Evidence: Abdominal pain; proton pump inhibitor indicated to protect gastric mucosa in liver disease")
p = doc.add_paragraph(style="List Bullet 2")
p.add_run("Management: T. Sompraz D 40 mg OD (Pantoprazole + Domperidone)")

numbered(doc, "Muscle Cramps")
p = doc.add_paragraph(style="List Bullet 2")
p.add_run("Evidence: Bilateral upper limb cramps - may be multifactorial (hypokalemia, hepatic disease)")
p = doc.add_paragraph(style="List Bullet 2")
p.add_run("Management: T. Baclofen OD (GABA-B agonist, muscle relaxant)")

numbered(doc, "Gut Dysbiosis / Hepatic Encephalopathy Prevention")
p = doc.add_paragraph(style="List Bullet 2")
p.add_run("Evidence: Liver disease associated with gut microbiome disruption and risk of hepatic encephalopathy")
p = doc.add_paragraph(style="List Bullet 2")
p.add_run("Management: T. VSL (probiotic) OD")

doc.add_paragraph()

add_sub_heading(doc, "Drug-Related Problems (DRPs)")

p = doc.add_paragraph()
p.style = doc.styles["Normal"]
run = p.add_run("DRP 1: Domperidone in Severe Hepatic Failure - Contraindication / Risk")
run.bold = True
body_para(doc,
    "Domperidone (component of Sompraz D) is contraindicated or requires extreme caution in severe "
    "hepatic impairment. It is extensively metabolised by the liver (CYP3A4), and accumulation in "
    "hepatic failure can prolong the QTc interval, increasing the risk of ventricular arrhythmias "
    "(Torsades de Pointes). Recommendation: Review use; consider switching to plain Pantoprazole "
    "monotherapy or an alternative prokinetic such as Metoclopramide at reduced dose with close ECG monitoring."
)

p = doc.add_paragraph()
p.style = doc.styles["Normal"]
run = p.add_run("DRP 2: Baclofen Accumulation in Hepatic Impairment - Encephalopathy Risk")
run.bold = True
body_para(doc,
    "Baclofen is primarily renally excreted but CNS depression is potentiated in hepatic impairment. "
    "There is an additive risk of precipitating or worsening hepatic encephalopathy. Recommendation: "
    "Use at the lowest effective dose, monitor for confusion, asterixis, or altered sensorium "
    "suggestive of encephalopathy. Consider alternative non-pharmacological cramp management or "
    "quinine sulfate (with caution) once hypokalemia is corrected."
)

p = doc.add_paragraph()
p.style = doc.styles["Normal"]
run = p.add_run("DRP 3: Dytor (Torasemide) + KCl - Appropriate Combination")
run.bold = True
body_para(doc,
    "Torasemide (loop diuretic) causes urinary potassium wasting, leading to or worsening "
    "hypokalemia. Co-prescribing KCl syrup is clinically appropriate and recommended to correct "
    "and maintain potassium levels. Serum electrolytes (K+, Na+) should be monitored regularly "
    "(every 48-72 hours during active diuresis). This combination is rational and well-managed."
)

doc.add_paragraph()

add_sub_heading(doc, "Drug Therapy Table")
add_table_with_headers(
    doc,
    headers=["#", "Drug", "Dose", "Frequency", "Class", "Indication"],
    rows_data=[
        ["1",  "T. Sompraz D 40 mg\n(Pantoprazole + Domperidone)", "40 mg",   "1-0-0 (OD AM)",     "PPI + Prokinetic",          "Gastroprotection / GERD"],
        ["2",  "T. Thiamine 100 mg",                               "100 mg",  "1-0-1 (BD)",         "Vitamin B1",                "Thiamine deficiency / Wernicke's prophylaxis"],
        ["3",  "T. Dytor 5 mg",                                    "5 mg",    "1-1-0 (BD AM+Noon)", "Loop Diuretic",             "Ascites / Oedema management"],
        ["4",  "T. UDCA 300 mg",                                   "300 mg",  "1-0-1 (BD)",         "Bile acid / Hepatoprotective","Hepatoprotection, bile flow improvement"],
        ["5",  "T. Evion LC",                                      "Standard","1-0-0 (OD AM)",      "Vitamin E",                 "Antioxidant, nutritional deficiency"],
        ["6",  "T. Shelcal HD",                                    "Standard","0-0-1 (OD PM)",      "Calcium + Vitamin D",       "Calcium/Vit D deficiency, bone health"],
        ["7",  "T. Neurobion Forte",                               "Standard","1-0-0 (OD AM)",      "B-complex vitamins",        "Alcohol-related B-vitamin deficiency"],
        ["8",  "T. VSL",                                           "Standard","1-0-0 (OD AM)",      "Probiotic",                 "Gut dysbiosis, hepatic encephalopathy prevention"],
        ["9",  "T. Baclofen",                                      "Standard","1-0-0 (OD AM)",      "GABA-B agonist / Muscle relaxant","Muscle cramps"],
        ["10", "Syp. KCl 5 mL",                                   "5 mL",    "TDS",                "Electrolyte supplement",    "Hypokalemia correction"],
    ],
    col_widths=[Inches(0.3), Inches(1.6), Inches(0.7), Inches(1.1), Inches(1.4), Inches(1.4)]
)


# ════════════════════════════════════════════════════════════════════════════
#  P – PLAN
# ════════════════════════════════════════════════════════════════════════════
add_section_heading(doc, "P - PLAN")

add_sub_heading(doc, "Pharmacological Plan")

numbered(doc, "Electrolyte Correction: Continue Syrup KCl 5 mL TDS until serum potassium normalises (target K+ 3.5-5.0 mEq/L). "
              "Repeat serum electrolytes every 48-72 hours during diuresis.")
numbered(doc, "Diuretic Therapy: Maintain T. Dytor 5 mg BD for ascites management. Titrate dose based on clinical response, "
              "body weight changes, and renal function. Add spironolactone if ascites is refractory.")
numbered(doc, "Hepatoprotection: Continue T. UDCA 300 mg BD for hepatoprotective effect. Monitor liver function tests (LFT) "
              "periodically to assess treatment response.")
numbered(doc, "Nutritional Supplementation: Continue Thiamine 100 mg BD (at least 3 months), Neurobion Forte OD, Evion LC OD, "
              "and Shelcal HD OD to correct alcohol-related nutritional deficiencies and prevent Wernicke's encephalopathy.")
numbered(doc, "DRP Review - Domperidone: Review Sompraz D; consider switching to plain Pantoprazole 40 mg OD if prokinetic "
              "effect is not clinically essential, to avoid QTc prolongation risk in severe hepatic failure. Obtain ECG.")
numbered(doc, "DRP Monitoring - Baclofen: Use at minimum effective dose; closely monitor for signs of hepatic encephalopathy "
              "(asterixis, confusion, altered consciousness). Reassess once hypokalemia is corrected as cramps may resolve.")

doc.add_paragraph()

add_sub_heading(doc, "Non-Pharmacological Plan")
bullet(doc, "Alcohol abstinence: Complete and permanent cessation of alcohol - most critical intervention to slow disease progression")
bullet(doc, "Dietary modification: High-protein (1.2-1.5 g/kg/day), nutritionally balanced diet to counter malnutrition")
bullet(doc, "Fluid restriction: Less than 1 litre per day to prevent worsening of ascites")
bullet(doc, "Salt (sodium) restriction: Less than 2 grams per day to reduce fluid retention")
bullet(doc, "Daily weight monitoring: Weigh at the same time each morning; report weight gain >1 kg/day or >2 kg/week")
bullet(doc, "Ophthalmology referral: Right eye cataract noted; refer to ophthalmology department for evaluation and management")
bullet(doc, "Adequate rest: Avoid strenuous physical activity during active decompensation")
bullet(doc, "Regular follow-up: Scheduled outpatient visits every 4 weeks or earlier if symptoms worsen")

doc.add_paragraph()

add_sub_heading(doc, "Monitoring Parameters")
add_table_with_headers(
    doc,
    headers=["Parameter", "Frequency", "Target / Action Level"],
    rows_data=[
        ["Serum Potassium (K+)",           "Every 48-72 hrs during diuresis, then weekly",    "3.5 - 5.0 mEq/L; supplement if low"],
        ["Serum Sodium (Na+)",             "Weekly",                                           "135-145 mEq/L; restrict fluid if low"],
        ["Liver Function Tests (LFT)",     "Every 2-4 weeks",                                  "Monitor bilirubin, ALT, AST, albumin, ALP"],
        ["PT / INR",                       "Every 2-4 weeks",                                  "INR >1.5 indicates significant coagulopathy"],
        ["Body Weight",                    "Daily (morning, same time)",                        "Alert if gain >1 kg/day or >2 kg/week"],
        ["Blood Pressure / Pulse Rate",    "Daily during admission; weekly outpatient",         "Target BP >90/60 mmHg; HR 60-100/min"],
        ["Renal Function (BUN, Creatinine)","Weekly",                                           "Monitor for hepatorenal syndrome"],
        ["Signs of Encephalopathy",        "Daily clinical assessment",                         "Asterixis, altered consciousness - withhold Baclofen if present"],
        ["ECG (QTc interval)",             "Before starting/continuing Domperidone",            "QTc <440 ms (male); withhold if prolonged"],
        ["Abdominal Girth",                "Weekly",                                            "Reduction indicates ascites response to therapy"],
    ],
    col_widths=[Inches(2.0), Inches(1.8), Inches(2.7)]
)

doc.add_paragraph()

add_sub_heading(doc, "Patient Counseling Points")
numbered(doc, "Alcohol cessation is the single most important step: Complete abstinence from alcohol is mandatory. "
              "Further alcohol intake will rapidly worsen liver disease and can be life-threatening.")
numbered(doc, "Medication compliance: Take all prescribed medications regularly as directed. Do not stop any medicine "
              "without consulting your doctor, even if you feel better.")
numbered(doc, "Diet and fluid restrictions: Follow a low-salt diet (less than 2 g/day) and restrict fluid intake to less "
              "than 1 litre per day to control abdominal swelling (ascites). Eat a nutritious, protein-rich diet.")
numbered(doc, "Daily weight monitoring: Weigh yourself every morning. If your weight increases by more than 1 kg in one "
              "day or 2 kg in one week, contact your doctor immediately as this may indicate fluid accumulation.")
numbered(doc, "Warning signs - seek immediate medical attention: Yellowing of skin/eyes worsening (jaundice), severe "
              "confusion or altered behaviour (possible encephalopathy), increased abdominal swelling, vomiting blood, "
              "or black tarry stools (GI bleeding).")
numbered(doc, "Eye care: You have been noted to have a cataract in the right eye. Please visit an ophthalmologist "
              "for a detailed evaluation and appropriate management.")

# ── Final spacer & end note ──────────────────────────────────────────────────
doc.add_paragraph()
add_horizontal_rule(doc)
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run("--- End of SOAP Analysis ---")
run.italic     = True
run.font.size  = Pt(10)
run.font.name  = "Arial"
run.font.color.rgb = RGBColor(100, 100, 100)

# ── Save ─────────────────────────────────────────────────────────────────────
buf = BytesIO()
doc.save(buf)
with open(OUT_FILE, "wb") as f:
    f.write(buf.getvalue())

print(f"SUCCESS: {OUT_FILE}")
Running Command

mkdir -p /tmp/workspace/sandhya_output

Writing File

~/create_soap_presentation.py

import os
from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.shapes import MSO_SHAPE_TYPE
from pptx.oxml.ns import qn
from lxml import etree
from pptx.oxml import parse_xml
from copy import deepcopy

os.makedirs("/tmp/workspace/sandhya_output", exist_ok=True)

# ── Color Palette ──────────────────────────────────────────────────────────────
NAVY         = RGBColor(0x00, 0x33, 0x66)   # #003366
DARK_NAVY    = RGBColor(0x00, 0x1A, 0x40)   # deeper navy for title bg accent
LIGHT_BLUE   = RGBColor(0xAD, 0xD8, 0xE6)   # #ADD8E6 table headers
ALICE_BLUE   = RGBColor(0xF0, 0xF8, 0xFF)   # #F0F8FF alt row
WHITE        = RGBColor(0xFF, 0xFF, 0xFF)
DARK_TEXT    = RGBColor(0x1A, 0x1A, 0x2E)
ACCENT_TEAL  = RGBColor(0x00, 0x80, 0x80)
MID_BLUE     = RGBColor(0x1E, 0x56, 0x9B)   # medium blue for sub-headers
PALE_NAVY    = RGBColor(0xE8, 0xF0, 0xFB)   # very pale blue for alt rows
GOLD         = RGBColor(0xF0, 0xAD, 0x00)   # accent gold
RED_ALERT    = RGBColor(0xC0, 0x39, 0x2B)

SW = Inches(13.333)
SH = Inches(7.5)

prs = Presentation()
prs.slide_width  = SW
prs.slide_height = SH

blank_layout = prs.slide_layouts[6]

# ── Helper Functions ──────────────────────────────────────────────────────────

def set_bg(slide, color: RGBColor):
    bg = slide.background
    bg.fill.solid()
    bg.fill.fore_color.rgb = color

def add_rect(slide, left, top, width, height, fill_color, line_color=None, line_width=None):
    from pptx.enum.shapes import MSO_SHAPE
    shp = slide.shapes.add_shape(1, left, top, width, height)  # 1 = RECTANGLE
    shp.fill.solid()
    shp.fill.fore_color.rgb = fill_color
    if line_color:
        shp.line.color.rgb = line_color
        if line_width:
            shp.line.width = Pt(line_width)
    else:
        shp.line.fill.background()
    shp.shadow.inherit = False
    return shp

def add_text(slide, text, left, top, width, height,
             font_name="Calibri", font_size=16, bold=False, italic=False,
             color=DARK_TEXT, align=PP_ALIGN.LEFT, v_anchor=MSO_ANCHOR.TOP,
             word_wrap=True, margin_l=Inches(0.1), margin_r=Inches(0.1),
             margin_t=Inches(0.05), margin_b=Inches(0.05)):
    tb = slide.shapes.add_textbox(left, top, width, height)
    tf = tb.text_frame
    tf.word_wrap = word_wrap
    tf.vertical_anchor = v_anchor
    tf.margin_left   = margin_l
    tf.margin_right  = margin_r
    tf.margin_top    = margin_t
    tf.margin_bottom = margin_b
    p = tf.paragraphs[0]
    p.alignment = align
    r = p.add_run()
    r.text = text
    r.font.name  = font_name
    r.font.size  = Pt(font_size)
    r.font.bold  = bold
    r.font.italic = italic
    r.font.color.rgb = color
    return tb, tf

def add_header_bar(slide, title_text, subtitle_tag=None):
    """Navy header bar across top with white title + optional colored tag pill."""
    bar = add_rect(slide, 0, 0, SW, Inches(1.0), NAVY)
    # Title text in bar
    tb = slide.shapes.add_textbox(Inches(0.35), Inches(0.07), Inches(11.0), Inches(0.85))
    tf = tb.text_frame
    tf.word_wrap = False
    tf.vertical_anchor = MSO_ANCHOR.MIDDLE
    tf.margin_left = Inches(0.1)
    tf.margin_top  = 0
    tf.margin_bottom = 0
    p = tf.paragraphs[0]
    p.alignment = PP_ALIGN.LEFT
    r = p.add_run()
    r.text = title_text
    r.font.name  = "Calibri"
    r.font.size  = Pt(28)
    r.font.bold  = True
    r.font.color.rgb = WHITE
    if subtitle_tag:
        tag_box = slide.shapes.add_textbox(Inches(11.5), Inches(0.25), Inches(1.5), Inches(0.5))
        tf2 = tag_box.text_frame
        tf2.word_wrap = False
        tf2.vertical_anchor = MSO_ANCHOR.MIDDLE
        tf2.margin_left = Inches(0.05)
        tf2.margin_top = 0
        tf2.margin_bottom = 0
        p2 = tf2.paragraphs[0]
        p2.alignment = PP_ALIGN.CENTER
        r2 = p2.add_run()
        r2.text = subtitle_tag
        r2.font.name = "Calibri"
        r2.font.size = Pt(11)
        r2.font.bold = True
        r2.font.color.rgb = NAVY

def add_bullet_section(slide, lines, left, top, width, height,
                       font_size=15, indent_char="  "):
    """Add a textbox with bullet lines. Lines starting with '  -' get sub-indent."""
    tb = slide.shapes.add_textbox(left, top, width, height)
    tf = tb.text_frame
    tf.word_wrap = True
    tf.margin_left   = Inches(0.05)
    tf.margin_right  = Inches(0.05)
    tf.margin_top    = Inches(0.04)
    tf.margin_bottom = Inches(0.04)
    first = True
    for line in lines:
        if first:
            p = tf.paragraphs[0]
            first = False
        else:
            p = tf.add_paragraph()
        is_sub = line.startswith("  -") or line.startswith("    ")
        r = p.add_run()
        r.text = line.strip()
        r.font.name = "Calibri"
        r.font.size = Pt(font_size - 1 if is_sub else font_size)
        r.font.color.rgb = DARK_TEXT
        p.level = 1 if is_sub else 0
        # Space after paragraph for readability
        p.space_after = Pt(3)
    return tb, tf

def style_table_cell(cell, text, fill_color=None, font_color=DARK_TEXT,
                     font_size=13, bold=False, align=PP_ALIGN.LEFT, wrap=True):
    cell.text_frame.word_wrap = wrap
    tf = cell.text_frame
    tf.margin_left   = Inches(0.06)
    tf.margin_right  = Inches(0.06)
    tf.margin_top    = Inches(0.04)
    tf.margin_bottom = Inches(0.04)
    p = tf.paragraphs[0]
    p.alignment = align
    # Clear existing runs
    for run in p.runs:
        run.text = ""
    r = p.add_run()
    r.text = text
    r.font.name = "Calibri"
    r.font.size = Pt(font_size)
    r.font.bold = bold
    r.font.color.rgb = font_color
    if fill_color:
        cell.fill.solid()
        cell.fill.fore_color.rgb = fill_color

def add_footer(slide, text="Nandha Medical College & Hospital | Pharmacotherapeutics-I | 2nd Pharm D"):
    foot = slide.shapes.add_textbox(0, Inches(7.2), SW, Inches(0.3))
    tf = foot.text_frame
    tf.margin_left = Inches(0.3)
    tf.margin_top  = 0
    tf.margin_bottom = 0
    p = tf.paragraphs[0]
    p.alignment = PP_ALIGN.CENTER
    r = p.add_run()
    r.text = text
    r.font.name = "Calibri"
    r.font.size = Pt(9)
    r.font.color.rgb = RGBColor(0x80, 0x80, 0x80)


# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 1 — TITLE SLIDE
# ══════════════════════════════════════════════════════════════════════════════
s1 = prs.slides.add_slide(blank_layout)
set_bg(s1, NAVY)

# Decorative left stripe
add_rect(s1, 0, 0, Inches(0.55), SH, DARK_NAVY)

# Top accent bar (thin gold line)
add_rect(s1, Inches(0.55), 0, SW - Inches(0.55), Inches(0.06), GOLD)

# Rx / medical cross icon area - decorative circle
circ = s1.shapes.add_shape(1, Inches(10.5), Inches(1.0), Inches(2.2), Inches(2.2))
circ.fill.solid(); circ.fill.fore_color.rgb = RGBColor(0x00, 0x4A, 0x8F)
circ.line.fill.background(); circ.shadow.inherit = False

circ2 = s1.shapes.add_shape(1, Inches(10.65), Inches(1.15), Inches(1.9), Inches(1.9))
circ2.fill.solid(); circ2.fill.fore_color.rgb = RGBColor(0x00, 0x5C, 0xAD)
circ2.line.fill.background(); circ2.shadow.inherit = False

# "Rx" label inside circle
tb_rx, tf_rx = add_text(s1, "Rx", Inches(10.9), Inches(1.5), Inches(1.4), Inches(1.0),
                         font_name="Georgia", font_size=42, bold=True, italic=True,
                         color=WHITE, align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)

# Main title "SOAP ANALYSIS"
tb_t, tf_t = add_text(s1, "SOAP ANALYSIS",
                       Inches(0.8), Inches(1.6), Inches(9.5), Inches(1.3),
                       font_name="Georgia", font_size=52, bold=True,
                       color=WHITE, align=PP_ALIGN.LEFT, v_anchor=MSO_ANCHOR.MIDDLE)

# Gold divider line
add_rect(s1, Inches(0.8), Inches(3.0), Inches(7.0), Inches(0.04), GOLD)

# Subtitle
tb_sub, tf_sub = add_text(s1, "Sandhya Case  |  Pharmacotherapeutics-I",
                            Inches(0.8), Inches(3.1), Inches(9.5), Inches(0.6),
                            font_name="Calibri", font_size=22, bold=False, italic=True,
                            color=LIGHT_BLUE, align=PP_ALIGN.LEFT)

# Presented by
tb_by, tf_by = add_text(s1, "Presented by:  Sindhana M  |  2nd Pharm D",
                          Inches(0.8), Inches(3.85), Inches(9.5), Inches(0.55),
                          font_name="Calibri", font_size=18, bold=True,
                          color=WHITE, align=PP_ALIGN.LEFT)

# Institution
tb_inst, tf_inst = add_text(s1, "Nandha Medical College & Hospital",
                              Inches(0.8), Inches(4.5), Inches(9.5), Inches(0.5),
                              font_name="Calibri", font_size=16,
                              color=LIGHT_BLUE, align=PP_ALIGN.LEFT)

# Exam label
tb_exam, tf_exam = add_text(s1, "Pharmacotherapeutics-I  |  Second Sessional Practical Examination",
                              Inches(0.8), Inches(5.1), Inches(9.5), Inches(0.45),
                              font_name="Calibri", font_size=13, italic=True,
                              color=RGBColor(0xB0, 0xC8, 0xE8), align=PP_ALIGN.LEFT)

# Bottom accent bar
add_rect(s1, Inches(0.55), Inches(7.3), SW - Inches(0.55), Inches(0.2), DARK_NAVY)
add_rect(s1, Inches(0.55), Inches(6.95), Inches(4.0), Inches(0.04), GOLD)


# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 2 — SUBJECTIVE
# ══════════════════════════════════════════════════════════════════════════════
s2 = prs.slides.add_slide(blank_layout)
set_bg(s2, WHITE)
add_header_bar(s2, "S — SUBJECTIVE: Patient Profile", "Slide 2")

# Left column box
add_rect(s2, Inches(0.35), Inches(1.15), Inches(5.8), Inches(5.9),
         RGBColor(0xF4, 0xF8, 0xFF), RGBColor(0xC0, 0xD8, 0xF0), 0.8)

# Right column box
add_rect(s2, Inches(6.4), Inches(1.15), Inches(6.6), Inches(5.9),
         RGBColor(0xF4, 0xF8, 0xFF), RGBColor(0xC0, 0xD8, 0xF0), 0.8)

# LEFT column sub-header
add_text(s2, "Patient Information", Inches(0.5), Inches(1.25), Inches(5.5), Inches(0.4),
         font_name="Calibri", font_size=14, bold=True, color=NAVY)

# LEFT column content
left_lines = [
    "Patient:  32-year-old Male",
    "Admitted:  25/03/2026",
    "Discharged:  28/03/2026",
    "",
    "Chief Complaints:",
    "  - Muscle cramps (B/L UL & right side)  ·  10 days",
    "  - Giddiness",
    "  - Abdominal pain",
    "",
    "Past History:",
    "  - K/C/O DCLD  ·  6 months",
    "  - On irregular medication",
]
add_bullet_section(s2, left_lines,
                   Inches(0.55), Inches(1.7), Inches(5.5), Inches(5.1), font_size=15)

# RIGHT column sub-header
add_text(s2, "Personal & Social History", Inches(6.55), Inches(1.25), Inches(6.3), Inches(0.4),
         font_name="Calibri", font_size=14, bold=True, color=NAVY)

# Alcohol icon pill
alc_box = add_rect(s2, Inches(6.55), Inches(1.75), Inches(2.8), Inches(0.45),
                   RGBColor(0xFF, 0xEE, 0xDD), RGBColor(0xE8, 0x80, 0x30), 1.0)
add_text(s2, "⚠ Alcohol  ·  7 Years", Inches(6.65), Inches(1.77), Inches(2.6), Inches(0.4),
         font_name="Calibri", font_size=13, bold=True, color=RGBColor(0xC0, 0x50, 0x00),
         align=PP_ALIGN.CENTER)

right_lines = [
    "Diet:  Mixed (non-vegetarian)",
    "",
    "Alcohol Use:  7 years (chronic)",
    "  - Primary etiology for liver disease",
    "",
    "Occupation:  Not documented",
    "",
    "Medication Adherence:",
    "  - Irregular / non-compliant",
    "  - High-risk for disease progression",
    "",
    "Allergies:  Not documented",
]
add_bullet_section(s2, right_lines,
                   Inches(6.55), Inches(2.35), Inches(6.3), Inches(4.5), font_size=15)

add_footer(s2)


# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 3 — OBJECTIVE
# ══════════════════════════════════════════════════════════════════════════════
s3 = prs.slides.add_slide(blank_layout)
set_bg(s3, WHITE)
add_header_bar(s3, "O — OBJECTIVE: Vitals & Examination", "Slide 3")

# LEFT panel - Vitals
add_rect(s3, Inches(0.35), Inches(1.12), Inches(6.1), Inches(6.0),
         RGBColor(0xF0, 0xF8, 0xFF), RGBColor(0xB0, 0xCE, 0xEC), 0.8)
add_text(s3, "Vital Signs", Inches(0.5), Inches(1.2), Inches(5.8), Inches(0.4),
         font_name="Calibri", font_size=15, bold=True, color=NAVY)

# Vitals - card rows
vitals = [
    ("BP", "100/70 mmHg", "Low-Normal", RGBColor(0xFF, 0xF5, 0xE0), RGBColor(0xE0, 0x80, 0x00)),
    ("PR", "111 / min", "Tachycardia ⚠", RGBColor(0xFF, 0xED, 0xED), RGBColor(0xC0, 0x20, 0x20)),
    ("RR", "20 / min", "Normal ✓", RGBColor(0xE8, 0xFF, 0xE8), RGBColor(0x20, 0x80, 0x20)),
    ("Temp", "98.6 °F", "Afebrile ✓", RGBColor(0xE8, 0xFF, 0xE8), RGBColor(0x20, 0x80, 0x20)),
]
for i, (param, val, interp, bg, fg) in enumerate(vitals):
    y = Inches(1.7) + i * Inches(1.22)
    # Card bg
    add_rect(s3, Inches(0.5), y, Inches(5.7), Inches(1.08), bg, RGBColor(0xCC, 0xCC, 0xCC), 0.5)
    # Param label
    add_text(s3, param, Inches(0.65), y + Inches(0.08), Inches(1.0), Inches(0.4),
             font_name="Calibri", font_size=13, bold=True, color=NAVY)
    # Value
    add_text(s3, val, Inches(0.65), y + Inches(0.45), Inches(2.5), Inches(0.45),
             font_name="Calibri", font_size=20, bold=True, color=DARK_TEXT)
    # Interpretation pill
    interp_box = add_rect(s3, Inches(3.4), y + Inches(0.28), Inches(2.6), Inches(0.45),
                          fg, None)
    add_text(s3, interp, Inches(3.4), y + Inches(0.3), Inches(2.6), Inches(0.4),
             font_name="Calibri", font_size=12, bold=True, color=WHITE,
             align=PP_ALIGN.CENTER)

# RIGHT panel - Examination
add_rect(s3, Inches(6.7), Inches(1.12), Inches(6.3), Inches(6.0),
         RGBColor(0xF8, 0xF4, 0xFF), RGBColor(0xB0, 0xA0, 0xD8), 0.8)
add_text(s3, "Clinical Examination", Inches(6.85), Inches(1.2), Inches(6.0), Inches(0.4),
         font_name="Calibri", font_size=15, bold=True, color=NAVY)

exam_entries = [
    ("General",   "Conscious, Oriented, Afebrile\nIcterus Present (+)"),
    ("CVS",        "S1 S2 heard normally"),
    ("RS",         "BAE (Bilateral Air Entry) present"),
    ("P/A",        "RHC tenderness present\nFree fluid (+) — Ascites"),
    ("CNS",        "NFND (No focal neurological deficit)"),
    ("L/E",        "Right eye cataract (noted)"),
]
for i, (system, finding) in enumerate(exam_entries):
    y = Inches(1.7) + i * Inches(0.88)
    # System label box
    add_rect(s3, Inches(6.85), y, Inches(1.0), Inches(0.75),
             NAVY, None)
    add_text(s3, system, Inches(6.85), y + Inches(0.05), Inches(1.0), Inches(0.65),
             font_name="Calibri", font_size=12, bold=True, color=WHITE,
             align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
    # Finding text
    add_text(s3, finding, Inches(8.0), y, Inches(4.8), Inches(0.78),
             font_name="Calibri", font_size=13, color=DARK_TEXT,
             word_wrap=True, v_anchor=MSO_ANCHOR.MIDDLE)
    # Thin separator
    if i < len(exam_entries) - 1:
        add_rect(s3, Inches(6.85), y + Inches(0.78), Inches(5.9), Inches(0.02),
                 RGBColor(0xCC, 0xCC, 0xDD))

add_footer(s3)


# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 4 — DIAGNOSIS
# ══════════════════════════════════════════════════════════════════════════════
s4 = prs.slides.add_slide(blank_layout)
set_bg(s4, NAVY)

# Decorative left stripe
add_rect(s4, 0, 0, Inches(0.55), SH, DARK_NAVY)
add_rect(s4, Inches(0.55), 0, SW - Inches(0.55), Inches(0.06), GOLD)

add_text(s4, "Final Diagnosis", Inches(0.8), Inches(0.3), Inches(11.5), Inches(0.7),
         font_name="Georgia", font_size=30, bold=True, color=WHITE, align=PP_ALIGN.CENTER)

# Big DCLD acronym
add_text(s4, "DCLD", Inches(2.0), Inches(1.1), Inches(9.3), Inches(2.0),
         font_name="Georgia", font_size=90, bold=True, color=GOLD,
         align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)

# Full name
add_text(s4, "Decompensated Chronic Liver Disease",
         Inches(1.5), Inches(3.1), Inches(10.3), Inches(0.65),
         font_name="Calibri", font_size=26, bold=False, italic=True,
         color=LIGHT_BLUE, align=PP_ALIGN.CENTER)

# Gold divider
add_rect(s4, Inches(2.5), Inches(3.85), Inches(8.3), Inches(0.04), GOLD)

# Three feature cards
features = [
    ("Alcohol-Induced", "7 years of chronic\nalcohol use", RGBColor(0x80, 0x30, 0x00)),
    ("Decompensation\nFeatures", "Ascites, Icterus,\nTachycardia", RGBColor(0x00, 0x50, 0x80)),
    ("Irregular\nMedication", "Non-adherence\nto prior therapy", RGBColor(0x40, 0x00, 0x80)),
]
for i, (title, desc, col) in enumerate(features):
    x = Inches(1.0) + i * Inches(3.9)
    add_rect(s4, x, Inches(4.05), Inches(3.5), Inches(2.5), col, GOLD, 1.0)
    add_text(s4, title, x + Inches(0.15), Inches(4.2), Inches(3.2), Inches(0.85),
             font_name="Calibri", font_size=15, bold=True, color=GOLD,
             align=PP_ALIGN.CENTER)
    add_text(s4, desc, x + Inches(0.15), Inches(5.1), Inches(3.2), Inches(1.1),
             font_name="Calibri", font_size=13, color=WHITE,
             align=PP_ALIGN.CENTER)

add_rect(s4, Inches(0.55), Inches(7.3), SW - Inches(0.55), Inches(0.2), DARK_NAVY)


# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 5 — ASSESSMENT: Clinical Problems (Table)
# ══════════════════════════════════════════════════════════════════════════════
s5 = prs.slides.add_slide(blank_layout)
set_bg(s5, WHITE)
add_header_bar(s5, "A — ASSESSMENT: Clinical Problems", "Slide 5")

rows_data = [
    ("Hypokalemia",          "Muscle cramps, Giddiness",          "Syp. KCl 5ml TDS"),
    ("Ascites",              "Free fluid (+), RHC tenderness",     "Dytor 5mg, Fluid/Salt restriction"),
    ("Hepatic dysfunction",  "Icterus, DCLD diagnosis",           "UDCA 300mg"),
    ("Nutritional deficiency","Alcohol 7 yrs, DCLD",              "Thiamine, Neurobion, Shelcal, Evion LC"),
    ("GERD / Peptic disease","Abdominal pain",                     "Sompraz D 40mg"),
    ("Muscle cramps",        "B/L upper limb cramps",             "Baclofen"),
]
headers = ["Problem", "Evidence", "Management"]
tbl_shape = s5.shapes.add_table(
    len(rows_data) + 1, 3,
    Inches(0.35), Inches(1.15),
    Inches(12.65), Inches(5.85)
)
tbl = tbl_shape.table
tbl.columns[0].width = Inches(3.2)
tbl.columns[1].width = Inches(4.5)
tbl.columns[2].width = Inches(4.95)

# Header row
for ci, hdr in enumerate(headers):
    style_table_cell(tbl.cell(0, ci), hdr,
                     fill_color=NAVY, font_color=WHITE,
                     font_size=15, bold=True, align=PP_ALIGN.CENTER)

# Data rows
alt_colors = [WHITE, ALICE_BLUE]
for ri, (prob, evid, mgmt) in enumerate(rows_data):
    bg = alt_colors[ri % 2]
    style_table_cell(tbl.cell(ri+1, 0), prob, fill_color=bg,
                     font_size=13, bold=True, color=MID_BLUE if True else DARK_TEXT,
                     font_color=MID_BLUE)
    style_table_cell(tbl.cell(ri+1, 1), evid, fill_color=bg, font_size=13)
    style_table_cell(tbl.cell(ri+1, 2), mgmt, fill_color=bg, font_size=13,
                     font_color=RGBColor(0x00, 0x60, 0x00))

add_footer(s5)


# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 6 — ASSESSMENT: Drug Chart
# ══════════════════════════════════════════════════════════════════════════════
s6 = prs.slides.add_slide(blank_layout)
set_bg(s6, WHITE)
add_header_bar(s6, "A — ASSESSMENT: Drug Chart", "Slide 6")

drug_data = [
    ("Sompraz D 40mg",    "1-0-0",  "GERD / Gastroprotection",   "PPI + Prokinetic"),
    ("Thiamine 100mg",    "1-0-1",  "Vit B1 / Wernicke's prevention", "Vitamin"),
    ("Dytor 5mg",         "1-1-0",  "Ascites / Edema",           "Loop Diuretic"),
    ("UDCA 300mg",        "1-0-1",  "Hepatoprotection",           "Bile Acid"),
    ("Evion LC",          "1-0-0",  "Antioxidant support",        "Vitamin E"),
    ("Shelcal HD",        "0-0-1",  "Calcium + Vitamin D",        "Mineral / Vitamin"),
    ("Neurobion Forte",   "1-0-0",  "B-complex supplementation",  "Multivitamin"),
    ("VSL",               "1-0-0",  "Gut flora restoration",      "Probiotic"),
    ("Baclofen",          "1-0-0",  "Muscle cramps",              "Muscle Relaxant"),
    ("Syp. KCl 5ml",      "TDS",    "Hypokalemia",                "K⁺ Supplement"),
]
drug_headers = ["Drug", "Dose / Freq", "Indication", "Drug Class"]
tbl2 = s6.shapes.add_table(
    len(drug_data) + 1, 4,
    Inches(0.35), Inches(1.12),
    Inches(12.65), Inches(6.1)
).table
tbl2.columns[0].width = Inches(2.8)
tbl2.columns[1].width = Inches(1.5)
tbl2.columns[2].width = Inches(4.7)
tbl2.columns[3].width = Inches(3.65)

for ci, hdr in enumerate(drug_headers):
    style_table_cell(tbl2.cell(0, ci), hdr,
                     fill_color=NAVY, font_color=WHITE, font_size=14, bold=True,
                     align=PP_ALIGN.CENTER)

for ri, (drug, dose, ind, cls) in enumerate(drug_data):
    bg = WHITE if ri % 2 == 0 else ALICE_BLUE
    style_table_cell(tbl2.cell(ri+1, 0), drug, fill_color=bg, font_size=12, bold=True,
                     font_color=NAVY)
    style_table_cell(tbl2.cell(ri+1, 1), dose, fill_color=bg, font_size=12,
                     align=PP_ALIGN.CENTER)
    style_table_cell(tbl2.cell(ri+1, 2), ind,  fill_color=bg, font_size=12)
    style_table_cell(tbl2.cell(ri+1, 3), cls,  fill_color=bg, font_size=12,
                     font_color=RGBColor(0x30, 0x60, 0x30))

add_footer(s6)


# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 7 — ASSESSMENT: Drug Related Problems
# ══════════════════════════════════════════════════════════════════════════════
s7 = prs.slides.add_slide(blank_layout)
set_bg(s7, WHITE)
add_header_bar(s7, "A — ASSESSMENT: Drug Related Problems (DRPs)", "Slide 7")

drp_data = [
    (
        "DRP 1", "Domperidone (in Sompraz D)",
        "Contraindicated in severe hepatic impairment — QT prolongation risk.",
        "Review and consider switching to plain Pantoprazole 40mg.",
        RED_ALERT, RGBColor(0xFF, 0xF0, 0xF0)
    ),
    (
        "DRP 2", "Baclofen in DCLD",
        "Hepatic metabolism with risk of drug accumulation and encephalopathy.",
        "Monitor closely; use lowest effective dose. Watch for confusion.",
        RGBColor(0xCC, 0x66, 0x00), RGBColor(0xFF, 0xF5, 0xE0)
    ),
    (
        "DRP 3", "Torasemide (Dytor) — K⁺ Loss",
        "Loop diuretic causes potassium depletion (hypokalemia risk).",
        "KCl supplementation appropriate. Monitor serum electrolytes regularly.",
        RGBColor(0x00, 0x70, 0xC0), RGBColor(0xE8, 0xF4, 0xFF)
    ),
    (
        "DRP 4", "Non-Adherence to Prior DCLD Medication",
        "Patient was on irregular medication — contributed to decompensation.",
        "Comprehensive patient counseling essential; simplify regimen if possible.",
        RGBColor(0x40, 0x80, 0x00), RGBColor(0xF0, 0xFF, 0xE8)
    ),
]

for i, (tag, drug, problem, action, accent, bg) in enumerate(drp_data):
    y = Inches(1.2) + i * Inches(1.47)
    # Card background
    add_rect(s7, Inches(0.35), y, Inches(12.65), Inches(1.35), bg,
             accent, 1.2)
    # DRP tag box
    add_rect(s7, Inches(0.35), y, Inches(1.1), Inches(1.35), accent, None)
    add_text(s7, tag, Inches(0.35), y + Inches(0.35), Inches(1.1), Inches(0.65),
             font_name="Calibri", font_size=14, bold=True, color=WHITE,
             align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
    # Drug name
    add_text(s7, drug, Inches(1.6), y + Inches(0.06), Inches(5.5), Inches(0.45),
             font_name="Calibri", font_size=14, bold=True, color=accent)
    # Problem
    add_text(s7, "Issue: " + problem, Inches(1.6), y + Inches(0.5), Inches(5.5), Inches(0.42),
             font_name="Calibri", font_size=12, color=DARK_TEXT, word_wrap=True)
    # Vertical divider
    add_rect(s7, Inches(7.4), y + Inches(0.1), Inches(0.03), Inches(1.15),
             RGBColor(0xCC, 0xCC, 0xCC))
    # Action label
    add_text(s7, "Recommendation:", Inches(7.55), y + Inches(0.06), Inches(5.1), Inches(0.35),
             font_name="Calibri", font_size=12, bold=True, color=accent)
    add_text(s7, action, Inches(7.55), y + Inches(0.44), Inches(5.1), Inches(0.75),
             font_name="Calibri", font_size=12, color=DARK_TEXT, word_wrap=True)

add_footer(s7)


# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 8 — PLAN: Pharmacological & Non-Pharmacological
# ══════════════════════════════════════════════════════════════════════════════
s8 = prs.slides.add_slide(blank_layout)
set_bg(s8, WHITE)
add_header_bar(s8, "P — PLAN: Pharmacological & Non-Pharmacological", "Slide 8")

# LEFT column
add_rect(s8, Inches(0.35), Inches(1.12), Inches(6.05), Inches(6.0),
         RGBColor(0xF0, 0xF8, 0xFF), NAVY, 0.8)
add_text(s8, "Pharmacological", Inches(0.5), Inches(1.2), Inches(5.75), Inches(0.45),
         font_name="Calibri", font_size=16, bold=True, color=NAVY)

pharm_lines = [
    "Continue all discharge medications as prescribed",
    "Monitor serum K+, Na+ weekly until stable",
    "Review Domperidone — consider switch to plain Pantoprazole",
    "Titrate Baclofen cautiously; lowest effective dose",
    "Thiamine & B-complex — essential (Wernicke's prevention)",
    "Repeat LFTs & coagulation panel at follow-up",
    "Electrolytes: K+, Na+, Mg2+ check in 1 week",
]
add_bullet_section(s8, pharm_lines,
                   Inches(0.5), Inches(1.75), Inches(5.7), Inches(5.1), font_size=14)

# RIGHT column
add_rect(s8, Inches(6.65), Inches(1.12), Inches(6.35), Inches(6.0),
         RGBColor(0xF0, 0xFF, 0xF0), RGBColor(0x20, 0x80, 0x20), 0.8)
add_text(s8, "Non-Pharmacological", Inches(6.8), Inches(1.2), Inches(6.05), Inches(0.45),
         font_name="Calibri", font_size=16, bold=True, color=RGBColor(0x10, 0x60, 0x10))

non_pharm_lines = [
    "STRICT alcohol abstinence (primary driver of progression)",
    "High-protein, low-sodium diet",
    "Fluid restriction  <  1 litre / day",
    "Salt restriction  <  2 g / day",
    "Daily weight monitoring (ascites control)",
    "Ophthalmology referral (right eye cataract)",
    "Regular follow-up adherence counseling",
]
add_bullet_section(s8, non_pharm_lines,
                   Inches(6.8), Inches(1.75), Inches(6.0), Inches(5.1), font_size=14)

add_footer(s8)


# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 9 — PLAN: Monitoring Parameters
# ══════════════════════════════════════════════════════════════════════════════
s9 = prs.slides.add_slide(blank_layout)
set_bg(s9, WHITE)
add_header_bar(s9, "P — PLAN: Monitoring Parameters", "Slide 9")

mon_data = [
    ("Serum K⁺",                "Weekly",                  "3.5 – 5.0 mEq/L"),
    ("Serum Na⁺",               "Weekly",                  "135 – 145 mEq/L"),
    ("Liver Function Tests (LFT)","At follow-up (2-4 wks)","Trending improvement"),
    ("PT / INR",                 "At follow-up",            "Monitor coagulopathy"),
    ("Body Weight",              "Daily",                   "Stable / decreasing"),
    ("BP & Pulse Rate",          "Daily",                   "Hemodynamic stability"),
    ("Signs of Encephalopathy",  "Every clinical visit",    "Absent — no confusion"),
]
mon_headers = ["Parameter", "Frequency", "Target / Goal"]
mon_tbl = s9.shapes.add_table(
    len(mon_data) + 1, 3,
    Inches(0.35), Inches(1.15),
    Inches(12.65), Inches(5.8)
).table
mon_tbl.columns[0].width = Inches(4.5)
mon_tbl.columns[1].width = Inches(3.2)
mon_tbl.columns[2].width = Inches(4.95)

for ci, hdr in enumerate(mon_headers):
    style_table_cell(mon_tbl.cell(0, ci), hdr,
                     fill_color=NAVY, font_color=WHITE, font_size=15, bold=True,
                     align=PP_ALIGN.CENTER)

for ri, (param, freq, target) in enumerate(mon_data):
    bg = WHITE if ri % 2 == 0 else ALICE_BLUE
    style_table_cell(mon_tbl.cell(ri+1, 0), param, fill_color=bg, font_size=13, bold=True,
                     font_color=NAVY)
    style_table_cell(mon_tbl.cell(ri+1, 1), freq, fill_color=bg, font_size=13,
                     align=PP_ALIGN.CENTER)
    style_table_cell(mon_tbl.cell(ri+1, 2), target, fill_color=bg, font_size=13,
                     font_color=RGBColor(0x10, 0x60, 0x10))

add_footer(s9)


# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 10 — PLAN: Patient Counseling
# ══════════════════════════════════════════════════════════════════════════════
s10 = prs.slides.add_slide(blank_layout)
set_bg(s10, WHITE)
add_header_bar(s10, "P — PLAN: Patient Counseling Points", "Slide 10")

counsel_items = [
    (
        "01", "Complete Alcohol Abstinence",
        "Alcohol is the primary driver of DCLD progression. Even small amounts can worsen liver failure.",
        RED_ALERT, RGBColor(0xFF, 0xF2, 0xF2)
    ),
    (
        "02", "Medication Adherence",
        "Take ALL medications regularly. Previous non-adherence contributed to this hospitalisation.",
        RGBColor(0xCC, 0x66, 0x00), RGBColor(0xFF, 0xF8, 0xEE)
    ),
    (
        "03", "Diet & Fluid Management",
        "Maintain low-salt diet (<2g/day) and fluid restriction (<1L/day) to control ascites.",
        RGBColor(0x00, 0x70, 0xC0), RGBColor(0xEE, 0xF6, 0xFF)
    ),
    (
        "04", "Warning Signs — ER Immediately",
        "Seek emergency care if: increased abdomen swelling, confusion/drowsiness, vomiting blood, high fever.",
        RGBColor(0x80, 0x00, 0x00), RGBColor(0xFF, 0xEE, 0xEE)
    ),
    (
        "05", "KCl Syrup Administration",
        "Always dilute Syp. KCl in water before taking. Do not take undiluted.",
        RGBColor(0x40, 0x80, 0x00), RGBColor(0xF2, 0xFF, 0xEC)
    ),
    (
        "06", "Follow-Up Schedule",
        "Return in 1–2 weeks for electrolyte check. Adhere to all scheduled appointments.",
        RGBColor(0x40, 0x00, 0x80), RGBColor(0xF5, 0xEE, 0xFF)
    ),
]

for i, (num, title, desc, accent, bg) in enumerate(counsel_items):
    col = i % 2
    row = i // 2
    x = Inches(0.35) + col * Inches(6.35)
    y = Inches(1.18) + row * Inches(1.95)
    w = Inches(6.2)
    h = Inches(1.82)

    add_rect(s10, x, y, w, h, bg, accent, 1.0)
    # Number circle
    add_rect(s10, x + Inches(0.1), y + Inches(0.1), Inches(0.6), Inches(0.6), accent, None)
    add_text(s10, num, x + Inches(0.1), y + Inches(0.1), Inches(0.6), Inches(0.6),
             font_name="Calibri", font_size=14, bold=True, color=WHITE,
             align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
    # Title
    add_text(s10, title, x + Inches(0.85), y + Inches(0.1), w - Inches(1.0), Inches(0.45),
             font_name="Calibri", font_size=14, bold=True, color=accent)
    # Description
    add_text(s10, desc, x + Inches(0.15), y + Inches(0.65), w - Inches(0.3), Inches(1.05),
             font_name="Calibri", font_size=12, color=DARK_TEXT, word_wrap=True)

add_footer(s10)


# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 11 — THANK YOU
# ══════════════════════════════════════════════════════════════════════════════
s11 = prs.slides.add_slide(blank_layout)
set_bg(s11, NAVY)

# Decorative elements
add_rect(s11, 0, 0, Inches(0.55), SH, DARK_NAVY)
add_rect(s11, Inches(0.55), 0, SW - Inches(0.55), Inches(0.06), GOLD)

# Large center circle
circ_t = s11.shapes.add_shape(1, Inches(5.4), Inches(1.3), Inches(2.55), Inches(2.55))
circ_t.fill.solid(); circ_t.fill.fore_color.rgb = RGBColor(0x00, 0x4A, 0x8F)
circ_t.line.color.rgb = GOLD; circ_t.line.width = Pt(2)
circ_t.shadow.inherit = False

add_text(s11, "✓", Inches(5.4), Inches(1.5), Inches(2.55), Inches(2.1),
         font_name="Calibri", font_size=64, bold=True, color=GOLD,
         align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)

# Thank You
add_text(s11, "Thank You", Inches(1.0), Inches(3.95), Inches(11.35), Inches(1.1),
         font_name="Georgia", font_size=52, bold=True, color=WHITE,
         align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)

# Gold line
add_rect(s11, Inches(2.5), Inches(5.15), Inches(8.35), Inches(0.04), GOLD)

# Presenter
add_text(s11, "Sindhana M  |  2nd Pharm D",
         Inches(1.0), Inches(5.3), Inches(11.35), Inches(0.55),
         font_name="Calibri", font_size=20, bold=True, color=WHITE, align=PP_ALIGN.CENTER)

add_text(s11, "Nandha Medical College & Hospital",
         Inches(1.0), Inches(5.95), Inches(11.35), Inches(0.45),
         font_name="Calibri", font_size=16, color=LIGHT_BLUE, align=PP_ALIGN.CENTER)

add_text(s11, "Pharmacotherapeutics-I  |  Second Sessional Practical Examination",
         Inches(1.0), Inches(6.48), Inches(11.35), Inches(0.4),
         font_name="Calibri", font_size=13, italic=True,
         color=RGBColor(0xB0, 0xC8, 0xE8), align=PP_ALIGN.CENTER)

add_rect(s11, Inches(0.55), Inches(7.3), SW - Inches(0.55), Inches(0.2), DARK_NAVY)


# ══════════════════════════════════════════════════════════════════════════════
# SAVE
# ══════════════════════════════════════════════════════════════════════════════
output_path = "/tmp/workspace/sandhya_output/Sandhya_SOAP_Presentation.pptx"
from io import BytesIO
buf = BytesIO()
prs.save(buf)
with open(output_path, "wb") as f:
    f.write(buf.getvalue())

print(f"SUCCESS: {output_path}")
print(f"File size: {os.path.getsize(output_path):,} bytes")
print(f"Slide count: {len(prs.slides)}")
Running Command

python3 /tmp/workspace/create_soap_docx.py

Running Command

python3 /tmp/skills/docx/scripts/office/validate.py /tmp/workspace/sandhya_output/Sandhya_SOAP_Analysis.docx

Running Command

# The settings.xml zoom issue is a benign python-docx default issue. # Let's unpack and fix it, then repack. python3 /tmp/skills/docx/scripts/office/unpack.py /tmp/workspace/sandhya_output/Sandhya_SOAP_Analysis.docx /tmp/workspace/sandhya_unpacked/

Searching Content

"zoom" in ~/sandhya_unpacked/word

Searching Content

"zoom" in ~/sandhya_unpacked/word/settings.xml

Editing File

~/sandhya_unpacked/word/settings.xml

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/sandhya_unpacked/word/settings.xml'
Running Command

python3 /tmp/skills/docx/scripts/office/pack.py /tmp/workspace/sandhya_unpacked/ /tmp/workspace/sandhya_output/Sandhya_SOAP_Analysis.docx --original /tmp/workspace/sandhya_output/Sandhya_SOAP_Analysis.docx

Running Command

python3 -c " from docx import Document doc = Document('/tmp/workspace/sandhya_output/Sandhya_SOAP_Analysis.docx') # Print headings and first paragraph of each section for p in doc.paragraphs: style = p.style.name if p.style else 'None' if p.text.strip(): if 'Heading' in style: print(f'[{style}] {p.text}') print() print('Total paragraphs:', len(doc.paragraphs)) print('Total tables:', len(doc.tables)) # Print table headers for i, t in enumerate(doc.tables): print(f' Table {i+1} cols={len(t.columns)}, rows={len(t.rows)}, header: {[c.text[:30] for c in t.rows[0].cells]}') "

Running Command

ls -lh /tmp/workspace/sandhya_output/Sandhya_SOAP_Analysis.docx

Running Command

cd /tmp/workspace && python create_soap_presentation.py 2>&1

Editing File

~/create_soap_presentation.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/create_soap_presentation.py'
Running Command

cd /tmp/workspace && python create_soap_presentation.py 2>&1

Running Command

python3 - <<'EOF' from pptx import Presentation from pptx.util import Emu, Inches path = "/tmp/workspace/sandhya_output/Sandhya_SOAP_Presentation.pptx" prs = Presentation(path) sw, sh = prs.slide_width, prs.slide_height print(f"=== CONTENT QA ===") print(f"Slide dims: {Emu(sw).inches:.3f}\" x {Emu(sh).inches:.3f}\"") print(f"Total slides: {len(prs.slides)}\n") for i, slide in enumerate(prs.slides, 1): print(f"--- Slide {i} ---") for shape in slide.shapes: if shape.has_text_frame: text = shape.text_frame.text.strip() if text: # Show first 120 chars display = text[:120].replace('\n', ' | ') print(f" TEXT: {display}") if hasattr(shape, "table"): tbl = shape.table print(f" TABLE: {tbl._tbl.tr_lst.__len__() if hasattr(tbl._tbl, 'tr_lst') else '?'} rows") print() EOF

Running Command

python3 - <<'EOF' from pptx import Presentation from pptx.util import Emu, Inches path = "/tmp/workspace/sandhya_output/Sandhya_SOAP_Presentation.pptx" prs = Presentation(path) sw, sh = prs.slide_width, prs.slide_height print("=== GEOMETRY QA ===") issues = [] for i, slide in enumerate(prs.slides, 1): for shape in slide.shapes: if shape.left is None or shape.top is None: continue left = shape.left top = shape.top width = shape.width or 0 height = shape.height or 0 right = left + width bottom = top + height if left < 0 or top < 0: issues.append(f"Slide {i}: shape starts off-slide (left={Emu(left).inches:.2f}\", top={Emu(top).inches:.2f}\")") if right > sw + 10000: # allow tiny rounding issues.append(f"Slide {i}: shape extends right ({Emu(right).inches:.2f}\" > {Emu(sw).inches:.2f}\")") if bottom > sh + 10000: issues.append(f"Slide {i}: shape extends below ({Emu(bottom).inches:.2f}\" > {Emu(sh).inches:.2f}\")") if issues: for iss in issues: print(" ISSUE:", iss) else: print(" No geometry issues found!") # Check table content print("\n=== TABLE CONTENT QA ===") for i, slide in enumerate(prs.slides, 1): for shape in slide.shapes: if hasattr(shape, "table"): tbl = shape.table print(f"Slide {i} table:") for ri in range(len(tbl.rows)): row_texts = [] for ci in range(len(tbl.columns)): cell_text = tbl.cell(ri, ci).text_frame.text.strip() row_texts.append(cell_text[:30] if cell_text else "(empty)") print(f" Row {ri}: {row_texts}") print() EOF

Running Command

ls -lh /tmp/workspace/sandhya_output/Sandhya_SOAP_Presentation.pptx && python3 -c " from pptx import Presentation prs = Presentation('/tmp/workspace/sandhya_output/Sandhya_SOAP_Presentation.pptx') from pptx.util import Emu print('Slides:', len(prs.slides)) print('Dims:', Emu(prs.slide_width).inches, 'x', Emu(prs.slide_height).inches) slide_titles = [] for slide in prs.slides: for shape in slide.shapes: if shape.has_text_frame: t = shape.text_frame.text.strip() if t and len(t) > 3: slide_titles.append(t.split('\n')[0][:60]) break for j, t in enumerate(slide_titles, 1): print(f' Slide {j:2d}: {t}') print() print('SUCCESS: /tmp/workspace/sandhya_output/Sandhya_SOAP_Presentation.pptx') "

Running Command

python3 << 'EOF' import os from docx import Document from docx.shared import Pt, Inches, RGBColor from docx.enum.text import WD_ALIGN_PARAGRAPH from docx.oxml.ns import qn from docx.oxml import OxmlElement os.makedirs("/tmp/workspace/sandhya_output", exist_ok=True) doc = Document() # Page margins from docx.shared import Inches as In sections = doc.sections for section in sections: section.top_margin = In(1) section.bottom_margin = In(1) section.left_margin = In(1.2) section.right_margin = In(1.2) style = doc.styles["Normal"] style.font.name = "Arial" style.font.size = Pt(11) NAVY = RGBColor(0, 51, 102) DARK_BLUE = RGBColor(0, 0, 139) GRAY = RGBColor(80, 80, 80) def set_font(run, bold=False, size=11, color=None): run.bold = bold run.font.size = Pt(size) if color: run.font.color.rgb = color def add_para(text, align=None, bold=False, size=11, color=None, space_before=0, space_after=6): p = doc.add_paragraph() if align: p.alignment = align p.paragraph_format.space_before = Pt(space_before) p.paragraph_format.space_after = Pt(space_after) run = p.add_run(text) set_font(run, bold=bold, size=size, color=color) return p def add_horizontal_rule(): p = doc.add_paragraph() p.paragraph_format.space_before = Pt(2) p.paragraph_format.space_after = Pt(2) pPr = p._p.get_or_add_pPr() pBdr = OxmlElement('w:pBdr') bottom = OxmlElement('w:bottom') bottom.set(qn('w:val'), 'single') bottom.set(qn('w:sz'), '6') bottom.set(qn('w:space'), '1') bottom.set(qn('w:color'), '003366') pBdr.append(bottom) pPr.append(pBdr) # ─── LETTERHEAD ─── p = doc.add_paragraph() p.alignment = WD_ALIGN_PARAGRAPH.CENTER r = p.add_run("NANDHA MEDICAL COLLEGE AND HOSPITAL") r.bold = True r.font.size = Pt(16) r.font.color.rgb = NAVY p2 = doc.add_paragraph() p2.alignment = WD_ALIGN_PARAGRAPH.CENTER r2 = p2.add_run("Department of Pharmacy Practice") r2.font.size = Pt(12) r2.font.color.rgb = DARK_BLUE p3 = doc.add_paragraph() p3.alignment = WD_ALIGN_PARAGRAPH.CENTER r3 = p3.add_run("Erode, Tamil Nadu, India") r3.font.size = Pt(11) r3.font.color.rgb = GRAY add_horizontal_rule() # Title add_para("MEDICAL REFERRAL LETTER", WD_ALIGN_PARAGRAPH.CENTER, bold=True, size=14, color=NAVY, space_before=6, space_after=4) add_horizontal_rule() # Date / Ref doc.add_paragraph() p_date = doc.add_paragraph() r_lbl = p_date.add_run("Date: ") r_lbl.bold = True r_lbl.font.size = Pt(11) p_date.add_run("25th March 2026") p_ref = doc.add_paragraph() r2 = p_ref.add_run("Reference No: ") r2.bold = True r2.font.size = Pt(11) p_ref.add_run("NMCH/PP/2026/0325") doc.add_paragraph() # To block add_para("To,", bold=False, size=11) add_para("The Consultant Ophthalmologist", bold=True, size=11, color=NAVY, space_after=0) add_para("Department of Ophthalmology", size=11, space_after=0) add_para("Nandha Medical College and Hospital", size=11, space_after=0) add_para("Erode, Tamil Nadu", size=11, space_after=10) add_para("Subject: Referral for Ophthalmological Evaluation – Right Eye Cataract", bold=True, size=11, color=DARK_BLUE, space_after=8) add_para("Dear Doctor,", size=11, space_after=6) # Body paragraphs body1 = ("We are referring Mr. [Patient Name], a 32-year-old male patient, currently under the care " "of the Department of Medicine at Nandha Medical College and Hospital (IP No: ________), " "for evaluation and management of an incidentally detected right eye cataract.") add_para(body1, size=11, space_after=8) # Patient summary box add_para("PATIENT SUMMARY", bold=True, size=11, color=NAVY, space_after=2) tbl = doc.add_table(rows=7, cols=2) tbl.style = "Table Grid" data = [ ("Age / Sex", "32 years / Male"), ("Admission Date", "25/03/2026"), ("Discharge Date", "28/03/2026"), ("Primary Diagnosis", "Decompensated Chronic Liver Disease (DCLD) – Alcohol-induced"), ("Co-morbidities", "Hypokalemia, Ascites, Icterus"), ("Current Medications", "Dytor 5mg, UDCA 300mg, Thiamine 100mg, KCl syrup, Baclofen, Sompraz D, Neurobion, Shelcal HD, Evion LC, VSL"), ("Ocular Finding", "Right eye cataract detected on L/E examination"), ] for i, (label, value) in enumerate(data): row = tbl.rows[i] c0, c1 = row.cells[0], row.cells[1] c0.paragraphs[0].clear() c1.paragraphs[0].clear() r0 = c0.paragraphs[0].add_run(label) r0.bold = True r0.font.size = Pt(10) r1 = c1.paragraphs[0].add_run(value) r1.font.size = Pt(10) # Header row shading from docx.oxml.ns import qn from docx.oxml import OxmlElement if i == 0: for cell in [c0, c1]: tc = cell._tc tcPr = tc.get_or_add_tcPr() shd = OxmlElement('w:shd') shd.set(qn('w:fill'), 'ADD8E6') shd.set(qn('w:val'), 'clear') tcPr.append(shd) # Set column widths from docx.shared import Inches as In2 tbl.columns[0].width = In2(1.8) tbl.columns[1].width = In2(4.0) doc.add_paragraph() reason = ("During the admission workup, a cataract was noted in the right eye on local examination. " "Given that the patient has a significant history of 7 years of chronic alcohol use and is on " "multiple long-term medications (including corticosteroids if any), ophthalmic assessment is " "warranted to determine the nature, grade, and visual impact of the cataract, and to advise " "on appropriate management or surgical intervention.") add_para(reason, size=11, space_after=8) add_para("Specific Request:", bold=True, size=11, space_after=4) bullets = [ "Complete slit-lamp examination and visual acuity assessment", "Grading of cataract (nuclear, cortical, posterior subcapsular) in the right eye", "Intraocular pressure measurement (rule out glaucoma given DCLD/medication history)", "Fundus examination (evaluate for hepatic retinopathy if applicable)", "Advice regarding timing and feasibility of surgical intervention given systemic disease (DCLD, coagulopathy risk)", "Recommendations for any ocular medications to be added to current drug regimen", ] for b in bullets: p = doc.add_paragraph(style="List Bullet") p.paragraph_format.space_after = Pt(3) r = p.add_run(b) r.font.size = Pt(11) doc.add_paragraph() note = ("Please note that the patient has Decompensated Chronic Liver Disease with coagulopathy risk. " "Pre-operative assessment including PT/INR should be reviewed before any surgical planning. " "We request your valued opinion and will be grateful for your expert management.") add_para(note, size=11, space_after=10) add_para("Thanking you,", size=11, space_after=16) # Signature block add_para("Dr. ______________________________", bold=True, size=11, space_after=0) add_para("Consultant Physician / Pharmacist-in-Charge", size=11, space_after=0) add_para("Department of Medicine / Pharmacy Practice", size=11, space_after=0) add_para("Nandha Medical College and Hospital", size=11, space_after=0) add_para("Contact: ____________________", size=11, space_after=12) add_horizontal_rule() footer_p = doc.add_paragraph() footer_p.alignment = WD_ALIGN_PARAGRAPH.CENTER r_f = footer_p.add_run("SOAP Analysis prepared by: Sindhana M, 2nd Pharm D | Pharmacotherapeutics-I | Second Sessional Practical Examination") r_f.font.size = Pt(9) r_f.font.color.rgb = GRAY r_f.italic = True out_path = "/tmp/workspace/sandhya_output/Sandhya_Referral_Letter.docx" doc.save(out_path) print(f"SUCCESS: {out_path}") EOF

Running Command

ls -lh /tmp/workspace/sandhya_output/

All three files are ready. Here are your downloads:

Sandhya Case - All Documents Created

FileDescriptionDownload
SOAP Analysis (Word)Full clinical SOAP with tables, DRP analysis, monitoring plan

Sandhya SOAP Analysis

Word Document · DOCX

SOAP Presentation (PowerPoint)11-slide professional presentation

Sandhya SOAP Presentation

Presentation · PPTX

Referral Letter (Word)Formal ophthalmology referral for right eye cataract

Sandhya Referral Letter

Word Document · DOCX


What's inside each file:

SOAP Analysis (.docx)
  • Complete S-O-A-P sections with formatted tables
  • Vital signs interpretation, systemic exam findings
  • 7 identified clinical problems with evidence and management
  • Full 10-drug chart with dose, frequency, indication, and class
  • 3 Drug-Related Problems (DRPs) flagged: Domperidone in hepatic failure, Baclofen accumulation risk, Dytor + KCl electrolyte monitoring
  • Monitoring parameter table + 6 patient counseling points
SOAP Presentation (.pptx) - 11 slides
  • Title slide → Subjective → Objective → Diagnosis → Clinical Problems → Drug Chart → DRPs → Plan → Monitoring → Counseling → Thank You
  • Navy blue + gold color scheme, all tables and two-column layouts
Referral Letter (.docx)
  • Formal referral from Medicine/Pharmacy Practice to Ophthalmology
  • Patient summary table, 6 specific referral requests
  • Note on coagulopathy risk (DCLD) before surgical planning
This is a shared conversation. Sign in to Orris to start your own chat.