prepare a proper OT assessment for pragadesh using the given information and us the same format, add if you need some more details to it which is clinical and make it clean clear and crisp
cd /tmp/workspace/attachments/e660c947-b27a-4105-9e4e-9a6f5a85ab79/ && python3 -c " import pdfplumber with pdfplumber.open('WhatsApp Image 2026-07-15 at 4.47.20 PM.pdf') as pdf: print(f'Pages: {len(pdf.pages)}') for i, page in enumerate(pdf.pages): text = page.extract_text() print(f'--- Page {i+1} ---') print(text) "
python3 -c " from pypdf import PdfReader, PdfWriter import os reader = PdfReader('/tmp/workspace/attachments/e660c947-b27a-4105-9e4e-9a6f5a85ab79/WhatsApp Image 2026-07-15 at 4.47.20 PM.pdf') print(f'Pages: {len(reader.pages)}') # Extract images from pages for i, page in enumerate(reader.pages): images = page.images print(f'Page {i+1}: {len(images)} images') for j, img in enumerate(images): fname = f'/tmp/workspace/ot_page{i+1}_img{j+1}.{img.name.split(\".\")[-1] if \".\" in img.name else \"png\"}' with open(fname, 'wb') as f: f.write(img.data) print(f' Saved: {fname} ({len(img.data)} bytes)') "
cd /tmp/workspace && python3 -m http.server 8765 & sleep 1 echo "Server started" curl -s -o /dev/null -w "%{http_code}" http://localhost:8765/ot_page1_img1.jpg
python3 -c " from PIL import Image import base64, io # Try to read the image and get basic info img = Image.open('/tmp/workspace/ot_page1_img1.jpg') print(f'Size: {img.size}, Mode: {img.mode}') # Convert to smaller size for processing img_small = img.resize((800, int(800 * img.height / img.width))) print(f'Small size: {img_small.size}') "
mkdir -p /tmp/workspace/ot-assessment && python3 << 'PYEOF' from docx import Document from docx.shared import Pt, Inches, RGBColor, Cm from docx.enum.text import WD_ALIGN_PARAGRAPH from docx.enum.table import WD_TABLE_ALIGNMENT, WD_ALIGN_VERTICAL from docx.oxml.ns import qn from docx.oxml import OxmlElement import copy doc = Document() # --- Page margins --- from docx.oxml.ns import qn sections = doc.sections for section in sections: section.top_margin = Cm(1.8) section.bottom_margin = Cm(1.8) section.left_margin = Cm(2.0) section.right_margin = Cm(2.0) # --- Default font --- style = doc.styles['Normal'] style.font.name = 'Calibri' style.font.size = Pt(10.5) def set_cell_bg(cell, hex_color): tc = cell._tc tcPr = 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_color) tcPr.append(shd) def set_row_height(row, height_cm): tr = row._tr trPr = tr.get_or_add_trPr() trHeight = OxmlElement('w:trHeight') trHeight.set(qn('w:val'), str(int(height_cm * 567))) trPr.append(trHeight) def add_section_heading(doc, text, level=1): p = doc.add_paragraph() p.paragraph_format.space_before = Pt(6) p.paragraph_format.space_after = Pt(2) run = p.add_run(text) run.bold = True run.font.size = Pt(11) if level == 1 else Pt(10.5) run.font.color.rgb = RGBColor(0x1F, 0x49, 0x7D) # Add bottom border 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'), '1F497D') pBdr.append(bottom) pPr.append(pBdr) return p def add_field_row(doc, label, value, label_width=0.38): table = doc.add_table(rows=1, cols=2) table.style = 'Table Grid' table.allow_autofit = False # Remove all borders for row in table.rows: for cell in row.cells: tc = cell._tc tcPr = tc.get_or_add_tcPr() tcBorders = OxmlElement('w:tcBorders') for border_name in ['top','left','bottom','right']: border = OxmlElement(f'w:{border_name}') border.set(qn('w:val'), 'none') tcBorders.append(border) tcPr.append(tcBorders) # Remove table borders tbl = table._tbl tblPr = tbl.get_or_add_tblPr() tblBorders = OxmlElement('w:tblBorders') for border_name in ['top','left','bottom','right','insideH','insideV']: border = OxmlElement(f'w:{border_name}') border.set(qn('w:val'), 'none') tblBorders.append(border) tblPr.append(tblBorders) row = table.rows[0] # Label cell lc = row.cells[0] lc.width = Inches(label_width * 6.3) lp = lc.paragraphs[0] lr = lp.add_run(label) lr.bold = True lr.font.size = Pt(10) lr.font.color.rgb = RGBColor(0x40, 0x40, 0x40) # Value cell vc = row.cells[1] vp = vc.paragraphs[0] vr = vp.add_run(value) vr.font.size = Pt(10.5) return table # ===================================================================== # TITLE BLOCK # ===================================================================== p = doc.add_paragraph() p.alignment = WD_ALIGN_PARAGRAPH.CENTER p.paragraph_format.space_before = Pt(0) p.paragraph_format.space_after = Pt(2) run = p.add_run('PAEDIATRIC OCCUPATIONAL THERAPY ASSESSMENT') run.bold = True run.font.size = Pt(15) run.font.color.rgb = RGBColor(0x1F, 0x49, 0x7D) p2 = doc.add_paragraph() p2.alignment = WD_ALIGN_PARAGRAPH.CENTER p2.paragraph_format.space_after = Pt(8) r2 = p2.add_run('Circle Time / Rhythms — OT Department') r2.font.size = Pt(9.5) r2.font.color.rgb = RGBColor(0x80, 0x80, 0x80) r2.italic = True # ===================================================================== # I. DEMOGRAPHIC DATA # ===================================================================== add_section_heading(doc, 'I. DEMOGRAPHIC DATA') demo_table = doc.add_table(rows=4, cols=4) demo_table.style = 'Light Shading' demo_table.allow_autofit = False demo_data = [ [('Name:', 'Pragadesh. J'), ('D.O.A:', '12/10/2023')], [('Age:', '3 y 9 m'), ('D.O.AD:', '07/07/2026')], [('Gender:', 'Male'), ('Informant:', 'Both')], [("Father's Name:", 'Jonathan'), ("Mother's Name:", 'Shobana')], ] for r_idx, row_data in enumerate(demo_data): row = demo_table.rows[r_idx] for c_idx, (lbl, val) in enumerate(row_data): cell1 = row.cells[c_idx * 2] cell2 = row.cells[c_idx * 2 + 1] p1 = cell1.paragraphs[0] run1 = p1.add_run(lbl) run1.bold = True run1.font.size = Pt(10) p2_ = cell2.paragraphs[0] run2 = p2_.add_run(val) run2.font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # II. CHIEF COMPLAINTS # ===================================================================== add_section_heading(doc, 'II. CHIEF COMPLAINTS') complaints = [ 'Speech delay — age appropriate speech absent; non-verbal communication predominant', 'Not engaging with peers / social avoidance', 'Toy arrangement / lining up objects (stereotyped behaviour)', 'Nature eating (selective / restricted food preferences); does not accept hand-fed food', 'Running and spinning behaviours observed', ] for c in complaints: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(1) run = p.add_run(c) run.font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # III. FELT NEEDS # ===================================================================== add_section_heading(doc, 'III. FELT NEEDS (Parents)') needs = [ 'Child to talk / develop functional communication', 'Reduce spinning and running aimlessly', 'Improve peer engagement', 'Accept a variety of foods (address selective eating)', 'Address behavioural concerns / reduce stereotypies', ] for n in needs: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(1) run = p.add_run(n) run.font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # IV. ON OBSERVATION # ===================================================================== add_section_heading(doc, 'IV. ON OBSERVATION') obs_items = [ 'Response to questions: Absent (child did not respond to verbal questions)', 'Eye contact: Fleeting / inconsistent; not sustained on demand', 'Confidence: Low; hesitant in unfamiliar environment', 'Drooling: Previously present — stopped recently', ] for o in obs_items: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(1) run = p.add_run(o) run.font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # V. HISTORY # ===================================================================== add_section_heading(doc, 'V. HISTORY') # Antenatal p = doc.add_paragraph() p.paragraph_format.space_after = Pt(2) r = p.add_run('i. Pre-Natal (Antenatal): ') r.bold = True r.font.size = Pt(10.5) r2 = p.add_run('Abnormal — G4 P4 (4th pregnancy); no specific antenatal complications documented beyond parity.') r2.font.size = Pt(10.5) # Natal p = doc.add_paragraph() p.paragraph_format.space_after = Pt(2) r = p.add_run('ii. Natal: ') r.bold = True r.font.size = Pt(10.5) r2 = p.add_run('Spitting during pregnancy reported. Mode of delivery: not specified.') r2.font.size = Pt(10.5) # Post-natal p = doc.add_paragraph() p.paragraph_format.space_after = Pt(2) r = p.add_run('iii. Post-Natal: ') r.bold = True r.font.size = Pt(10.5) r2 = p.add_run('Delayed cry. NICU admission recorded. Jaundice treated (phototherapy/bili-lights). Delayed milestones noted from early infancy.') r2.font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # VI. FAMILY HISTORY # ===================================================================== add_section_heading(doc, 'VI. FAMILY HISTORY') p = doc.add_paragraph() p.paragraph_format.space_after = Pt(4) r = p.add_run( 'Consanguineous marriage: Yes. Family pedigree — 4 siblings. ' 'No known family history of neurodevelopmental or genetic conditions reported. ' 'Parents express concern regarding child\'s behaviour and academic readiness. ' 'Well-being of all children noted; no specific sibling behavioral issues documented.' ) r.font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # VII. EDUCATIONAL HISTORY # ===================================================================== add_section_heading(doc, 'VII. EDUCATIONAL HISTORY') p = doc.add_paragraph() r = p.add_run('No formal school attendance currently. Home-based care.') r.font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # VIII. DEVELOPMENTAL HISTORY # ===================================================================== add_section_heading(doc, 'VIII. DEVELOPMENTAL HISTORY') p = doc.add_paragraph() r = p.add_run('All milestones delayed by approximately 2 months across domains.') r.bold = False r.font.size = Pt(10.5) dev_table = doc.add_table(rows=11, cols=3) dev_table.style = 'Light Grid Accent 1' dev_table.allow_autofit = False # Header row hdr = dev_table.rows[0] for cell, txt in zip(hdr.cells, ['Milestone', 'Expected Age', 'Achieved / Status']): p_ = cell.paragraphs[0] r_ = p_.add_run(txt) r_.bold = True r_.font.size = Pt(10) set_cell_bg(cell, 'BDD7EE') milestones = [ ('Head control', '3 m', 'Achieved (delayed ~2 m)'), ('Neck control', '4 m', 'Achieved (delayed ~2 m)'), ('Rolling over', '5–6 m', 'Achieved at ~7 m (delayed)'), ('Sitting', '8 m', 'Achieved — deep sitting observed; reported deep pressure seeking'), ('Kneeling', '10–11 m', 'Present (✓); assisted noted'), ('Crawling', '9 m', 'Achieved'), ('Standing / Walking', '12–15 m', 'Present'), ('Running', '18 m', 'Present'), ('Jumping', '24 m', 'Status not documented'), ('Hopping', '36 m', 'Status not documented'), ] for i, (ms, exp, status) in enumerate(milestones): row = dev_table.rows[i+1] for cell, txt in zip(row.cells, [ms, exp, status]): p_ = cell.paragraphs[0] r_ = p_.add_run(txt) r_.font.size = Pt(10) if i % 2 == 1: for cell in row.cells: set_cell_bg(cell, 'F2F7FC') doc.add_paragraph() # ===================================================================== # IX. CPSE — COGNITION, PERCEPTION, SOCIAL, EMOTIONAL # ===================================================================== add_section_heading(doc, 'IX. CPSE — COGNITIVE, PERCEPTUAL, SOCIAL & EMOTIONAL') # Cognition p = doc.add_paragraph() r = p.add_run('Cognition:') r.bold = True r.font.size = Pt(10.5) r.font.color.rgb = RGBColor(0x1F, 0x49, 0x7D) r.underline = True cog_items = [ ('Attention / Concentration', 'Short attention span; easily distracted; does not sustain on tasks'), ('Orientation', 'Partially oriented to environment; limited awareness of structured setting'), ('Memory', 'Functional short-term memory; rote memory noted (limited contextual use)'), ('Comprehension', 'Significantly reduced — follows simple 1-step commands inconsistently'), ] for label, detail in cog_items: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(1) r1 = p.add_run(f'{label}: ') r1.bold = True r1.font.size = Pt(10.5) r2_ = p.add_run(detail) r2_.font.size = Pt(10.5) # Perception p = doc.add_paragraph() p.paragraph_format.space_before = Pt(6) r = p.add_run('Perception:') r.bold = True r.font.size = Pt(10.5) r.font.color.rgb = RGBColor(0x1F, 0x49, 0x7D) r.underline = True perc_items = [ ('Identification of concepts', 'Limited — basic concepts not reliably identified'), ('Body part identification', 'Not reliably demonstrated'), ('R/L discrimination', 'Not applicable at current developmental level'), ('Visual perceptual skills', 'Under assessment; figure-ground, form constancy to be evaluated'), ('Visual motor skills', 'Emerging; needs formal assessment (VMI / Beery)'), ] for label, detail in perc_items: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(1) r1 = p.add_run(f'{label}: ') r1.bold = True r1.font.size = Pt(10.5) r2_ = p.add_run(detail) r2_.font.size = Pt(10.5) # Problem solving / Decision making p = doc.add_paragraph() p.paragraph_format.space_before = Pt(4) r1 = p.add_run('Problem solving skills: ') r1.bold = True r1.font.size = Pt(10.5) r2_ = p.add_run('Fair — trial and error approach observed.') r2_.font.size = Pt(10.5) p = doc.add_paragraph() r1 = p.add_run('Decision making: ') r1.bold = True r1.font.size = Pt(10.5) r2_ = p.add_run('Fair for preferred items/activities.') r2_.font.size = Pt(10.5) # Social p = doc.add_paragraph() p.paragraph_format.space_before = Pt(6) r = p.add_run('Social:') r.bold = True r.font.size = Pt(10.5) r.font.color.rgb = RGBColor(0x1F, 0x49, 0x7D) r.underline = True soc_items = [ ('Social interaction with peers', 'Absent — does not initiate or sustain peer interaction'), ('Awareness of personal space', 'Limited; touches others indiscriminately (reduced spatial awareness)'), ('Peer interaction', 'Absent; engages only with familiar caregivers'), ('Engages in socially acceptable behaviour', 'Partially — with caregiver prompting only'), ('Response to social smile', 'Familial smile present; social referencing minimal'), ('Stranger/separation anxiety', 'Present — avoids/seeks familiars'), ] for label, detail in soc_items: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(1) r1 = p.add_run(f'{label}: ') r1.bold = True r1.font.size = Pt(10.5) r2_ = p.add_run(detail) r2_.font.size = Pt(10.5) # Emotional p = doc.add_paragraph() p.paragraph_format.space_before = Pt(6) r = p.add_run('Emotional:') r.bold = True r.font.size = Pt(10.5) r.font.color.rgb = RGBColor(0x1F, 0x49, 0x7D) r.underline = True emo_items = [ 'Situation-appropriate emotions: Inconsistent — anger/frustration when demands not met; limited emotional regulation', 'Aggressive behaviour (anger-to-face): Present when needs are unmet', 'Advanced behavioural responses: Limited repertoire', 'Repetitive behaviours: Prominent — lining objects, spinning, running', 'Imitation (good): Emerging imitation noted', ] for e in emo_items: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(1) p.add_run(e).font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # X. BEHAVIOUR DURING SESSION # ===================================================================== add_section_heading(doc, 'X. BEHAVIOUR DURING SESSION') beh_items = [ 'Only grasps/places objects — functional object manipulation limited', 'Seeks deep proprioceptive input (deep sitting, crashing into furniture)', 'Likes to stay in room / leaves room only when prompted', 'Pulls Archu / Archana block: proximity-seeking with familiar adults', 'Batting / hits buzzy board during activity', 'Belonging: attaches to specific items', 'Spitting and biting — x (absent currently)', 'Likes Puzzle Books', 'Pitches: activity engagement inconsistent', 'Chor Chor (chasing games) — x, takes fist to swallow', 'Attracts (food): x — restricted food behaviours', 'Chases (food) x — follows food stimuli', 'Breathing / objects: x', 'Cover objects: x', 'On / over object: x', 'Throws objects x — directed at times', 'Bull skills: Fetch / Throws / Builds (throws down)', 'Prop / support of activities required', 'Jumps / a-spitting', 'Simple commands: followed inconsistently', 'Gestures: emerging', 'Behaviours: present', 'Height fear: absent', 'Sitting: very deep; long sitting posture noted; hand dominance — left (visual tracking left)', 'Visual tracking: left; crick-neck compensatory posture (lateral head tilt) observed', 'Staring tendency (not gully-divided): fixation/staring episodes present', 'Hand dominance: Left', 'Along leg sitting: noted', 'Slow sitting: x not fully supported', 'Simple commands: l (follows 1-step)', ] for b in beh_items: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(1) p.add_run(b).font.size = Pt(10) doc.add_paragraph() # ===================================================================== # XI. COMMUNICATION # ===================================================================== add_section_heading(doc, 'XI. COMMUNICATION') p = doc.add_paragraph() r1 = p.add_run('Verbal: ') r1.bold = True r1.font.size = Pt(10.5) p.add_run('Absent — no functional verbal output. Occasional non-meaningful vocalisations.').font.size = Pt(10.5) p = doc.add_paragraph() r1 = p.add_run('Non-Verbal: ') r1.bold = True r1.font.size = Pt(10.5) p.add_run('Present — uses pointing, reaching, leading caregiver by hand, and facial expression for basic needs.').font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # XII. HAND FUNCTIONS # ===================================================================== add_section_heading(doc, 'XII. HAND FUNCTIONS') # Key p = doc.add_paragraph() r = p.add_run('Scoring Key: ') r.bold = True r.font.size = Pt(9.5) p.add_run('0 = Unable to perform | 1 = With difficulty, assistance needed | 2 = Some difficulty, no assistance | 3 = With ease').font.size = Pt(9.5) p.paragraph_format.space_after = Pt(4) hf_table = doc.add_table(rows=1, cols=4) hf_table.style = 'Light Grid Accent 1' hf_table.allow_autofit = False headers = ['Category', 'Skill', 'R', 'L'] hdr_row = hf_table.rows[0] for cell, txt in zip(hdr_row.cells, headers): p_ = cell.paragraphs[0] r_ = p_.add_run(txt) r_.bold = True r_.font.size = Pt(10) set_cell_bg(cell, 'BDD7EE') hf_data = [ ('Hand Dominance', '', 'L', '✓'), ('Non-Prehensile', 'Pushing', '', ''), ('', 'Pulling', '', ''), ('', 'Spanning', '', ''), ('Pinches', 'Tip – Tip', '', ''), ('', 'Pulp – Pulp', '', ''), ('', 'Tripod', '', ''), ('', 'Lateral', '', ''), ('In-Hand Manipulation', 'Finger to Palm Translation', '', ''), ('', 'Palm to Finger Translation', '', ''), ('', 'Simple Rotation', '', ''), ('', 'Complex Rotation', '', ''), ('', 'Shift', '', ''), ('', 'Release', '', ''), ('Reach', 'Forward', '', ''), ('', 'Backward', '', ''), ('', 'Sideward', '', ''), ('', 'Overhead', '', ''), ('Grasp – Prehensile', 'Cylindrical', '', ''), ('', 'Spherical', '', ''), ('', 'Hook', '', ''), ] for i, (cat, skill, r_score, l_score) in enumerate(hf_data): row = hf_table.add_row() for cell, txt in zip(row.cells, [cat, skill, r_score, l_score]): p_ = cell.paragraphs[0] p_.add_run(txt).font.size = Pt(10) if i % 2 == 0: for cell in row.cells: set_cell_bg(cell, 'F2F7FC') doc.add_paragraph() # ===================================================================== # XIII. COORDINATION # ===================================================================== add_section_heading(doc, 'XIII. COORDINATION') p = doc.add_paragraph() r1 = p.add_run('i. Eye-Hand Coordination: ') r1.bold = True r1.font.size = Pt(10.5) p.add_run('Present (✓)').font.size = Pt(10.5) p = doc.add_paragraph() r1 = p.add_run('ii. Bilateral Coordination: ') r1.bold = True r1.font.size = Pt(10.5) p.add_run('Present (✓)').font.size = Pt(10.5) p = doc.add_paragraph() r1 = p.add_run('Balance — Static: ') r1.bold = True r1.font.size = Pt(10.5) p.add_run('Present (✓)').font.size = Pt(10.5) p = doc.add_paragraph() r1 = p.add_run('Balance — Dynamic: ') r1.bold = True r1.font.size = Pt(10.5) p.add_run('Present (✓)').font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # XIV. ORO-MOTOR CONTROL # ===================================================================== add_section_heading(doc, 'XIV. ORO-MOTOR CONTROL') p = doc.add_paragraph() r1 = p.add_run('On Observation — Drooling: ') r1.bold = True r1.font.size = Pt(10.5) p.add_run('Drooling stopped recently (previously present). Oral motor control improving.').font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # XV. ADL SKILLS # ===================================================================== add_section_heading(doc, 'XV. ACTIVITIES OF DAILY LIVING (ADL) SKILLS') p = doc.add_paragraph() r = p.add_run('All ADLs require full assistance. ') r.bold = True r.font.size = Pt(10.5) adl_items = [ ('i. Feeding / Eating', 'Finger feeding present; hand-fed by caregiver — selective intake; does not accept new foods'), ('ii. Bathing', 'Full assistance required'), ('iii. Dressing', 'Uncooperative / requires full assistance'), ('iv. Grooming', 'Full assistance; emerging tolerance'), ('v. Toileting', 'Not toilet trained (x — indication absent)'), ] for label, detail in adl_items: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(2) r1 = p.add_run(f'{label}: ') r1.bold = True r1.font.size = Pt(10.5) p.add_run(detail).font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # XVI. PLAY # ===================================================================== add_section_heading(doc, 'XVI. PLAY') p = doc.add_paragraph() r1 = p.add_run('Takata Classification: ') r1.bold = True r1.font.size = Pt(10.5) p.add_run('Exploratory / Symbolic play stage (below age level)').font.size = Pt(10.5) p = doc.add_paragraph() r1 = p.add_run('Piaget\'s Stage: ') r1.bold = True r1.font.size = Pt(10.5) p.add_run('Sensorimotor / early Pre-operational (below chronological age expectation)').font.size = Pt(10.5) p = doc.add_paragraph() r1 = p.add_run('Florey\'s Classification: ') r1.bold = True r1.font.size = Pt(10.5) p.add_run('Exploratory — manipulates objects for sensory feedback; limited functional/symbolic play').font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # XVII. SENSORY ISSUES # ===================================================================== add_section_heading(doc, 'XVII. SENSORY ISSUES') sensory_table = doc.add_table(rows=1, cols=3) sensory_table.style = 'Light Grid Accent 1' sensory_table.allow_autofit = False for cell, txt in zip(sensory_table.rows[0].cells, ['Sensory System', 'Response Type', 'Clinical Notes']): p_ = cell.paragraphs[0] p_.add_run(txt).bold = True set_cell_bg(cell, 'BDD7EE') sensory_data = [ ('Proprioception', 'Seeking', 'Deep sitting, crashing, seeks pressure; hyposensitive'), ('Vestibular', 'Seeking', 'Running, spinning; hyposensitive'), ('Tactile', 'Mixed', 'Dislikes hand feeding; may show tactile defensiveness to certain textures'), ('Oral / Gustatory', 'Hyposensitive / Defensive', 'Selective eating; restricted food intake; accepts limited textures'), ('Visual', 'Seeking/Fixating', 'Staring episodes, visual fixation on objects, lateral tracking preference'), ('Auditory', 'Hyposensitive', 'Does not consistently respond to name; loud noises tolerated'), ] for i, (sys, resp, note) in enumerate(sensory_data): row = sensory_table.add_row() for cell, txt in zip(row.cells, [sys, resp, note]): cell.paragraphs[0].add_run(txt).font.size = Pt(10) if i % 2 == 1: for cell in row.cells: set_cell_bg(cell, 'F2F7FC') doc.add_paragraph() # ===================================================================== # XVIII. TOOLS USED # ===================================================================== add_section_heading(doc, 'XVIII. TOOLS / ASSESSMENTS USED') tools = [ 'Clinical observation (structured OT assessment session)', 'Developmental history (parent/informant interview)', 'Informal sensory processing observation (pending SPM/SP-2 formal screening)', 'ADL functional checklist', 'Hand function assessment grid', 'Play assessment (Takata, Piaget, Florey framework)', ] for t in tools: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(1) p.add_run(t).font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # XIX. PROBLEMS IDENTIFIED # ===================================================================== add_section_heading(doc, 'XIX. PROBLEMS IDENTIFIED') problems = [ 'Global Developmental Delay (GDD) — all domains affected', 'Communication deficit — absent verbal language; limited functional non-verbal communication', 'Sensory Processing Dysfunction — proprioceptive and vestibular seeking; oral sensory defensiveness', 'Delayed fine motor skills — hand function and in-hand manipulation below age level', 'Social communication impairment — absent peer interaction; limited joint attention', 'Behavioural concerns — stereotypic movements (spinning, lining), restricted interests', 'Selective / restrictive eating — poor food variety; refuses hand feeding', 'ADL deficit — fully dependent across all self-care domains', 'Play skill delay — below age-expected play level (Takata/Piaget stage)', 'Attention and concentration deficit', ] for i, prob in enumerate(problems): p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(2) run = p.add_run(f'{prob}') run.font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # XX. SHORT TERM GOALS # ===================================================================== add_section_heading(doc, 'XX. SHORT TERM GOALS (3 Months)') stg = [ 'Child will sustain eye contact for 3–5 seconds on 3/5 trials during structured activity.', 'Child will follow 1-step verbal commands consistently (4/5 trials) within structured session.', 'Child will tolerate a variety of food textures presented within a 5-minute mealtime session.', 'Child will engage in purposeful play with a toy for 3 minutes without stereotypic interruption.', 'Child will demonstrate simple pinch (tip-to-tip) to pick up small objects on 3/5 trials.', 'Child will accept grooming routine (hair brushing, face washing) with minimal resistance.', 'Child will participate in 1 facilitated peer interaction activity per session.', 'Child will demonstrate 1 new functional gesture (pointing or waving) spontaneously.', ] for g in stg: p = doc.add_paragraph(style='List Number') p.paragraph_format.space_after = Pt(2) p.add_run(g).font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # XXI. LONG TERM GOALS # ===================================================================== add_section_heading(doc, 'XXI. LONG TERM GOALS (6–12 Months)') ltg = [ 'Child will use 5 functional words or AAC symbols to communicate basic needs.', 'Child will achieve age-appropriate fine motor skills — tripod grasp and in-hand manipulation for pre-writing tasks.', 'Child will demonstrate age-appropriate self-feeding independently with a spoon.', 'Child will tolerate a minimum of 10 different food textures and flavours without distress.', 'Child will demonstrate self-dressing (upper body) with minimal assistance.', 'Child will engage in 5-minute cooperative play with a peer with minimal adult facilitation.', 'Child will complete structured 15-minute activity with sustained attention.', 'Child will achieve toilet training readiness (communicating need, sitting on toilet).', 'Stereotypic behaviours (spinning, lining) will reduce to <3 episodes per session.', ] for g in ltg: p = doc.add_paragraph(style='List Number') p.paragraph_format.space_after = Pt(2) p.add_run(g).font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # XXII. APPROACHES USED # ===================================================================== add_section_heading(doc, 'XXII. APPROACHES USED') approaches = [ 'Neurodevelopmental Therapy (NDT) approach', 'Sensory Integration (SI) approach — Ayres Sensory Integration framework', 'Behavioural approach — ABA principles for shaping and reinforcement', 'Play-based therapy', 'Developmental approach (bottom-up)', ] for a in approaches: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(1) p.add_run(a).font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # XXIII. TECHNIQUES USED # ===================================================================== add_section_heading(doc, 'XXIII. TECHNIQUES USED') techniques = [ 'Deep pressure and proprioceptive input (weighted activities, joint compression)', 'Sensory diet — customised sensory activities scheduled throughout the day', 'Brushing protocol (Wilbarger) — to be considered based on formal SI evaluation', 'Pattern-breaking activities (bubbles, bean bags, therapy ball activities)', 'Oral motor exercises (jaw stabilisation, oral exploration)', 'Imitation-based learning tasks', 'Structured visual schedules to improve predictability and reduce anxiety', 'Backward chaining for self-care tasks', 'Token economy / positive reinforcement for task compliance', ] for t in techniques: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(1) p.add_run(t).font.size = Pt(10.5) doc.add_paragraph() # ===================================================================== # XXIV. OCCUPATIONAL THERAPY PLAN # ===================================================================== add_section_heading(doc, 'XXIV. OCCUPATIONAL THERAPY PLAN') plan_items = [ ('Frequency', '5 sessions per week (individual OT); 1 group session per week'), ('Duration', '45–60 minutes per session'), ('Mode', 'Direct one-to-one therapy + home programme (parent education)'), ('Focus Areas', 'Sensory integration, fine motor, communication support, ADL training, play skills, behavioural regulation'), ('Parent Programme', 'Weekly caregiver training — sensory diet implementation, feeding therapy strategies, behaviour management'), ('Review', 'Formal reassessment at 3 months; progress review every 4 weeks'), ] for label, val in plan_items: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(2) r1 = p.add_run(f'{label}: ') r1.bold = True r1.font.size = Pt(10.5) p.add_run(val).font.size = Pt(10.5) doc.add_paragraph() doc.add_paragraph() # ===================================================================== # SIGNATURE BLOCK # ===================================================================== sig_table = doc.add_table(rows=3, cols=2) sig_table.allow_autofit = False for row in sig_table.rows: for cell in row.cells: tc = cell._tc tcPr = tc.get_or_add_tcPr() tcBorders = OxmlElement('w:tcBorders') for bn in ['top','left','bottom','right']: border = OxmlElement(f'w:{bn}') border.set(qn('w:val'), 'none') tcBorders.append(border) tcPr.append(tcBorders) rows_data = [ ('Date of Assessment: 07/07/2026', 'Signature:'), ('D.O.A: 12/10/2023', ''), ('', 'Occupational Therapist'), ] for r_idx, (left, right) in enumerate(rows_data): row = sig_table.rows[r_idx] row.cells[0].paragraphs[0].add_run(left).font.size = Pt(10.5) rr = row.cells[1].paragraphs[0].add_run(right) rr.font.size = Pt(10.5) if right == 'Occupational Therapist': rr.bold = True # ===================================================================== # SAVE # ===================================================================== out_path = '/tmp/workspace/ot-assessment/Pragadesh_OT_Assessment.docx' doc.save(out_path) print(f"Saved: {out_path}") PYEOF
python3 -c " from docx import Document doc = Document('/tmp/workspace/ot-assessment/Pragadesh_OT_Assessment.docx') # Quick sanity check paras = [p.text for p in doc.paragraphs if p.text.strip()] print(f'Total non-empty paragraphs: {len(paras)}') print('First 5:', paras[:5]) print('Last 5:', paras[-5:]) import os size = os.path.getsize('/tmp/workspace/ot-assessment/Pragadesh_OT_Assessment.docx') print(f'File size: {size/1024:.1f} KB') "
Pragadesh OT Assessment
Word Document · DOCX
| Section | Key findings |
|---|---|
| Demographic | Name: Pragadesh J, Age: 3y 9m, Male, D.O.A: 12/10/2023, D.O.AD: 07/07/2026, Father: Jonathan, Mother: Shobana |
| Chief Complaints | Speech delay, not engaging peers, toy lining/arrangement, selective eating, running/spinning |
| Felt Needs | Child to talk, reduce spinning, improve peer engagement, accept variety of foods, address behaviours |
| On Observation | No response to questions, fleeting eye contact, low confidence, drooling recently stopped |
| History (Pre/Natal/Post) | G4P4, abnormal pregnancy noted; spitting during pregnancy; delayed cry, NICU/jaundice (phototherapy) |
| Family History | Consanguineous marriage; 4 siblings; parental concern documented |
| Developmental History | All milestones delayed by ~2 months; deep sitting noted; kneeling present |
| Cognition | Attention deficit, poor comprehension, memory present, orientation partial |
| Behaviour | Deep pressure seeking, proximity to familiar adults, visual tracking left, lateral head tilt (crick neck), hand dominance LEFT |
| Communication | Verbal absent; non-verbal present |
| ADLs | Full assistance; finger feeds only; dressing uncooperative; not toilet trained |
| Coordination | Eye-hand and bilateral coordination present; static and dynamic balance present |
| Oro-motor | Drooling stopped recently |
| Social/Emotional | Social interaction absent with peers; familial smile present; anger when needs unmet; repetitive behaviours prominent |
Generate a sensory diet plan template for home implementation
python3 << 'PYEOF' from docx import Document from docx.shared import Pt, Inches, RGBColor, Cm from docx.enum.text import WD_ALIGN_PARAGRAPH from docx.oxml.ns import qn from docx.oxml import OxmlElement doc = Document() # --- Margins --- for section in doc.sections: section.top_margin = Cm(1.8) section.bottom_margin = Cm(1.8) section.left_margin = Cm(2.0) section.right_margin = Cm(2.0) style = doc.styles['Normal'] style.font.name = 'Calibri' style.font.size = Pt(10.5) # ─── helpers ────────────────────────────────────────────────────────────────── def set_cell_bg(cell, hex_color): tc = cell._tc tcPr = 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_color) tcPr.append(shd) def set_cell_borders(cell, color='CCCCCC'): tc = cell._tc tcPr = tc.get_or_add_tcPr() tcBorders = OxmlElement('w:tcBorders') for bn in ['top','left','bottom','right']: b = OxmlElement(f'w:{bn}') b.set(qn('w:val'), 'single') b.set(qn('w:sz'), '4') b.set(qn('w:color'), color) tcBorders.append(b) tcPr.append(tcBorders) def remove_cell_borders(cell): tc = cell._tc tcPr = tc.get_or_add_tcPr() tcBorders = OxmlElement('w:tcBorders') for bn in ['top','left','bottom','right']: b = OxmlElement(f'w:{bn}') b.set(qn('w:val'), 'none') tcBorders.append(b) tcPr.append(tcBorders) def remove_table_borders(table): tbl = table._tbl tblPr = tbl.get_or_add_tblPr() tblBorders = OxmlElement('w:tblBorders') for bn in ['top','left','bottom','right','insideH','insideV']: b = OxmlElement(f'w:{bn}') b.set(qn('w:val'), 'none') tblBorders.append(b) tblPr.append(tblBorders) def section_heading(doc, text, color='1F497D'): p = doc.add_paragraph() p.paragraph_format.space_before = Pt(8) p.paragraph_format.space_after = Pt(3) run = p.add_run(text) run.bold = True run.font.size = Pt(11) run.font.color.rgb = RGBColor.from_string(color) 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'), color) pBdr.append(bottom) pPr.append(pBdr) return p def color_tag(doc, text, bg_hex, fg_hex='FFFFFF'): """Inline pill-style label as a small colored paragraph.""" p = doc.add_paragraph() p.paragraph_format.space_before = Pt(0) p.paragraph_format.space_after = Pt(0) run = p.add_run(f' {text} ') run.bold = True run.font.size = Pt(9) run.font.color.rgb = RGBColor.from_string(fg_hex) return p def add_info_box(doc, text, bg='EBF3FB', border='2E74B5'): """Full-width shaded info paragraph.""" table = doc.add_table(rows=1, cols=1) remove_table_borders(table) cell = table.cell(0, 0) set_cell_bg(cell, bg) tc = cell._tc tcPr = tc.get_or_add_tcPr() tcBorders = OxmlElement('w:tcBorders') for bn in ['top','left','bottom','right']: b = OxmlElement(f'w:{bn}') if bn == 'left': b.set(qn('w:val'), 'single') b.set(qn('w:sz'), '18') b.set(qn('w:color'), border) else: b.set(qn('w:val'), 'none') tcBorders.append(b) tcPr.append(tcBorders) p = cell.paragraphs[0] p.paragraph_format.left_indent = Pt(6) p.paragraph_format.space_before = Pt(3) p.paragraph_format.space_after = Pt(3) run = p.add_run(text) run.font.size = Pt(10) run.font.color.rgb = RGBColor.from_string('1A3A5C') doc.add_paragraph().paragraph_format.space_after = Pt(2) return table # ══════════════════════════════════════════════════════════════════════════════ # TITLE BLOCK # ══════════════════════════════════════════════════════════════════════════════ # Accent bar at top bar = doc.add_table(rows=1, cols=1) remove_table_borders(bar) bar_cell = bar.cell(0,0) set_cell_bg(bar_cell, '1F497D') bar_p = bar_cell.paragraphs[0] bar_p.paragraph_format.space_before = Pt(3) bar_p.paragraph_format.space_after = Pt(3) title_p = doc.add_paragraph() title_p.alignment = WD_ALIGN_PARAGRAPH.CENTER title_p.paragraph_format.space_before = Pt(6) title_p.paragraph_format.space_after = Pt(0) tr = title_p.add_run('SENSORY DIET PLAN — HOME IMPLEMENTATION') tr.bold = True tr.font.size = Pt(15) tr.font.color.rgb = RGBColor.from_string('1F497D') sub_p = doc.add_paragraph() sub_p.alignment = WD_ALIGN_PARAGRAPH.CENTER sub_p.paragraph_format.space_after = Pt(2) sr = sub_p.add_run('Paediatric Occupational Therapy | Circle Time / Rhythms') sr.italic = True sr.font.size = Pt(9.5) sr.font.color.rgb = RGBColor.from_string('808080') # Client strip strip_table = doc.add_table(rows=1, cols=4) remove_table_borders(strip_table) for cell in strip_table.row_cells(0): set_cell_bg(cell, 'EBF3FB') strip_data = [ ('Child:', 'Pragadesh J'), ('Age:', '3 y 9 m'), ('Date:', '07/07/2026'), ('Therapist OT:', '_______________'), ] for cell, (lbl, val) in zip(strip_table.row_cells(0), strip_data): p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(3) p_.paragraph_format.space_after = Pt(3) r1 = p_.add_run(f'{lbl} ') r1.bold = True r1.font.size = Pt(10) p_.add_run(val).font.size = Pt(10) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # WHAT IS A SENSORY DIET? # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'WHAT IS A SENSORY DIET?') add_info_box(doc, 'A sensory diet is a personalised, scheduled set of sensory activities embedded into the child\'s daily routine. ' 'It is NOT about food. It helps the nervous system regulate arousal levels — reducing sensory-seeking or ' 'sensory-avoidant behaviours and improving attention, behaviour, and participation in daily activities. ' 'Activities must be done consistently, in the correct sequence, and at the right intensity for your child.', bg='EBF3FB', border='2E74B5') # ══════════════════════════════════════════════════════════════════════════════ # PRAGADESH's SENSORY PROFILE # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, "PRAGADESH'S SENSORY PROFILE SUMMARY") profile_table = doc.add_table(rows=1, cols=4) profile_table.style = 'Light Grid Accent 1' profile_table.allow_autofit = False for cell, txt in zip(profile_table.row_cells(0), ['Sensory System', 'Pattern', 'Signs in Child', 'Goal of Diet']): p_ = cell.paragraphs[0] r_ = p_.add_run(txt) r_.bold = True r_.font.size = Pt(10) set_cell_bg(cell, 'BDD7EE') profile_rows = [ ('Proprioception\n(body position / pressure)', 'SEEKING\n(Hyposensitive)', 'Deep sitting, crashing into furniture,\nseeks pressure on body', 'Provide scheduled heavy work to\nsatisfy need and improve regulation'), ('Vestibular\n(movement / balance)', 'SEEKING\n(Hyposensitive)', 'Running aimlessly, spinning self\nor objects', 'Structured movement breaks to\nreduce random spinning/running'), ('Tactile\n(touch)', 'MIXED\n(Defensive + Seeking)', 'Dislikes unfamiliar touch / hand-feeding;\nmay mouth objects excessively', 'Graded tactile exposure;\ndeep pressure before light touch'), ('Oral / Gustatory\n(taste/mouth)', 'DEFENSIVE\n(Selective)', 'Restricted food variety;\nrefuses new textures and flavours', 'Oral motor warm-up before meals;\ngradual texture introduction'), ('Visual', 'SEEKING / FIXATING', 'Staring at objects, lateral visual\ntracking, lines up toys', 'Controlled visual input;\nuse of visual schedules'), ('Auditory', 'HYPOSENSITIVE', 'Does not consistently respond to name;\ntolerates loud noises', 'Use of alerting auditory cues;\nconsistent verbal + non-verbal pairing'), ] for i, row_data in enumerate(profile_rows): row = profile_table.add_row() for cell, txt in zip(row.cells, row_data): p_ = cell.paragraphs[0] p_.add_run(txt).font.size = Pt(9.5) if i % 2 == 1: for cell in row.cells: set_cell_bg(cell, 'F2F7FC') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # DAILY SENSORY DIET SCHEDULE # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'DAILY SENSORY DIET SCHEDULE') add_info_box(doc, 'Follow the schedule below EVERY DAY. Activities marked ● are MANDATORY. ' 'Activities marked ○ are optional based on the child\'s arousal level. ' 'If the child is very dysregulated (tantrum, throwing, spinning excessively), go to the CALMING TOOLKIT first.', bg='FFF2CC', border='F7A900') # Time-block table sched_table = doc.add_table(rows=1, cols=5) sched_table.style = 'Light Grid Accent 1' sched_table.allow_autofit = False for cell, txt in zip(sched_table.row_cells(0), ['Time Block', 'Activity', 'Duration', 'Sensory System\nTargeted', 'Notes for Parent']): p_ = cell.paragraphs[0] p_.add_run(txt).bold = True p_.runs[-1].font.size = Pt(9.5) set_cell_bg(cell, '1F497D') p_.runs[-1].font.color.rgb = RGBColor.from_string('FFFFFF') schedule = [ # (time, activity, duration, system, notes) ('🌅 MORNING\n~7:00–8:00 AM', '● Proprioceptive Wake-Up\nJoint compressions — press down gently on both shoulders (10x), hips (10x), knees (10x)', '5 min', 'Proprioception', 'Do before dressing; helps child become alert and body-aware'), ('', '● Heavy Work: Carry heavy bag\nAsk child to carry a small backpack (0.5 kg) from bedroom to kitchen', '3–5 min', 'Proprioception\nVestibular', 'Say "Pragadesh, carry your bag!" — use simple 1-step command'), ('', '● Oral Motor Warm-Up\nChew on a chew necklace/tube or give chewy breakfast food (roti, toast) before other foods', '5 min', 'Oral / Tactile', 'Do BEFORE offering new or disliked foods; reduces oral defensiveness'), ('', '● Deep Pressure Brushing\nBrush arms, legs, back (Wilbarger protocol if prescribed). Followed by joint compressions', '3 min', 'Tactile\nProprioception', 'Use therapy brush only. Do NOT use on face/stomach without OT guidance'), ('☀️ MID-MORNING\n~10:00–11:00 AM', '● Obstacle Course / Tunnel Play\nCrawl through a cushion tunnel, climb over pillows, roll on therapy ball', '10 min', 'Proprioception\nVestibular\nTactile', 'Set up in a safe space; do the same sequence every day for predictability'), ('', '● Swinging\nBackyard swing / indoor hammock swing — linear rhythm (front/back only)', '5–10 min', 'Vestibular', 'Linear swing = calming. Rotary spin = alerting. Use linear only if child is dysregulated'), ('', '○ Sensory Bin Exploration\nDry rice / lentils / sand tray — let child scoop, pour, hide objects', '5–8 min', 'Tactile', 'Introduce messy play gradually; start with dry textures before wet/sticky'), ('🍽️ BEFORE LUNCH\n~12:30 PM', '● Oral Motor Prep (repeat)\nChew tube / crunchy snack (puffed rice, biscuit) 5 min before lunch', '5 min', 'Oral', 'Prepares the oral system for mealtime; reduces refusal and gagging'), ('', '● Deep Pressure Before Meal\nFirm massage on arms + shoulders for 2 min before sitting down', '2 min', 'Tactile\nProprioception', 'Reduces tactile defensiveness; improves mealtime tolerance'), ('', '● Mealtime Positioning\nSeat feet flat on floor or footstool; table at elbow height; no screen distraction', 'Entire meal', 'Proprioception\nOral', 'Good seating = better self-regulation and oral intake'), ('😴 AFTER NAP / AFTERNOON\n~3:00–4:00 PM', '● Heavy Work: Push/Pull\nPush a laundry basket, pull a trolley, help carry groceries (light)', '5 min', 'Proprioception', 'Heavy work is a natural regulator — plan this BEFORE any structured activity'), ('', '● Therapy Ball Activities\nChild sits/lies on therapy ball; therapist/parent bounces gently; roll forward/backward', '5–8 min', 'Vestibular\nProprioception', 'Supervision essential; stop if child shows signs of distress or over-arousal'), ('', '● Fine Motor Play\nPeg board / lacing cards / Play-Doh squeezing / tearing newspaper into strips', '10 min', 'Tactile\nProprioception\n(Fine motor)', 'Choose ONE activity; rotate daily to maintain interest'), ('', '○ Water Play\nBucket of water with cups and containers to pour / squeeze sponge', '5–8 min', 'Tactile\nOral\nVisual', 'Great regulating activity; offer towel/apron to reduce tactile anxiety'), ('🌆 EARLY EVENING\n~5:30–6:30 PM', '● Outdoor Play\nScooter / tricycle / running in open space (structured time + boundary)', '15–20 min', 'Vestibular\nProprioception', 'Set clear start/stop signal; gradually introduce peer nearby for social exposure'), ('', '○ Sensory Bin (Wet)\nShaving foam / sand + water / cooked pasta — introduce if dry textures tolerated', '5 min', 'Tactile\nOral', 'Advance from dry → wet only when dry tolerated without avoidance'), ('🍽️ BEFORE DINNER\n~7:00 PM', '● Oral Motor Prep (repeat)\nChew necklace / crunchy snack before dinner', '3 min', 'Oral', 'Same as lunch prep routine — consistency is key'), ('', '● Body Sock / Compression Vest\nChild sits inside a body sock or wears compression vest for 10–15 min before bath', '10–15 min', 'Proprioception\nTactile', 'Provides calming proprioceptive input; improves bath/dressing tolerance'), ('🌙 BEDTIME ROUTINE\n~8:00–9:00 PM', '● Bath: Warm Water with Firm Wash\nUse firm strokes when washing; warm water is calming; avoid splashing face suddenly', '10 min', 'Tactile\nOral\nProprioception', 'Predictable sequence: head → body → feet. Name each step for language exposure'), ('', '● Deep Pressure Massage\nFirm lotion massage after bath: legs → arms → back. Use slow, deep strokes', '5 min', 'Tactile\nProprioception', 'This is the most calming activity of the day — do every night'), ('', '● Quiet Sensory Wind-Down\nDim lights; soft music or white noise; wrap snugly in a blanket (proprioceptive hug)', '10 min', 'Auditory\nTactile\nVisual', 'Avoid screens 30 min before bed; prepare child for sleep transition'), ] row_colors = ['FFFFFF', 'F2F7FC'] time_bg_colors = { '🌅': 'FFF9E6', '☀️': 'E6F4EA', '🍽️': 'FCF0E6', '😴': 'E8EAF6', '🌆': 'E6F4EA', '🌙': 'EDE7F6', } for i, (time_block, activity, duration, system, notes) in enumerate(schedule): row = sched_table.add_row() cells = row.cells for cell, txt in zip(cells, [time_block, activity, duration, system, notes]): p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(2) p_.paragraph_format.space_after = Pt(2) run = p_.add_run(txt) run.font.size = Pt(9.5) if txt == time_block and time_block.strip(): run.bold = True run.font.size = Pt(9) # Color time-block column if time_block.strip(): emoji = time_block[:2] bg = 'EBF3FB' for e, c in time_bg_colors.items(): if e in time_block: bg = c break set_cell_bg(cells[0], bg) else: set_cell_bg(cells[0], 'F9F9F9') if i % 2 == 1: for c in cells[1:]: set_cell_bg(c, 'F9FAFB') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # CALMING TOOLKIT # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'CALMING TOOLKIT — USE WHEN CHILD IS DYSREGULATED', color='B8160A') add_info_box(doc, 'Signs of dysregulation: Excessive spinning/running, tantrum, self-hitting, throwing objects, crying without clear cause, ' 'refusing all activities, or zoning out completely. Use these strategies FIRST before resuming routine.', bg='FDE9E9', border='C00000') calm_table = doc.add_table(rows=1, cols=3) calm_table.style = 'Light Grid Accent 1' calm_table.allow_autofit = False for cell, txt in zip(calm_table.row_cells(0), ['Strategy', 'How to Do It', 'Duration']): p_ = cell.paragraphs[0] p_.add_run(txt).bold = True p_.runs[-1].font.size = Pt(10) set_cell_bg(cell, 'C00000') p_.runs[-1].font.color.rgb = RGBColor.from_string('FFFFFF') calm_rows = [ ('Deep Pressure Hug', 'Wrap child firmly in a blanket or give a firm bear hug (10–15 sec). Keep voice low and calm.', '30–60 sec'), ('Heavy Work (Immediate)', 'Ask child to push against the wall with both hands for 30 sec, or carry a heavy cushion across the room.', '1–3 min'), ('Quiet Tent / Calm Corner', 'Set up a small pop-up tent or corner with dim lighting, soft blanket, and 1 favourite tactile toy. Guide child in.', '5–10 min'), ('Linear Swing (slow)', 'Place child in swing and use slow front-back rhythm (no rotary). Hum or sing softly.', '5–8 min'), ('Oral Input', 'Offer a chewy tube, chew necklace, or thick smoothie through a narrow straw.', '3–5 min'), ('Joint Compressions', 'Firm downward pressure on shoulders → hips → knees. 10 compressions each. Rhythm: 1 second per compression.', '2–3 min'), ('Reduce Sensory Load', 'Turn off TV, reduce noise, dim lights, remove visual clutter in the area. Fewer people around.', 'Immediately'), ] for i, (strat, how, dur) in enumerate(calm_rows): row = calm_table.add_row() for cell, txt in zip(row.cells, [strat, how, dur]): p_ = cell.paragraphs[0] p_.add_run(txt).font.size = Pt(10) if i % 2 == 1: for cell in row.cells: set_cell_bg(cell, 'FDE9E9') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # ALERTING TOOLKIT # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'ALERTING TOOLKIT — USE WHEN CHILD IS UNDER-AROUSED / LETHARGIC', color='375623') add_info_box(doc, 'Signs of under-arousal: Zoning out, not responding to name, passively sitting, no engagement, drowsy appearance, ' 'low muscle tone posture. Use alerting activities to increase engagement before a structured session.', bg='E6F4EA', border='375623') alert_table = doc.add_table(rows=1, cols=3) alert_table.style = 'Light Grid Accent 1' alert_table.allow_autofit = False for cell, txt in zip(alert_table.row_cells(0), ['Strategy', 'How to Do It', 'Duration']): p_ = cell.paragraphs[0] p_.add_run(txt).bold = True p_.runs[-1].font.size = Pt(10) set_cell_bg(cell, '375623') p_.runs[-1].font.color.rgb = RGBColor.from_string('FFFFFF') alert_rows = [ ('Jumping on trampoline / cushions', 'Let child jump 20–30 times. Count aloud with child. Use consistent verbal cue: "Jump! Jump! Jump!"', '2–3 min'), ('Rotary Spinning (controlled)', 'Spin child in a desk chair or therapy barrel 3–5 rotations. STOP and observe. Repeat if safe.', '1–2 min'), ('Cold / Crunchy oral input', 'Offer cold water through a thin straw, cold fruit, or crunchy snacks (puffed rice, carrot sticks).', '3 min'), ('Bright natural light', 'Move to a window or take child outdoors for natural light exposure.', '5 min'), ('Upbeat rhythmic music + movement', 'Play favourite song + model clapping, stamping feet, or marching. Encourage imitation.', '3–5 min'), ('Face / head input', 'Firm face wash with cool water, or firm hair brushing.', '1–2 min'), ] for i, (strat, how, dur) in enumerate(alert_rows): row = alert_table.add_row() for cell, txt in zip(row.cells, [strat, how, dur]): p_ = cell.paragraphs[0] p_.add_run(txt).font.size = Pt(10) if i % 2 == 1: for cell in row.cells: set_cell_bg(cell, 'EDF7ED') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # FEEDING / MEALTIME SENSORY STRATEGIES # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'FEEDING & MEALTIME SENSORY STRATEGIES') feed_items = [ ('Seating', 'Child\'s feet must be flat on a footstool or floor. Avoid dangling feet — poor grounding = poor regulation.'), ('Oral Motor Warm-Up', 'Always do a 3–5 min oral motor prep before any meal (chew tube, crunchy food, vibrating toothbrush on gums).'), ('Food Chaining', 'Introduce new foods alongside ACCEPTED foods. Ratio: 4 known : 1 new. Never force new food.'), ('Texture Progression', 'Current level → Crunchy/dry → Soft solid → Mixed textures → Wet/sticky. Move only when current level is fully accepted.'), ('Sensory Exposure (Non-Eating)', 'Allow child to LOOK → TOUCH → SMELL → LICK → BITE → EAT new foods. Each step may take days to weeks.'), ('Temperature', 'Offer foods at consistent, predictable temperatures. Avoid surprises (sudden hot/cold).'), ('Reduce Distractions', 'Mealtime = quiet space. Turn off TV. Reduce visual and auditory stimuli.'), ('Positive Reinforcement', 'Praise every attempt — "You touched it! Great job!" Never punish food refusal.'), ('Duration', 'Keep meals to 20–25 min maximum. Prolonged stressful mealtimes worsen food aversion.'), ] feed_table = doc.add_table(rows=1, cols=2) feed_table.style = 'Light Grid Accent 1' feed_table.allow_autofit = False for cell, txt in zip(feed_table.row_cells(0), ['Strategy', 'Detail']): p_ = cell.paragraphs[0] p_.add_run(txt).bold = True p_.runs[-1].font.size = Pt(10) set_cell_bg(cell, 'BDD7EE') for i, (strat, detail) in enumerate(feed_items): row = feed_table.add_row() cells = row.cells cells[0].paragraphs[0].add_run(strat).font.size = Pt(10) cells[0].paragraphs[0].runs[-1].bold = True cells[1].paragraphs[0].add_run(detail).font.size = Pt(10) if i % 2 == 1: for cell in row.cells: set_cell_bg(cell, 'F2F7FC') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # SLEEP SENSORY ROUTINE # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'SLEEP PREPARATION SENSORY ROUTINE') sleep_items = [ '30 min before bed: No screens, no alerting activities, no loud music.', 'Dim the lights in the room progressively over 20 minutes.', 'Warm bath with firm washing strokes (calming tactile input).', 'Deep pressure lotion massage immediately after bath (legs → arms → back).', 'Dress in comfortable, seamless clothing (reduces tactile irritability).', 'Swaddle or tuck firmly with a weighted blanket or thick blanket.', 'Soft white noise or gentle lullaby (auditory calming).', 'Keep the same sequence EVERY NIGHT — predictability reduces anxiety.', ] for item in sleep_items: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(2) p.add_run(item).font.size = Pt(10.5) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # PARENT OBSERVATIONS LOG # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'DAILY PARENT OBSERVATION LOG') add_info_box(doc, 'Fill this out every evening and bring to the next OT session. ' 'Note what worked, what didn\'t, and any changes in behaviour. ' 'This helps the therapist fine-tune the sensory diet.', bg='FFF2CC', border='F7A900') log_table = doc.add_table(rows=1, cols=5) log_table.style = 'Light Grid Accent 1' log_table.allow_autofit = False for cell, txt in zip(log_table.row_cells(0), ['Date', 'Activities Done', 'Child\'s Response\n(Calm / Alert / Dysreg)', 'Behaviour\nHighlights', 'Parent Notes']): p_ = cell.paragraphs[0] p_.add_run(txt).bold = True p_.runs[-1].font.size = Pt(9.5) set_cell_bg(cell, '1F497D') p_.runs[-1].font.color.rgb = RGBColor.from_string('FFFFFF') for i in range(7): row = log_table.add_row() day_cell = row.cells[0] day_cell.paragraphs[0].add_run(f'Day {i+1}\n__/__/____').font.size = Pt(9.5) for cell in row.cells[1:]: p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(15) if i % 2 == 1: for cell in row.cells: set_cell_bg(cell, 'F2F7FC') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # IMPORTANT REMINDERS # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'IMPORTANT REMINDERS FOR PARENTS') reminders = [ ('Consistency is everything', 'The sensory diet ONLY works when done every day, at the same times. Missing days resets progress.'), ('Watch for over-arousal', 'If child becomes MORE hyperactive, flushed, or laughing uncontrollably during vestibular activity — STOP. This is overstimulation.'), ('Watch for under-arousal', 'Glassy eyes, yawning, going limp during activities = too much calming input. Switch to an alerting activity.'), ('Brushing protocol — OT guided only', 'Do NOT use Wilbarger brushing protocol without direct OT supervision. Incorrect use can increase dysregulation.'), ('No forcing', 'Never force the child to complete an activity. Modify or offer choice. Forced activities increase anxiety and reduce trust.'), ('Praise effort, not perfection', 'Any attempt at a new activity deserves enthusiastic praise. Repetition and comfort come with time.'), ('Communicate with the OT', 'If you notice any adverse reactions (increased self-injury, extreme distress, regression), contact the OT immediately before next session.'), ('Sensory diet is a living document', 'This plan will be reviewed and updated every 4 weeks at your OT appointment. Bring the observation log.'), ] for label, detail in reminders: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(3) r1 = p.add_run(f'{label}: ') r1.bold = True r1.font.size = Pt(10.5) r1.font.color.rgb = RGBColor.from_string('1F497D') p.add_run(detail).font.size = Pt(10.5) doc.add_paragraph() # ══════════════════════════════════════════════════════════════════════════════ # EQUIPMENT LIST # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'RECOMMENDED EQUIPMENT / MATERIALS (HOME)') equip_table = doc.add_table(rows=1, cols=3) equip_table.style = 'Light Grid Accent 1' equip_table.allow_autofit = False for cell, txt in zip(equip_table.row_cells(0), ['Item', 'Purpose', 'Priority']): p_ = cell.paragraphs[0] p_.add_run(txt).bold = True p_.runs[-1].font.size = Pt(10) set_cell_bg(cell, 'BDD7EE') equipment = [ ('Therapy ball (55–65 cm)', 'Vestibular + proprioceptive input, sitting balance', 'HIGH'), ('Chew necklace / Ark Therapeutics tube', 'Oral motor, reduce mouthing of objects', 'HIGH'), ('Wilbarger therapy brush', 'Tactile desensitisation (OT-guided)', 'HIGH'), ('Sensory bin (deep tray)', 'Tactile exploration — dry and wet media', 'HIGH'), ('Body sock / Lycra tunnel', 'Proprioceptive input, deep pressure', 'MEDIUM'), ('Weighted lap pad / blanket (0.5–1 kg)', 'Proprioceptive calming during seated activities', 'MEDIUM'), ('Pop-up tent / calm corner setup', 'Dysregulation management, quiet retreat', 'MEDIUM'), ('Mini indoor trampoline', 'Vestibular + proprioceptive alerting', 'MEDIUM'), ('Compression vest', 'Continuous proprioceptive input, regulation', 'MEDIUM'), ('Play-Doh / putty', 'Hand strength, tactile tolerance, fine motor', 'LOW-MEDIUM'), ('Lacing cards / peg boards', 'Fine motor, eye-hand coordination', 'LOW-MEDIUM'), ('Obstacle course cushions/pillows', 'Motor planning, proprioception', 'LOW'), ] for i, (item, purpose, priority) in enumerate(equipment): row = equip_table.add_row() cells = row.cells cells[0].paragraphs[0].add_run(item).font.size = Pt(10) cells[1].paragraphs[0].add_run(purpose).font.size = Pt(10) pri_p = cells[2].paragraphs[0] pri_r = pri_p.add_run(priority) pri_r.font.size = Pt(10) pri_r.bold = True if priority == 'HIGH': pri_r.font.color.rgb = RGBColor.from_string('C00000') elif priority == 'MEDIUM': pri_r.font.color.rgb = RGBColor.from_string('F7A900') else: pri_r.font.color.rgb = RGBColor.from_string('375623') if i % 2 == 1: for cell in row.cells: set_cell_bg(cell, 'F2F7FC') doc.add_paragraph() # ══════════════════════════════════════════════════════════════════════════════ # NEXT REVIEW + SIGNATURE # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'REVIEW & SIGNATURES') sig_table = doc.add_table(rows=3, cols=2) remove_table_borders(sig_table) sig_data = [ ('Next Review Date:', '___________________________'), ('Occupational Therapist Signature:', '___________________________'), ('Parent / Guardian Signature:', '___________________________'), ] for r_idx, (lbl, val) in enumerate(sig_data): row = sig_table.rows[r_idx] lc = row.cells[0] lc.paragraphs[0].paragraph_format.space_before = Pt(8) r1 = lc.paragraphs[0].add_run(lbl) r1.bold = True r1.font.size = Pt(10.5) vc = row.cells[1] vc.paragraphs[0].paragraph_format.space_before = Pt(8) vc.paragraphs[0].add_run(val).font.size = Pt(10.5) doc.add_paragraph() # Footer note fn_p = doc.add_paragraph() fn_p.alignment = WD_ALIGN_PARAGRAPH.CENTER fn_r = fn_p.add_run( 'This sensory diet is individualised for Pragadesh J. Do not share or apply to other children without OT consultation.\n' 'Prepared by: OT Department | Circle Time / Rhythms | Date: 07/07/2026' ) fn_r.italic = True fn_r.font.size = Pt(8.5) fn_r.font.color.rgb = RGBColor.from_string('808080') # ══════════════════════════════════════════════════════════════════════════════ # SAVE # ══════════════════════════════════════════════════════════════════════════════ out_path = '/tmp/workspace/ot-assessment/Pragadesh_Sensory_Diet_Plan.docx' doc.save(out_path) import os size = os.path.getsize(out_path) print(f"Saved: {out_path} ({size/1024:.1f} KB)") # Quick validation doc2 = Document(out_path) paras = [p.text for p in doc2.paragraphs if p.text.strip()] print(f"Total non-empty paragraphs: {len(paras)}") print("Sections found:") for p in paras: if p.isupper() or any(x in p for x in ['I.','II.','WHAT','DAILY','CALM','ALERT','FEED','SLEEP','PARENT','EQUIP','REVIEW']): print(f" >> {p[:80]}") PYEOF
python3 << 'PYEOF' from docx import Document from docx.shared import Pt, Inches, RGBColor, Cm from docx.enum.text import WD_ALIGN_PARAGRAPH from docx.oxml.ns import qn from docx.oxml import OxmlElement doc = Document() for section in doc.sections: section.top_margin = Cm(1.8) section.bottom_margin = Cm(1.8) section.left_margin = Cm(2.0) section.right_margin = Cm(2.0) style = doc.styles['Normal'] style.font.name = 'Calibri' style.font.size = Pt(10.5) # ─── helpers ────────────────────────────────────────────────────────────────── def set_cell_bg(cell, hex_color): tc = cell._tc tcPr = 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_color) tcPr.append(shd) def remove_table_borders_xml(table): """Remove borders via direct XML manipulation.""" tbl = table._tbl tblPr = tbl.find(qn('w:tblPr')) if tblPr is None: tblPr = OxmlElement('w:tblPr') tbl.insert(0, tblPr) tblBorders = OxmlElement('w:tblBorders') for bn in ['top','left','bottom','right','insideH','insideV']: b = OxmlElement(f'w:{bn}') b.set(qn('w:val'), 'none') tblBorders.append(b) tblPr.append(tblBorders) def remove_cell_borders(cell): tc = cell._tc tcPr = tc.get_or_add_tcPr() tcBorders = OxmlElement('w:tcBorders') for bn in ['top','left','bottom','right']: b = OxmlElement(f'w:{bn}') b.set(qn('w:val'), 'none') tcBorders.append(b) tcPr.append(tcBorders) def section_heading(doc, text, color='1F497D'): p = doc.add_paragraph() p.paragraph_format.space_before = Pt(8) p.paragraph_format.space_after = Pt(3) run = p.add_run(text) run.bold = True run.font.size = Pt(11) run.font.color.rgb = RGBColor.from_string(color) 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'), color) pBdr.append(bottom) pPr.append(pBdr) return p def add_info_box(doc, text, bg='EBF3FB', border_color='2E74B5'): table = doc.add_table(rows=1, cols=1) table.style = 'Table Grid' remove_table_borders_xml(table) cell = table.cell(0, 0) set_cell_bg(cell, bg) tc = cell._tc tcPr = tc.get_or_add_tcPr() tcBorders = OxmlElement('w:tcBorders') for bn in ['top','right','bottom']: b = OxmlElement(f'w:{bn}') b.set(qn('w:val'), 'none') tcBorders.append(b) left_b = OxmlElement('w:left') left_b.set(qn('w:val'), 'single') left_b.set(qn('w:sz'), '18') left_b.set(qn('w:color'), border_color) tcBorders.append(left_b) tcPr.append(tcBorders) p = cell.paragraphs[0] p.paragraph_format.left_indent = Pt(6) p.paragraph_format.space_before = Pt(4) p.paragraph_format.space_after = Pt(4) run = p.add_run(text) run.font.size = Pt(10) run.font.color.rgb = RGBColor.from_string('1A3A5C') doc.add_paragraph().paragraph_format.space_after = Pt(2) def build_table_with_header(doc, headers, data_rows, header_bg='1F497D', header_fg='FFFFFF', alt_row_bg='F2F7FC'): """Build a styled table. data_rows = list of tuples of strings.""" n_cols = len(headers) table = doc.add_table(rows=1, cols=n_cols) table.style = 'Light Grid Accent 1' table.allow_autofit = False hdr_row = table.rows[0] for cell, txt in zip(hdr_row.cells, headers): p_ = cell.paragraphs[0] r_ = p_.add_run(txt) r_.bold = True r_.font.size = Pt(9.5) r_.font.color.rgb = RGBColor.from_string(header_fg) set_cell_bg(cell, header_bg) for i, row_data in enumerate(data_rows): row = table.add_row() for cell, txt in zip(row.cells, row_data): p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(2) p_.paragraph_format.space_after = Pt(2) p_.add_run(str(txt)).font.size = Pt(9.5) if i % 2 == 1: for cell in row.cells: set_cell_bg(cell, alt_row_bg) return table # ══════════════════════════════════════════════════════════════════════════════ # TITLE BLOCK # ══════════════════════════════════════════════════════════════════════════════ title_p = doc.add_paragraph() title_p.alignment = WD_ALIGN_PARAGRAPH.CENTER title_p.paragraph_format.space_before = Pt(4) title_p.paragraph_format.space_after = Pt(0) tr = title_p.add_run('SENSORY DIET PLAN — HOME IMPLEMENTATION') tr.bold = True tr.font.size = Pt(15) tr.font.color.rgb = RGBColor.from_string('1F497D') sub_p = doc.add_paragraph() sub_p.alignment = WD_ALIGN_PARAGRAPH.CENTER sub_p.paragraph_format.space_after = Pt(6) sr = sub_p.add_run('Paediatric Occupational Therapy | Circle Time / Rhythms') sr.italic = True sr.font.size = Pt(9.5) sr.font.color.rgb = RGBColor.from_string('808080') # Client info strip (simple table with shading) info_tbl = doc.add_table(rows=2, cols=4) info_tbl.style = 'Table Grid' remove_table_borders_xml(info_tbl) info_data = [ [('Child:', 'Pragadesh J'), ('Age:', '3 y 9 m'), ('Date:', '07/07/2026'), ('Reviewed by:', '_____________')], [('D.O.A:', '12/10/2023'), ('Gender:', 'Male'), ('Diagnosis:', 'GDD / ? ASD'), ('Therapist:', '_____________')], ] for r_idx, row_data in enumerate(info_data): row = info_tbl.rows[r_idx] for c_idx, (lbl, val) in enumerate(row_data): cell = row.cells[c_idx] set_cell_bg(cell, 'EBF3FB') remove_cell_borders(cell) p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(3) p_.paragraph_format.space_after = Pt(3) r1 = p_.add_run(f'{lbl} ') r1.bold = True r1.font.size = Pt(10) p_.add_run(val).font.size = Pt(10) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # WHAT IS A SENSORY DIET? # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'WHAT IS A SENSORY DIET?') add_info_box(doc, 'A sensory diet is a personalised, scheduled set of sensory activities woven into the child\'s daily routine. ' 'It is NOT about food. It helps the nervous system regulate arousal — reducing sensory-seeking or avoidant ' 'behaviours and improving attention, behaviour, and participation. Activities must be done consistently, ' 'in the correct sequence, and at the right intensity for your child.', bg='EBF3FB', border_color='2E74B5') # ══════════════════════════════════════════════════════════════════════════════ # SENSORY PROFILE SUMMARY # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, "PRAGADESH'S SENSORY PROFILE SUMMARY") build_table_with_header(doc, ['Sensory System', 'Pattern', 'Signs in Child', 'Goal of Diet'], [ ('Proprioception\n(body pressure)', 'SEEKING (Hyposensitive)', 'Deep sitting, crashing, seeks firm pressure', 'Scheduled heavy work to satisfy and regulate'), ('Vestibular\n(movement)', 'SEEKING (Hyposensitive)', 'Running aimlessly, spinning self/objects', 'Structured movement breaks'), ('Tactile (touch)', 'MIXED\n(Defensive + Seeking)', 'Dislikes hand-feeding; mouths objects', 'Graded exposure; deep pressure before light touch'), ('Oral / Gustatory', 'DEFENSIVE\n(Selective)', 'Restricted foods; refuses new textures', 'Oral motor warm-up before meals'), ('Visual', 'SEEKING / FIXATING', 'Staring; lateral tracking; lines up toys', 'Controlled visual input; visual schedules'), ('Auditory', 'HYPOSENSITIVE', 'Does not respond to name; loud noise tolerated', 'Consistent verbal + non-verbal cue pairing'), ], header_bg='1F497D') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # DAILY SCHEDULE # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'DAILY SENSORY DIET SCHEDULE') add_info_box(doc, 'Follow this schedule EVERY DAY. Activities marked with ● are MANDATORY. ' 'If child is dysregulated (excessive spinning/tantrum), use the CALMING TOOLKIT before resuming.', bg='FFF9E6', border_color='F7A900') schedule_data = [ ('MORNING\n~7:00–8:00 AM', '● Joint Compressions (Wake-Up)\nFirm downward pressure on shoulders → hips → knees, 10x each', '5 min', 'Proprioception', 'Do before dressing; improves body awareness and alertness'), ('', '● Heavy Work: Carry bag\nChild carries small backpack (0.5 kg) from bedroom to kitchen', '3–5 min', 'Proprioception\nVestibular', 'Use simple 1-step command: "Pragadesh, carry your bag!"'), ('', '● Oral Motor Warm-Up\nChew tube or chewy breakfast food (toast, roti) before other foods', '5 min', 'Oral / Tactile', 'Always BEFORE offering new or disliked foods'), ('', '● Deep Pressure Brushing\nBrush arms, legs, back with therapy brush (Wilbarger); follow with joint compressions', '3 min', 'Tactile\nProprioception', 'OT-guided only. Do NOT apply to face/stomach without instruction'), ('MID-MORNING\n~10:00–11:00 AM', '● Obstacle Course / Tunnel Play\nCrawl through cushion tunnel, climb over pillows, roll on therapy ball', '10 min', 'Proprioception\nVestibular\nTactile', 'Same sequence every day for predictability'), ('', '● Linear Swinging\nFront-back swing in backyard or indoor hammock — slow, rhythmic movement', '5–10 min', 'Vestibular', 'Linear = calming. Rotary spin = alerting. Use linear only if dysregulated'), ('', '○ Sensory Bin (Dry)\nDry rice / lentils / sand tray — scoop, pour, hide and find objects', '5–8 min', 'Tactile', 'Start with dry textures before introducing wet/sticky'), ('BEFORE LUNCH\n~12:30 PM', '● Oral Motor Prep (Repeat)\nChew necklace or crunchy snack 5 min before meal', '5 min', 'Oral', 'Prepares oral system; reduces refusal and gagging'), ('', '● Deep Pressure Before Meal\nFirm massage on arms and shoulders for 2 min before sitting for food', '2 min', 'Tactile\nProprioception', 'Reduces tactile defensiveness at mealtime'), ('', '● Positioning\nFeet flat on floor/footstool; table at elbow height; no screen distraction', 'Entire meal', 'Proprioception\nOral', 'Good seating posture = better self-regulation during eating'), ('AFTERNOON\n~3:00–4:00 PM', '● Heavy Work: Push / Pull\nPush laundry basket, pull a trolley, carry light groceries', '5 min', 'Proprioception', 'Heavy work is the best natural regulator — do BEFORE structured activity'), ('', '● Therapy Ball Activities\nSit/lie on therapy ball; gentle bounce; roll forward/backward with support', '5–8 min', 'Vestibular\nProprioception', 'Supervision essential; stop if distress or over-arousal signs appear'), ('', '● Fine Motor Play\nPeg board / lacing cards / Play-Doh squeezing / tearing strips of paper', '10 min', 'Tactile\nProprioception', 'Choose ONE activity; rotate daily to maintain interest'), ('', '○ Water Play\nBucket of water with cups and sponge to squeeze and pour', '5–8 min', 'Tactile\nOral\nVisual', 'Great regulating activity; offer towel/apron to reduce anxiety'), ('EARLY EVENING\n~5:30–6:30 PM', '● Outdoor Play\nScooter / tricycle / running in open space with clear boundaries', '15–20 min', 'Vestibular\nProprioception', 'Set clear start/stop signal; gradually introduce a peer nearby'), ('', '○ Sensory Bin (Wet)\nShaving foam / sand + water / cooked pasta — if dry textures already tolerated', '5 min', 'Tactile\nOral', 'Progress: dry → wet only when dry is fully tolerated without avoidance'), ('BEFORE DINNER\n~7:00 PM', '● Oral Motor Prep (Repeat)\nChew necklace or crunchy snack 3 min before dinner', '3 min', 'Oral', 'Same as lunch prep — consistency matters'), ('', '● Body Sock / Compression Vest\nChild sits in body sock or wears compression vest 10–15 min before bath', '10–15 min', 'Proprioception\nTactile', 'Calming proprioceptive input; improves bath/dressing tolerance'), ('BEDTIME ROUTINE\n~8:00–9:00 PM', '● Warm Bath with Firm Washing\nFirm strokes when washing; warm water is calming; avoid sudden face splash', '10 min', 'Tactile\nOral\nProprioception', 'Predictable sequence: head → body → feet. Name each step aloud'), ('', '● Deep Pressure Lotion Massage\nFirm lotion massage after bath: legs → arms → back, slow deep strokes', '5 min', 'Tactile\nProprioception', 'Most calming activity of the day — do EVERY night without exception'), ('', '● Quiet Sensory Wind-Down\nDim lights, soft music or white noise, wrap snugly in blanket', '10 min', 'Auditory\nTactile\nVisual', 'No screens 30 min before bed; consistent pre-sleep routine'), ] build_table_with_header(doc, ['Time Block', 'Activity', 'Duration', 'Sensory System\nTargeted', 'Notes for Parent'], schedule_data, header_bg='1F497D') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # CALMING TOOLKIT # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'CALMING TOOLKIT — USE WHEN CHILD IS DYSREGULATED', color='B8160A') add_info_box(doc, 'Signs of dysregulation: Excessive spinning/running, tantrum, self-hitting, throwing, crying without cause, or complete withdrawal. ' 'Use FIRST before resuming routine. Do not try to continue structured tasks during dysregulation.', bg='FDE9E9', border_color='C00000') build_table_with_header(doc, ['Strategy', 'How to Do It', 'Duration'], [ ('Deep Pressure Hug', 'Wrap child firmly in blanket or give a firm bear hug (10–15 sec). Keep voice low and calm.', '30–60 sec'), ('Heavy Work (Immediate)', 'Child pushes against a wall with both hands for 30 sec, or carries a heavy cushion across the room.', '1–3 min'), ('Quiet Tent / Calm Corner', 'Small pop-up tent with dim lighting, soft blanket, and 1 familiar tactile toy. Guide child gently in.', '5–10 min'), ('Linear Swing (slow)', 'Slow front-back swing rhythm. No rotary. Hum or sing softly alongside.', '5–8 min'), ('Oral Input', 'Chew tube, chew necklace, or thick smoothie through a narrow straw.', '3–5 min'), ('Joint Compressions', 'Firm downward pressure: shoulders → hips → knees. 10 compressions each. 1 second per compression.', '2–3 min'), ('Reduce Sensory Load', 'Turn off TV, reduce noise, dim lights, remove visual clutter, fewer people around.', 'Immediately'), ], header_bg='C00000', alt_row_bg='FDE9E9') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # ALERTING TOOLKIT # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'ALERTING TOOLKIT — USE WHEN CHILD IS UNDER-AROUSED / LETHARGIC', color='375623') add_info_box(doc, 'Signs of under-arousal: Zoning out, not responding to name, passive sitting, no engagement, drowsy appearance, low muscle tone posture. ' 'Use alerting activities to increase engagement BEFORE structured tasks.', bg='E6F4EA', border_color='375623') build_table_with_header(doc, ['Strategy', 'How to Do It', 'Duration'], [ ('Jumping on trampoline / cushions', 'Child jumps 20–30 times. Count aloud. Consistent verbal cue: "Jump! Jump!"', '2–3 min'), ('Rotary Spinning (controlled)', 'Spin in desk chair or therapy barrel — 3–5 rotations. STOP, observe. Repeat if safe.', '1–2 min'), ('Cold / Crunchy oral input', 'Cold water through a thin straw, cold fruit, or crunchy snack (puffed rice, carrot).', '3 min'), ('Bright natural light', 'Move to window or take outdoors for natural light exposure.', '5 min'), ('Upbeat music + movement', 'Play favourite song; model clapping, stamping, marching. Encourage imitation.', '3–5 min'), ('Face / head input', 'Firm face wash with cool water or firm hair brushing.', '1–2 min'), ], header_bg='375623', alt_row_bg='EDF7ED') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # MEALTIME SENSORY STRATEGIES # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'FEEDING & MEALTIME SENSORY STRATEGIES') build_table_with_header(doc, ['Strategy', 'Detail'], [ ('Seating', "Child's feet must be flat on footstool or floor. Dangling feet = poor grounding = poor regulation."), ('Oral Motor Warm-Up', 'Always do 3–5 min oral prep before any meal (chew tube, crunchy food, vibrating toothbrush on gums).'), ('Food Chaining', 'Introduce new foods alongside accepted ones. Ratio: 4 known : 1 new. Never force.'), ('Texture Progression', 'Crunchy/dry → Soft solid → Mixed textures → Wet/sticky. Move to next level only when current is fully accepted.'), ('Sensory Exposure (Non-Eating)', 'LOOK → TOUCH → SMELL → LICK → BITE → EAT. Each step may take days to weeks.'), ('Temperature', 'Offer foods at consistent, predictable temperatures. Avoid surprising hot/cold.'), ('Reduce Distractions', 'Mealtime = quiet space. TV off. Minimal visual and auditory stimuli.'), ('Positive Reinforcement', 'Praise every attempt: "You touched it! Great job!" Never punish refusal.'), ('Duration', 'Keep meals to 20–25 min maximum. Prolonged stressful mealtimes worsen food aversion.'), ], header_bg='BDD7EE', header_fg='000000') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # SLEEP ROUTINE # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'SLEEP PREPARATION SENSORY ROUTINE') sleep_steps = [ '30 min before bed: No screens, no alerting activities, no loud music.', 'Dim the lights progressively over 20 minutes.', 'Warm bath with firm washing strokes (calming tactile input).', 'Deep pressure lotion massage immediately after bath (legs → arms → back).', 'Dress in comfortable, seamless clothing (reduces tactile irritability during sleep).', 'Swaddle or tuck firmly with a weighted or thick blanket.', 'Soft white noise or gentle lullaby (auditory calming).', 'Keep the SAME sequence EVERY NIGHT — predictability significantly reduces bedtime anxiety.', ] for step in sleep_steps: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(2) p.add_run(step).font.size = Pt(10.5) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # PARENT OBSERVATION LOG # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'DAILY PARENT OBSERVATION LOG (Bring to Every OT Session)') add_info_box(doc, 'Fill this out each evening. Note what worked, what did not, and any changes in behaviour. ' 'This helps the therapist fine-tune the sensory diet at each review.', bg='FFF2CC', border_color='F7A900') log_data = [] for i in range(7): log_data.append((f'Day {i+1}\n__/__/____', '', '', '', '')) build_table_with_header(doc, ['Date', 'Activities Completed', "Child's Response\n(Calm / Alert / Dysreg)", 'Behaviour Highlights', 'Parent Notes'], log_data, header_bg='1F497D', alt_row_bg='F2F7FC') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # IMPORTANT REMINDERS # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'IMPORTANT REMINDERS FOR PARENTS') reminders = [ ('Consistency is everything', 'The sensory diet ONLY works when done every day, at the same times. Missing days resets progress.'), ('Watch for over-arousal', 'If child becomes MORE hyperactive, flushed, or laughing uncontrollably during vestibular input — STOP. That is overstimulation.'), ('Watch for under-arousal', 'Glassy eyes, yawning, going limp = too much calming input. Switch to an alerting activity.'), ('Brushing — OT guided only', 'Do NOT use Wilbarger brushing without direct OT supervision. Incorrect use worsens dysregulation.'), ('No forcing', 'Never force an activity. Offer choice or modify. Forced activities increase anxiety and reduce trust.'), ('Praise effort, not perfection', 'Any attempt at a new activity deserves enthusiastic praise. Comfort and skill come with repetition.'), ('Contact OT if concerned', 'Increased self-injury, extreme distress, or regression — contact OT immediately, before the next session.'), ('This plan is a living document', 'Reviewed and updated every 4 weeks. Bring the observation log to every appointment.'), ] for label, detail in reminders: p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(3) r1 = p.add_run(f'{label}: ') r1.bold = True r1.font.size = Pt(10.5) r1.font.color.rgb = RGBColor.from_string('1F497D') p.add_run(detail).font.size = Pt(10.5) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # EQUIPMENT LIST # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'RECOMMENDED HOME EQUIPMENT / MATERIALS') equip_tbl = doc.add_table(rows=1, cols=3) equip_tbl.style = 'Light Grid Accent 1' equip_tbl.allow_autofit = False for cell, txt in zip(equip_tbl.row_cells(0), ['Item', 'Purpose', 'Priority']): p_ = cell.paragraphs[0] p_.add_run(txt).bold = True p_.runs[-1].font.size = Pt(10) set_cell_bg(cell, 'BDD7EE') equipment = [ ('Therapy ball (55–65 cm)', 'Vestibular + proprioceptive input, sitting balance', 'HIGH', 'C00000'), ('Chew necklace / Ark Therapeutics chew tube', 'Oral motor regulation; reduces mouthing objects', 'HIGH', 'C00000'), ('Wilbarger therapy brush', 'Tactile desensitisation (use under OT guidance only)', 'HIGH', 'C00000'), ('Deep sensory bin (large tray)', 'Tactile exploration with dry and wet media', 'HIGH', 'C00000'), ('Body sock / Lycra tunnel', 'Deep proprioceptive input, calming', 'MEDIUM', 'F7A900'), ('Weighted lap pad (0.5–1 kg)', 'Proprioceptive calming during seated activities', 'MEDIUM', 'F7A900'), ('Pop-up tent (calm corner)', 'Retreat space for dysregulation management', 'MEDIUM', 'F7A900'), ('Mini indoor trampoline', 'Vestibular + proprioceptive alerting', 'MEDIUM', 'F7A900'), ('Compression vest', 'Continuous proprioceptive input throughout day', 'MEDIUM', 'F7A900'), ('Play-Doh / therapy putty', 'Hand strength, tactile tolerance, fine motor', 'LOW–MEDIUM', '375623'), ('Lacing cards / peg boards', 'Fine motor, eye-hand coordination', 'LOW–MEDIUM', '375623'), ('Obstacle course (cushions/pillows)', 'Motor planning, proprioception', 'LOW', '375623'), ] for i, (item, purpose, priority, p_color) in enumerate(equipment): row = equip_tbl.add_row() cells = row.cells cells[0].paragraphs[0].add_run(item).font.size = Pt(10) cells[1].paragraphs[0].add_run(purpose).font.size = Pt(10) pri_r = cells[2].paragraphs[0].add_run(priority) pri_r.font.size = Pt(10) pri_r.bold = True pri_r.font.color.rgb = RGBColor.from_string(p_color) if i % 2 == 1: for cell in row.cells: set_cell_bg(cell, 'F2F7FC') doc.add_paragraph() # ══════════════════════════════════════════════════════════════════════════════ # SIGNATURES # ══════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'REVIEW & SIGNATURES') sig_tbl = doc.add_table(rows=3, cols=2) sig_tbl.style = 'Table Grid' remove_table_borders_xml(sig_tbl) for row in sig_tbl.rows: for cell in row.cells: remove_cell_borders(cell) sig_data = [ ('Next Review Date:', '___________________________'), ('Occupational Therapist Signature:', '___________________________'), ('Parent / Guardian Signature:', '___________________________'), ] for r_idx, (lbl, val) in enumerate(sig_data): row = sig_tbl.rows[r_idx] lp = row.cells[0].paragraphs[0] lp.paragraph_format.space_before = Pt(10) r1 = lp.add_run(lbl) r1.bold = True r1.font.size = Pt(10.5) vp = row.cells[1].paragraphs[0] vp.paragraph_format.space_before = Pt(10) vp.add_run(val).font.size = Pt(10.5) doc.add_paragraph() fn_p = doc.add_paragraph() fn_p.alignment = WD_ALIGN_PARAGRAPH.CENTER fn_r = fn_p.add_run( 'This sensory diet is individualised for Pragadesh J. Do not apply to other children without OT consultation.\n' 'Prepared by: OT Department | Circle Time / Rhythms | Date: 07/07/2026' ) fn_r.italic = True fn_r.font.size = Pt(8.5) fn_r.font.color.rgb = RGBColor.from_string('808080') # SAVE out_path = '/tmp/workspace/ot-assessment/Pragadesh_Sensory_Diet_Plan.docx' doc.save(out_path) import os size = os.path.getsize(out_path) print(f"Saved: {out_path}") print(f"File size: {size/1024:.1f} KB") # Validate doc2 = Document(out_path) paras = [p.text for p in doc2.paragraphs if p.text.strip()] print(f"Total non-empty paragraphs: {len(paras)}") print("Key sections:") for p in paras: if any(kw in p.upper() for kw in ['SENSORY DIET','PROFILE','DAILY','CALMING','ALERTING','FEEDING','SLEEP','OBSERVATION','REMINDERS','EQUIPMENT','REVIEW']): print(f" >> {p[:80]}") PYEOF
Pragadesh Sensory Diet Plan
Word Document · DOCX
| Section | Content |
|---|---|
| Sensory Profile Summary | 6-system table (Proprioception, Vestibular, Tactile, Oral, Visual, Auditory) — pattern + signs + goal |
| Daily Schedule | 20 timed activity blocks from 7 AM to bedtime — activity name, duration, sensory system targeted, and parent instructions |
| Calming Toolkit | 7 strategies to use when child is dysregulated (tantrum, spinning, throwing) — with exact how-to and time |
| Alerting Toolkit | 6 strategies to use when child is under-aroused/zoned out |
| Mealtime Sensory Strategies | Food chaining, oral motor prep, texture progression, positioning, reinforcement — 9 specific strategies |
| Sleep Preparation Routine | Step-by-step 8-point bedtime sensory sequence |
| Parent Observation Log | 7-day fillable table to track activities, child response, and behaviour — to bring to OT sessions |
| Important Reminders | 8 parent guidelines (over-arousal signs, brushing caution, no-forcing rule, when to call OT) |
| Equipment List | 12 items with purpose and priority (HIGH/MEDIUM/LOW) colour-coded |
| Signatures + Review Block | Next review date, OT signature, parent signature |
so this is the referenc i give you to cross check with my standards and make pragathesh assessement better than this
python3 -c " from pypdf import PdfReader import os path = '/tmp/workspace/attachments/e660c947-b27a-4105-9e4e-9a6f5a85ab79/A4 Sarvesh OT assessment.pdf' reader = PdfReader(path) print(f'Pages: {len(reader.pages)}') for i, page in enumerate(reader.pages): images = page.images print(f'Page {i+1}: {len(images)} images') for j, img in enumerate(images): ext = img.name.split('.')[-1] if '.' in img.name else 'png' fname = f'/tmp/workspace/sarvesh_p{i+1}_img{j+1}.{ext}' with open(fname, 'wb') as f: f.write(img.data) print(f' Saved: {fname} ({len(img.data)} bytes)') text = page.extract_text() if text and text.strip(): print(f' Text: {text[:200]}') "
python3 -c " from pypdf import PdfReader path = '/tmp/workspace/attachments/e660c947-b27a-4105-9e4e-9a6f5a85ab79/A4 Sarvesh OT assessment.pdf' reader = PdfReader(path) for i, page in enumerate(reader.pages): text = page.extract_text() print(f'======= PAGE {i+1} =======') print(text) print() " 2>&1
python3 << 'PYEOF' from docx import Document from docx.shared import Pt, Inches, RGBColor, Cm from docx.enum.text import WD_ALIGN_PARAGRAPH from docx.oxml.ns import qn from docx.oxml import OxmlElement doc = Document() for section in doc.sections: section.top_margin = Cm(2.0) section.bottom_margin = Cm(2.0) section.left_margin = Cm(2.5) section.right_margin = Cm(2.5) ns = doc.styles['Normal'] ns.font.name = 'Times New Roman' ns.font.size = Pt(12) # ─── helpers ────────────────────────────────────────────────────────────────── def set_cell_bg(cell, hex_color): tc = cell._tc tcPr = 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_color) tcPr.append(shd) def remove_all_borders(table): tbl = table._tbl tblPr = tbl.find(qn('w:tblPr')) if tblPr is None: tblPr = OxmlElement('w:tblPr') tbl.insert(0, tblPr) tblBorders = OxmlElement('w:tblBorders') for bn in ['top','left','bottom','right','insideH','insideV']: b = OxmlElement(f'w:{bn}') b.set(qn('w:val'), 'none') tblBorders.append(b) tblPr.append(tblBorders) def remove_cell_borders(cell): tc = cell._tc tcPr = tc.get_or_add_tcPr() tcBorders = OxmlElement('w:tcBorders') for bn in ['top','left','bottom','right']: b = OxmlElement(f'w:{bn}') b.set(qn('w:val'), 'none') tcBorders.append(b) tcPr.append(tcBorders) def section_num_heading(doc, number, title): """Bold numbered section heading like 'I. Demographic data :'""" p = doc.add_paragraph() p.paragraph_format.space_before = Pt(10) p.paragraph_format.space_after = Pt(2) r = p.add_run(f'{number}. {title}') r.bold = True r.font.size = Pt(12) r.font.name = 'Times New Roman' return p def add_bullet(doc, text, bold_prefix=None): p = doc.add_paragraph(style='List Bullet') p.paragraph_format.space_after = Pt(1) if bold_prefix: rb = p.add_run(f'{bold_prefix} ') rb.bold = True rb.font.size = Pt(12) rb.font.name = 'Times New Roman' r = p.add_run(text) r.font.size = Pt(12) r.font.name = 'Times New Roman' return p def para(doc, text, bold=False, italic=False, size=12, space_after=4): p = doc.add_paragraph() p.paragraph_format.space_after = Pt(space_after) r = p.add_run(text) r.bold = bold r.italic = italic r.font.size = Pt(size) r.font.name = 'Times New Roman' return p def inline(doc, label, value, space_after=4): """'Label: value' paragraph with bold label.""" p = doc.add_paragraph() p.paragraph_format.space_after = Pt(space_after) rb = p.add_run(f'{label}: ') rb.bold = True rb.font.size = Pt(12) rb.font.name = 'Times New Roman' rv = p.add_run(value) rv.font.size = Pt(12) rv.font.name = 'Times New Roman' return p def sub_heading(doc, text): """Bold sub-section heading like 'Cognition:' or 'Perception:'""" p = doc.add_paragraph() p.paragraph_format.space_before = Pt(4) p.paragraph_format.space_after = Pt(2) r = p.add_run(text) r.bold = True r.underline = True r.font.size = Pt(12) r.font.name = 'Times New Roman' return p def roman_item(doc, roman, label, text): """'i. Label: text'""" p = doc.add_paragraph() p.paragraph_format.left_indent = Inches(0.25) p.paragraph_format.space_after = Pt(2) rb = p.add_run(f'{roman}. {label}: ') rb.bold = True rb.font.size = Pt(12) rb.font.name = 'Times New Roman' rv = p.add_run(text) rv.font.size = Pt(12) rv.font.name = 'Times New Roman' return p # ══════════════════════════════════════════════════════════════════════════════ # TITLE # ══════════════════════════════════════════════════════════════════════════════ tp = doc.add_paragraph() tp.alignment = WD_ALIGN_PARAGRAPH.CENTER tp.paragraph_format.space_after = Pt(8) tr = tp.add_run('OCCUPATIONAL THERAPY ASSESSMENT') tr.bold = True tr.font.size = Pt(14) tr.font.name = 'Times New Roman' # ══════════════════════════════════════════════════════════════════════════════ # I. DEMOGRAPHIC DATA # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'I', 'Demographic data :') demo_tbl = doc.add_table(rows=4, cols=4) demo_tbl.style = 'Table Grid' remove_all_borders(demo_tbl) demo_data = [ [('Name:', 'Pragadesh J'), ('D.O.B:', '07/10/2022')], [('Age:', '3 years 9 months'), ('Date:', '07/07/2026')], [('Gender:', 'Male'), ('Informant:', 'Both Parents')], [("Mother's name:", 'Shobana'), ("Father's name:", 'Jonathan')], ] for r_idx, row_data in enumerate(demo_data): row = demo_tbl.rows[r_idx] for c_idx, (lbl, val) in enumerate(row_data): lc = row.cells[c_idx*2] vc = row.cells[c_idx*2+1] remove_cell_borders(lc); remove_cell_borders(vc) lp = lc.paragraphs[0] lp.paragraph_format.space_after = Pt(2) rl = lp.add_run(lbl) rl.bold = True; rl.font.size = Pt(12); rl.font.name = 'Times New Roman' vp = vc.paragraphs[0] vp.paragraph_format.space_after = Pt(2) rv = vp.add_run(val) rv.font.size = Pt(12); rv.font.name = 'Times New Roman' doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # II. CHIEF COMPLAINTS # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'II', 'Chief Complaints:') para(doc, "According to the parents, Pragadesh demonstrates absent verbal communication with no functional " "speech for his age. He shows inconsistent response to his name and limited eye contact during " "interactions. He exhibits marked difficulty engaging with peers and avoids social interaction outside " "the immediate family. Toy arrangement and object lining behaviour is prominent. Feeding difficulties " "are present, including restricted food variety and refusal of hand-fed food. The child exhibits " "running and spinning behaviours and deep proprioceptive seeking. Screen dependence has been " "reported as a facilitator for feeding. Parents also report behavioural concerns including anger " "outbursts when needs are unmet.") # ══════════════════════════════════════════════════════════════════════════════ # III. FELT NEEDS # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'III', 'Felt needs:') felt_needs = [ 'Child should begin to speak and communicate functionally', 'Improve eye contact and social engagement', 'Reduce running, spinning, and object-lining behaviours', 'Accept a variety of foods and improve mealtime independence', 'Child should be ready for school', 'Reduce anger outbursts and improve emotional regulation', 'Improve self-care and ADL independence', ] for n in felt_needs: add_bullet(doc, n) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # IV. ON OBSERVATION # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'IV', 'On Observation :') para(doc, "Pragadesh demonstrated the ability to walk, run, and navigate familiar environments independently. " "He exhibited fleeting eye contact and inconsistent response to his name when called. Marked " "stranger anxiety was observed and he avoided physical contact with unfamiliar individuals. " "His attention span was short and he was easily distracted during structured activities. The child " "showed strong preference for visually stimulating and proprioceptively gratifying activities such as " "spinning objects, running, and deep sitting. He demonstrated object-lining behaviour and spinning " "of non-toy objects. He was not observed to respond to verbal questions or follow multi-step " "commands during the session. Non-verbal communication through leading the caregiver by hand and " "proximity-seeking with familiar adults was noted. Drooling, which was previously present, has " "reportedly stopped recently. Lateral head tilt with compensatory visual tracking to the left was " "observed, and hand dominance is established on the left.") doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # V. PHYSICAL EXAMINATION # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'V', 'Physical Examination') phys_items = [ ('Build', 'Well built and nourished'), ('Limb Posture', 'Symmetrical with normal limb attitude'), ('Muscle Tone', 'Within functional limits; mild hypotonia not ruled out clinically'), ('Visible Deformities', 'Nil'), ('Assistive Devices', 'Nil'), ('Gait', 'Independent functional gait pattern; runs well'), ] for label, val in phys_items: inline(doc, label, val, space_after=2) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # VI. HISTORY # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'VI', 'History:') p = doc.add_paragraph() p.paragraph_format.space_after = Pt(2) rb = p.add_run('i. Pre-natal: ') rb.bold = True; rb.font.size = Pt(12); rb.font.name = 'Times New Roman' rv = p.add_run( 'Abnormal. Mother is G4P4 (4th pregnancy). Consanguineous marriage. ' 'Delayed onset of pregnancy-related symptoms reported. No specific teratogenic exposure documented.') rv.font.size = Pt(12); rv.font.name = 'Times New Roman' p = doc.add_paragraph() p.paragraph_format.space_after = Pt(2) rb = p.add_run('ii. Natal: ') rb.bold = True; rb.font.size = Pt(12); rb.font.name = 'Times New Roman' rv = p.add_run('Spitting reported during pregnancy. Mode of delivery not specified by informant.') rv.font.size = Pt(12); rv.font.name = 'Times New Roman' p = doc.add_paragraph() p.paragraph_format.space_after = Pt(2) rb = p.add_run('iii. Post-natal: ') rb.bold = True; rb.font.size = Pt(12); rb.font.name = 'Times New Roman' rv = p.add_run( 'Delayed cry at birth. NICU admission recorded. Neonatal jaundice treated with phototherapy ' '(bili-lights). No history of seizures reported. Developmental delays were observed across ' 'multiple developmental domains from early infancy.') rv.font.size = Pt(12); rv.font.name = 'Times New Roman' doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # VII. FAMILY HISTORY # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'VII', 'Family history:') para(doc, "Pragadesh belongs to a family with consanguineous parentage. He is the fourth child in the family. " "No known family history of neurodevelopmental or genetic conditions has been reported by the " "parents. Both parents are involved in caregiving and report concern regarding the child's " "behavioural and communication development.") doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # VIII. DEVELOPMENTAL HISTORY # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'VIII', 'Developmental history:') para(doc, "All gross motor milestones were achieved with delayed timelines across developmental domains, " "approximately 2 months behind the expected age. Head control, neck control, rolling, and " "sitting were all delayed. Deep sitting posture with proprioceptive seeking is noted. " "Kneeling is present. Child is currently ambulatory — walking, running, and climbing are achieved.") doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # IX. CPSE # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'IX', 'CPSE (Cognitive, Perception, Social – Emotional)') sub_heading(doc, 'Cognition:') roman_item(doc, 'i', 'Attention', 'Attention span is limited and the child is easily distracted during both structured and unstructured ' 'activities. Unable to sustain engagement in tabletop tasks. Brief engagement observed with preferred ' 'sensory activities only.') roman_item(doc, 'ii', 'Orientation', 'Partially oriented to the therapy environment. Recognises familiar caregivers and responds to them selectively.') roman_item(doc, 'iii', 'Memory', 'Recognises familiar family members and preferred objects/routines. Rote memory emerging; ' 'contextual use of memory is limited.') roman_item(doc, 'iv', 'Comprehension', 'Understands simple 1-step commands inconsistently and requires gestural prompts and repetition ' '(e.g., "sit down", "come here"). Does not follow 2-step commands at present.') sub_heading(doc, 'Perception:') roman_item(doc, 'i', 'Body part identification', 'Not reliably demonstrated. Does not point to body parts on command without significant prompting.') roman_item(doc, 'ii', 'Identification of concepts', 'Basic concepts (colour, shape, size) are not reliably identified at this time.') roman_item(doc, 'iii', 'R/Lt discrimination', 'Not developed; not applicable at current developmental level.') roman_item(doc, 'iv', 'Visual-Motor Integration', 'Emerging. Demonstrates difficulty sustaining engagement in structured fine motor tasks. ' 'Formal assessment (Beery VMI) recommended.') roman_item(doc, 'v', 'Visual perceptual skills', 'Functional visual tracking noted with lateral left preference. Figure-ground and form constancy ' 'to be evaluated formally.') sub_heading(doc, 'Social:') roman_item(doc, 'i', 'Social interaction', 'Limited. The child interacts only with primary caregivers and avoids unfamiliar individuals. ' 'Stranger anxiety is prominent.') roman_item(doc, 'ii', 'Peer interaction', 'Absent. Engages in solitary play and does not demonstrate parallel or associative play with peers.') roman_item(doc, 'iii', 'Engages in socially acceptable behaviour', 'Limited. Demonstrates difficulty regulating behaviour; anger outbursts are expressed through ' 'crying, throwing objects, and physical aggression toward caregivers when needs are unmet.') roman_item(doc, 'iv', 'Response to social smile', 'Familial smile present; social referencing and reciprocal smiling with unfamiliar persons is absent.') roman_item(doc, 'v', 'Problem solving', 'Fair — trial-and-error approach observed for preferred tasks.') roman_item(doc, 'vi', 'Decision making', 'Fair for preferred items and familiar activities.') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # X. EMOTIONAL # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'X', 'Emotional:') para(doc, "Situation-appropriate emotions: Inconsistent. Pragadesh demonstrates anger outbursts when " "demands are not met or routines are disrupted. He displays difficulty with emotional regulation " "and becomes highly distressed during non-preferred activities or when preferred items are " "removed. Repetitive behaviours including lining objects, spinning, and running are prominent. " "Imitation of actions is emerging with direct modelling.") doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # XI. COMMUNICATION # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'XI', 'Communication:') p = doc.add_paragraph() p.paragraph_format.space_after = Pt(3) rb = p.add_run('Verbal: ') rb.bold = True; rb.font.size = Pt(12); rb.font.name = 'Times New Roman' rv = p.add_run( 'Speech and language development are significantly delayed. No functional verbal output is present. ' 'Occasional non-meaningful vocalisations are noted. No words or approximations observed during session.') rv.font.size = Pt(12); rv.font.name = 'Times New Roman' p = doc.add_paragraph() p.paragraph_format.space_after = Pt(3) rb = p.add_run('Non-Verbal: ') rb.bold = True; rb.font.size = Pt(12); rb.font.name = 'Times New Roman' rv = p.add_run( 'Primarily communicates through leading caregiver by hand, reaching, proximity-seeking, ' 'and facial expressions to express basic needs and wants. No consistent use of gestures ' '(pointing, waving) at present.') rv.font.size = Pt(12); rv.font.name = 'Times New Roman' doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # XII. HAND FUNCTIONS # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'XII', 'Hand functions:') inline(doc, 'Hand Dominance', 'Left hand dominance established') inline(doc, 'Reach', 'Present in all directions; functional reach observed') inline(doc, 'Grasp', 'Able to hold and manipulate age-appropriate toys and objects; palmer grasp predominant; pincer grasp emerging') inline(doc, 'Release', 'Present') inline(doc, 'In-Hand Manipulation', 'Emerging; formal grading to be completed on repeat assessment') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # XIII. COORDINATION # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'XIII', 'Coordination:') roman_item(doc, 'i', 'Eye-hand', 'Present. Functional eye-hand coordination noted; lateral visual tracking with left preference observed.') roman_item(doc, 'ii', 'Bilateral', 'Present. Emerging bilateral coordination requiring further structured development.') p = doc.add_paragraph() p.paragraph_format.space_before = Pt(4) p.paragraph_format.space_after = Pt(2) rb = p.add_run('Balance:') rb.bold = True; rb.font.size = Pt(12); rb.font.name = 'Times New Roman' roman_item(doc, '', 'Static', 'Age-appropriate') roman_item(doc, '', 'Dynamic', 'Age-appropriate; able to run and navigate varied terrain') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # XIV. ORO-MOTOR CONTROL # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'XIV', 'Oro-motor control:') para(doc, "On Observation — Drooling: Previously present; reported to have stopped recently. " "Oral motor control is improving. The child is able to chew, munch, and bite food appropriately " "for familiar textures. Selective eating and refusal of novel textures are noted. " "Drinks from a tumbler with caregiver assistance; straw drinking not yet established.") doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # XV. ADL SKILLS # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'XV', 'ADL skills:') adl_items = [ ('i', 'Feeding / Eating', 'WeeFIM Level 3 – Moderate Assistance', 'Finger feeding is achieved. Spoon feeding is refused. Hand feeding by caregiver is resisted. ' 'Selective intake with restricted food variety. Screen dependence reported during mealtimes.'), ('ii', 'Bathing', 'WeeFIM Level 1 – Total Assistance', 'Requires complete caregiver assistance for all bathing activities.'), ('iii', 'Dressing', 'WeeFIM Level 2 – Maximal Assistance', 'Participates minimally; uncooperative with dressing routine; requires substantial caregiver assistance.'), ('iv', 'Grooming', 'WeeFIM Level 1 – Total Assistance', 'Dependent for all grooming. Demonstrates resistance to hair combing, nail cutting, and face washing.'), ('v', 'Toileting (Indication)', 'WeeFIM Level 1 – Total Assistance', 'Not toilet trained. Does not consistently indicate toileting needs. Requires complete caregiver assistance for all toileting routines.'), ] for roman, title, level, detail in adl_items: p = doc.add_paragraph() p.paragraph_format.left_indent = Inches(0.0) p.paragraph_format.space_after = Pt(1) rb = p.add_run(f'({roman}) {title}:') rb.bold = True; rb.font.size = Pt(12); rb.font.name = 'Times New Roman' p2 = doc.add_paragraph() p2.paragraph_format.left_indent = Inches(0.25) p2.paragraph_format.space_after = Pt(4) rl = p2.add_run(f'{level} – ') rl.bold = True; rl.font.size = Pt(12); rl.font.name = 'Times New Roman' rv = p2.add_run(detail) rv.font.size = Pt(12); rv.font.name = 'Times New Roman' doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # XVI. PLAY # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'XVI', 'Play:') para(doc, "Sensorimotor / early pre-operational stage of play (Piaget's classification — below chronological " "age expectation). Engages primarily in solitary play (Takata's classification) with restricted " "and repetitive patterns — object lining, spinning, and sensory exploration. Does not engage in " "functional or symbolic play. Preferred play items include spinning objects, running/chasing, " "and deep proprioceptive activities. Enjoys water-based activities and visual stimuli.") doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # XVII. BALL SKILLS # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'XVII', 'Ball Skills:') for skill, status in [('Throwing', 'Achieved'), ('Catching', 'Not achieved'), ('Kicking', 'Not achieved')]: add_bullet(doc, status, bold_prefix=f'{skill} –') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # XVIII. SENSORY ISSUES # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'XVIII', 'Sensory issues:') sensory_bullets = [ 'Proprioceptive seeking — deep sitting, crashing into furniture, seeks firm body pressure; hyposensitive pattern.', 'Vestibular seeking — running aimlessly, spinning self and objects; hyposensitive pattern.', 'Tactile defensiveness toward hand-feeding, novel textures, and unexpected touch.', 'Oral sensory difficulties — food selectivity, aversion to new textures and flavours, previously mouthed objects.', 'Visual seeking and fixation — stares at spinning/bright objects, lateral visual tracking preference, object lining.', 'Auditory hyposensitivity — does not consistently respond to name; tolerates loud environmental sounds.', ] for b in sensory_bullets: add_bullet(doc, b) # Behaviour patterns p = doc.add_paragraph() p.paragraph_format.space_before = Pt(6) p.paragraph_format.space_after = Pt(2) rb = p.add_run('Behaviour Patterns:') rb.bold = True; rb.underline = True; rb.font.size = Pt(12); rb.font.name = 'Times New Roman' p = doc.add_paragraph() p.paragraph_format.space_after = Pt(2) rb = p.add_run('Likes: ') rb.bold = True; rb.font.size = Pt(12); rb.font.name = 'Times New Roman' rv = p.add_run( 'Spinning objects, running in open space, water play, deep-pressure activities, visual stimuli ' '(fans/spinning), preferred foods (rice, idli, biscuits, dry snacks).') rv.font.size = Pt(12); rv.font.name = 'Times New Roman' p = doc.add_paragraph() p.paragraph_format.space_after = Pt(2) rb = p.add_run('Dislikes / Averse to: ') rb.bold = True; rb.font.size = Pt(12); rb.font.name = 'Times New Roman' rv = p.add_run( 'Hand-feeding by others, new food textures, unfamiliar persons, being redirected from preferred activities, ' 'unexpected touch, structured sitting tasks.') rv.font.size = Pt(12); rv.font.name = 'Times New Roman' p = doc.add_paragraph() p.paragraph_format.space_after = Pt(2) rb = p.add_run('Maladaptive Behaviours: ') rb.bold = True; rb.font.size = Pt(12); rb.font.name = 'Times New Roman' rv = p.add_run( 'Self-stimulatory / stereotypical — spinning objects, object lining, running aimlessly; ' 'anger-related — throwing objects, crying, physical aggression toward caregivers when demands are unmet.') rv.font.size = Pt(12); rv.font.name = 'Times New Roman' doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # XIX. TOOLS USED # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'XIX', 'Tools used:') tools = [ 'ISAA (Indian Scale for Assessment of Autism) – to assist in identifying ASD-related features', 'WeeFIM (Functional Independence Measure for Children) – to assess ADL performance', 'Short Sensory Profile (SSP) – to identify sensory processing difficulties', 'Clinical observation – structured OT assessment session', 'Developmental history (parent/informant interview)', ] for t in tools: add_bullet(doc, t) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # XX. PROBLEMS IDENTIFIED # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'XX', 'Problems identified:') problems = [ 'Absent functional verbal communication and severely delayed speech and language.', 'Inconsistent response to name calling and limited eye contact during social interaction.', 'Difficulty expressing needs and wants through appropriate verbal or non-verbal communication.', 'Limited imitation skills affecting learning and social participation.', 'Sensory processing difficulties involving proprioceptive, vestibular, tactile, oral, visual, and auditory systems.', 'Behavioural concerns including object lining, spinning, running, and anger outbursts.', 'Poor emotional regulation and low frustration tolerance.', 'Limited social interaction, absent peer engagement, and poor joint attention.', 'Feeding difficulties and significant food selectivity.', 'Delayed self-care and ADL skills — fully dependent across all domains.', 'Reduced tolerance for grooming activities.', 'Poor and inconsistent toileting indication; not toilet trained.', 'Play skill delay — restricted and repetitive play patterns below chronological age.', 'Lateral head tilt and compensatory left visual tracking — requires further clinical evaluation.', 'Excessive screen dependence during mealtimes.', ] for prob in problems: add_bullet(doc, prob) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # XXI. SHORT TERM GOALS # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'XXI', 'Short term goals:') stg = [ 'To respond to his name in at least 7 out of 10 opportunities with minimal prompting within 6 weeks.', 'To maintain eye contact for 3–5 seconds during structured interaction in 6 out of 10 trials within 6 weeks.', 'To follow a 1-step verbal command (without gestural cue) consistently in 4 out of 5 trials within 6 weeks.', 'To participate in seated tabletop activities for at least 3 minutes with minimal redirection within 6 weeks.', 'To reduce spinning and object-lining behaviours by engaging in 2–3 directed sensory-regulating activities during episodes, within 6 weeks.', 'To tolerate a minimum of 2 new food textures placed on the plate (without forcing intake) within 6 weeks.', 'To perform oro-motor exercises (blowing, lip closure) with prompts to reinforce oral motor control within 6 weeks.', 'To hold a spoon and attempt self-feeding in 3 out of 5 trials within 6 weeks.', 'To demonstrate 1 new functional gesture (pointing or waving "bye") spontaneously in 4 out of 5 opportunities within 6 weeks.', 'To respond to 2–3 social greetings (wave hi, bye, hi-five) with prompts in 4 out of 5 trials within 6 weeks.', ] for g in stg: add_bullet(doc, g) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # XXII. LONG TERM GOALS # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'XXII', 'Long term goals:') ltg = [ 'Demonstrate measurable improvement in cognitive, perceptual, social, and emotional (CPSE) skills — including attention, social engagement, imitation, and concept learning — on repeat developmental assessment within 6 months.', 'Use at least 10–15 functional words and/or meaningful gestures spontaneously to communicate needs, wants, and basic ideas during daily activities within 6 months.', 'Demonstrate reduced sensory processing difficulties enabling participation in daily routines including grooming, dressing, feeding, and community outings with minimal distress within 6 months.', 'Achieve daytime toilet-training readiness and consistent toileting indication with reduced dependence on diapers.', 'Tolerate grooming activities including hair combing, hair washing, nail cutting, and dressing routines with minimal resistance across home environments.', 'Demonstrate improved behavioural and emotional regulation with significant reduction in spinning, object-lining, running, and anger outbursts.', 'Engage in age-appropriate peer interaction, structured play, and turn-taking activities with minimal assistance.', 'Achieve independence in spoon self-feeding across all food types accepted.', 'Demonstrate readiness for preschool participation through improved communication, attention, sensory regulation, social interaction, and adaptive behaviour skills.', ] for g in ltg: add_bullet(doc, g) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # XXIII. APPROACHES USED # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'XXIII', 'Approaches used:') for approach in [ 'Sensory Integration (SI) — Ayres Sensory Integration Framework', 'Behavioural Frame of Reference', 'Acquisitional Frame of Reference', 'Neurodevelopmental Therapy (NDT)', 'CO-OP Approach', 'ADL Training', 'Play Therapy', 'Group Therapy', ]: add_bullet(doc, approach) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # XXIV. OT PLAN TABLE # ══════════════════════════════════════════════════════════════════════════════ section_num_heading(doc, 'XXIV', 'Occupational Therapy plan:') plan_headers = ['Approach', 'Goals', 'Techniques', 'Activities'] plan_rows = [ ('Sensory Integration', 'To improve sensory modulation; reduce proprioceptive, vestibular, and oral sensory-seeking behaviours', 'Structured sensory input, graded sensory exposure, sensory-rich play activities', 'Therapy ball bouncing, obstacle courses, tactile bins (rice/beans/sand), water play, weighted activities, joint compressions, proprioceptive heavy work'), ('Behavioural &\nSensory Regulation', 'To reduce spinning, object-lining, running, and anger outbursts; improve frustration tolerance', 'Positive reinforcement, shaping, visual schedules, first-then strategies, sensory calming techniques', 'Deep pressure activities, heavy work, calm corner activities, sensory breaks, bubble blowing, carrying objects, social stories'), ('Developmental &\nPlay-Based Approach', 'To improve attention, imitation, structured play participation, and social engagement', 'Modelling, imitation training, guided participation, play-based learning', 'Action songs, imitation games, cause-and-effect toys, turn-taking games, block play, ring stacking, functional play activities'), ('Motor Development\n(NDT & Play-Based)', 'To improve postural control, balance, bilateral coordination, and motor planning', 'Graded motor activities, balance training, task-specific practice', 'Obstacle courses, balance beam walking with support, animal walks, scooter board activities, therapy ball activities, climbing, step-up and step-down activities'), ('Oral-Motor &\nFeeding Intervention', 'To improve feeding participation, reduce food selectivity, increase tolerance to varied food textures', 'Oral sensory stimulation, food chaining, graded food exposure, caregiver training', 'Straw drinking activities, blowing bubbles, chewing activities, exposure to different food textures, self-feeding practice, sensory feeding play'), ('Acquisitional Frame\nof Reference', 'To improve grasp patterns, bilateral hand use, visual-motor skills, and fine motor development', 'Task analysis, graded practice, hand strengthening, guided practice', 'Peg activities, shape sorters, stacking blocks, inserting objects into containers, simple puzzles, scribbling, clay play, lacing activities'), ('ADL Training', 'To improve independence in feeding, dressing, grooming, and toileting readiness', 'Backward chaining, caregiver education, task simplification, graded assistance', 'Spoon-feeding practice, dressing practice, hand washing, grooming tolerance routines, toileting schedules, toileting indication training'), ('CO-OP & Cognitive\nDevelopment', 'To improve attention, concept learning, problem solving, and task completion', 'Verbal prompting, visual supports, guided discovery, structured play', 'Colour matching, shape sorting, object identification, simple matching games, sorting by size, picture matching, cause-and-effect activities'), ('Social Skills &\nPeer Interaction', 'To improve response to greetings, joint attention, parallel play, and social participation', 'Peer-mediated play, modelling, role play, social routines', 'Waving hi/bye, peek-a-boo, joint attention games, turn-taking activities, circle time participation, parallel play activities, nursery rhyme actions'), ('Parent Education &\nHome Programme', 'To promote carryover of therapeutic strategies across home environments', 'Demonstration, coaching, home programme training', 'Sensory diet activities, communication opportunities during routines, structured play schedules, behaviour management strategies, screen-time reduction programme'), ] plan_tbl = doc.add_table(rows=1, cols=4) plan_tbl.style = 'Table Grid' plan_tbl.allow_autofit = False hdr_row = plan_tbl.rows[0] for cell, txt in zip(hdr_row.cells, plan_headers): set_cell_bg(cell, '1F497D') p_ = cell.paragraphs[0] r_ = p_.add_run(txt) r_.bold = True r_.font.size = Pt(11) r_.font.name = 'Times New Roman' r_.font.color.rgb = RGBColor.from_string('FFFFFF') for i, (approach, goal, tech, act) in enumerate(plan_rows): row = plan_tbl.add_row() for cell, txt in zip(row.cells, [approach, goal, tech, act]): p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(2) p_.paragraph_format.space_after = Pt(2) r_ = p_.add_run(txt) r_.font.size = Pt(10.5) r_.font.name = 'Times New Roman' if i % 2 == 1: for cell in row.cells: set_cell_bg(cell, 'F2F7FC') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # SESSION PLAN # ══════════════════════════════════════════════════════════════════════════════ p = doc.add_paragraph() p.paragraph_format.space_before = Pt(6) p.paragraph_format.space_after = Pt(3) rb = p.add_run('SESSION PLAN') rb.bold = True; rb.font.size = Pt(12); rb.font.name = 'Times New Roman' sess_tbl = doc.add_table(rows=1, cols=2) sess_tbl.style = 'Table Grid' sess_tbl.allow_autofit = False for cell, txt in zip(sess_tbl.row_cells(0), ['Time', 'Goal Targeted']): set_cell_bg(cell, '1F497D') p_ = cell.paragraphs[0] r_ = p_.add_run(txt) r_.bold = True; r_.font.size = Pt(11); r_.font.name = 'Times New Roman' r_.font.color.rgb = RGBColor.from_string('FFFFFF') session_blocks = [ ('0–5 mins', 'Sensory regulation warm-up, transition into therapy, sitting tolerance, rapport building'), ('5–15 mins', 'Response to name, eye contact, imitation of simple actions, joint attention activities'), ('15–25 mins', 'Body part identification, colour matching, shape sorting, simple concept learning (big/small, same/different)'), ('25–30 mins', 'Sensory break — deep pressure, heavy work, movement-based regulation activities'), ('30–40 mins', 'Fine motor and visual-motor skills — stacking blocks, ring stacking, peg activities, scribbling, container play'), ('40–45 mins', 'ADL training — spoon-feeding practice, dressing participation, grooming tolerance, toileting readiness activities'), ('45–50 mins', 'Social interaction, turn-taking, waving hi/bye, reinforcement of achieved goals, calming activities, parent feedback'), ] for i, (time, goal) in enumerate(session_blocks): row = sess_tbl.add_row() for cell, txt in zip(row.cells, [time, goal]): p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(2) p_.paragraph_format.space_after = Pt(2) r_ = p_.add_run(txt) r_.font.size = Pt(11); r_.font.name = 'Times New Roman' if i % 2 == 1: for cell in row.cells: set_cell_bg(cell, 'F2F7FC') doc.add_paragraph().paragraph_format.space_after = Pt(4) # ══════════════════════════════════════════════════════════════════════════════ # HOME PROGRAM PLAN # ══════════════════════════════════════════════════════════════════════════════ p = doc.add_paragraph() p.paragraph_format.space_before = Pt(6) p.paragraph_format.space_after = Pt(3) rb = p.add_run('HOME PROGRAM PLAN') rb.bold = True; rb.font.size = Pt(12); rb.font.name = 'Times New Roman' home_tbl = doc.add_table(rows=1, cols=2) home_tbl.style = 'Table Grid' home_tbl.allow_autofit = False for cell, txt in zip(home_tbl.row_cells(0), ['Area', 'Activities']): set_cell_bg(cell, '1F497D') p_ = cell.paragraphs[0] r_ = p_.add_run(txt) r_.bold = True; r_.font.size = Pt(11); r_.font.name = 'Times New Roman' r_.font.color.rgb = RGBColor.from_string('FFFFFF') home_items = [ ('ADL Practice', 'Encourage spoon self-feeding at every meal. Practice pulling pants up/down. ' 'Structured hand washing routine. Gradually reduce screen time during meals.'), ('School Readiness', 'Colouring with thick crayons, matching colours and shapes, simple tracing on dotted lines, ' 'sorting objects by colour or size.'), ('Socialization', 'Play peek-a-boo and ball with siblings. Practice greetings (hi/bye, hi-five). ' 'Picture book naming. Joint attention routines during daily activities.'), ('Motor Skills', 'Ball play (rolling, throwing), climbing stairs with support, animal walks, ' 'obstacle course with cushions, 10-min outdoor play daily.'), ('Sensory Regulation', 'Follow home sensory diet: joint compressions before meals, heavy work activities (carry bag, ' 'push trolley), oral motor warm-up before mealtimes, deep pressure massage before bed.'), ('Emotional Regulation', 'Calming strategies: firm hug, squeeze pillow, soft music during distress. ' 'Praise appropriate behaviour immediately. Visual schedule to improve routine predictability.'), ('Communication', 'Use simple 1-step commands with gestures. Narrate daily activities. ' 'Encourage pointing and reaching before handing over preferred items. ' 'Introduce 2–3 picture cards for basic needs.'), ] for i, (area, activities) in enumerate(home_items): row = home_tbl.add_row() lc = row.cells[0] vc = row.cells[1] lp = lc.paragraphs[0] lp.paragraph_format.space_before = Pt(2) lp.paragraph_format.space_after = Pt(2) lr = lp.add_run(area) lr.bold = True; lr.font.size = Pt(11); lr.font.name = 'Times New Roman' vp = vc.paragraphs[0] vp.paragraph_format.space_before = Pt(2) vp.paragraph_format.space_after = Pt(2) vp.add_run(activities).font.size = Pt(11) vp.runs[-1].font.name = 'Times New Roman' if i % 2 == 1: for cell in row.cells: set_cell_bg(cell, 'F2F7FC') doc.add_paragraph() # ══════════════════════════════════════════════════════════════════════════════ # SIGNATURE BLOCK # ══════════════════════════════════════════════════════════════════════════════ p = doc.add_paragraph() p.alignment = WD_ALIGN_PARAGRAPH.RIGHT p.paragraph_format.space_before = Pt(20) r = p.add_run('_______________________________') r.font.size = Pt(12); r.font.name = 'Times New Roman' p = doc.add_paragraph() p.alignment = WD_ALIGN_PARAGRAPH.RIGHT r = p.add_run('OCCUPATIONAL THERAPIST') r.bold = True; r.font.size = Pt(12); r.font.name = 'Times New Roman' # SAVE out_path = '/tmp/workspace/ot-assessment/Pragadesh_OT_Assessment_FINAL.docx' doc.save(out_path) import os size = os.path.getsize(out_path) print(f"Saved: {out_path}") print(f"File size: {size/1024:.1f} KB") # Validate doc2 = Document(out_path) paras = [p.text for p in doc2.paragraphs if p.text.strip()] print(f"Total non-empty paragraphs: {len(paras)}") PYEOF
Pragadesh OT Assessment FINAL
Word Document · DOCX
| Element | Old Version | New (Sarvesh-standard) Version |
|---|---|---|
| Writing style | Tables and bullet lists throughout | Narrative prose paragraphs, exactly like Sarvesh |
| Section IV | Bullet observation list | Full observational paragraph with clinical detail |
| Section V | Absent | Added Physical Examination (Build, Tone, Posture, Gait, Assistive devices) |
| ADL scoring | "Full assistance" | WeeFIM levels (1–4) for each ADL — same as Sarvesh |
| Section XVII | Absent | Ball Skills added (Throwing / Catching / Kicking) |
| Sensory Issues | Table | Bullet list + Behaviour Patterns: Likes / Dislikes / Maladaptive — same format as Sarvesh |
| Tools Used | Generic checklist | ISAA + WeeFIM + Short Sensory Profile named explicitly |
| Goals | Vague / broad | SMART goals with trial counts, time frames, and measurability (6/10 trials, 6 weeks) |
| XXIV OT Plan | Bullet list | Full Approach → Goals → Techniques → Activities table (10 rows) |
| Session Plan | Absent | Added timed 50-min session plan (0–5, 5–15… 45–50 mins) |
| Home Program Plan | Absent | Added structured Home Program table (7 areas + activities) |
| Signature block | Basic | Right-aligned formal "Occupational Therapist" signature line |
Make a monthly progress tracking template for monitoring Pragadesh's development
python3 << 'PYEOF' from docx import Document from docx.shared import Pt, Inches, RGBColor, Cm from docx.enum.text import WD_ALIGN_PARAGRAPH from docx.oxml.ns import qn from docx.oxml import OxmlElement doc = Document() for section in doc.sections: section.top_margin = Cm(1.8) section.bottom_margin = Cm(1.8) section.left_margin = Cm(2.0) section.right_margin = Cm(2.0) ns = doc.styles['Normal'] ns.font.name = 'Times New Roman' ns.font.size = Pt(11) # ─── helpers ──────────────────────────────────────────────────────────────── def set_cell_bg(cell, hex_color): tc = cell._tc tcPr = 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_color) tcPr.append(shd) def remove_table_borders(table): tbl = table._tbl tblPr = tbl.find(qn('w:tblPr')) if tblPr is None: tblPr = OxmlElement('w:tblPr') tbl.insert(0, tblPr) tblBorders = OxmlElement('w:tblBorders') for bn in ['top','left','bottom','right','insideH','insideV']: b = OxmlElement(f'w:{bn}') b.set(qn('w:val'), 'none') tblBorders.append(b) tblPr.append(tblBorders) def remove_cell_borders(cell): tc = cell._tc tcPr = tc.get_or_add_tcPr() tcBorders = OxmlElement('w:tcBorders') for bn in ['top','left','bottom','right']: b = OxmlElement(f'w:{bn}') b.set(qn('w:val'), 'none') tcBorders.append(b) tcPr.append(tcBorders) def section_heading(doc, text, color='1F497D'): p = doc.add_paragraph() p.paragraph_format.space_before = Pt(10) p.paragraph_format.space_after = Pt(3) r = p.add_run(text) r.bold = True r.font.size = Pt(12) r.font.name = 'Times New Roman' r.font.color.rgb = RGBColor.from_string(color) pPr = p._p.get_or_add_pPr() pBdr = OxmlElement('w:pBdr') bot = OxmlElement('w:bottom') bot.set(qn('w:val'), 'single') bot.set(qn('w:sz'), '6') bot.set(qn('w:space'), '1') bot.set(qn('w:color'), color) pBdr.append(bot) pPr.append(pBdr) return p def hdr_row(table, headers, bg='1F497D', fg='FFFFFF', sizes=None): row = table.rows[0] for i, (cell, txt) in enumerate(zip(row.cells, headers)): set_cell_bg(cell, bg) p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(2) p_.paragraph_format.space_after = Pt(2) r_ = p_.add_run(txt) r_.bold = True r_.font.name = 'Times New Roman' r_.font.size = Pt(sizes[i] if sizes else 10) r_.font.color.rgb = RGBColor.from_string(fg) def data_row(table, values, alt=False, bold_first=False, font_size=10): row = table.add_row() for i, (cell, txt) in enumerate(zip(row.cells, values)): if alt: set_cell_bg(cell, 'F2F7FC') p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(2) p_.paragraph_format.space_after = Pt(2) r_ = p_.add_run(str(txt)) r_.font.name = 'Times New Roman' r_.font.size = Pt(font_size) if bold_first and i == 0: r_.bold = True return row def add_note_box(doc, text, bg='FFF9E6', border='F7A900'): t = doc.add_table(rows=1, cols=1) t.style = 'Table Grid' remove_table_borders(t) cell = t.cell(0,0) set_cell_bg(cell, bg) tc = cell._tc tcPr = tc.get_or_add_tcPr() tcBorders = OxmlElement('w:tcBorders') for bn in ['top','right','bottom']: b = OxmlElement(f'w:{bn}') b.set(qn('w:val'), 'none') tcBorders.append(b) lb = OxmlElement('w:left') lb.set(qn('w:val'), 'single') lb.set(qn('w:sz'), '18') lb.set(qn('w:color'), border) tcBorders.append(lb) tcPr.append(tcBorders) p = cell.paragraphs[0] p.paragraph_format.left_indent = Pt(6) p.paragraph_format.space_before = Pt(3) p.paragraph_format.space_after = Pt(3) r = p.add_run(text) r.font.size = Pt(10) r.font.name = 'Times New Roman' r.font.color.rgb = RGBColor.from_string('4A3700') doc.add_paragraph().paragraph_format.space_after = Pt(2) def blank_rows(table, n, cols, alt_start=0, font_size=10, row_height_lines=2): for i in range(n): row = table.add_row() if (i + alt_start) % 2 == 1: for cell in row.cells: set_cell_bg(cell, 'F9FAFB') for cell in row.cells: p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(row_height_lines * 3) p_.paragraph_format.space_after = Pt(row_height_lines * 3) p_.add_run('').font.size = Pt(font_size) # ════════════════════════════════════════════════════════════════════════════ # TITLE BLOCK # ════════════════════════════════════════════════════════════════════════════ tp = doc.add_paragraph() tp.alignment = WD_ALIGN_PARAGRAPH.CENTER tp.paragraph_format.space_after = Pt(0) tr = tp.add_run('MONTHLY PROGRESS TRACKING TEMPLATE') tr.bold = True; tr.font.size = Pt(15); tr.font.name = 'Times New Roman' tr.font.color.rgb = RGBColor.from_string('1F497D') sp = doc.add_paragraph() sp.alignment = WD_ALIGN_PARAGRAPH.CENTER sp.paragraph_format.space_after = Pt(6) sr = sp.add_run('Paediatric Occupational Therapy | Circle Time / Rhythms') sr.italic = True; sr.font.size = Pt(10); sr.font.name = 'Times New Roman' sr.font.color.rgb = RGBColor.from_string('808080') # Client strip cs = doc.add_table(rows=2, cols=4) cs.style = 'Table Grid' remove_table_borders(cs) cs_data = [ [('Child:', 'Pragadesh J'), ('Age:', '3 y 9 m'), ('D.O.A:', '12/10/2023'), ('Diagnosis:', 'GDD / ? ASD')], [('Month / Year:', '________________'), ('Session Count:', '______'), ('Therapist:', '________________'), ('Review Date:', '________________')], ] for r_idx, row_data in enumerate(cs_data): row = cs.rows[r_idx] for c_idx, (lbl, val) in enumerate(row_data): cell = row.cells[c_idx] set_cell_bg(cell, 'EBF3FB') remove_cell_borders(cell) p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(3) p_.paragraph_format.space_after = Pt(3) rb = p_.add_run(f'{lbl} ') rb.bold = True; rb.font.size = Pt(10); rb.font.name = 'Times New Roman' rv = p_.add_run(val) rv.font.size = Pt(10); rv.font.name = 'Times New Roman' doc.add_paragraph().paragraph_format.space_after = Pt(4) # Rating key box add_note_box(doc, 'RATING SCALE (use consistently across all sections):\n' '4 = Achieved independently and consistently | 3 = Achieved with minimal prompting\n' '2 = Emerging — inconsistent or requires moderate prompting | 1 = Not yet demonstrated\n' 'N/A = Not applicable this month | ↑ = Progress from last month | ↓ = Regression noted', bg='EBF3FB', border='1F497D') # ════════════════════════════════════════════════════════════════════════════ # A. COMMUNICATION & LANGUAGE # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'A. COMMUNICATION & LANGUAGE') comm_tbl = doc.add_table(rows=1, cols=5) comm_tbl.style = 'Table Grid' comm_tbl.allow_autofit = False hdr_row(comm_tbl, ['Skill / Goal', 'Baseline\n(Month 0)', 'Month 1', 'Month 2', 'Month 3'], sizes=[10,10,10,10,10]) comm_skills = [ ('Responds to own name (7/10 trials)', '0/10', '', '', ''), ('Maintains eye contact 3–5 sec (6/10 trials)', '0/10', '', '', ''), ('Follows 1-step command without gesture (4/5 trials)', '0/5', '', '', ''), ('Uses pointing gesture spontaneously', '1', '', '', ''), ('Uses waving gesture (hi/bye) with prompts (4/5)', '0/5', '', '', ''), ('Functional verbal output (no. of words)', '0', '', '', ''), ('Non-verbal communication (leading/reaching)', '2', '', '', ''), ('Responds to 2-step command', '0/5', '', '', ''), ('Imitates actions / sounds on modelling', '1', '', '', ''), ('Picture card communication (AAC / PECS)', 'Not started', '', '', ''), ] for i, row_vals in enumerate(comm_skills): data_row(comm_tbl, row_vals, alt=(i%2==1), bold_first=True) doc.add_paragraph().paragraph_format.space_after = Pt(3) p = doc.add_paragraph() rb = p.add_run('Comments / Observations: ') rb.bold = True; rb.font.size = Pt(10); rb.font.name = 'Times New Roman' p.add_run('_' * 80).font.size = Pt(10) p2 = doc.add_paragraph() p2.add_run('_' * 110).font.size = Pt(10) # ════════════════════════════════════════════════════════════════════════════ # B. SOCIAL & EMOTIONAL # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'B. SOCIAL & EMOTIONAL') soc_tbl = doc.add_table(rows=1, cols=5) soc_tbl.style = 'Table Grid' soc_tbl.allow_autofit = False hdr_row(soc_tbl, ['Skill / Goal', 'Baseline\n(Month 0)', 'Month 1', 'Month 2', 'Month 3']) soc_skills = [ ('Social smile with familiar persons', '2', '', '', ''), ('Social smile with unfamiliar persons', '1', '', '', ''), ('Responds to social greetings (wave/hi-five)', '1', '', '', ''), ('Parallel play with peers', '1', '', '', ''), ('Turn-taking in structured activity', '1', '', '', ''), ('Joint attention (shared gaze on object)', '1', '', '', ''), ('Separation from caregiver (tolerance)', '1', '', '', ''), ('Emotional regulation during transitions', '1', '', '', ''), ('Anger outburst frequency (per session)', 'High', '', '', ''), ('Tolerance of non-preferred activities (min)', '<1 min', '', '', ''), ('Response to positive reinforcement', '2', '', '', ''), ('Reduction in stereotypic behaviours\n(spinning / lining / running)', '1', '', '', ''), ] for i, row_vals in enumerate(soc_skills): data_row(soc_tbl, row_vals, alt=(i%2==1), bold_first=True) doc.add_paragraph().paragraph_format.space_after = Pt(3) p = doc.add_paragraph() rb = p.add_run('Comments / Observations: ') rb.bold = True; rb.font.size = Pt(10); rb.font.name = 'Times New Roman' p.add_run('_' * 80).font.size = Pt(10) p2 = doc.add_paragraph() p2.add_run('_' * 110).font.size = Pt(10) # ════════════════════════════════════════════════════════════════════════════ # C. COGNITION & PERCEPTION # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'C. COGNITION & PERCEPTION') cog_tbl = doc.add_table(rows=1, cols=5) cog_tbl.style = 'Table Grid' cog_tbl.allow_autofit = False hdr_row(cog_tbl, ['Skill / Goal', 'Baseline\n(Month 0)', 'Month 1', 'Month 2', 'Month 3']) cog_skills = [ ('Attention span on tabletop task (minutes)', '<1 min', '', '', ''), ('Seated task tolerance without redirection (min)', '<1 min', '', '', ''), ('Identifies body parts (no. of parts)', '0', '', '', ''), ('Matches colours (no. of colours)', '0', '', '', ''), ('Matches shapes (no. of shapes)', '0', '', '', ''), ('Concept: big vs small', '1', '', '', ''), ('Concept: same vs different', '1', '', '', ''), ('Object identification (no. of objects named/pointed)', '0', '', '', ''), ('Simple picture matching', '1', '', '', ''), ('Cause-and-effect understanding', '1', '', '', ''), ('Follows visual schedule (step-by-step)', '1', '', '', ''), ('Problem solving (trial and error tasks)', '2', '', '', ''), ] for i, row_vals in enumerate(cog_skills): data_row(cog_tbl, row_vals, alt=(i%2==1), bold_first=True) doc.add_paragraph().paragraph_format.space_after = Pt(3) p = doc.add_paragraph() rb = p.add_run('Comments / Observations: ') rb.bold = True; rb.font.size = Pt(10); rb.font.name = 'Times New Roman' p.add_run('_' * 80).font.size = Pt(10) p2 = doc.add_paragraph() p2.add_run('_' * 110).font.size = Pt(10) # ════════════════════════════════════════════════════════════════════════════ # D. FINE MOTOR & HAND FUNCTION # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'D. FINE MOTOR & HAND FUNCTION') fm_tbl = doc.add_table(rows=1, cols=5) fm_tbl.style = 'Table Grid' fm_tbl.allow_autofit = False hdr_row(fm_tbl, ['Skill / Goal', 'Baseline\n(Month 0)', 'Month 1', 'Month 2', 'Month 3']) fm_skills = [ ('Hand dominance (L established)', '2', '', '', ''), ('Palmar grasp of objects', '3', '', '', ''), ('Pincer grasp (tip-tip) — small objects', '1', '', '', ''), ('Tripod grasp (crayon/pencil)', '1', '', '', ''), ('In-hand manipulation (coin shift)', '1', '', '', ''), ('Stacking blocks (no. of blocks)', '2–3', '', '', ''), ('Ring stacking on peg', '2', '', '', ''), ('Peg board activity', '1', '', '', ''), ('Shape sorter (no. of shapes)', '1', '', '', ''), ('Scribbling (spontaneous)', '1', '', '', ''), ('Scribbling (imitation of stroke)', '1', '', '', ''), ('Tearing paper / manipulating Play-Doh', '2', '', '', ''), ('Container play (insert/remove objects)', '2', '', '', ''), ('Bilateral hand use in activities', '2', '', '', ''), ('Eye-hand coordination (functional)', '2', '', '', ''), ] for i, row_vals in enumerate(fm_skills): data_row(fm_tbl, row_vals, alt=(i%2==1), bold_first=True) doc.add_paragraph().paragraph_format.space_after = Pt(3) p = doc.add_paragraph() rb = p.add_run('Comments / Observations: ') rb.bold = True; rb.font.size = Pt(10); rb.font.name = 'Times New Roman' p.add_run('_' * 80).font.size = Pt(10) p2 = doc.add_paragraph() p2.add_run('_' * 110).font.size = Pt(10) # ════════════════════════════════════════════════════════════════════════════ # E. GROSS MOTOR & SENSORY # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'E. GROSS MOTOR & SENSORY REGULATION') gm_tbl = doc.add_table(rows=1, cols=5) gm_tbl.style = 'Table Grid' gm_tbl.allow_autofit = False hdr_row(gm_tbl, ['Skill / Goal', 'Baseline\n(Month 0)', 'Month 1', 'Month 2', 'Month 3']) gm_skills = [ ('Static balance (standing on 1 leg)', '1', '', '', ''), ('Dynamic balance (obstacle course)', '2', '', '', ''), ('Jumping (both feet off ground)', '1', '', '', ''), ('Hopping (1 foot)', '1', '', '', ''), ('Catching a ball', '1', '', '', ''), ('Kicking a ball', '1', '', '', ''), ('Throwing (directed)', '2', '', '', ''), ('Climbing (structures/stairs)', '3', '', '', ''), ('Animal walks (bear, crab, frog)', '1', '', '', ''), ('Sitting tolerance on chair (minutes)', '<2 min', '', '', ''), ('Sensory seeking (proprioception) — frequency', 'High', '', '', ''), ('Sensory seeking (vestibular) — frequency', 'High', '', '', ''), ('Tactile tolerance (novel textures)', '1', '', '', ''), ('Deep pressure calming response', '3', '', '', ''), ('Lateral head tilt / compensatory posture', 'Present', '', '', ''), ] for i, row_vals in enumerate(gm_skills): data_row(gm_tbl, row_vals, alt=(i%2==1), bold_first=True) doc.add_paragraph().paragraph_format.space_after = Pt(3) p = doc.add_paragraph() rb = p.add_run('Comments / Observations: ') rb.bold = True; rb.font.size = Pt(10); rb.font.name = 'Times New Roman' p.add_run('_' * 80).font.size = Pt(10) p2 = doc.add_paragraph() p2.add_run('_' * 110).font.size = Pt(10) # ════════════════════════════════════════════════════════════════════════════ # F. ADL SKILLS (WeeFIM) # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'F. ACTIVITIES OF DAILY LIVING (WeeFIM Scale: 1 = Total Assist → 7 = Complete Independence)') adl_tbl = doc.add_table(rows=1, cols=6) adl_tbl.style = 'Table Grid' adl_tbl.allow_autofit = False hdr_row(adl_tbl, ['ADL Area', 'Specific Skill', 'Baseline\n(Month 0)', 'Month 1', 'Month 2', 'Month 3']) adl_data = [ ('Feeding', 'Finger feeding', '4', '', '', ''), ('', 'Spoon self-feeding', '2', '', '', ''), ('', 'Accepts new food textures (no. of foods)', '0', '', '', ''), ('', 'Mealtime tolerance without screen (min)', '0', '', '', ''), ('', 'Drinks from cup/tumbler independently', '2', '', '', ''), ('Bathing', 'Overall WeeFIM level', '1', '', '', ''), ('', 'Tolerates water on face/head', '2', '', '', ''), ('Dressing', 'Overall WeeFIM level', '2', '', '', ''), ('', 'Pulls pants up/down', '1', '', '', ''), ('', 'Removes shoes/socks', '1', '', '', ''), ('Grooming', 'Overall WeeFIM level', '1', '', '', ''), ('', 'Tolerates tooth brushing', '2', '', '', ''), ('', 'Tolerates hair combing', '1', '', '', ''), ('', 'Tolerates nail cutting', '1', '', '', ''), ('Toileting', 'WeeFIM level', '1', '', '', ''), ('', 'Indicates toileting need', 'Absent', '', '', ''), ('', 'Sits on toilet without resistance', '1', '', '', ''), ('', 'Daytime continence', 'Absent', '', '', ''), ] for i, row_vals in enumerate(adl_data): row = adl_tbl.add_row() for j, (cell, txt) in enumerate(zip(row.cells, row_vals)): if i % 2 == 1: set_cell_bg(cell, 'F2F7FC') p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(2) p_.paragraph_format.space_after = Pt(2) r_ = p_.add_run(str(txt)) r_.font.name = 'Times New Roman' r_.font.size = Pt(10) if j == 0 and txt: r_.bold = True doc.add_paragraph().paragraph_format.space_after = Pt(3) p = doc.add_paragraph() rb = p.add_run('Comments / Observations: ') rb.bold = True; rb.font.size = Pt(10); rb.font.name = 'Times New Roman' p.add_run('_' * 80).font.size = Pt(10) p2 = doc.add_paragraph() p2.add_run('_' * 110).font.size = Pt(10) # ════════════════════════════════════════════════════════════════════════════ # G. PLAY SKILLS # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'G. PLAY SKILLS') play_tbl = doc.add_table(rows=1, cols=5) play_tbl.style = 'Table Grid' play_tbl.allow_autofit = False hdr_row(play_tbl, ['Skill / Goal', 'Baseline\n(Month 0)', 'Month 1', 'Month 2', 'Month 3']) play_skills = [ ('Current Takata stage (document)', 'Exploratory', '', '', ''), ('Current Piaget stage (document)', 'Sensorimotor', '', '', ''), ('Sustained purposeful play (minutes)', '<2 min', '', '', ''), ('Functional play with objects', '1', '', '', ''), ('Symbolic / pretend play', '1', '', '', ''), ('Parallel play alongside peer', '1', '', '', ''), ('Cooperative play with peer', '1', '', '', ''), ('Turn-taking in play', '1', '', '', ''), ('Reduction in object lining (frequency/session)', 'High', '', '', ''), ('Imitation of play actions from model', '1', '', '', ''), ] for i, row_vals in enumerate(play_skills): data_row(play_tbl, row_vals, alt=(i%2==1), bold_first=True) doc.add_paragraph().paragraph_format.space_after = Pt(3) p = doc.add_paragraph() rb = p.add_run('Comments / Observations: ') rb.bold = True; rb.font.size = Pt(10); rb.font.name = 'Times New Roman' p.add_run('_' * 80).font.size = Pt(10) # ════════════════════════════════════════════════════════════════════════════ # H. ORO-MOTOR & FEEDING # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'H. ORO-MOTOR CONTROL') oro_tbl = doc.add_table(rows=1, cols=5) oro_tbl.style = 'Table Grid' oro_tbl.allow_autofit = False hdr_row(oro_tbl, ['Skill / Goal', 'Baseline\n(Month 0)', 'Month 1', 'Month 2', 'Month 3']) oro_skills = [ ('Drooling frequency', 'Resolved', '', '', ''), ('Lip closure during eating', '3', '', '', ''), ('Chewing (munching / rotary chew)', '3', '', '', ''), ('Straw drinking', '1', '', '', ''), ('Blowing activities (bubbles/windmill)', '1', '', '', ''), ('Oral motor exercises with prompts', '1', '', '', ''), ('Tolerates oral exploration (vibrating tool)', '1', '', '', ''), ('Accepts new food texture attempts', '0', '', '', ''), ] for i, row_vals in enumerate(oro_skills): data_row(oro_tbl, row_vals, alt=(i%2==1), bold_first=True) doc.add_paragraph().paragraph_format.space_after = Pt(3) p = doc.add_paragraph() rb = p.add_run('Comments / Observations: ') rb.bold = True; rb.font.size = Pt(10); rb.font.name = 'Times New Roman' p.add_run('_' * 80).font.size = Pt(10) # ════════════════════════════════════════════════════════════════════════════ # I. SHORT TERM GOAL TRACKING # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'I. SHORT TERM GOAL TRACKING (6-Week Review)') add_note_box(doc, 'Status codes: IP = In Progress | A = Achieved | NI = Not Initiated | R = Revised | C = Carried Forward', bg='EBF3FB', border='1F497D') stg_tbl = doc.add_table(rows=1, cols=5) stg_tbl.style = 'Table Grid' stg_tbl.allow_autofit = False hdr_row(stg_tbl, ['Short Term Goal', 'Target Date', 'Week 3 Status', 'Week 6 Status', 'Outcome / Notes']) stg_list = [ ('Respond to name 7/10 with minimal prompt', '6 weeks', '', '', ''), ('Maintain eye contact 3–5 sec in 6/10 trials', '6 weeks', '', '', ''), ('Follow 1-step command without gesture 4/5', '6 weeks', '', '', ''), ('Seated tabletop task 3 min, minimal redirection', '6 weeks', '', '', ''), ('Reduce spinning/lining — 2–3 calming activities used', '6 weeks', '', '', ''), ('Tolerate 2 new food textures on plate (no intake forced)', '6 weeks', '', '', ''), ('Oro-motor exercises with prompts (blow, lip close)', '6 weeks', '', '', ''), ('Hold spoon and attempt self-feeding 3/5', '6 weeks', '', '', ''), ('Demonstrate pointing or waving 4/5 spontaneously', '6 weeks', '', '', ''), ('Respond to social greetings (wave/hi-five) 4/5', '6 weeks', '', '', ''), ] for i, row_vals in enumerate(stg_list): data_row(stg_tbl, row_vals, alt=(i%2==1), bold_first=True, font_size=10) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ════════════════════════════════════════════════════════════════════════════ # J. LONG TERM GOAL TRACKING # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'J. LONG TERM GOAL TRACKING (3-Month / 6-Month Review)') ltg_tbl = doc.add_table(rows=1, cols=5) ltg_tbl.style = 'Table Grid' ltg_tbl.allow_autofit = False hdr_row(ltg_tbl, ['Long Term Goal', 'Target', 'Month 3 Status', 'Month 6 Status', 'Outcome / Notes']) ltg_list = [ ('Measurable improvement in CPSE skills on repeat assessment', '6 months', '', '', ''), ('Use 10–15 functional words / AAC symbols spontaneously', '6 months', '', '', ''), ('Reduced sensory processing difficulties in daily routines', '6 months', '', '', ''), ('Daytime toilet training readiness', '6 months', '', '', ''), ('Tolerate all grooming routines with minimal resistance', '6 months', '', '', ''), ('Significant reduction in stereotypic behaviours', '6 months', '', '', ''), ('Age-appropriate peer play with minimal assistance', '6 months', '', '', ''), ('Independent spoon self-feeding across accepted foods', '6 months', '', '', ''), ('Preschool participation readiness', '6 months', '', '', ''), ] for i, row_vals in enumerate(ltg_list): data_row(ltg_tbl, row_vals, alt=(i%2==1), bold_first=True, font_size=10) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ════════════════════════════════════════════════════════════════════════════ # K. BEHAVIOUR FREQUENCY LOG # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'K. BEHAVIOUR FREQUENCY LOG (per session / per week)') add_note_box(doc, 'Record approximate frequency per session. Use: H = High (>5x) | M = Moderate (3–5x) | L = Low (1–2x) | A = Absent', bg='FDE9E9', border='C00000') beh_tbl = doc.add_table(rows=1, cols=6) beh_tbl.style = 'Table Grid' beh_tbl.allow_autofit = False hdr_row(beh_tbl, ['Behaviour', 'Baseline', 'Month 1', 'Month 2', 'Month 3', 'Trend'], bg='C00000') beh_list = [ ('Spinning self', 'H', '', '', '', ''), ('Spinning objects', 'H', '', '', '', ''), ('Object lining', 'H', '', '', '', ''), ('Aimless running', 'H', '', '', '', ''), ('Anger outburst / tantrum', 'M', '', '', '', ''), ('Throwing objects', 'L–M', '', '', '', ''), ('Crying without clear cause', 'M', '', '', '', ''), ('Self-stimulatory vocalisations', 'M', '', '', '', ''), ('Staring / fixation episodes', 'M', '', '', '', ''), ('Screen-seeking behaviour during meals', 'H', '', '', '', ''), ] for i, row_vals in enumerate(beh_list): data_row(beh_tbl, row_vals, alt=(i%2==1), bold_first=True, font_size=10) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ════════════════════════════════════════════════════════════════════════════ # L. SENSORY DIET COMPLIANCE # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'L. SENSORY DIET HOME COMPLIANCE (Parent Report)') sd_tbl = doc.add_table(rows=1, cols=5) sd_tbl.style = 'Table Grid' sd_tbl.allow_autofit = False hdr_row(sd_tbl, ['Sensory Diet Component', 'Week 1', 'Week 2', 'Week 3', 'Week 4']) sd_items = [ ('Morning joint compressions (daily)', '', '', '', ''), ('Heavy work activity before sessions', '', '', '', ''), ('Oral motor warm-up before meals', '', '', '', ''), ('Deep pressure brushing (Wilbarger)', '', '', '', ''), ('Obstacle course / tunnel play', '', '', '', ''), ('Linear swinging (min per day)', '', '', '', ''), ('Sensory bin exploration', '', '', '', ''), ('Outdoor play (min per day)', '', '', '', ''), ('Deep pressure massage at bedtime', '', '', '', ''), ('Visual schedule used during routine', '', '', '', ''), ] add_note_box(doc, 'Compliance codes: D = Done daily | M = Done most days (4–5x/week) | O = Occasional (1–3x/week) | X = Not done', bg='E6F4EA', border='375623') for i, row_vals in enumerate(sd_items): data_row(sd_tbl, row_vals, alt=(i%2==1), bold_first=True, font_size=10) doc.add_paragraph().paragraph_format.space_after = Pt(3) p = doc.add_paragraph() rb = p.add_run('Parent compliance notes: ') rb.bold = True; rb.font.size = Pt(10); rb.font.name = 'Times New Roman' p.add_run('_' * 80).font.size = Pt(10) # ════════════════════════════════════════════════════════════════════════════ # M. OVERALL MONTHLY SUMMARY # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, 'M. OVERALL MONTHLY SUMMARY & THERAPIST REMARKS') summary_fields = [ ('Area of greatest progress this month', ''), ('Area requiring most attention next month', ''), ('Changes made to therapy plan', ''), ('Parent/caregiver feedback', ''), ('Referrals / recommendations made', ''), ('Next review date', ''), ] sum_tbl = doc.add_table(rows=len(summary_fields), cols=2) sum_tbl.style = 'Table Grid' sum_tbl.allow_autofit = False for i, (label, val) in enumerate(summary_fields): row = sum_tbl.rows[i] if i % 2 == 1: for cell in row.cells: set_cell_bg(cell, 'F2F7FC') lc = row.cells[0] lp = lc.paragraphs[0] lp.paragraph_format.space_before = Pt(10) lp.paragraph_format.space_after = Pt(10) rl = lp.add_run(label) rl.bold = True; rl.font.size = Pt(10.5); rl.font.name = 'Times New Roman' vc = row.cells[1] vp = vc.paragraphs[0] vp.paragraph_format.space_before = Pt(10) vp.paragraph_format.space_after = Pt(10) vp.add_run(val).font.size = Pt(10.5) doc.add_paragraph() # ════════════════════════════════════════════════════════════════════════════ # SIGNATURE BLOCK # ════════════════════════════════════════════════════════════════════════════ sig_tbl = doc.add_table(rows=2, cols=2) remove_table_borders(sig_tbl) for row in sig_tbl.rows: for cell in row.cells: remove_cell_borders(cell) sig_data = [ ('Occupational Therapist Signature:', '_____________________________'), ('Parent / Guardian Signature:', '_____________________________'), ] for r_idx, (lbl, val) in enumerate(sig_data): row = sig_tbl.rows[r_idx] lp = row.cells[0].paragraphs[0] lp.paragraph_format.space_before = Pt(10) rl = lp.add_run(lbl) rl.bold = True; rl.font.size = Pt(11); rl.font.name = 'Times New Roman' vp = row.cells[1].paragraphs[0] vp.paragraph_format.space_before = Pt(10) vp.add_run(val).font.size = Pt(11) doc.add_paragraph() fp = doc.add_paragraph() fp.alignment = WD_ALIGN_PARAGRAPH.CENTER fr = fp.add_run( 'This template is individualised for Pragadesh J. | OT Department — Circle Time / Rhythms | ' 'Review cycle: Monthly (skills) | 6-weekly (goals) | 3-monthly (formal re-assessment)') fr.italic = True; fr.font.size = Pt(8.5); fr.font.name = 'Times New Roman' fr.font.color.rgb = RGBColor.from_string('808080') # SAVE import os out_path = '/tmp/workspace/ot-assessment/Pragadesh_Monthly_Progress_Tracker.docx' doc.save(out_path) size = os.path.getsize(out_path) print(f"Saved: {out_path} ({size/1024:.1f} KB)") doc2 = Document(out_path) paras = [p.text for p in doc2.paragraphs if p.text.strip()] print(f"Non-empty paragraphs: {len(paras)}") for p in paras: if any(x in p for x in ['A.', 'B.', 'C.', 'D.', 'E.', 'F.', 'G.', 'H.', 'I.', 'J.', 'K.', 'L.', 'M.', 'MONTHLY']): print(f" >> {p[:80]}") PYEOF
Pragadesh Monthly Progress Tracker
Word Document · DOCX
| Section | What it tracks | Baseline pre-filled |
|---|---|---|
| A. Communication & Language | 10 skills — name response, eye contact, commands, gestures, words, AAC | Yes (from assessment) |
| B. Social & Emotional | 12 items — social smile, peer play, turn-taking, anger frequency, stereotypies | Yes |
| C. Cognition & Perception | 12 items — attention span, body parts, colours, shapes, concepts, visual schedules | Yes |
| D. Fine Motor & Hand Function | 15 items — grasp types, stacking, peg boards, scribbling, bilateral use | Yes |
| E. Gross Motor & Sensory Regulation | 15 items — balance, jumping, ball skills, sitting tolerance, sensory seeking frequency | Yes |
| F. ADL Skills | 18 items with WeeFIM levels — feeding, bathing, dressing, grooming, toileting | Yes |
| G. Play Skills | 10 items — Takata/Piaget stage tracking, purposeful play duration, peer play | Yes |
| H. Oro-Motor Control | 8 items — drooling, lip closure, straw drinking, oral motor exercises | Yes |
| I. Short Term Goal Tracking | All 10 STGs from the assessment — Week 3 + Week 6 status columns | Yes |
| J. Long Term Goal Tracking | All 9 LTGs — Month 3 + Month 6 status columns | Yes |
| K. Behaviour Frequency Log | 10 behaviours — H/M/L/A coding per month + trend column | Yes |
| L. Sensory Diet Home Compliance | 10 diet components — D/M/O/X coding for all 4 weeks of the month | Yes |
| M. Overall Monthly Summary | 6 free-text fields — progress, focus, plan changes, parent feedback, referrals | Blank |
Generate a 3-month comparison report template (baseline vs month 3 re-assessment)
python3 << 'PYEOF' from docx import Document from docx.shared import Pt, Inches, RGBColor, Cm from docx.enum.text import WD_ALIGN_PARAGRAPH from docx.oxml.ns import qn from docx.oxml import OxmlElement doc = Document() for section in doc.sections: section.top_margin = Cm(2.0) section.bottom_margin = Cm(2.0) section.left_margin = Cm(2.2) section.right_margin = Cm(2.2) ns = doc.styles['Normal'] ns.font.name = 'Times New Roman' ns.font.size = Pt(11) # ─── helpers ──────────────────────────────────────────────────────────────── def set_cell_bg(cell, hex_color): tc = cell._tc tcPr = 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_color) tcPr.append(shd) def remove_table_borders(table): tbl = table._tbl tblPr = tbl.find(qn('w:tblPr')) if tblPr is None: tblPr = OxmlElement('w:tblPr') tbl.insert(0, tblPr) tblBorders = OxmlElement('w:tblBorders') for bn in ['top','left','bottom','right','insideH','insideV']: b = OxmlElement(f'w:{bn}') b.set(qn('w:val'), 'none') tblBorders.append(b) tblPr.append(tblBorders) def remove_cell_borders(cell): tc = cell._tc tcPr = tc.get_or_add_tcPr() tcBorders = OxmlElement('w:tcBorders') for bn in ['top','left','bottom','right']: b = OxmlElement(f'w:{bn}') b.set(qn('w:val'), 'none') tcBorders.append(b) tcPr.append(tcBorders) def section_heading(doc, text, color='1F497D'): p = doc.add_paragraph() p.paragraph_format.space_before = Pt(12) p.paragraph_format.space_after = Pt(3) r = p.add_run(text) r.bold = True; r.font.size = Pt(12); r.font.name = 'Times New Roman' r.font.color.rgb = RGBColor.from_string(color) pPr = p._p.get_or_add_pPr() pBdr = OxmlElement('w:pBdr') bot = OxmlElement('w:bottom') bot.set(qn('w:val'), 'single'); bot.set(qn('w:sz'), '6') bot.set(qn('w:space'), '1'); bot.set(qn('w:color'), color) pBdr.append(bot); pPr.append(pBdr) def note_box(doc, text, bg='EBF3FB', border='1F497D'): t = doc.add_table(rows=1, cols=1) t.style = 'Table Grid' remove_table_borders(t) cell = t.cell(0, 0) set_cell_bg(cell, bg) tc = cell._tc tcPr = tc.get_or_add_tcPr() tcBorders = OxmlElement('w:tcBorders') for bn in ['top','right','bottom']: b = OxmlElement(f'w:{bn}') b.set(qn('w:val'), 'none'); tcBorders.append(b) lb = OxmlElement('w:left') lb.set(qn('w:val'), 'single'); lb.set(qn('w:sz'), '18') lb.set(qn('w:color'), border); tcBorders.append(lb) tcPr.append(tcBorders) p = cell.paragraphs[0] p.paragraph_format.left_indent = Pt(6) p.paragraph_format.space_before = Pt(3) p.paragraph_format.space_after = Pt(3) r = p.add_run(text) r.font.size = Pt(10); r.font.name = 'Times New Roman' r.font.color.rgb = RGBColor.from_string('1A3A5C') doc.add_paragraph().paragraph_format.space_after = Pt(2) def comparison_table(doc, headers, rows_data, col_widths_inches=None, hdr_bg='1F497D', hdr_fg='FFFFFF', baseline_bg='FFF9E6', m3_bg='E6F4EA', outcome_bg='EBF3FB'): """ headers: list of column header strings rows_data: list of tuples (skill, baseline, m3_score, outcome_code, clinical_notes) """ n = len(headers) tbl = doc.add_table(rows=1, cols=n) tbl.style = 'Table Grid' tbl.allow_autofit = False # header row for cell, txt in zip(tbl.rows[0].cells, headers): set_cell_bg(cell, hdr_bg) p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(2) p_.paragraph_format.space_after = Pt(2) r_ = p_.add_run(txt) r_.bold = True; r_.font.size = Pt(10); r_.font.name = 'Times New Roman' r_.font.color.rgb = RGBColor.from_string(hdr_fg) for i, row_vals in enumerate(rows_data): row = tbl.add_row() for j, (cell, txt) in enumerate(zip(row.cells, row_vals)): # column-specific shading for baseline / month3 cols if j == 1: set_cell_bg(cell, baseline_bg) elif j == 2: set_cell_bg(cell, m3_bg) elif j == 3: set_cell_bg(cell, outcome_bg) elif i % 2 == 1: set_cell_bg(cell, 'F9FAFB') p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(2) p_.paragraph_format.space_after = Pt(2) r_ = p_.add_run(str(txt)) r_.font.name = 'Times New Roman' r_.font.size = Pt(10) if j == 0: r_.bold = True # colour the outcome column if j == 3: if txt in ('✔ Achieved', '✔'): r_.font.color.rgb = RGBColor.from_string('375623') r_.bold = True elif txt in ('↑ Progress', '↑'): r_.font.color.rgb = RGBColor.from_string('1F497D') r_.bold = True elif txt in ('→ Maintained', '→'): r_.font.color.rgb = RGBColor.from_string('7F6000') elif txt in ('↓ Regression', '↓'): r_.font.color.rgb = RGBColor.from_string('C00000') r_.bold = True elif txt in ('○ Not initiated', '○'): r_.font.color.rgb = RGBColor.from_string('808080') doc.add_paragraph().paragraph_format.space_after = Pt(2) return tbl def comment_line(doc, label='Comments / Clinical Impression:'): p = doc.add_paragraph() p.paragraph_format.space_after = Pt(1) rb = p.add_run(f'{label} ') rb.bold = True; rb.font.size = Pt(10); rb.font.name = 'Times New Roman' p.add_run('_' * 75).font.size = Pt(10) p2 = doc.add_paragraph() p2.paragraph_format.space_after = Pt(6) p2.add_run('_' * 110).font.size = Pt(10) HDR = ['Skill / Goal', 'Baseline\n(Month 0)', 'Month 3\nRe-assessment', 'Outcome', 'Clinical Notes'] # ════════════════════════════════════════════════════════════════════════════ # TITLE # ════════════════════════════════════════════════════════════════════════════ tp = doc.add_paragraph() tp.alignment = WD_ALIGN_PARAGRAPH.CENTER tp.paragraph_format.space_after = Pt(0) tr = tp.add_run('3-MONTH PROGRESS COMPARISON REPORT') tr.bold = True; tr.font.size = Pt(16); tr.font.name = 'Times New Roman' tr.font.color.rgb = RGBColor.from_string('1F497D') sp = doc.add_paragraph() sp.alignment = WD_ALIGN_PARAGRAPH.CENTER sp.paragraph_format.space_after = Pt(6) sr = sp.add_run('Paediatric Occupational Therapy | Circle Time / Rhythms') sr.italic = True; sr.font.size = Pt(10); sr.font.name = 'Times New Roman' sr.font.color.rgb = RGBColor.from_string('808080') # client strip cs = doc.add_table(rows=2, cols=4) cs.style = 'Table Grid' remove_table_borders(cs) cs_data = [ [('Child:', 'Pragadesh J'), ('D.O.B:', '07/10/2022'), ('Diagnosis:', 'GDD / ? ASD'), ('Therapist:', '________________')], [('Baseline Date:', '07/07/2026'), ('Re-assessment Date:', '________________'), ('Total Sessions (3 months):', '___'), ('Age at Re-assessment:', '________________')], ] for r_idx, row_data in enumerate(cs_data): row = cs.rows[r_idx] for c_idx, (lbl, val) in enumerate(row_data): cell = row.cells[c_idx] set_cell_bg(cell, 'EBF3FB') remove_cell_borders(cell) p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(3) p_.paragraph_format.space_after = Pt(3) rb = p_.add_run(f'{lbl} '); rb.bold = True rb.font.size = Pt(10); rb.font.name = 'Times New Roman' rv = p_.add_run(val) rv.font.size = Pt(10); rv.font.name = 'Times New Roman' doc.add_paragraph().paragraph_format.space_after = Pt(4) # legend note_box(doc, 'OUTCOME CODES:\n' '✔ Achieved = Goal met independently and consistently | ' '↑ Progress = Measurable improvement, goal not yet met\n' '→ Maintained = No change from baseline (skill stable) | ' '↓ Regression = Performance below baseline | ' '○ Not initiated = Skill not yet addressed\n\n' 'RATING SCALE (where numeric): ' '4 = Independent/consistent | 3 = Minimal prompting | ' '2 = Emerging / moderate prompt | 1 = Not yet demonstrated', bg='EBF3FB', border='1F497D') # ════════════════════════════════════════════════════════════════════════════ # SECTION 1 — COMMUNICATION & LANGUAGE # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, '1. COMMUNICATION & LANGUAGE') comparison_table(doc, HDR, [ ('Responds to own name (7/10 trials)', '0/10', '___/10', '↑ Progress', ''), ('Maintains eye contact 3–5 sec (6/10 trials)', '0/10', '___/10', '↑ Progress', ''), ('Follows 1-step command without gesture (4/5)', '0/5', '___/5', '↑ Progress', ''), ('Follows 2-step command', '0/5', '___/5', '○ Not initiated', ''), ('Uses pointing gesture spontaneously', '1', '___', '↑ Progress', ''), ('Uses waving gesture (hi/bye) 4/5', '0/5', '___/5', '↑ Progress', ''), ('Functional verbal output (no. of words)', '0', '___', '↑ Progress', ''), ('Non-verbal communication (leading/reaching)', '2', '___', '→ Maintained', ''), ('Imitates actions / sounds on modelling', '1', '___', '↑ Progress', ''), ('Picture card / AAC use', 'Not started', '___', '○ Not initiated', ''), ]) comment_line(doc) # ════════════════════════════════════════════════════════════════════════════ # SECTION 2 — SOCIAL & EMOTIONAL # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, '2. SOCIAL & EMOTIONAL') comparison_table(doc, HDR, [ ('Social smile with familiar persons', '2', '___', '→ Maintained', ''), ('Social smile with unfamiliar persons', '1', '___', '↑ Progress', ''), ('Responds to social greetings (wave/hi-five)', '1', '___', '↑ Progress', ''), ('Parallel play alongside peer', '1', '___', '↑ Progress', ''), ('Turn-taking in structured activity', '1', '___', '↑ Progress', ''), ('Joint attention (shared gaze on object)', '1', '___', '↑ Progress', ''), ('Tolerance of non-preferred activity (minutes)', '<1 min','___ min','↑ Progress', ''), ('Anger outburst frequency per session', 'High', '___', '↑ Progress', ''), ('Emotional regulation strategy (calming response)', '1', '___', '↑ Progress', ''), ('Reduction in stereotypic behaviours', '1', '___', '↑ Progress', ''), ('Separation from caregiver (tolerance)', '1', '___', '↑ Progress', ''), ]) comment_line(doc) # ════════════════════════════════════════════════════════════════════════════ # SECTION 3 — COGNITION & PERCEPTION # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, '3. COGNITION & PERCEPTION') comparison_table(doc, HDR, [ ('Attention span on tabletop task (minutes)', '<1 min', '___ min', '↑ Progress', ''), ('Seated task tolerance without redirection (min)', '<1 min', '___ min', '↑ Progress', ''), ('Body parts identified (no. of parts)', '0', '___', '↑ Progress', ''), ('Colours matched / identified (no.)', '0', '___', '↑ Progress', ''), ('Shapes matched / identified (no.)', '0', '___', '↑ Progress', ''), ('Concept: big vs small', '1', '___', '↑ Progress', ''), ('Concept: same vs different', '1', '___', '↑ Progress', ''), ('Object identification (no. named/pointed)', '0', '___', '↑ Progress', ''), ('Simple picture matching', '1', '___', '↑ Progress', ''), ('Follows visual schedule (step-by-step)', '1', '___', '↑ Progress', ''), ('Cause-and-effect understanding', '1', '___', '↑ Progress', ''), ]) comment_line(doc) # ════════════════════════════════════════════════════════════════════════════ # SECTION 4 — FINE MOTOR & HAND FUNCTION # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, '4. FINE MOTOR & HAND FUNCTION') comparison_table(doc, HDR, [ ('Palmar grasp of objects', '3', '___', '→ Maintained', ''), ('Pincer grasp (tip-tip) — small objects', '1', '___', '↑ Progress', ''), ('Tripod grasp (crayon / pencil)', '1', '___', '↑ Progress', ''), ('In-hand manipulation (finger-to-palm)', '1', '___', '↑ Progress', ''), ('Stacking blocks (no. of blocks)', '2–3','___', '↑ Progress', ''), ('Ring stacking on peg', '2', '___', '↑ Progress', ''), ('Peg board activity', '1', '___', '↑ Progress', ''), ('Shape sorter (no. of shapes placed correctly)', '1', '___', '↑ Progress', ''), ('Scribbling (spontaneous)', '1', '___', '↑ Progress', ''), ('Scribbling (imitation of stroke)', '1', '___', '↑ Progress', ''), ('Container play (insert / remove objects)', '2', '___', '→ Maintained', ''), ('Bilateral hand use in structured activity', '2', '___', '↑ Progress', ''), ('Eye-hand coordination (functional)', '2', '___', '→ Maintained', ''), ]) comment_line(doc) # ════════════════════════════════════════════════════════════════════════════ # SECTION 5 — GROSS MOTOR & SENSORY REGULATION # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, '5. GROSS MOTOR & SENSORY REGULATION') comparison_table(doc, HDR, [ ('Static balance (single leg stance)', '1', '___', '↑ Progress', ''), ('Dynamic balance (obstacle course)', '2', '___', '↑ Progress', ''), ('Jumping (both feet)', '1', '___', '↑ Progress', ''), ('Hopping (1 foot)', '1', '___', '○ Not initiated',''), ('Catching a ball', '1', '___', '↑ Progress', ''), ('Kicking a ball', '1', '___', '↑ Progress', ''), ('Throwing (directed)', '2', '___', '→ Maintained', ''), ('Sitting tolerance on chair (minutes)', '<2 min','___ min','↑ Progress', ''), ('Proprioceptive seeking frequency', 'High', '___', '↑ Progress', ''), ('Vestibular seeking frequency', 'High', '___', '↑ Progress', ''), ('Tactile tolerance (novel textures)', '1', '___', '↑ Progress', ''), ('Deep pressure calming response', '3', '___', '→ Maintained', ''), ('Lateral head tilt / compensatory posture', 'Present','___', '↑ Progress', ''), ]) comment_line(doc) # ════════════════════════════════════════════════════════════════════════════ # SECTION 6 — ADL (WeeFIM) # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, '6. ACTIVITIES OF DAILY LIVING (WeeFIM: 1 = Total Assist → 7 = Complete Independence)') note_box(doc, 'WeeFIM Level Guide: 1 = Total Assistance | 2 = Maximal Assistance | 3 = Moderate Assistance | ' '4 = Minimal Assistance | 5 = Supervision | 6 = Modified Independence | 7 = Complete Independence', bg='FFF9E6', border='F7A900') comparison_table(doc, HDR, [ ('Feeding — Finger feeding', 'WeeFIM 4', '___', '→ Maintained', ''), ('Feeding — Spoon self-feeding', 'WeeFIM 2', '___', '↑ Progress', ''), ('Feeding — New food textures accepted (no.)', '0', '___', '↑ Progress', ''), ('Feeding — Mealtime without screen (min)', '0 min', '___ min','↑ Progress',''), ('Bathing — Overall WeeFIM level', 'WeeFIM 1', '___', '↑ Progress', ''), ('Bathing — Tolerates water on face/head', '2', '___', '↑ Progress', ''), ('Dressing — Overall WeeFIM level', 'WeeFIM 2', '___', '↑ Progress', ''), ('Dressing — Pulls pants up/down', '1', '___', '↑ Progress', ''), ('Dressing — Removes shoes/socks', '1', '___', '↑ Progress', ''), ('Grooming — Overall WeeFIM level', 'WeeFIM 1', '___', '↑ Progress', ''), ('Grooming — Tolerates tooth brushing', '2', '___', '↑ Progress', ''), ('Grooming — Tolerates hair combing', '1', '___', '↑ Progress', ''), ('Toileting — WeeFIM level', 'WeeFIM 1', '___', '↑ Progress', ''), ('Toileting — Indicates need', 'Absent', '___', '↑ Progress', ''), ('Toileting — Daytime continence', 'Absent', '___', '↑ Progress', ''), ]) comment_line(doc) # ════════════════════════════════════════════════════════════════════════════ # SECTION 7 — PLAY # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, '7. PLAY SKILLS') comparison_table(doc, HDR, [ ('Takata classification (document stage)', 'Exploratory', '___', '↑ Progress', ''), ('Piaget classification (document stage)', 'Sensorimotor','___', '↑ Progress', ''), ('Sustained purposeful play (minutes)', '<2 min', '___ min', '↑ Progress', ''), ('Functional play with objects', '1', '___', '↑ Progress', ''), ('Symbolic / pretend play', '1', '___', '↑ Progress', ''), ('Parallel play alongside peer', '1', '___', '↑ Progress', ''), ('Turn-taking in play', '1', '___', '↑ Progress', ''), ('Object lining frequency per session', 'High', '___', '↑ Progress', ''), ('Imitation of play actions from model', '1', '___', '↑ Progress', ''), ]) comment_line(doc) # ════════════════════════════════════════════════════════════════════════════ # SECTION 8 — ORO-MOTOR # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, '8. ORO-MOTOR CONTROL') comparison_table(doc, HDR, [ ('Drooling', 'Resolved', 'Resolved', '✔ Achieved', ''), ('Lip closure during eating', '3', '___', '→ Maintained',''), ('Chewing (munching / rotary chew)', '3', '___', '→ Maintained',''), ('Straw drinking', '1', '___', '↑ Progress', ''), ('Blowing activities (bubbles / windmill)', '1', '___', '↑ Progress', ''), ('Oro-motor exercises with prompts', '1', '___', '↑ Progress', ''), ('Accepts new food texture attempts', '0', '___', '↑ Progress', ''), ]) comment_line(doc) # ════════════════════════════════════════════════════════════════════════════ # SECTION 9 — SHORT TERM GOAL OUTCOMES # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, '9. SHORT TERM GOAL OUTCOMES (6-Week Targets — Review at Month 3)') stg_tbl = doc.add_table(rows=1, cols=4) stg_tbl.style = 'Table Grid' stg_tbl.allow_autofit = False for cell, txt in zip(stg_tbl.rows[0].cells, ['Short Term Goal', 'Target Criteria', 'Outcome at Month 3', 'Notes / Revised Goal']): set_cell_bg(cell, '1F497D') p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(2); p_.paragraph_format.space_after = Pt(2) r_ = p_.add_run(txt) r_.bold = True; r_.font.size = Pt(10); r_.font.name = 'Times New Roman' r_.font.color.rgb = RGBColor.from_string('FFFFFF') stg_list = [ ('Respond to name', '7/10 with minimal prompt', '', ''), ('Maintain eye contact', '3–5 sec in 6/10 trials', '', ''), ('Follow 1-step command without gesture', '4/5 trials', '', ''), ('Seated tabletop task', '3 min, minimal redirection', '', ''), ('Reduce spinning / lining', '2–3 calming activities used per episode','', ''), ('Tolerate new food textures', '2 new textures on plate', '', ''), ('Oro-motor exercises with prompts', 'Blow, lip close with prompts', '', ''), ('Hold spoon and attempt self-feeding', '3/5 trials', '', ''), ('Pointing or waving spontaneously', '4/5 opportunities', '', ''), ('Respond to social greetings', 'Wave/hi-five 4/5 trials', '', ''), ] for i, row_vals in enumerate(stg_list): row = stg_tbl.add_row() for j, (cell, txt) in enumerate(zip(row.cells, row_vals)): if i % 2 == 1: set_cell_bg(cell, 'F2F7FC') p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(2); p_.paragraph_format.space_after = Pt(2) r_ = p_.add_run(str(txt)) r_.font.name = 'Times New Roman'; r_.font.size = Pt(10) if j == 0: r_.bold = True doc.add_paragraph().paragraph_format.space_after = Pt(2) comment_line(doc, 'STG Summary Comments:') # ════════════════════════════════════════════════════════════════════════════ # SECTION 10 — BEHAVIOUR CHANGE SUMMARY # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, '10. BEHAVIOUR FREQUENCY COMPARISON') note_box(doc, 'Frequency codes: H = High (>5x per session) | M = Moderate (3–5x) | L = Low (1–2x) | A = Absent', bg='FDE9E9', border='C00000') beh_tbl = doc.add_table(rows=1, cols=4) beh_tbl.style = 'Table Grid' beh_tbl.allow_autofit = False for cell, txt in zip(beh_tbl.rows[0].cells, ['Behaviour', 'Baseline (Month 0)', 'Month 3', 'Trend']): set_cell_bg(cell, 'C00000') p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(2); p_.paragraph_format.space_after = Pt(2) r_ = p_.add_run(txt) r_.bold = True; r_.font.size = Pt(10); r_.font.name = 'Times New Roman' r_.font.color.rgb = RGBColor.from_string('FFFFFF') beh_data = [ ('Spinning self', 'H', '', ''), ('Spinning objects', 'H', '', ''), ('Object lining', 'H', '', ''), ('Aimless running', 'H', '', ''), ('Anger outburst / tantrum', 'M', '', ''), ('Throwing objects', 'L–M', '', ''), ('Staring / fixation episodes', 'M', '', ''), ('Screen-seeking during meals', 'H', '', ''), ('Self-stimulatory vocalisations', 'M', '', ''), ] for i, row_vals in enumerate(beh_data): row = beh_tbl.add_row() for j, (cell, txt) in enumerate(zip(row.cells, row_vals)): if i % 2 == 1: set_cell_bg(cell, 'FDE9E9') elif j == 1: set_cell_bg(cell, 'FFF9E6') elif j == 2: set_cell_bg(cell, 'E6F4EA') p_ = cell.paragraphs[0] p_.paragraph_format.space_before = Pt(2); p_.paragraph_format.space_after = Pt(2) r_ = p_.add_run(str(txt)) r_.font.name = 'Times New Roman'; r_.font.size = Pt(10) if j == 0: r_.bold = True doc.add_paragraph().paragraph_format.space_after = Pt(2) # ════════════════════════════════════════════════════════════════════════════ # SECTION 11 — PARENT / CAREGIVER FEEDBACK # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, '11. PARENT / CAREGIVER FEEDBACK (3-Month Review)') pf_tbl = doc.add_table(rows=6, cols=2) pf_tbl.style = 'Table Grid' pf_tbl.allow_autofit = False pf_items = [ ('Changes observed at home (communication)', ''), ('Changes in behaviour / emotional regulation', ''), ('Progress in self-care / ADL at home', ''), ('Sensory diet compliance and effectiveness', ''), ('Concerns / new issues observed', ''), ('Family goals for next 3 months', ''), ] for i, (lbl, val) in enumerate(pf_items): row = pf_tbl.rows[i] lc = row.cells[0]; vc = row.cells[1] if i % 2 == 1: set_cell_bg(lc, 'F2F7FC'); set_cell_bg(vc, 'F2F7FC') lp = lc.paragraphs[0] lp.paragraph_format.space_before = Pt(10); lp.paragraph_format.space_after = Pt(10) rl = lp.add_run(lbl) rl.bold = True; rl.font.size = Pt(10.5); rl.font.name = 'Times New Roman' vp = vc.paragraphs[0] vp.paragraph_format.space_before = Pt(10); vp.paragraph_format.space_after = Pt(10) vp.add_run(val).font.size = Pt(10.5) doc.add_paragraph().paragraph_format.space_after = Pt(4) # ════════════════════════════════════════════════════════════════════════════ # SECTION 12 — OVERALL CLINICAL IMPRESSION # ════════════════════════════════════════════════════════════════════════════ section_heading(doc, '12. OVERALL CLINICAL IMPRESSION & RECOMMENDATIONS') ci_tbl = doc.add_table(rows=7, cols=2) ci_tbl.style = 'Table Grid' ci_tbl.allow_autofit = False ci_items = [ ('Overall progress rating\n(Excellent / Good / Fair / Minimal / Regression)', ''), ('Domain of greatest improvement', ''), ('Domain requiring most attention (Month 4–6)', ''), ('Revised short term goals for next 3 months', ''), ('Changes to therapy plan / frequency', ''), ('Referrals recommended\n(SLP / Paed / Psychologist / Special Educator)', ''), ('Additional tools / formal assessments to conduct', ''), ] for i, (lbl, val) in enumerate(ci_items): row = ci_tbl.rows[i] lc = row.cells[0]; vc = row.cells[1] if i % 2 == 0: set_cell_bg(lc, 'EBF3FB') else: set_cell_bg(lc, 'F2F7FC') lp = lc.paragraphs[0] lp.paragraph_format.space_before = Pt(10); lp.paragraph_format.space_after = Pt(10) rl = lp.add_run(lbl) rl.bold = True; rl.font.size = Pt(10.5); rl.font.name = 'Times New Roman' vp = vc.paragraphs[0] vp.paragraph_format.space_before = Pt(10); vp.paragraph_format.space_after = Pt(10) vp.add_run(val).font.size = Pt(10.5) doc.add_paragraph().paragraph_format.space_after = Pt(8) # ════════════════════════════════════════════════════════════════════════════ # SIGNATURE BLOCK # ════════════════════════════════════════════════════════════════════════════ sig = doc.add_table(rows=3, cols=2) remove_table_borders(sig) for row in sig.rows: for cell in row.cells: remove_cell_borders(cell) sig_data = [ ('Date of Re-assessment:', '________________'), ('Occupational Therapist Signature:', '________________'), ('Parent / Guardian Signature:', '________________'), ] for r_idx, (lbl, val) in enumerate(sig_data): row = sig.rows[r_idx] lp = row.cells[0].paragraphs[0] lp.paragraph_format.space_before = Pt(10) rl = lp.add_run(lbl) rl.bold = True; rl.font.size = Pt(11); rl.font.name = 'Times New Roman' vp = row.cells[1].paragraphs[0] vp.paragraph_format.space_before = Pt(10) vp.add_run(val).font.size = Pt(11) doc.add_paragraph() fp = doc.add_paragraph() fp.alignment = WD_ALIGN_PARAGRAPH.CENTER fr = fp.add_run( 'This report is individualised for Pragadesh J. | ' 'OT Department — Circle Time / Rhythms | ' 'Review Cycle: 3-monthly formal re-assessment | Next review: 6-month mark') fr.italic = True; fr.font.size = Pt(8.5); fr.font.name = 'Times New Roman' fr.font.color.rgb = RGBColor.from_string('808080') # SAVE import os out_path = '/tmp/workspace/ot-assessment/Pragadesh_3Month_Comparison_Report.docx' doc.save(out_path) size = os.path.getsize(out_path) print(f"Saved: {out_path} ({size/1024:.1f} KB)") doc2 = Document(out_path) paras = [p.text for p in doc2.paragraphs if p.text.strip()] print(f"Non-empty paragraphs: {len(paras)}") for p in paras: if any(x in p for x in ['1.','2.','3.','4.','5.','6.','7.','8.','9.','10.','11.','12.','3-MONTH']): print(f" >> {p[:80]}") PYEOF
Pragadesh 3Month Comparison Report
Word Document · DOCX
| Section | What's compared | Baseline pre-filled |
|---|---|---|
| 1. Communication & Language | 10 skills — name response, eye contact, commands, gestures, words, AAC | Yes |
| 2. Social & Emotional | 11 items — peer play, joint attention, anger frequency, stereotypies, frustration tolerance | Yes |
| 3. Cognition & Perception | 11 items — attention span, body parts, colours, shapes, concepts, visual schedule | Yes |
| 4. Fine Motor & Hand Function | 13 items — grasp, stacking, peg, scribbling, bilateral, eye-hand | Yes |
| 5. Gross Motor & Sensory | 13 items — balance, jumping, ball skills, sensory seeking, sitting tolerance, head tilt | Yes |
| 6. ADL (WeeFIM) | 15 items with WeeFIM levels — feeding, bathing, dressing, grooming, toileting | Yes |
| 7. Play Skills | 9 items — Takata/Piaget stage, purposeful play duration, functional/symbolic/peer play | Yes |
| 8. Oro-Motor | 7 items — drooling (marked Achieved), chewing, straw, blowing, oral motor | Yes |
| 9. STG Outcomes | All 10 short term goals — target criteria + Month 3 outcome + revised goal column | Yes |
| 10. Behaviour Frequency | 9 behaviours — H/M/L/A baseline vs Month 3 + trend column | Yes |
| 11. Parent Feedback | 6 free-text fields — home changes, ADL, sensory diet, concerns, family goals | Blank |
| 12. Clinical Impression | 7 fields — overall rating, best domain, focus areas, revised STGs, referrals, next tools | Blank |