I need a physical examination check list for my osce exam about Brest exam
"clinical breast examination" AND "physical examination"
breast examination palpation technique vertical strip pattern

Make a one-page PDF cheat sheet of this checklist
ls -la /tmp/workspace/
mkdir -p /tmp/workspace/breast-osce/output && cat > /tmp/workspace/breast-osce/gen.py << 'EOF' from reportlab.lib.pagesizes import A4 from reportlab.pdfgen import canvas from reportlab.lib.colors import HexColor, white from reportlab.platypus import Paragraph, Frame from reportlab.lib.styles import ParagraphStyle W, H = A4 out = "/tmp/workspace/breast-osce/output/Breast_Exam_OSCE_Cheat_Sheet.pdf" c = canvas.Canvas(out, pagesize=A4) NAVY = HexColor("#1F3A5F"); PINK = HexColor("#B83280"); LIGHT = HexColor("#F4F6FA") # header c.setFillColor(NAVY); c.rect(0, H-62, W, 62, fill=1, stroke=0) c.setFillColor(white); c.setFont("Helvetica-Bold", 20) c.drawString(30, H-30, "Breast Examination - OSCE Cheat Sheet") c.setFont("Helvetica", 9.5) c.drawString(30, H-48, "Mnemonic: I-N-P-A = Inspect (3 positions) | Nodes | Palpate (supine, systematic) | Assess/Report") body = ParagraphStyle("b", fontName="Helvetica", fontSize=8.2, leading=10.2, leftIndent=9, bulletIndent=0) def box(x, y, w, h, title, items, color=NAVY): c.setFillColor(LIGHT); c.setStrokeColor(color); c.setLineWidth(0.8) c.roundRect(x, y, w, h, 5, fill=1, stroke=1) c.setFillColor(color); c.roundRect(x, y+h-16, w, 16, 5, fill=1, stroke=0) c.rect(x, y+h-16, w, 8, fill=1, stroke=0) c.setFillColor(white); c.setFont("Helvetica-Bold", 9.5); c.drawString(x+6, y+h-12, title) paras = [Paragraph(i, body, bulletText="\u25A1") for i in items] f = Frame(x+3, y+2, w-6, h-20, leftPadding=3, rightPadding=3, topPadding=2, bottomPadding=0, showBoundary=0) rest = f.addFromList(paras, c) colw = (W-60-10)/2 x1, x2 = 30, 30+colw+10 top = H-72 box(x1, top-132, colw, 132, "1. PREP & INTRO", [ "Wash hands; introduce self, confirm name + DOB", "Explain exam, get <b>consent</b>", "Offer <b>chaperone</b> (document accept/decline)", "Privacy; ask about pain; offer gown", "Expose to waist, cover what is not examined", "Position sitting upright (45 deg), good lighting"]) box(x1, top-132-10-190, colw, 190, "2. INSPECTION (sitting, both breasts)", [ "<b>Arms at sides</b>", "<b>Arms raised</b> above head (lower breast, inframammary fold)", "<b>Hands on hips</b> +/- pectoral contraction (tethering)", "Optional: lean forward (accentuates retraction)", "<b>Symmetry, size, shape</b> (mild asymmetry normal)", "<b>Skin:</b> dimpling, peau d'orange, erythema, ulcer, veins, scars, lump", "<b>Nipple-areola:</b> new inversion, discharge, eczema/crusting (<b>Paget</b>)", "Look at axillae and supraclavicular fossae"]) box(x1, top-132-10-190-10-130, colw, 130, "3. LYMPH NODES (still sitting)", [ "Ask about tenderness first", "<b>Support ipsilateral arm</b> to relax pectoralis", "Axilla: central, anterior, posterior, lateral, apical", "Infraclavicular, supraclavicular, cervical nodes", "Describe: size, consistency, <b>mobile vs matted/fixed</b>, tender?"]) box(x2, top-205, colw, 205, "4. BREAST PALPATION (supine)", [ "Ipsilateral arm <b>above head</b>; cover other breast", "Ask patient to point out lump; examine that area <b>last</b>", "Use <b>flat of fingers</b>; no grasping or pinching", "Extent: <b>clavicle to lower ribs</b>, <b>sternum to mid-axillary line</b>", "Systematic pattern: <b>vertical strip</b> (preferred, includes nipple), circles, or radial spokes", "Include <b>axillary tail</b>; palpate under nipple, check discharge", "Normal nodularity: upper outer quadrant, inframammary ridge, subareolar", "Cup/mould breast for retraction; bimanual if large breasts", "Repeat on the <b>other breast</b> and compare"], PINK) box(x2, top-205-10-150, colw, 150, "5. DESCRIBE A LUMP (SSSCCCTTT)", [ "<b>Site</b> (quadrant/clock position, cm from nipple); <b>Size</b>; <b>Shape</b>/surface", "<b>Consistency</b> (soft/firm/hard); <b>Contour</b>/edge", "<b>Tenderness</b>; <b>Temperature</b>", "<b>Mobility</b>: skin, chest wall (hands on hips, re-palpate)", "<b>Tethering</b> / fixation of skin", "<b>Transillumination</b> if cystic suspected", "Associated: nodes, nipple change, skin change"], PINK) box(x2, top-205-10-150-10-97, colw, 97, "6. COMPLETION", [ "Help patient re-dress, thank her, wash hands", "Summarise findings to examiner", "Suggest <b>triple assessment</b>: clinical exam + imaging (US <40 y, mammo 40+) + core biopsy", "Document on breast diagram"], NAVY) # pitfalls strip y = 30 c.setFillColor(HexColor("#FDECEC")); c.setStrokeColor(HexColor("#C0392B")); c.roundRect(30, y+16, W-60, 44, 5, fill=1, stroke=1) c.setFillColor(HexColor("#C0392B")); c.setFont("Helvetica-Bold", 9); c.drawString(37, y+49, "COMMON PITFALLS (lost marks)") c.setFillColor(HexColor("#222222")); c.setFont("Helvetica", 8.2) c.drawString(37, y+37, "No chaperone/consent | Skipping axilla or supraclavicular nodes | Forgetting the other breast | Using fingertips / pinching") c.drawString(37, y+25, "Omitting arms-up and hands-on-hips positions | Over-exposing the patient | Not comparing both sides") c.setFont("Helvetica-Oblique", 7); c.setFillColor(HexColor("#666666")) c.drawString(30, y+4, "Sources: Schwartz's Principles of Surgery 11e; Mulholland & Greenfield's Surgery 7e (Clinical Breast Examination); Bailey & Love 28e. Check your own station mark sheet.") c.save() EOF python3 /tmp/workspace/breast-osce/gen.py && python3 -c " import pdfplumber p=pdfplumber.open('/tmp/workspace/breast-osce/output/Breast_Exam_OSCE_Cheat_Sheet.pdf');print(len(p.pages));print(p.pages[0].extract_text())"
cd /tmp/workspace/breast-osce && python3 -c " try: import fitz d=fitz.open('output/Breast_Exam_OSCE_Cheat_Sheet.pdf');d[0].get_pixmap(dpi=110).save('preview.png');print('fitz ok') except Exception as e: print('fitz fail',e) import pypdfium2 as p p.PdfDocument('output/Breast_Exam_OSCE_Cheat_Sheet.pdf')[0].render(scale=1.5).to_pil().save('preview.png');print('pdfium ok') "
cd /tmp/workspace/breast-osce && python3 - << 'EOF' import re s = open('gen.py').read() # bigger font, hollow checkbox, spacing s = s.replace('fontSize=8.2, leading=10.2, leftIndent=9, bulletIndent=0)', 'fontSize=9.6, leading=12, leftIndent=13, bulletIndent=0, bulletFontName="ZapfDingbats", bulletFontSize=9, spaceAfter=3.2)') s = s.replace('bulletText="\\u25A1"', 'bulletText="o"') # dynamic heights: replace box signature to auto-size using a helper s = s.replace('def box(x, y, w, h, title, items, color=NAVY):', '''def need(w, items): t = 0 for i in items: p = Paragraph(i, body, bulletText="o") _, ph = p.wrap(w-6-6, 1000) t += ph + body.spaceAfter return t + 28 def box(x, y, w, h, title, items, color=NAVY):''') open('gen.py','w').write(s) EOF grep -n "box(x" gen.py | head
cd /tmp/workspace/breast-osce && cat > gen2.py << 'EOF' from reportlab.lib.pagesizes import A4 from reportlab.pdfgen import canvas from reportlab.lib.colors import HexColor, white from reportlab.platypus import Paragraph, Frame from reportlab.lib.styles import ParagraphStyle W, H = A4 out = "/tmp/workspace/breast-osce/output/Breast_Exam_OSCE_Cheat_Sheet.pdf" c = canvas.Canvas(out, pagesize=A4) NAVY = HexColor("#1F3A5F"); PINK = HexColor("#B83280"); LIGHT = HexColor("#F4F6FA") c.setFillColor(NAVY); c.rect(0, H-62, W, 62, fill=1, stroke=0) c.setFillColor(white); c.setFont("Helvetica-Bold", 20) c.drawString(30, H-30, "Breast Examination - OSCE Cheat Sheet") c.setFont("Helvetica", 9.5) c.drawString(30, H-48, "Mnemonic: I-N-P-A = Inspect (3 positions) | Nodes | Palpate (supine, systematic) | Assess/Report") body = ParagraphStyle("b", fontName="Helvetica", fontSize=9.6, leading=12, leftIndent=14, bulletIndent=0, bulletFontName="ZapfDingbats", bulletFontSize=9, spaceAfter=3.5) colw = (W-60-10)/2 x1, x2 = 30, 30+colw+10 GAP = 10 def paras(items): return [Paragraph(i, body, bulletText="o") for i in items] def need(items): t = 0 for p in paras(items): _, ph = p.wrap(colw-6-6, 1000); t += ph + body.spaceAfter return t + 30 def box(x, ytop, h, title, items, color=NAVY): y = ytop - h c.setFillColor(LIGHT); c.setStrokeColor(color); c.setLineWidth(0.8) c.roundRect(x, y, colw, h, 5, fill=1, stroke=1) c.setFillColor(color); c.roundRect(x, y+h-18, colw, 18, 5, fill=1, stroke=0) c.rect(x, y+h-18, colw, 9, fill=1, stroke=0) c.setFillColor(white); c.setFont("Helvetica-Bold", 10.5); c.drawString(x+7, y+h-13, title) f = Frame(x+3, y+2, colw-6, h-22, leftPadding=3, rightPadding=3, topPadding=3, bottomPadding=0, showBoundary=0) left = f.addFromList(paras(items), c) assert not left or True return y def column(x, specs, top, bottom): needs = [need(s[1]) for s in specs] avail = top - bottom - GAP*(len(specs)-1) extra = (avail - sum(needs)) / len(specs) assert extra >= 0, ("overflow", avail, sum(needs)) y = top for (title, items, col), n in zip(specs, needs): y = box(x, y, n+extra, title, items, col) - GAP L = [ ("1. PREP & INTRO", [ "Wash hands; introduce self; confirm name + DOB", "Explain exam and get <b>consent</b>", "Offer <b>chaperone</b> (document accept/decline)", "Privacy; ask about pain; offer gown", "Expose to waist, cover what is not examined", "Sit patient upright (45 deg) with good lighting"], NAVY), ("2. INSPECTION (sitting, both breasts)", [ "<b>Arms at sides</b>", "<b>Arms raised</b> above head (lower breast, inframammary fold)", "<b>Hands on hips</b> +/- pectoral contraction (tethering)", "Optional: lean forward (accentuates retraction)", "<b>Symmetry, size, shape</b> (mild asymmetry is normal)", "<b>Skin:</b> dimpling, peau d'orange, erythema, ulcer, veins, scars, lump", "<b>Nipple-areola:</b> new inversion, discharge, eczema/crusting (<b>Paget</b>)", "Look at axillae and supraclavicular fossae"], NAVY), ("3. LYMPH NODES (still sitting)", [ "Ask about tenderness first", "<b>Support ipsilateral arm</b> to relax pectoralis", "Axilla: central, anterior, posterior, lateral, apical", "Infraclavicular, supraclavicular, cervical nodes", "Describe size, consistency, <b>mobile vs matted/fixed</b>, tender?"], NAVY), ] R = [ ("4. BREAST PALPATION (supine)", [ "Ipsilateral arm <b>above head</b>; cover other breast", "Ask patient to point out lump; examine that area <b>last</b>", "Use <b>flat of fingers</b>; no grasping or pinching", "Extent: <b>clavicle to lower ribs</b>, <b>sternum to mid-axillary line</b>", "Systematic pattern: <b>vertical strip</b> (preferred, includes nipple), circles, or radial spokes", "Include <b>axillary tail</b>; palpate under nipple, check for discharge", "Normal nodularity: upper outer quadrant, inframammary ridge, subareolar", "Cup/mould breast for retraction; bimanual if large breasts", "Repeat on the <b>other breast</b> and compare"], PINK), ("5. DESCRIBE A LUMP (SSSCCCTTT)", [ "<b>Site</b> (quadrant/clock position, cm from nipple); <b>Size</b>; <b>Shape</b>/surface", "<b>Consistency</b> (soft/firm/hard); <b>Contour</b>/edge", "<b>Tenderness</b>; <b>Temperature</b>", "<b>Mobility</b>: skin, chest wall (hands on hips, re-palpate)", "<b>Tethering</b> / fixation of skin", "<b>Transillumination</b> if cystic lump suspected", "Associated: nodes, nipple change, skin change"], PINK), ("6. COMPLETION", [ "Help patient re-dress, thank her, wash hands", "Summarise findings to examiner", "Suggest <b>triple assessment</b>: clinical exam + imaging (US if <40 y, mammography if 40+) + core biopsy", "Document on a breast diagram"], NAVY), ] top = H-74; bottom = 118 column(x1, L, top, bottom) column(x2, R, top, bottom) y = 28 c.setFillColor(HexColor("#FDECEC")); c.setStrokeColor(HexColor("#C0392B")); c.roundRect(30, y+16, W-60, 66, 5, fill=1, stroke=1) c.setFillColor(HexColor("#C0392B")); c.setFont("Helvetica-Bold", 10.5); c.drawString(38, y+68, "COMMON PITFALLS (lost marks)") c.setFillColor(HexColor("#222222")); c.setFont("Helvetica", 9.4) c.drawString(38, y+53, "No chaperone or consent | Skipping axilla or supraclavicular nodes | Forgetting the other breast") c.drawString(38, y+40, "Using fingertips or pinching | Omitting arms-up and hands-on-hips positions") c.drawString(38, y+27, "Over-exposing the patient | Not comparing both sides") c.setFont("Helvetica-Oblique", 7); c.setFillColor(HexColor("#666666")) c.drawString(30, y+4, "Sources: Schwartz's Principles of Surgery 11e; Mulholland & Greenfield's Surgery 7e (Clinical Breast Examination); Bailey & Love 28e. Check your own station mark sheet.") c.save() EOF python3 gen2.py && python3 -c " import pypdfium2 as p d=p.PdfDocument('output/Breast_Exam_OSCE_Cheat_Sheet.pdf');print(len(d));d[0].render(scale=1.5).to_pil().save('preview.png')"
cd /tmp/workspace/breast-osce && ls -la output/ && python3 -c " import pypdfium2 as p d=p.PdfDocument('output/Breast_Exam_OSCE_Cheat_Sheet.pdf');print(len(d));d[0].render(scale=1.5).to_pil().save('preview2.png')"
cd /tmp/workspace/breast-osce && ls -la . output && python3 gen2.py && python3 -c " import pypdfium2 as p d=p.PdfDocument('output/Breast_Exam_OSCE_Cheat_Sheet.pdf');print(len(d));d[0].render(scale=1.5).to_pil().save('/tmp/workspace/breast-osce/preview_v2.png')" && ls -la
cd /tmp/workspace/breast-osce && md5sum preview*.png output/*.pdf && sed -i 's#output/Breast_Exam_OSCE_Cheat_Sheet.pdf#output/Breast_Exam_OSCE_Cheat_Sheet_v2.pdf#; s#/tmp/workspace/breast-osce/output/Breast_Exam_OSCE_Cheat_Sheet.pdf#/tmp/workspace/breast-osce/output/Breast_Exam_OSCE_Cheat_Sheet_v2.pdf#' gen2.py && grep -n "^out" gen2.py && python3 gen2.py && python3 -c " import pypdfium2 as p d=p.PdfDocument('/tmp/workspace/breast-osce/output/Breast_Exam_OSCE_Cheat_Sheet_v2.pdf');print(len(d));d[0].render(scale=1.5).to_pil().save('/tmp/workspace/breast-osce/final_preview.png')" && md5sum output/*.pdf final_preview.png
Breast Exam OSCE Cheat Sheet v2
PDF Document · PDF