Can you generate notes in a pucturized ans attractive way
AV blocks
AV blocks
electrocardiogram examples first degree Mobitz I Mobitz II complete heart block AV block
"atrioventricular block" AND electrocardiography
2025 ACC AHA atrioventricular block ECG first degree Mobitz I Mobitz II complete heart block guideline
A labeled educational medical infographic showing atrioventricular block ECG patterns side by side: first-degree AV block with a long PR interval and every P wave conducted; Mobitz I Wenckebach with progressive PR prolongation then a dropped QRS; Mobitz II with fixed PR intervals then a dropped QRS; third-degree complete heart block with independent P waves and QRS complexes. Include simple conduction pathway from atria through AV node to ventricles and a short legend. Accurate black ECG traces on a white background.

SA node → Atria (P wave) → AV node / His-Purkinje system → Ventricles (QRS)
✖ Conduction delay or failure = AV block
| Type | PR interval | Dropped QRS? | Main idea |
|---|---|---|---|
| First-degree | Prolonged, fixed | No | Every P conducts, but slowly |
| Second-degree Mobitz I | Progressively lengthens | Yes | PR gets longer, then one QRS drops |
| Second-degree Mobitz II | Fixed | Yes | Sudden dropped QRS |
| High-grade AV block | Variable | Multiple | ≥2 consecutive P waves do not conduct |
| Third-degree / complete | No consistent relation | AV dissociation | Atria and ventricles beat independently |
P ───────── QRS P ───────── QRS P ───────── QRS
PR > 200 ms PR > 200 ms PR > 200 ms
P--QRS P---QRS P-----QRS P P--QRS
short PR longer PR longest PR ↓ cycle repeats
dropped QRS
Longer, longer, longer, drop.
P--QRS P--QRS P P--QRS
fixed PR fixed PR ↓ fixed PR
dropped QRS
PR is fixed, then a QRS suddenly drops.
P--QRS P P P--QRS
↓ ↓
two non-conducted P waves
P P P P P P ← atria: regular
QRS QRS QRS QRS ← ventricles: slower, regular
No fixed PR relationship = AV dissociation
| Escape focus | QRS | Rate | Relative concern |
|---|---|---|---|
| Junctional escape | Narrow | ~40-60/min | More stable |
| Ventricular escape | Broad | ~20-40/min | Less reliable, more dangerous |
Unstable bradycardia / complete block
↓
ABC assessment + cardiac monitor + IV access
↓
Stop reversible offending drugs and correct electrolytes
↓
Atropine may help if nodal block, but may fail in infranodal block
↓
Transcutaneous pacing → transvenous temporary pacing if required
↓
Permanent pacemaker if persistent and not reversible
| Feature | Mobitz I | Mobitz II |
|---|---|---|
| Other name | Wenckebach | Classical Mobitz II |
| PR interval | Progressively prolongs | Constant |
| Dropped QRS | After PR lengthening | Sudden |
| Level of block | Usually AV node | Usually His-Purkinje system |
| QRS | Often narrow | May be broad |
| Risk of complete block | Lower | Higher |
| Usual pacing need | If symptomatic / special cases | Usually required unless reversible |
Wenckebach wears out: PR interval gets progressively longer before the beat drops.
II = Impending complete block.
1st degree: delay only
Mobitz I: PR longer → dropped QRS
Mobitz II: fixed PR → dropped QRS
3rd degree: P waves and QRS have no relationship
As a pdf
~/
mkdir -p "/tmp/workspace/av-blocks-notes/src" "/tmp/workspace/av-blocks-notes/assets" "/tmp/workspace/av-blocks-notes/output" && curl -L "https://cdn.orris.care/image-gen/213bd129ca284bc98821ea73de2476eb.png" -o "/tmp/workspace/av-blocks-notes/assets/av_block_ecg_infographic.png" && python - <<'PY' from reportlab.lib import colors from reportlab.lib.enums import TA_CENTER, TA_LEFT from reportlab.lib.pagesizes import A4 from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.units import cm from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Image, PageBreak, KeepTogether from reportlab.pdfbase.pdfmetrics import stringWidth from PIL import Image as PILImage import os base='/tmp/workspace/av-blocks-notes' out=f'{base}/output/AV_Blocks_Picturized_Notes.pdf' img_path=f'{base}/assets/av_block_ecg_infographic.png' NAVY=colors.HexColor('#102A43'); BLUE=colors.HexColor('#247BA0'); TEAL=colors.HexColor('#159A9C'); RED=colors.HexColor('#D64550'); ORANGE=colors.HexColor('#E67E22'); GREEN=colors.HexColor('#2E8B57'); PALE=colors.HexColor('#F2F7FA'); INK=colors.HexColor('#1F2933'); GRAY=colors.HexColor('#52616B') styles=getSampleStyleSheet() styles.add(ParagraphStyle(name='Title2', parent=styles['Title'], fontName='Helvetica-Bold', fontSize=26, leading=30, textColor=NAVY, alignment=TA_CENTER, spaceAfter=7)) styles.add(ParagraphStyle(name='Sub', parent=styles['Normal'], fontName='Helvetica', fontSize=10.5, leading=14, textColor=GRAY, alignment=TA_CENTER, spaceAfter=13)) styles.add(ParagraphStyle(name='H1x', parent=styles['Heading1'], fontName='Helvetica-Bold', fontSize=16, leading=19, textColor=colors.white, backColor=NAVY, borderPadding=(5,7,5,7), spaceBefore=10, spaceAfter=8)) styles.add(ParagraphStyle(name='H2x', parent=styles['Heading2'], fontName='Helvetica-Bold', fontSize=13, leading=16, textColor=BLUE, spaceBefore=8, spaceAfter=4)) styles.add(ParagraphStyle(name='Bodyx', parent=styles['BodyText'], fontName='Helvetica', fontSize=9.2, leading=13, textColor=INK, spaceAfter=5)) styles.add(ParagraphStyle(name='Small', parent=styles['BodyText'], fontName='Helvetica', fontSize=8.2, leading=11, textColor=INK)) styles.add(ParagraphStyle(name='Callout', parent=styles['BodyText'], fontName='Helvetica-Bold', fontSize=9.6, leading=13, textColor=NAVY, backColor=colors.HexColor('#E8F4F8'), borderColor=BLUE, borderWidth=0.6, borderPadding=7, spaceBefore=4, spaceAfter=7)) styles.add(ParagraphStyle(name='Emergency', parent=styles['BodyText'], fontName='Helvetica-Bold', fontSize=9.5, leading=13, textColor=colors.HexColor('#8A1C1C'), backColor=colors.HexColor('#FCEBEC'), borderColor=RED, borderWidth=0.8, borderPadding=7, spaceBefore=4, spaceAfter=7)) def P(text, sty='Bodyx'): return Paragraph(text, styles[sty]) def box(title, body, bg=PALE, color=BLUE): t=Table([[P(f'<b>{title}</b><br/>{body}','Small')]], colWidths=[17.2*cm]) t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),bg),('BOX',(0,0),(-1,-1),0.7,color),('LEFTPADDING',(0,0),(-1,-1),8),('RIGHTPADDING',(0,0),(-1,-1),8),('TOPPADDING',(0,0),(-1,-1),7),('BOTTOMPADDING',(0,0),(-1,-1),7)])) return t def footer(canvas, doc): canvas.saveState(); canvas.setStrokeColor(colors.HexColor('#D9E2EC')); canvas.line(1.5*cm,1.25*cm,19.5*cm,1.25*cm) canvas.setFont('Helvetica',8); canvas.setFillColor(GRAY) canvas.drawString(1.5*cm,.82*cm,'AV Blocks - Picturized Revision Notes') canvas.drawRightString(19.5*cm,.82*cm,f'Page {doc.page}') canvas.restoreState() doc=SimpleDocTemplate(out,pagesize=A4,rightMargin=1.5*cm,leftMargin=1.5*cm,topMargin=1.35*cm,bottomMargin=1.6*cm,title='AV Blocks - Picturized Revision Notes',author='Orris') story=[] story += [P('ATRIOVENTRICULAR (AV) BLOCKS','Title2'),P('High-yield ECG recognition, causes, risk, and management overview','Sub')] # image im=PILImage.open(img_path); w,h=im.size; maxw=17.6*cm; maxh=8.1*cm; scale=min(maxw/w,maxh/h); story.append(Image(img_path,width=w*scale,height=h*scale)); story.append(Spacer(1,7)) story.append(box('Core definition', 'An <b>AV block</b> is delayed or failed conduction of an electrical impulse from the atria to the ventricles. P wave = atrial depolarization; QRS = ventricular depolarization.', colors.HexColor('#E8F4F8'), TEAL)); story.append(Spacer(1,8)) story.append(P('1. Classification at a Glance','H1x')) data=[[P('<b>Type</b>','Small'),P('<b>PR interval</b>','Small'),P('<b>Dropped QRS?</b>','Small'),P('<b>Key ECG idea</b>','Small')], [P('<b>First-degree</b>','Small'),P('Prolonged, fixed','Small'),P('No','Small'),P('Every P conducts, but slowly','Small')], [P('<b>Mobitz I</b>','Small'),P('Progressively longer','Small'),P('Yes','Small'),P('Longer, longer, longer, drop','Small')], [P('<b>Mobitz II</b>','Small'),P('Fixed','Small'),P('Yes','Small'),P('Fixed PR, sudden drop','Small')], [P('<b>High-grade</b>','Small'),P('Variable','Small'),P('Multiple','Small'),P('≥2 successive P waves do not conduct','Small')], [P('<b>Third-degree</b>','Small'),P('No fixed relation','Small'),P('AV dissociation','Small'),P('Atria and ventricles are independent','Small')]] t=Table(data,colWidths=[3.3*cm,3.4*cm,3.1*cm,7.8*cm],repeatRows=1) t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,0),NAVY),('TEXTCOLOR',(0,0),(-1,0),colors.white),('GRID',(0,0),(-1,-1),0.35,colors.HexColor('#BCCCDC')),('BACKGROUND',(0,1),(-1,-1),colors.white),('ROWBACKGROUNDS',(0,1),(-1,-1),[colors.white,PALE]),('VALIGN',(0,0),(-1,-1),'MIDDLE'),('LEFTPADDING',(0,0),(-1,-1),6),('RIGHTPADDING',(0,0),(-1,-1),6),('TOPPADDING',(0,0),(-1,-1),5),('BOTTOMPADDING',(0,0),(-1,-1),5)])); story += [t,Spacer(1,8)] story.append(P('2. First-degree AV block','H1x')) story += [P('<b>ECG:</b> PR interval <b>>200 ms</b>, constant, with <b>1:1 AV conduction</b>. Every P wave is followed by a QRS complex.'),box('Visual cue','P ───────── QRS P ───────── QRS P ───────── QRS<br/><b>Long but fixed PR; no dropped beat.</b>',colors.HexColor('#F5F8FA'),BLUE),P('<b>Causes:</b> increased vagal tone, athletes/sleep, beta-blockers, verapamil/diltiazem, digoxin, inferior MI, myocarditis, conduction-system fibrosis.'),P('<b>Clinical approach:</b> usually asymptomatic. Review medications and reversible causes. Pacing is usually not needed unless symptoms are clearly attributable or the PR delay is markedly prolonged and hemodynamically important.')] story.append(P('3. Second-degree AV block','H1x')) story.append(P('A. Mobitz type I (Wenckebach)','H2x')) story += [box('ECG rule: “Longer, longer, longer, drop”','The PR interval progressively lengthens until a P wave is not conducted, causing a dropped QRS. Usually produces grouped beating.',colors.HexColor('#E7F7F4'),TEAL),P('<b>Usual location:</b> AV node. <b>Causes:</b> vagal tone, inferior MI, AV-nodal blocking drugs, myocarditis.'),P('<b>Risk / management:</b> commonly transient and relatively benign when nodal. Treat reversible causes. If symptomatic bradycardia occurs, monitor and consider acute bradycardia treatment and pacing based on instability.')] story.append(P('B. Mobitz type II','H2x')) story += [box('ECG rule: “Fixed PR, sudden drop”','Conducted beats have a constant PR interval, then an unexpected P wave is not followed by QRS.','%s'%colors.HexColor('#FFF4E5'),ORANGE),P('<b>Usual location:</b> His-Purkinje system, below the AV node. A wide QRS may support infranodal disease.'),P('<b>Why it matters:</b> may progress suddenly to high-grade or complete heart block.'),P('<b>Approach:</b> admit/monitor, correct reversible factors, and obtain urgent pacing evaluation. Persistent Mobitz II without a reversible cause generally requires a permanent pacemaker.')] story.append(PageBreak()) story.append(P('4. High-grade and complete AV block','H1x')) story.append(P('High-grade AV block','H2x')) story += [P('<b>Definition:</b> at least two consecutive P waves fail to conduct.'),box('Pattern','P--QRS P P P--QRS<br/><b>Two non-conducted P waves occur in sequence.</b>',colors.HexColor('#FFF4E5'),ORANGE),P('It commonly signifies substantial conduction disease and should be managed with urgent monitoring and pacing assessment, particularly when symptomatic.')] story.append(P('Third-degree (complete) AV block','H2x')) story += [P('<b>Definition:</b> no atrial impulse conducts to the ventricles. The atria and ventricles beat independently: <b>AV dissociation</b>.'),box('ECG recognition','P P P P P P ← atria<br/> QRS QRS QRS ← ventricles, slower<br/><b>No consistent PR relationship.</b>',colors.HexColor('#FCEBEC'),RED),P('<b>Escape rhythm:</b> a narrow, junctional escape is often ~40-60/min and comparatively more stable. A broad ventricular escape is often ~20-40/min and less reliable.'),P('<b>Causes:</b> degenerative conduction disease, MI, AV-nodal medications, myocarditis including Lyme carditis, post-operative block, congenital block, and infiltrative disease.'),P('🚨 <b>Symptomatic complete heart block is an emergency.</b>')] story.append(P('5. Acute management framework','H1x')) steps=[[P('<b>1. Recognize instability</b>','Small'),P('Hypotension, shock, syncope, altered mental status, ischemic chest discomfort, or acute heart failure.','Small')],[P('<b>2. Immediate actions</b>','Small'),P('ABC assessment, cardiac monitor, IV access, 12-lead ECG; stop offending AV-nodal drugs and correct reversible metabolic/electrolyte causes.','Small')],[P('<b>3. Pacing-oriented care</b>','Small'),P('For unstable high-grade or complete block, prepare transcutaneous pacing, followed by transvenous temporary pacing when required. Atropine may help nodal block but may fail in infranodal block.','Small')],[P('<b>4. Definitive therapy</b>','Small'),P('Persistent Mobitz II, high-grade, or third-degree AV block without a reversible cause warrants permanent pacemaker evaluation.','Small')]] t=Table(steps,colWidths=[4.2*cm,13.4*cm]); t.setStyle(TableStyle([('GRID',(0,0),(-1,-1),0.4,colors.HexColor('#F3B0B6')),('BACKGROUND',(0,0),(0,-1),colors.HexColor('#FCEBEC')),('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),7),('RIGHTPADDING',(0,0),(-1,-1),7),('TOPPADDING',(0,0),(-1,-1),6),('BOTTOMPADDING',(0,0),(-1,-1),6)]));story += [t,Spacer(1,8)] story.append(P('6. Mobitz I vs Mobitz II: exam table','H1x')) data=[[P('<b>Feature</b>','Small'),P('<b>Mobitz I</b>','Small'),P('<b>Mobitz II</b>','Small')],[P('PR interval','Small'),P('Progressively prolongs','Small'),P('Constant','Small')],[P('Dropped QRS','Small'),P('After PR lengthening','Small'),P('Unexpected','Small')],[P('Site','Small'),P('Usually AV node','Small'),P('Usually His-Purkinje','Small')],[P('Risk','Small'),P('Usually lower if nodal','Small'),P('Higher risk of complete block','Small')],[P('Pacing','Small'),P('If symptoms / selected cases','Small'),P('Usually indicated unless reversible','Small')]] t=Table(data,colWidths=[4.1*cm,6.75*cm,6.75*cm],repeatRows=1);t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,0),NAVY),('TEXTCOLOR',(0,0),(-1,0),colors.white),('GRID',(0,0),(-1,-1),0.35,colors.HexColor('#BCCCDC')),('ROWBACKGROUNDS',(0,1),(-1,-1),[colors.white,PALE]),('VALIGN',(0,0),(-1,-1),'MIDDLE'),('LEFTPADDING',(0,0),(-1,-1),7),('RIGHTPADDING',(0,0),(-1,-1),7),('TOPPADDING',(0,0),(-1,-1),6),('BOTTOMPADDING',(0,0),(-1,-1),6)]));story += [t,Spacer(1,10)] story.append(P('7. Rapid revision','H1x')) story += [P('<b>1st degree:</b> delay only - PR >200 ms, every P conducts.'),P('<b>Mobitz I:</b> PR gets longer then QRS drops.'),P('<b>Mobitz II:</b> PR stays fixed then QRS drops.'),P('<b>Complete block:</b> P waves and QRS complexes have no fixed relationship.'),P('⚠️ <b>2:1 AV block:</b> cannot reliably be labelled Mobitz I or II from the ECG alone. A wide QRS or other evidence of infranodal disease should raise concern.'),P('<b>Mnemonic:</b> <font color="#159A9C">Wenckebach wears out</font> (PR progressively lengthens). <font color="#D64550">Mobitz II = impending complete block.</font>','Callout')] story.append(Spacer(1,8)); story.append(P('Educational note: This handout supports study and ECG pattern recognition. In clinical practice, symptomatic bradycardia or suspected high-grade/complete AV block needs urgent professional assessment.','Small')) story.append(Spacer(1,6)); story.append(P('Sources: Braunwald’s Heart Disease, 2-volume set, pp. 1315-1317; 2018 ACC/AHA/HRS Guideline on Bradycardia and Cardiac Conduction Delay.','Small')) doc.build(story,onFirstPage=footer,onLaterPages=footer) print(out) PY python - <<'PY' from pypdf import PdfReader p='/tmp/workspace/av-blocks-notes/output/AV_Blocks_Picturized_Notes.pdf' r=PdfReader(p) print('exists',os.path.exists(p) if False else True,'pages',len(r.pages),'bytes',__import__('os').path.getsize(p)) print(r.pages[0].extract_text()[:200]) PY
AV Blocks Picturized Notes
PDF Document · PDF
I want doodled kind of notes
ACC AHA HRS atrioventricular block guideline Mobitz II complete heart block pacing
~/av-blocks-notes/
python - <<'PY' from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.units import cm from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont from reportlab.pdfbase.pdfmetrics import stringWidth import os, math, random base='/tmp/workspace/av-blocks-notes' out=f'{base}/output/AV_Blocks_Doodle_Notes.pdf' font='/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf' bold='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf' pdfmetrics.registerFont(TTFont('Doodle',font)); pdfmetrics.registerFont(TTFont('DoodleBold',bold)) W,H=A4 random.seed(8) C={'ink':colors.HexColor('#25313B'),'pink':colors.HexColor('#FF6F91'),'yellow':colors.HexColor('#FFD166'),'blue':colors.HexColor('#4D96FF'),'mint':colors.HexColor('#62D2A2'),'purple':colors.HexColor('#A66CFF'),'orange':colors.HexColor('#FF9F43'),'paper':colors.HexColor('#FFFDF5'),'red':colors.HexColor('#E84855')} def paper(c,pg): c.setFillColor(C['paper']); c.rect(0,0,W,H,fill=1,stroke=0) c.setStrokeColor(colors.HexColor('#DDEAF5'));c.setLineWidth(.45) for y in range(35,int(H),18): c.line(0,y,W,y) c.setStrokeColor(colors.HexColor('#FFB6C1'));c.setLineWidth(.7);c.line(42,0,42,H) c.setFillColor(colors.HexColor('#73808A')); c.setFont('Doodle',7.5);c.drawRightString(W-25,18,f'AV BLOCKS | {pg}') def txt(c,s,x,y,size=10,color=None,bold=False): c.setFillColor(color or C['ink']);c.setFont('DoodleBold' if bold else 'Doodle',size);c.drawString(x,y,s) def wrap(c,s,x,y,width,size=10,leading=13,color=None,bold=False): words=s.split(); line=''; yy=y for wd in words: trial=(line+' '+wd).strip() if stringWidth(trial,'DoodleBold' if bold else 'Doodle',size)<=width: line=trial else: txt(c,line,x,yy,size,color,bold); yy-=leading;line=wd if line:txt(c,line,x,yy,size,color,bold);yy-=leading return yy def marker(c,x,y,w,color): c.setFillColor(color);c.setStrokeColor(color);c.setLineWidth(1) c.roundRect(x,y-4,w,13,4,fill=1,stroke=0) def title(c,s,y,sub=None): marker(c,60,y-7,min(360,stringWidth(s,'DoodleBold',25)+18),C['yellow']) txt(c,s,66,y,25,C['ink'],True) if sub: txt(c,sub,67,y-19,9,C['purple'],False) def cloud(c,x,y,w,h,label,color=C['blue']): c.setStrokeColor(color);c.setLineWidth(1.7);c.setFillColor(colors.white) # bubbly rounded box c.roundRect(x,y,w,h,12,fill=1,stroke=1) c.setFillColor(color);c.setFont('DoodleBold',10);c.drawCentredString(x+w/2,y+h/2-4,label) def arrow(c,x1,y1,x2,y2,color=C['ink']): c.setStrokeColor(color);c.setFillColor(color);c.setLineWidth(1.5);c.line(x1,y1,x2,y2) a=math.atan2(y2-y1,x2-x1);L=8 c.line(x2,y2,x2-L*math.cos(a-.45),y2-L*math.sin(a-.45));c.line(x2,y2,x2-L*math.cos(a+.45),y2-L*math.sin(a+.45)) def ecg(c,x,y,segments,scale=1): # segment: list of p-qrs composites including 'drop' xx=x;c.setStrokeColor(C['ink']);c.setLineWidth(1.5) for kind,pr in segments: # P c.line(xx,y,xx+6*scale,y);c.bezier(xx+6*scale,y,xx+9*scale,y+8*scale,xx+14*scale,y+8*scale,xx+17*scale,y); c.line(xx+17*scale,y,xx+19*scale,y) if kind=='drop': c.setStrokeColor(C['pink']);c.setDash(2,2);c.line(xx+19*scale,y,xx+(19+pr)*scale,y);c.setDash();c.setStrokeColor(C['ink']);xx+=(24+pr)*scale;continue c.line(xx+19*scale,y,xx+(19+pr-4)*scale,y);q=xx+(19+pr)*scale c.line(q,y,q+3*scale,y+18*scale);c.line(q+3*scale,y+18*scale,q+6*scale,y-10*scale);c.line(q+6*scale,y-10*scale,q+10*scale,y);c.line(q+10*scale,y,q+17*scale,y+6*scale);c.line(q+17*scale,y+6*scale,q+23*scale,y);xx=q+27*scale return xx def note(c,x,y,w,h,head,body,color=C['mint']): c.setFillColor(colors.white);c.setStrokeColor(color);c.setLineWidth(1.4);c.roundRect(x,y-h,w,h,8,fill=1,stroke=1) marker(c,x+10,y-18,min(w-20,stringWidth(head,'DoodleBold',11)+8),color);txt(c,head,x+14,y-15,11,C['ink'],True) wrap(c,body,x+12,y-35,w-24,9.2,12,C['ink']) c=canvas.Canvas(out,pagesize=A4) # page 1 paper(c,1);title(c,'AV BLOCKS',770,'doodle-style ECG revision sheet') # conduction doodle cloud(c,75,650,100,42,'SA node',C['yellow']);cloud(c,240,650,100,42,'AV node',C['blue']);cloud(c,405,650,120,42,'ventricles',C['pink']) arrow(c,175,671,238,671,C['purple']);arrow(c,340,671,403,671,C['purple']);txt(c,'P wave',91,631,9,C['purple'],True);txt(c,'PR interval',249,631,9,C['purple'],True);txt(c,'QRS',442,631,9,C['purple'],True) txt(c,'BLOCK = the message is delayed or fails to pass ↓',74,600,12,C['red'],True) # map marker(c,63,557,230,C['yellow']);txt(c,'THE BIG MAP',69,560,16,C['ink'],True) items=[('1°','delay only','every P → QRS',C['mint']),('2° I','Wenckebach','PR grows → drop',C['blue']),('2° II','danger zone','fixed PR → drop',C['orange']),('3°','complete block','P and QRS divorce!',C['pink'])] x=62 for a,b,d,col in items: c.setFillColor(colors.white);c.setStrokeColor(col);c.setLineWidth(2);c.roundRect(x,470,118,70,10,fill=1,stroke=1) txt(c,a,x+10,516,17,col,True);txt(c,b,x+10,499,9,C['ink'],True);txt(c,d,x+10,484,8.2,C['ink']);x+=126 # 1 degree marker(c,63,432,310,C['mint']);txt(c,'1° AV BLOCK = SLOW, BUT ALL GET THROUGH',69,435,14,C['ink'],True) ec=c; ecg(c,75,385,[('go',28),('go',28),('go',28)],1.25) txt(c,'PR > 200 ms',75,350,13,C['purple'],True);arrow(c,165,354,149,384,C['purple']) note(c,65,320,220,85,'REMEMBER','Every P wave has a QRS. It is really AV delay, not a true dropped-beat block.',C['mint']) note(c,310,320,220,85,'CAUSES','Vagal tone, sleep/athletes, AV-nodal drugs, inferior MI, myocarditis.',C['yellow']) txt(c,'No symptoms? Usually observe + review drugs.',70,210,11,C['blue'],True) # doodles c.setStrokeColor(C['pink']);c.setLineWidth(2);c.circle(500,230,21,stroke=1,fill=0);c.line(500,251,500,263);c.line(500,197,500,207);c.line(479,230,467,230);c.line(521,230,533,230);txt(c,'slow mail delivery!',424,178,9,C['pink'],True) c.showPage() # page2 paper(c,2);title(c,'SECOND-DEGREE BLOCKS',770,'spot the dropped QRS') # mobitz one marker(c,63,722,260,C['blue']);txt(c,'A. MOBITZ I = WENCKEBACH',69,725,15,C['ink'],True) txt(c,'“Longer, longer, longer... DROP!”',68,701,12,C['purple'],True) ec=c;ecg(c,75,653,[('go',12),('go',22),('go',32),('drop',40),('go',12)],1.25) txt(c,'PR',92,614,8,C['blue'],True);txt(c,'PR',170,614,8,C['blue'],True);txt(c,'PR',262,614,8,C['blue'],True);txt(c,'dropped!',378,614,9,C['pink'],True) arrow(c,400,617,411,654,C['pink']) note(c,65,570,220,85,'WHERE?','Usually in the AV node. Often narrow QRS.',C['blue']) note(c,310,570,220,85,'WHY?','Vagal tone, inferior MI, AV-nodal drugs, myocarditis.',C['yellow']) note(c,65,468,465,72,'WHAT TO DO','Often benign if nodal. Treat cause and monitor. Pacing is considered when symptoms are clearly due to the block.',C['mint']) # mobitz 2 marker(c,63,410,220,C['orange']);txt(c,'B. MOBITZ II',69,413,15,C['ink'],True) txt(c,'“Fixed PR... then an unexpected DROP!”',68,389,12,C['red'],True) ec=c;ecg(c,75,340,[('go',22),('go',22),('drop',22),('go',22)],1.4) txt(c,'same PR',91,302,9,C['purple'],True);txt(c,'same PR',187,302,9,C['purple'],True);txt(c,'NO QRS!',305,302,10,C['red'],True) note(c,65,260,220,90,'WHERE?','Usually below AV node in the His-Purkinje system. QRS may be wide.',C['orange']) note(c,310,260,220,90,'WHY WORRY?','Can suddenly progress to complete heart block.',C['pink']) # big caution c.setFillColor(colors.HexColor('#FFF0F1'));c.setStrokeColor(C['red']);c.setLineWidth(2);c.roundRect(65,125,465,90,14,fill=1,stroke=1) txt(c,'⚠ MOBITZ II = URGENT PACING EVALUATION',85,181,14,C['red'],True) wrap(c,'Monitor, identify reversible causes, and prepare pacing if unstable. Persistent acquired Mobitz II without a reversible cause generally needs a permanent pacemaker.',85,158,420,10.2,14,C['ink']) c.showPage() # page3 paper(c,3);title(c,'HIGH-GRADE + COMPLETE BLOCK',770,'when the atria and ventricles stop talking') marker(c,63,718,185,C['orange']);txt(c,'HIGH-GRADE AV BLOCK',69,721,14,C['ink'],True) txt(c,'≥ 2 P waves in a row do NOT conduct',69,697,11,C['ink'],True) ec=c;ecg(c,75,650,[('go',20),('drop',20),('drop',20),('go',20)],1.5) txt(c,'two missed messages!',250,616,10,C['red'],True);arrow(c,300,620,300,652,C['red']) marker(c,63,566,270,C['pink']);txt(c,'3° AV BLOCK = COMPLETE BLOCK',69,569,15,C['ink'],True) # independent rhythm lines c.setStrokeColor(C['purple']);c.setLineWidth(1.5) # P waves upper for xx in [85,135,185,235,285,335,385,435,485]: c.line(xx,506,xx+5,506);c.bezier(xx+5,506,xx+8,514,xx+13,514,xx+16,506);c.line(xx+16,506,xx+20,506) # QRS lower slower for xx in [120,250,380]: c.line(xx,455,xx+16,455);c.line(xx+16,455,xx+20,478);c.line(xx+20,478,xx+25,440);c.line(xx+25,440,xx+31,455);c.line(xx+31,455,xx+42,455) txt(c,'P waves: regular, faster',68,525,9,C['purple'],True);txt(c,'QRS: regular, slower',68,430,9,C['pink'],True) txt(c,'NO fixed PR relationship = AV dissociation',70,402,13,C['red'],True) note(c,65,365,220,95,'ESCAPE RHYTHM','Junctional: narrow QRS, roughly 40-60/min. Ventricular: broad QRS, roughly 20-40/min.',C['purple']) note(c,310,365,220,95,'CAUSES','Fibrosis, MI, AV-nodal drugs, myocarditis/Lyme, post-op disease, congenital or infiltrative disease.',C['yellow']) # emergency ladder marker(c,63,242,275,C['pink']);txt(c,'UNSTABLE BRADYCARDIA? ACT FAST',69,245,14,C['ink'],True) steps=[('1','Monitor + IV + 12-lead ECG'),('2','Stop culprit drugs / correct causes'),('3','Pacing: transcutaneous → transvenous if needed'),('4','Permanent pacemaker if persistent, not reversible')] y=204 for n,s in steps: c.setFillColor(C['blue']);c.circle(82,y+3,12,fill=1,stroke=0);txt(c,n,78,y,10,colors.white,True);txt(c,s,105,y,10,C['ink'],True) if n!='4':arrow(c,82,y-10,82,y-27,C['blue']) y-=40 # recap marker(c,63,46,280,C['yellow']);txt(c,'ONE-LINE RECAP',69,49,13,C['ink'],True) txt(c,'1°: long PR | Mobitz I: longer PR then drop | Mobitz II: fixed PR then drop | 3°: P ≠ QRS',68,28,8.8,C['ink'],True) c.save() print(out) PY python - <<'PY' from pypdf import PdfReader import os p='/tmp/workspace/av-blocks-notes/output/AV_Blocks_Doodle_Notes.pdf' r=PdfReader(p) print('exists=',os.path.exists(p),'pages=',len(r.pages),'size=',os.path.getsize(p)) for i,pag in enumerate(r.pages): print(i+1, len(pag.extract_text() or '')) PY
python - <<'PY' from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.units import cm from reportlab.pdfbase.pdfmetrics import stringWidth from pypdf import PdfReader import os, math out='/tmp/workspace/av-blocks-notes/output/AV_Blocks_Doodle_Notes.pdf'; W,H=A4 ink=colors.HexColor('#263238'); paper=colors.HexColor('#FFFDF5'); blue=colors.HexColor('#4D96FF'); pink=colors.HexColor('#FF6F91'); yellow=colors.HexColor('#FFD166'); mint=colors.HexColor('#62D2A2'); orange=colors.HexColor('#FF9F43'); purple=colors.HexColor('#9B6BCE'); red=colors.HexColor('#DF3E51') def text(c,s,x,y,n=10,col=ink,b=0): c.setFillColor(col);c.setFont('Helvetica-Bold' if b else 'Helvetica',n);c.drawString(x,y,s) def page(c,n): c.setFillColor(paper);c.rect(0,0,W,H,fill=1,stroke=0);c.setStrokeColor(colors.HexColor('#E1EDF7'));c.setLineWidth(.4) for y in range(30,int(H),18):c.line(0,y,W,y) c.setStrokeColor(colors.HexColor('#FFA6B4'));c.setLineWidth(.8);c.line(42,0,42,H);text(c,f'AV BLOCKS | {n}',W-100,18,7,colors.grey) def hi(c,s,x,y,col=yellow,n=18): c.setFillColor(col);c.roundRect(x-4,y-5,stringWidth(s,'Helvetica-Bold',n)+12,n+7,4,fill=1,stroke=0);text(c,s,x,y,n,ink,1) def box(c,x,y,w,h,head,body,col): c.setFillColor(colors.white);c.setStrokeColor(col);c.setLineWidth(1.5);c.roundRect(x,y-h,w,h,10,fill=1,stroke=1);hi(c,head,x+12,y-20,col,11); wrap(c,body,x+12,y-42,w-24,9,12) def wrap(c,s,x,y,w,n=10,lead=13): line=''; yy=y for a in s.split(): t=(line+' '+a).strip() if stringWidth(t,'Helvetica',n)<=w:line=t else:text(c,line,x,yy,n);yy-=lead;line=a text(c,line,x,yy,n) def ecg(c,x,y,arr,sc=1): c.setStrokeColor(ink);c.setLineWidth(1.4) for kind,pr in arr: c.line(x,y,x+6*sc,y);c.bezier(x+6*sc,y,x+9*sc,y+8*sc,x+14*sc,y+8*sc,x+17*sc,y);c.line(x+17*sc,y,x+19*sc,y) if kind=='d':c.setStrokeColor(pink);c.setDash(2,2);c.line(x+19*sc,y,x+(19+pr)*sc,y);c.setDash();c.setStrokeColor(ink);x+=(25+pr)*sc;continue q=x+(19+pr)*sc;c.line(x+19*sc,y,q,y);c.line(q,y,q+3*sc,y+17*sc);c.line(q+3*sc,y+17*sc,q+7*sc,y-9*sc);c.line(q+7*sc,y-9*sc,q+11*sc,y);c.line(q+11*sc,y,q+18*sc,y+6*sc);c.line(q+18*sc,y+6*sc,q+25*sc,y);x=q+29*sc def arr(c,x,y,x2,y2,col=purple): c.setStrokeColor(col);c.setLineWidth(1.5);c.line(x,y,x2,y2);a=math.atan2(y2-y,x2-x);c.line(x2,y2,x2-8*math.cos(a-.4),y2-8*math.sin(a-.4));c.line(x2,y2,x2-8*math.cos(a+.4),y2-8*math.sin(a+.4)) c=canvas.Canvas(out,pagesize=A4) # 1 page(c,1);hi(c,'AV BLOCKS - DOODLE NOTES',62,770,yellow,23);text(c,'Quick ECG patterns + memory hooks',66,747,10,purple,1) # pathway for x,l,col in [(75,'SA node',yellow),(250,'AV node',blue),(425,'ventricles',pink)]: c.setFillColor(colors.white);c.setStrokeColor(col);c.setLineWidth(2);c.circle(x+43,675,37,fill=1,stroke=1);text(c,l,x+15,671,10,col,1) arr(c,155,675,210,675);arr(c,330,675,385,675);text(c,'message delayed / blocked here!',225,625,11,red,1);arr(c,300,620,293,652,red) hi(c,'THE BIG MAP',62,575,yellow,16) for i,(a,b,col) in enumerate([('1 degree','delay only',mint),('Mobitz I','longer then drop',blue),('Mobitz II','fixed then drop',orange),('3 degree','P and QRS split',pink)]): x=62+i*125;c.setFillColor(colors.white);c.setStrokeColor(col);c.roundRect(x,490,115,60,9,fill=1,stroke=1.5);text(c,a,x+9,526,11,col,1);text(c,b,x+9,506,8.5,ink) hi(c,'1 DEGREE = SLOW... BUT ALL GET THROUGH',62,450,mint,14);ecg(c,75,400,[('g',28),('g',28),('g',28)],1.3);text(c,'PR > 200 ms, fixed. Every P has QRS.',75,360,11,purple,1);arr(c,180,365,165,398,purple) box(c,65,320,220,95,'REMEMBER','No dropped beat. It is AV delay, not truly a blocked P wave.',mint);box(c,310,320,220,95,'COMMON CAUSES','High vagal tone, sleep/athletes, beta blockers, diltiazem/verapamil, digoxin.',yellow) text(c,'Usually observe + review medicines if asymptomatic.',70,195,11,blue,1) c.showPage() # 2 page(c,2);hi(c,'SECOND-DEGREE BLOCKS',62,770,yellow,22);text(c,'Look for the dropped QRS!',66,747,10,purple,1) hi(c,'A. MOBITZ I = WENCKEBACH',62,700,blue,15);text(c,'Longer... longer... longer... DROP!',68,677,12,purple,1);ecg(c,75,625,[('g',12),('g',22),('g',32),('d',38),('g',12)],1.25);text(c,'progressive PR lengthening',75,580,10,blue,1);text(c,'dropped QRS!',380,580,10,pink,1);arr(c,415,584,420,625,pink) box(c,65,540,220,82,'WHERE?','Usually AV node. Often a narrow QRS.',blue);box(c,310,540,220,82,'WHAT TO DO','Often benign if nodal. Treat cause and pace only if clinically needed.',mint) hi(c,'B. MOBITZ II',62,410,orange,15);text(c,'Fixed PR... then a surprise DROP!',68,387,12,red,1);ecg(c,75,335,[('g',22),('g',22),('d',22),('g',22)],1.4);text(c,'same PR',85,295,10,purple,1);text(c,'same PR',185,295,10,purple,1);text(c,'NO QRS!',300,295,11,red,1) box(c,65,250,220,85,'WHERE?','Usually His-Purkinje disease below the AV node. QRS may be broad.',orange);box(c,310,250,220,85,'WHY WORRY?','May progress suddenly to complete heart block.',pink) c.setFillColor(colors.HexColor('#FFF0F1'));c.setStrokeColor(red);c.roundRect(65,110,465,95,13,fill=1,stroke=2);text(c,'MOBITZ II = URGENT PACING EVALUATION',85,174,14,red,1);wrap(c,'Monitor, find reversible causes, and prepare pacing if unstable. Persistent acquired Mobitz II without a reversible cause generally needs a permanent pacemaker.',85,151,420,10,14) c.showPage() # 3 page(c,3);hi(c,'HIGH-GRADE + COMPLETE BLOCK',62,770,yellow,21);text(c,'when messages stop reaching the ventricles',66,747,10,purple,1) hi(c,'HIGH-GRADE AV BLOCK',62,700,orange,15);text(c,'2 or more P waves in a row do not conduct',68,677,11,ink);ecg(c,75,625,[('g',20),('d',20),('d',20),('g',20)],1.45);text(c,'two missed messages!',245,580,11,red,1) hi(c,'3 DEGREE = COMPLETE HEART BLOCK',62,525,pink,15);text(c,'P waves and QRS complexes have NO fixed relationship.',68,502,11,red,1) # independent lines for x in range(85,500,48): c.setStrokeColor(purple);c.line(x,450,x+5,450);c.bezier(x+5,450,x+8,458,x+13,458,x+16,450);c.line(x+16,450,x+22,450) for x in [120,260,400]: c.setStrokeColor(pink);c.line(x,390,x+15,390);c.line(x+15,390,x+20,415);c.line(x+20,415,x+26,375);c.line(x+26,375,x+33,390);c.line(x+33,390,x+46,390) text(c,'P waves: regular + faster',68,470,10,purple,1);text(c,'QRS: regular + slower',68,365,10,pink,1) box(c,65,330,220,92,'ESCAPE RHYTHM','Junctional: narrow QRS, about 40-60/min. Ventricular: broad QRS, about 20-40/min.',purple);box(c,310,330,220,92,'CAUSES','Fibrosis, MI, AV nodal drugs, myocarditis, post-op disease, congenital or infiltrative disease.',yellow) hi(c,'UNSTABLE? THINK PACING.',62,200,pink,16) for i,s in enumerate(['Monitor + IV + 12 lead ECG','Stop culprit drugs, correct causes','Transcutaneous then transvenous pacing if needed','Permanent pacemaker if persistent / not reversible']): y=165-i*32;c.setFillColor(blue);c.circle(82,y+3,10,fill=1,stroke=0);text(c,str(i+1),79,y,8,colors.white,1);text(c,s,102,y,10,ink,1) text(c,'RECAP: 1 degree = long PR | Mobitz I = longer then drop | Mobitz II = fixed then drop | 3 degree = P does not match QRS',64,29,7.8,ink,1) c.save() r=PdfReader(out); print('created',os.path.exists(out),len(r.pages),os.path.getsize(out)) PY
python - <<'PY' from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.pdfbase.pdfmetrics import stringWidth from pypdf import PdfReader import os,math out='/tmp/workspace/av-blocks-notes/output/AV_Blocks_Doodle_Notes.pdf'; W,H=A4 ink=colors.HexColor('#25313B'); paper=colors.HexColor('#FFFDF5'); blue=colors.HexColor('#4D96FF'); pink=colors.HexColor('#FF6F91'); yellow=colors.HexColor('#FFD166'); mint=colors.HexColor('#62D2A2'); orange=colors.HexColor('#FF9F43'); purple=colors.HexColor('#9B6BCE'); red=colors.HexColor('#DF3E51') def t(c,s,x,y,n=10,col=ink,b=False):c.setFillColor(col);c.setFont('Helvetica-Bold' if b else 'Helvetica',n);c.drawString(x,y,s) def pg(c,n): c.setFillColor(paper);c.rect(0,0,W,H,fill=1,stroke=0);c.setStrokeColor(colors.HexColor('#DFECF6'));c.setLineWidth(.4) for y in range(35,int(H),18):c.line(0,y,W,y) c.setStrokeColor(colors.HexColor('#FFB6C1'));c.setLineWidth(.8);c.line(42,0,42,H);t(c,f'AV BLOCKS | {n}',W-105,18,7,colors.grey) def hi(c,s,x,y,col=yellow,n=17):c.setFillColor(col);c.roundRect(x-4,y-5,stringWidth(s,'Helvetica-Bold',n)+12,n+8,4,fill=1,stroke=0);t(c,s,x,y,n,ink,True) def wrap(c,s,x,y,w,n=9,lead=12): line='';yy=y for z in s.split(): q=(line+' '+z).strip() if stringWidth(q,'Helvetica',n)<=w:line=q else:t(c,line,x,yy,n);yy-=lead;line=z t(c,line,x,yy,n) def box(c,x,y,w,h,head,body,col): c.setFillColor(colors.white);c.setStrokeColor(col);c.setLineWidth(1.5);c.roundRect(x,y-h,w,h,9,fill=1,stroke=1);hi(c,head,x+10,y-19,col,10);wrap(c,body,x+11,y-40,w-22,9,12) def arrow(c,x,y,X,Y,col=purple): c.setStrokeColor(col);c.setLineWidth(1.5);c.line(x,y,X,Y);a=math.atan2(Y-y,X-x) for d in [-.42,.42]:c.line(X,Y,X-8*math.cos(a+d),Y-8*math.sin(a+d)) def ecg(c,x,y,a,s=1): c.setStrokeColor(ink);c.setLineWidth(1.35) for kind,pr in a: c.line(x,y,x+6*s,y);c.bezier(x+6*s,y,x+9*s,y+8*s,x+14*s,y+8*s,x+17*s,y);c.line(x+17*s,y,x+19*s,y) if kind=='d':c.setStrokeColor(pink);c.setDash(2,2);c.line(x+19*s,y,x+(19+pr)*s,y);c.setDash();c.setStrokeColor(ink);x+=(24+pr)*s;continue q=x+(19+pr)*s;c.line(x+19*s,y,q,y);c.line(q,y,q+3*s,y+17*s);c.line(q+3*s,y+17*s,q+7*s,y-9*s);c.line(q+7*s,y-9*s,q+11*s,y);c.line(q+11*s,y,q+18*s,y+6*s);c.line(q+18*s,y+6*s,q+25*s,y);x=q+29*s c=canvas.Canvas(out,pagesize=A4) # page one pg(c,1);hi(c,'AV BLOCKS - DOODLE NOTES',62,770,yellow,23);t(c,'Quick ECG patterns + memory hooks',66,747,10,purple,True) for x,l,col in [(75,'SA node',yellow),(250,'AV node',blue),(425,'ventricles',pink)]:c.setFillColor(colors.white);c.setStrokeColor(col);c.setLineWidth(2);c.circle(x+43,675,37,fill=1,stroke=1);t(c,l,x+14,671,10,col,True) arrow(c,155,675,210,675);arrow(c,330,675,385,675);t(c,'BLOCK = delayed / failed message',190,625,12,red,True);arrow(c,300,620,293,652,red) hi(c,'THE BIG MAP',62,575,yellow,16) for i,(a,b,col) in enumerate([('1 degree','delay only',mint),('Mobitz I','longer then drop',blue),('Mobitz II','fixed then drop',orange),('3 degree','P and QRS split',pink)]): x=62+i*125;c.setFillColor(colors.white);c.setStrokeColor(col);c.setLineWidth(1.5);c.roundRect(x,490,115,60,9,fill=1,stroke=1);t(c,a,x+9,526,11,col,True);t(c,b,x+9,506,8.5) hi(c,'1 DEGREE = SLOW... BUT ALL GET THROUGH',62,450,mint,14);ecg(c,75,400,[('g',28),('g',28),('g',28)],1.3);t(c,'PR > 200 ms, fixed. Every P has QRS.',75,360,11,purple,True);arrow(c,180,365,165,398,purple) box(c,65,320,220,95,'REMEMBER','No dropped beat. It is AV delay, not truly a blocked P wave.',mint);box(c,310,320,220,95,'COMMON CAUSES','High vagal tone, sleep or athletes, beta blockers, diltiazem/verapamil, digoxin.',yellow);t(c,'Usually observe + review medicines if asymptomatic.',70,195,11,blue,True) c.showPage() # page 2 pg(c,2);hi(c,'SECOND-DEGREE BLOCKS',62,770,yellow,22);t(c,'Look for the dropped QRS!',66,747,10,purple,True) hi(c,'A. MOBITZ I = WENCKEBACH',62,700,blue,15);t(c,'Longer... longer... longer... DROP!',68,677,12,purple,True);ecg(c,75,625,[('g',12),('g',22),('g',32),('d',38),('g',12)],1.25);t(c,'progressive PR lengthening',75,580,10,blue,True);t(c,'dropped QRS!',380,580,10,pink,True);arrow(c,415,584,420,625,pink) box(c,65,540,220,82,'WHERE?','Usually AV node. Often a narrow QRS.',blue);box(c,310,540,220,82,'WHAT TO DO','Often benign if nodal. Treat cause and pace only if clinically needed.',mint) hi(c,'B. MOBITZ II',62,410,orange,15);t(c,'Fixed PR... then a surprise DROP!',68,387,12,red,True);ecg(c,75,335,[('g',22),('g',22),('d',22),('g',22)],1.4);t(c,'same PR',85,295,10,purple,True);t(c,'same PR',185,295,10,purple,True);t(c,'NO QRS!',300,295,11,red,True) box(c,65,250,220,85,'WHERE?','Usually His-Purkinje disease below the AV node. QRS may be broad.',orange);box(c,310,250,220,85,'WHY WORRY?','May progress suddenly to complete heart block.',pink) c.setFillColor(colors.HexColor('#FFF0F1'));c.setStrokeColor(red);c.setLineWidth(2);c.roundRect(65,110,465,95,13,fill=1,stroke=1);t(c,'MOBITZ II = URGENT PACING EVALUATION',85,174,14,red,True);wrap(c,'Monitor, find reversible causes, and prepare pacing if unstable. Persistent acquired Mobitz II without a reversible cause generally needs a permanent pacemaker.',85,151,420,10,14) c.showPage() # page 3 pg(c,3);hi(c,'HIGH-GRADE + COMPLETE BLOCK',62,770,yellow,21);t(c,'when messages stop reaching the ventricles',66,747,10,purple,True) hi(c,'HIGH-GRADE AV BLOCK',62,700,orange,15);t(c,'2 or more P waves in a row do not conduct',68,677,11);ecg(c,75,625,[('g',20),('d',20),('d',20),('g',20)],1.45);t(c,'two missed messages!',245,580,11,red,True) hi(c,'3 DEGREE = COMPLETE HEART BLOCK',62,525,pink,15);t(c,'P waves and QRS complexes have NO fixed relationship.',68,502,11,red,True) for x in range(85,500,48):c.setStrokeColor(purple);c.line(x,450,x+5,450);c.bezier(x+5,450,x+8,458,x+13,458,x+16,450);c.line(x+16,450,x+22,450) for x in [120,260,400]:c.setStrokeColor(pink);c.line(x,390,x+15,390);c.line(x+15,390,x+20,415);c.line(x+20,415,x+26,375);c.line(x+26,375,x+33,390);c.line(x+33,390,x+46,390) t(c,'P waves: regular + faster',68,470,10,purple,True);t(c,'QRS: regular + slower',68,365,10,pink,True) box(c,65,330,220,92,'ESCAPE RHYTHM','Junctional: narrow QRS, about 40-60/min. Ventricular: broad QRS, about 20-40/min.',purple);box(c,310,330,220,92,'CAUSES','Fibrosis, MI, AV nodal drugs, myocarditis, post-op disease, congenital or infiltrative disease.',yellow) hi(c,'UNSTABLE? THINK PACING.',62,200,pink,16) for i,s in enumerate(['Monitor + IV + 12 lead ECG','Stop culprit drugs, correct causes','Transcutaneous then transvenous pacing if needed','Permanent pacemaker if persistent / not reversible']): y=165-i*32;c.setFillColor(blue);c.circle(82,y+3,10,fill=1,stroke=0);t(c,str(i+1),79,y,8,colors.white,True);t(c,s,102,y,10,ink,True) t(c,'RECAP: 1 degree = long PR | Mobitz I = longer then drop | Mobitz II = fixed then drop | 3 degree = P does not match QRS',64,29,7.8,ink,True) c.save();r=PdfReader(out);print('created=',os.path.exists(out),'pages=',len(r.pages),'bytes=',os.path.getsize(out)) PY
AV Blocks Doodle Notes
PDF Document · PDF