We need to make a POWER presentation on oxygen therapy for Wednesday clinical meeting. The aim is to explain indications, escalation/de-escalation and safe use of oxygen along with various oxygen devices make it detailed
~/
oxygen therapy AND safety
British Thoracic Society Guideline oxygen use adults healthcare emergency settings target saturation 94 98 88 92
oxygen delivery devices nasal cannula Venturi mask non rebreather mask high flow nasal oxygen diagram
oxygen dissociation curve hypercapnia oxygen therapy physiology diagram
https://www.brit-thoracic.org.uk/clinical-resources/guidelin…
oxygen therapy acute illness AND mortality
mkdir -p "/tmp/workspace/oxygen-therapy-clinical-meeting/src" "/tmp/workspace/oxygen-therapy-clinical-meeting/output"
~/oxygen-therapy-clinical-meeting/src/create_deck.py
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.shapes import MSO_SHAPE, MSO_CONNECTOR
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.dml import MSO_THEME_COLOR
from pptx.enum.shapes import MSO_AUTO_SHAPE_TYPE
from pptx.oxml.xmlchemy import OxmlElement
from pptx.oxml.ns import qn
OUT='/tmp/workspace/oxygen-therapy-clinical-meeting/output/Oxygen_Therapy_Clinical_Meeting.pptx'
prs=Presentation(); prs.slide_width=Inches(13.333); prs.slide_height=Inches(7.5)
blank=prs.slide_layouts[6]
# palette
NAVY=RGBColor(10,34,58); TEAL=RGBColor(0,135,145); SKY=RGBColor(70,171,190); PALE=RGBColor(232,246,247)
INK=RGBColor(24,39,54); GREY=RGBColor(96,112,126); LIGHT=RGBColor(245,248,250); WHITE=RGBColor(255,255,255)
ORANGE=RGBColor(232,130,38); RED=RGBColor(190,62,62); GREEN=RGBColor(36,142,100); YELLOW=RGBColor(245,199,70)
def bg(slide, color=WHITE):
shp=slide.background.fill; shp.solid(); shp.fore_color.rgb=color
def rect(slide,x,y,w,h,fill, radius=False, line=None):
s=slide.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE if radius else MSO_SHAPE.RECTANGLE, Inches(x),Inches(y),Inches(w),Inches(h))
s.fill.solid(); s.fill.fore_color.rgb=fill
s.line.color.rgb = line if line else fill
return s
def txt(slide,x,y,w,h,text,size=18,color=INK,bold=False,align=PP_ALIGN.LEFT, font='Aptos', valign=MSO_ANCHOR.TOP):
s=slide.shapes.add_textbox(Inches(x),Inches(y),Inches(w),Inches(h)); tf=s.text_frame; tf.clear(); tf.word_wrap=True
tf.margin_left=tf.margin_right=tf.margin_top=tf.margin_bottom=0
tf.vertical_anchor=valign
lines=text.split('\n')
for i,line in enumerate(lines):
p=tf.paragraphs[0] if i==0 else tf.add_paragraph(); p.text=line; p.alignment=align
p.space_after=Pt(4)
for r in p.runs:
r.font.name=font; r.font.size=Pt(size); r.font.bold=bold; r.font.color.rgb=color
return s
def title(slide,t,sub=None,n=None):
rect(slide,0,0,13.333,.18,TEAL)
txt(slide,.58,.34,11.9,.45,t,28,NAVY,True)
if sub: txt(slide,.6,.82,11.9,.28,sub,10,GREY)
if n: txt(slide,12.3,.38,.45,.25,str(n).zfill(2),10,TEAL,True,PP_ALIGN.RIGHT)
def footer(slide):
rect(slide,.58,7.14,12.15,.012,RGBColor(210,220,226))
txt(slide,.6,7.2,8,.16,'Oxygen therapy | Adult acute care clinical meeting | 30 September 2026',8,GREY)
def pill(slide,x,y,w,text,fill=PALE,color=TEAL):
s=rect(slide,x,y,w,.35,fill,True); txt(slide,x+.12,y+.06,w-.24,.2,text,10,color,True,PP_ALIGN.CENTER); return s
def bullet_list(slide,x,y,w,items,size=16,color=INK,lead=0.33):
s=slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(5.7)); tf=s.text_frame; tf.clear(); tf.word_wrap=True
tf.margin_left=tf.margin_right=tf.margin_top=tf.margin_bottom=0
for i,item in enumerate(items):
p=tf.paragraphs[0] if i==0 else tf.add_paragraph(); p.text=item; p.level=0; p.space_after=Pt(10); p.font.size=Pt(size); p.font.color.rgb=color; p.font.name='Aptos'
# XML bullet
pPr=p._p.get_or_add_pPr(); bu=OxmlElement('a:buChar'); bu.set('char','•'); pPr.insert(0,bu)
return s
def add_note(slide, text):
notes=slide.notes_slide.notes_text_frame
notes.text=text
# 1
s=prs.slides.add_slide(blank); bg(s,NAVY)
rect(s,.65,.72,.1,5.95,TEAL); pill(s,.98,.82,2.25,'WEDNESDAY CLINICAL MEETING',RGBColor(19,65,84),WHITE)
txt(s,.98,1.5,10.9,1.5,'Oxygen therapy',42,WHITE,True)
txt(s,1.0,3.02,10.8,.8,'Indications, target-based escalation, de-escalation and safe device use',23,RGBColor(205,231,235))
txt(s,1.0,5.45,8,.35,'Adult acute-care focus',16,WHITE,True)
txt(s,1.0,5.9,8,.55,'Clinical meeting | 30 September 2026',16,RGBColor(178,209,214))
# pulse visual
for i,(lab,col) in enumerate([('AIR',SKY),('O₂',TEAL),('TARGET',GREEN)]):
rect(s,9.4+i*1.05,5.95,.85,.48,col,True); txt(s,9.4+i*1.05,6.09,.85,.14,lab,9,WHITE,True,PP_ALIGN.CENTER)
add_note(s,'Use oxygen as a titrated drug, not a default comfort measure. This meeting is an adult acute-care overview; follow local escalation and oxygen prescribing policies.')
#2
s=prs.slides.add_slide(blank); bg(s); title(s,'Learning objectives','By the end, participants should be able to make a safe bedside oxygen plan.',2); footer(s)
objs=[('01','Recognize','when oxygen is indicated and when it is not.'),('02','Prescribe','a target saturation, device and flow, then document response.'),('03','Escalate','oxygen support while treating the cause and identifying ventilatory failure.'),('04','Step down','oxygen safely once the patient is stable.')]
for i,(num,verb,rest) in enumerate(objs):
y=1.45+i*1.28; rect(s,.7,y,11.85,.94,LIGHT,True); rect(s,.7,y,.9,.94,TEAL,True); txt(s,.7,y+.27,.9,.25,num,18,WHITE,True,PP_ALIGN.CENTER); txt(s,1.85,y+.18,2.05,.28,verb,18,NAVY,True); txt(s,3.75,y+.2,8.2,.35,rest,16,INK)
#3 physiology
s=prs.slides.add_slide(blank); bg(s); title(s,'What oxygen therapy can and cannot fix','Oxygen raises inspired oxygen and arterial oxygenation. It does not correct every cause of tissue hypoxia.',3); footer(s)
rect(s,.68,1.35,5.85,4.95,PALE,True); txt(s,.98,1.66,5.2,.35,'The clinical objective',21,NAVY,True); txt(s,.98,2.3,5.25,.85,'Adequate tissue oxygen delivery (DO₂)',24,TEAL,True,PP_ALIGN.CENTER)
txt(s,1.25,3.35,4.7,.5,'DO₂ = cardiac output × arterial O₂ content',17,INK,True,PP_ALIGN.CENTER)
txt(s,1.05,4.2,5.1,1.25,'CaO₂ ≈ (1.34 × Hb × SaO₂) + (0.003 × PaO₂)\nMost oxygen is carried on haemoglobin.',15,GREY,False,PP_ALIGN.CENTER)
rect(s,6.85,1.35,5.78,4.95,LIGHT,True); txt(s,7.18,1.66,5.1,.35,'Bedside implication',21,NAVY,True)
bullet_list(s,7.2,2.35,5.05,['Hypoxaemia may improve with oxygen.','Anaemia needs haemorrhage control and/or transfusion strategy.','Low cardiac output or shock needs cause-directed resuscitation.','Ventilatory failure needs assessment of PaCO₂, pH and ventilatory support.'],15)
txt(s,.82,6.55,11.5,.28,'Do not confuse a normal SpO₂ with adequate oxygen delivery in severe anaemia or shock.',13,RED,True,PP_ALIGN.CENTER)
#4 indications
s=prs.slides.add_slide(blank); bg(s); title(s,'Indications: give oxygen for hypoxaemia, not breathlessness alone','Start promptly if critically unwell, then confirm with oximetry and/or blood gas.',4); footer(s)
rect(s,.7,1.35,5.9,4.85,RGBColor(236,248,242),True); txt(s,1.0,1.68,5.2,.3,'Accepted acute indications',20,GREEN,True)
bullet_list(s,1.0,2.25,5.15,['Documented hypoxaemia: generally PaO₂ <60 mmHg or SaO₂/SpO₂ <90%.','Suspected hypoxaemia with respiratory distress while assessment is underway.','Severe trauma, severe acute anaemia, shock/low cardiac output with metabolic acidosis.','Acute MI only when hypoxaemic.'],15)
rect(s,6.8,1.35,5.82,4.85,RGBColor(253,244,239),True); txt(s,7.1,1.68,5.05,.3,'Do not use oxygen as a reflex',20,ORANGE,True)
bullet_list(s,7.1,2.25,5.05,['Dyspnoea with normal oxygenation requires diagnosis and symptom management, not automatic oxygen.','Normoxaemic acute coronary syndrome does not need routine oxygen.','Oxygen may be used for comfort in palliative care only after considering goals of care.','Always investigate and treat the underlying cause.'],15)
#5 targets
s=prs.slides.add_slide(blank); bg(s); title(s,'Prescribe a target range before choosing a device','Oxygen is a drug: target range + delivery device + flow + monitoring.',5); footer(s)
rect(s,.7,1.35,5.85,4.9,RGBColor(231,246,248),True); txt(s,1.0,1.7,5.2,.35,'Most acutely ill adults',21,NAVY,True); txt(s,1.0,2.35,5.15,.84,'SpO₂ 94-98%',38,TEAL,True,PP_ALIGN.CENTER); txt(s,1.0,3.45,5.15,.55,'Unless a different target is clinically specified.',15,GREY,False,PP_ALIGN.CENTER); pill(s,2.1,4.65,3.1,'Controlled, target-based oxygen',TEAL,WHITE)
rect(s,6.78,1.35,5.85,4.9,RGBColor(254,241,239),True); txt(s,7.1,1.7,5.2,.35,'Risk of hypercapnic respiratory failure',20,RED,True); txt(s,7.1,2.35,5.15,.84,'SpO₂ 88-92%',38,RED,True,PP_ALIGN.CENTER); txt(s,7.1,3.45,5.15,.85,'Known COPD or previous hypercapnic respiratory failure, morbid obesity, neuromuscular/chest-wall disease or other local-policy risks, pending blood gases.',14,GREY,False,PP_ALIGN.CENTER); pill(s,8.2,4.82,3.0,'Use controlled oxygen',ORANGE,WHITE)
txt(s,.85,6.57,11.7,.25,'If critically ill, start oxygen immediately. Do not delay resuscitation for a blood gas.',13,NAVY,True,PP_ALIGN.CENTER)
#6 assess
s=prs.slides.add_slide(blank); bg(s); title(s,'First 5 minutes: assess, stabilize, define the problem','Pulse oximetry is a monitoring tool, not a complete respiratory assessment.',6); footer(s)
steps=[('1','ABCDE','Airway, work of breathing, RR, mental state, perfusion and exposure.'),('2','Oximetry','Record SpO₂, target range, device and flow. Check waveform and probe site.'),('3','Blood gas','Obtain early if severe illness, risk of hypercapnia, unexplained hypoxaemia, or deterioration.'),('4','Cause','CXR/POCUS, ECG, labs and sepsis/PE/heart-failure evaluation as clinically indicated.'),('5','Response','Reassess after any device or flow change and escalate early if failing.')]
for i,(n,a,b) in enumerate(steps):
x=.75+(i%3)*4.15; y=1.45+(i//3)*2.3
rect(s,x,y,3.72,1.73,LIGHT,True); rect(s,x+.2,y+.2,.55,.55,TEAL,True); txt(s,x+.2,y+.35,.55,.13,n,13,WHITE,True,PP_ALIGN.CENTER)
txt(s,x+.9,y+.22,2.45,.25,a,17,NAVY,True); txt(s,x+.25,y+.94,3.15,.55,b,12,INK)
#7 devices table
s=prs.slides.add_slide(blank); bg(s); title(s,'Oxygen delivery devices: match device to physiology and required support','FiO₂ is approximate with variable-performance systems and varies with inspiratory demand.',7); footer(s)
headers=['Device','Typical flow','Approx. FiO₂','Best use / key limitation']
rows=[['Nasal cannula','1-6 L/min','~24-45%','Comfortable, eating/talking. Variable FiO₂; needs nasal patency.'],['Simple face mask','5-10 L/min','~35-60%','Moderate need. Never run <5 L/min due to CO₂ rebreathing risk.'],['Venturi mask','Fixed by adaptor','24-60%','Predictable controlled FiO₂, especially hypercapnia risk.'],['Non-rebreather mask','10-15 L/min','up to ~95%','Severe hypoxaemia while definitive support arranged. Keep reservoir inflated.'],['HFNO','up to 60 L/min','21-100%','High flow, humidified, reliable FiO₂; monitored setting and failure recognition.'],['CPAP / NIV','Device-specific','Titrated','Positive pressure. NIV for ventilatory failure when appropriate, not just higher oxygen.']]
xs=[.7,3.05,4.72,6.35]; widths=[2.25,1.55,1.45,6.2]
for x,w,h in zip(xs,widths,headers): rect(s,x,1.35,w,.54,NAVY); txt(s,x+.08,1.52,w-.16,.16,h,12,WHITE,True,PP_ALIGN.CENTER)
for r,row in enumerate(rows):
y=1.89+r*.72; fill=LIGHT if r%2==0 else WHITE
for x,w,val in zip(xs,widths,row): rect(s,x,y,w,.72,fill,line=RGBColor(220,228,233)); txt(s,x+.08,y+.14,w-.16,.45,val,11,INK, r==0 and False)
#8 device selection ladder
s=prs.slides.add_slide(blank); bg(s); title(s,'Practical escalation: device is not the endpoint','Escalate for failure to maintain target, rising work of breathing, worsening gases or altered mental state.',8); footer(s)
levels=[('1','LOW','Nasal cannula\n1-6 L/min',SKY),('2','CONTROLLED','Venturi mask\nfixed FiO₂',TEAL),('3','HIGH CONCENTRATION','Non-rebreather\n10-15 L/min',ORANGE),('4','ADVANCED','HFNO / CPAP / NIV\ncritical-care pathway',RED)]
for i,(n,lab,desc,col) in enumerate(levels):
x=.72+i*3.15; y=2.1-i*.27; rect(s,x,y,2.72,3.0,col,True); txt(s,x+.2,y+.27,.36,.2,n,14,WHITE,True); txt(s,x+.28,y+.85,2.15,.3,lab,15,WHITE,True,PP_ALIGN.CENTER); txt(s,x+.25,y+1.5,2.2,.65,desc,16,WHITE,False,PP_ALIGN.CENTER)
if i<3:
ar=s.shapes.add_connector(MSO_CONNECTOR.STRAIGHT,Inches(x+2.75),Inches(y+1.5),Inches(x+3.08),Inches(y+1.5)); ar.line.color.rgb=NAVY; ar.line.width=Pt(2)
txt(s,.85,5.85,11.7,.55,'At every step: reassess SpO₂ target, RR, work of breathing, mental state, haemodynamics and blood gases when indicated. Treat the underlying diagnosis in parallel.',15,NAVY,True,PP_ALIGN.CENTER)
#9 failure
s=prs.slides.add_slide(blank); bg(s); title(s,'Recognize oxygen failure early','A rising oxygen requirement can be the first sign of clinical deterioration.',9); footer(s)
cols=[('Oxygenation failure',['SpO₂ remains below target despite correct device and adequate flow','Rapidly increasing FiO₂/flow requirement','Severe hypoxaemia or peri-arrest physiology'],RED),('Ventilatory failure',['Rising PaCO₂ or respiratory acidosis','Exhaustion, reduced consciousness, poor respiratory effort','COPD exacerbation: consider NIV pathway when appropriate'],ORANGE),('Clinical failure',['RR rising, increased work of breathing, inability to speak','Haemodynamic instability, confusion, cyanosis','Call senior/critical-care support early'],TEAL)]
for i,(hd,items,col) in enumerate(cols):
x=.7+i*4.18; rect(s,x,1.45,3.78,4.75,LIGHT,True); rect(s,x,1.45,3.78,.65,col,True); txt(s,x+.15,1.66,3.45,.2,hd,16,WHITE,True,PP_ALIGN.CENTER); bullet_list(s,x+.25,2.45,3.22,items,14)
#10 hypercapnia
s=prs.slides.add_slide(blank); bg(s); title(s,'Hypercapnia risk: controlled oxygen, blood gases and ventilation','Do not withhold oxygen from a hypoxaemic patient. Titrate to 88-92% while assessing PaCO₂ and pH.',10); footer(s)
rect(s,.7,1.35,3.7,4.95,RGBColor(254,241,239),True); txt(s,1,1.7,3.08,.3,'Who is at risk?',20,RED,True); bullet_list(s,1,2.28,3.05,['Known COPD with prior CO₂ retention','Obesity hypoventilation syndrome','Neuromuscular disease or chest-wall disorders','Previous oxygen alert card / local record'],15)
rect(s,4.78,1.35,3.7,4.95,PALE,True); txt(s,5.05,1.7,3.1,.3,'Initial approach',20,TEAL,True); bullet_list(s,5.05,2.28,3.05,['Set target 88-92%.','Use Venturi mask or low-flow cannula as clinically appropriate.','Obtain arterial or arterialised capillary blood gas early.','Recheck gases after significant changes or deterioration.'],15)
rect(s,8.85,1.35,3.78,4.95,RGBColor(246,240,252),True); txt(s,9.15,1.7,3.1,.3,'If acidosis develops',20,NAVY,True); bullet_list(s,9.15,2.28,3.05,['Treat trigger: bronchodilators, antibiotics, diuresis, etc.','Consider NIV if cooperative and haemodynamically stable, according to local protocol.','Escalate urgently for worsening acidosis, exhaustion or reduced consciousness.'],15)
#11 deescalation
s=prs.slides.add_slide(blank); bg(s); title(s,'De-escalation: reduce oxygen once stable','Oxygen should be stepped down, not simply left running after the acute event.',11); footer(s)
flow=[('1. Confirm stability','SpO₂ in target range, improving work of breathing, stable haemodynamics and no new deterioration.'),('2. Reduce support','Lower flow/FiO₂ or change to a simpler device. One change at a time when feasible.'),('3. Reassess','Check SpO₂, RR, work of breathing and clinical status after reduction; repeat gas if indicated.'),('4. Discontinue','Stop oxygen when stable on room air within prescribed target. Continue observation.'),('5. Re-escalate','If SpO₂ falls, reinstate prior effective support and reassess the cause.')]
for i,(hd,body) in enumerate(flow):
y=1.35+i*1.05; rect(s,.75,y,11.83,.8,LIGHT,True); rect(s,.75,y,.36,.8,TEAL,True); txt(s,1.32,y+.15,2.7,.25,hd,15,NAVY,True); txt(s,4.02,y+.15,8.12,.36,body,13,INK)
txt(s,.9,6.72,11.45,.2,'Do not “wean” by accepting below-target saturations. A fall in saturation requires reassessment.',13,RED,True,PP_ALIGN.CENTER)
#12 safety
s=prs.slides.add_slide(blank); bg(s); title(s,'Safe administration: a bedside checklist','Most oxygen harm is preventable through target-based prescribing, monitoring and basic equipment checks.',12); footer(s)
checks=[('Prescription','Target range, device and flow documented. Emergency oxygen can start immediately, then prescribe promptly.'),('Device','Correct device and flow. Venturi adaptor matches prescribed FiO₂. Reservoir bag inflated on non-rebreather.'),('Monitoring','Record SpO₂ with device/flow, RR and response. Verify pulse-ox waveform and clinical correlation.'),('Skin & comfort','Check nares, ears and mask pressure areas. Humidify appropriately for prolonged high-flow therapy per local policy.'),('Fire safety','No smoking, flames, sparks or petroleum-based products near oxygen. Display oxygen-in-use precautions.'),('Transport','Ensure adequate cylinder volume, secure cylinder, correct regulator and handover of target/device/flow.')]
for i,(a,b) in enumerate(checks):
x=.72+(i%2)*6.15; y=1.35+(i//2)*1.7; rect(s,x,y,5.78,1.34,LIGHT,True); pill(s,x+.2,y+.18,1.28,a,TEAL,WHITE); txt(s,x+.2,y+.72,5.26,.4,b,12,INK)
#13 pitfalls
s=prs.slides.add_slide(blank); bg(s); title(s,'Common pitfalls and safer alternatives','Make the oxygen plan visible at the bedside and in handover.',13); footer(s)
pairs=[('“Oxygen for any shortness of breath”','Confirm hypoxaemia. Treat asthma, PE, oedema, acidosis, pain or anxiety appropriately.'),('“100% until someone says stop”','Set the prescribed target and titrate down once immediate danger is controlled.'),('“SpO₂ is all that matters”','Assess RR, effort, consciousness, perfusion, waveform, Hb, CO and blood gases when indicated.'),('“More oxygen fixes CO₂ retention”','Controlled oxygen, early gas analysis and ventilatory support pathway if acidotic.'),('“Stable at rest means safe for transfer”','Reassess on exertion/transfer and confirm cylinder supply, device, target and handover.')]
for i,(bad,good) in enumerate(pairs):
y=1.3+i*1.05; rect(s,.7,y,3.9,.75,RGBColor(253,239,239),True); txt(s,.92,y+.18,3.43,.25,bad,13,RED,True); rect(s,4.87,y,7.75,.75,RGBColor(237,248,243),True); txt(s,5.12,y+.18,7.25,.25,good,13,GREEN,True)
#14 mini cases
s=prs.slides.add_slide(blank); bg(s); title(s,'Apply the framework: 3 rapid cases','Ask: What is the target? What device? When will you reassess and escalate?',14); footer(s)
cases=[('Case A: pneumonia','SpO₂ 86% on room air, RR 32, alert, no chronic CO₂-retention history.','Target 94-98%. Give prompt oxygen, assess severity and cause, monitor response. Escalate device/support if target not achieved.'),('Case B: COPD exacerbation','SpO₂ 82% on room air, drowsy, previous hypercapnic admission.','Target 88-92%. Controlled oxygen, urgent blood gas, treat exacerbation. Escalate for acidosis/ventilatory failure.'),('Case C: post-operative dyspnoea','SpO₂ 97% room air, tachypnoea, pleuritic pain.','Oxygen is not the primary treatment. Assess urgently for PE, atelectasis, pain, sepsis or other cause; monitor and intervene based on findings.')]
for i,(a,b,c) in enumerate(cases):
x=.68+i*4.22; rect(s,x,1.35,3.86,4.9,LIGHT,True); rect(s,x,1.35,3.86,.62,[TEAL,ORANGE,RED][i],True); txt(s,x+.15,1.57,3.56,.16,a,15,WHITE,True,PP_ALIGN.CENTER); txt(s,x+.25,2.35,3.28,1.25,b,14,INK); rect(s,x+.25,4.15,3.28,1.45,PALE,True); txt(s,x+.43,4.36,2.92,1.04,c,13,NAVY)
#15 algorithm
s=prs.slides.add_slide(blank); bg(s); title(s,'One-page bedside algorithm','Use alongside local emergency, NIV, ICU and prescribing policies.',15); footer(s)
boxes=[('1. Suspect hypoxaemia / critical illness','ABCDE. Start oxygen immediately if unstable; attach oximetry.'),('2. Set target','94-98% for most. 88-92% if hypercapnia risk pending gases.'),('3. Select device','Low-flow or Venturi if appropriate. High-concentration mask for severe hypoxaemia.'),('4. Reassess promptly','SpO₂, RR, effort, consciousness, haemodynamics; blood gas if indicated.'),('5. Failing?','Escalate device and call senior/critical-care support. Address oxygenation vs ventilation failure.'),('6. Improving?','Reduce device/flow while maintaining target. Stop when stable on room air.')]
for i,(a,b) in enumerate(boxes):
x=.85+(i%3)*4.18; y=1.4+(i//3)*2.45; rect(s,x,y,3.5,1.65,PALE if i<3 else LIGHT,True); txt(s,x+.2,y+.22,3.08,.25,a,15,NAVY,True,PP_ALIGN.CENTER); txt(s,x+.26,y+.72,2.98,.55,b,12,INK,False,PP_ALIGN.CENTER)
if i<3:
ln=s.shapes.add_connector(MSO_CONNECTOR.STRAIGHT,Inches(x+3.53), Inches(y+.82), Inches(x+4.08), Inches(y+.82)); ln.line.color.rgb=TEAL; ln.line.width=Pt(2)
#16 key takeaways
s=prs.slides.add_slide(blank); bg(s,NAVY)
txt(s,.8,.6,11.7,.38,'Key takeaways',30,WHITE,True); txt(s,.82,1.12,10.9,.25,'The safest oxygen plan is targeted, reassessed and cause-directed.',16,RGBColor(190,220,225))
keys=[('1','Oxygen is a drug','Prescribe a saturation target, device and flow.'),('2','Treat hypoxaemia','Do not use oxygen as routine therapy for normoxaemic breathlessness.'),('3','Escalate early','A rising oxygen requirement is a deterioration signal, not a diagnosis.'),('4','Do not overlook ventilation','Blood gases and pH matter when hypercapnia risk or clinical failure is present.'),('5','Step down deliberately','Reduce and stop oxygen once stable, with continued observation.')]
for i,(n,a,b) in enumerate(keys):
y=1.7+i*.92; rect(s,.85,y,11.6,.7,RGBColor(19,62,80),True); pill(s,1.03,y+.16,.52,n,TEAL,WHITE); txt(s,1.82,y+.17,2.65,.22,a,14,WHITE,True); txt(s,4.55,y+.17,7.2,.25,b,13,RGBColor(211,233,236))
txt(s,.85,6.72,11.6,.25,'Please align this deck with your organisation’s oxygen policy, escalation pathways and equipment availability.',11,RGBColor(180,209,214),False,PP_ALIGN.CENTER)
#17 refs
s=prs.slides.add_slide(blank); bg(s); title(s,'References and local adaptation','Core sources used for this clinical teaching deck.',17); footer(s)
refs=[
'British Thoracic Society. Guideline for oxygen use in healthcare and emergency settings. Thorax. 2017;72(Suppl 1):ii1-ii90. Current BTS page notes 94-98% for most acutely ill adults and 88-92% for patients at risk of hypercapnic respiratory failure.',
'O’Driscoll BR, Howard LS, Earis J, Mak V. BTS summary of guideline for hospital use. Oxygen should be prescribed to a target range, with device/flow recorded; reduce and discontinue in stable patients.',
'Fishman’s Pulmonary Diseases and Disorders, 6th ed. Chapter 143: Supplemental Oxygen Therapy. Oxygen is a drug with indications, a therapeutic window, monitoring requirements and potential toxicities.',
'Murray & Nadel’s Textbook of Respiratory Medicine, 7th ed. Chapter 137: Oxygen Therapy and Oxygen Delivery Systems. Device characteristics, approximate flows and FiO₂ values.',
'Cao L, et al. Effects of oxygenation targets on mortality in critically ill patients in ICUs: systematic review and meta-analysis. Anesth Analg. 2024. PMID: 38315626.'
]
bullet_list(s,.78,1.35,11.7,refs,13)
rect(s,.78,5.95,11.7,.65,PALE,True); txt(s,1.0,6.15,11.25,.2,'Local additions before presenting: your hospital oxygen prescription chart, MET/rapid response criteria, NIV/ICU referral pathway, transport policy and device formulary.',12,NAVY,True,PP_ALIGN.CENTER)
# Slide metadata
prs.core_properties.title='Oxygen Therapy: Indications, Escalation, De-escalation and Safe Use'
prs.core_properties.subject='Adult acute-care clinical meeting'
prs.core_properties.author='Orris'
prs.save(OUT)
print(OUT)
python "/tmp/workspace/oxygen-therapy-clinical-meeting/src/create_deck.py" && ls -lh "/tmp/workspace/oxygen-therapy-clinical-meeting/output/Oxygen_Therapy_Clinical_Meeting.pptx"
python - <<'PY' from pptx import Presentation p='/tmp/workspace/oxygen-therapy-clinical-meeting/output/Oxygen_Therapy_Clinical_Meeting.pptx' prs=Presentation(p) print('slides',len(prs.slides)) for i,s in enumerate(prs.slides,1): texts=[] for sh in s.shapes: if sh.has_text_frame and sh.text.strip(): texts.append(sh.text.replace('\n',' | ')) print(i, len(texts), ' :: ', ' / '.join(texts[:3])) PY
Oxygen Therapy Clinical Meeting
Presentation · PPTX