med-math-practice / index.html
josgrevar's picture
Static med math practice
98e9e4e verified
Raw History Blame Contribute Delete
4.38 kB
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/>
<title>Med Math Practice</title>
<style>
body{font-family:system-ui,sans-serif;max-width:720px;margin:2rem auto;padding:0 1rem;background:#f7fafc;color:#1a202c}
.card{background:#fff;border-radius:12px;padding:1.25rem;box-shadow:0 1px 3px rgba(0,0,0,.08)}
h1{font-size:1.4rem} .muted{color:#4a5568;font-size:.9rem}
pre{white-space:pre-wrap;background:#edf2f7;padding:.75rem;border-radius:8px}
input{padding:.5rem;border:1px solid #cbd5e0;border-radius:8px;width:8rem}
button{margin-top:.75rem;margin-right:.5rem;padding:.55rem 1rem;border:0;border-radius:8px;background:#2b6cb0;color:#fff;cursor:pointer}
button.secondary{background:#718096}
#feedback{margin-top:1rem;padding:.75rem;border-radius:8px} .ok{background:#c6f6d5} .bad{background:#fed7d7}
</style></head><body>
<div class="card">
<h1>Medication Math Practice</h1>
<p class="muted">Educational practice only — not for real dosing decisions. Check your work against your course rules.</p>
<p id="meta" class="muted"></p>
<pre id="prompt"></pre>
<label>Your answer <input id="ans" type="number" step="any"/> <span id="unit"></span></label><br/>
<button id="check">Check</button>
<button id="next" class="secondary">Next</button>
<div id="feedback" hidden></div>
<p id="score" class="muted"></p>
</div>
<script>
const P = [{"kind": "Oral dosage", "prompt": "Ordered: amoxicillin 500 mg PO. Available: 250 mg capsules. How many capsules?", "answer": 2.0, "unit": "capsules", "explain": "500 \u00f7 250 = 2 capsules."}, {"kind": "Oral dosage", "prompt": "Ordered: digoxin 0.125 mg PO. Available: 0.25 mg tablets. How many tablets?", "answer": 0.5, "unit": "tablets", "explain": "0.125 \u00f7 0.25 = 0.5 tablet."}, {"kind": "Oral dosage", "prompt": "Ordered: acetaminophen 650 mg PO. Available: 325 mg tablets. How many tablets?", "answer": 2.0, "unit": "tablets", "explain": "650 \u00f7 325 = 2 tablets."}, {"kind": "Oral liquid", "prompt": "Ordered: amoxicillin 400 mg PO. Available: 200 mg/5 mL. How many mL?", "answer": 10.0, "unit": "mL", "explain": "400 \u00f7 200 \u00d7 5 = 10 mL."}, {"kind": "Oral liquid", "prompt": "Ordered: diphenhydramine 25 mg PO. Available: 12.5 mg/5 mL. How many mL?", "answer": 10.0, "unit": "mL", "explain": "25 \u00f7 12.5 \u00d7 5 = 10 mL."}, {"kind": "Weight-based", "prompt": "Ordered: acetaminophen 15 mg/kg for a 20 kg child. Total dose in mg?", "answer": 300.0, "unit": "mg", "explain": "15 \u00d7 20 = 300 mg."}, {"kind": "IV drip", "prompt": "Infuse 1000 mL over 8 hours. Drop factor 15 gtt/mL. gtt/min?", "answer": 31.0, "unit": "gtt/min", "explain": "(1000\u00d715)/(8\u00d760) \u2248 31 gtt/min."}, {"kind": "IV drip", "prompt": "Infuse 500 mL over 4 hours. Drop factor 10 gtt/mL. gtt/min?", "answer": 21.0, "unit": "gtt/min", "explain": "(500\u00d710)/(4\u00d760) \u2248 21 gtt/min."}, {"kind": "IV rate", "prompt": "Infuse 1000 mL over 10 hours. mL/hr?", "answer": 100.0, "unit": "mL/hr", "explain": "1000 \u00f7 10 = 100 mL/hr."}, {"kind": "IV rate", "prompt": "Infuse 250 mL over 2 hours. mL/hr?", "answer": 125.0, "unit": "mL/hr", "explain": "250 \u00f7 2 = 125 mL/hr."}];
let i=0, correct=0, answered=false;
const meta=document.getElementById('meta'), prompt=document.getElementById('prompt'), unit=document.getElementById('unit'), feedback=document.getElementById('feedback'), score=document.getElementById('score'), ans=document.getElementById('ans');
function render(){
answered=false; feedback.hidden=true; ans.value='';
const p=P[i]; meta.textContent=`Problem ${i+1} of ${P.length} · ${p.kind}`;
prompt.textContent=p.prompt; unit.textContent=p.unit;
score.textContent=`Score: ${correct} / ${i} checked`;
}
document.getElementById('check').onclick=()=>{
if(ans.value===''){feedback.hidden=false;feedback.textContent='Enter a number.';return;}
if(answered)return; answered=true;
const p=P[i], val=parseFloat(ans.value), ok=Math.abs(val-p.answer)<0.51;
if(ok)correct++;
feedback.hidden=false; feedback.className=ok?'ok':'bad';
feedback.innerHTML=(ok?'Correct. ':'Not quite. Expected about '+p.answer+' '+p.unit+'. ')+p.explain;
score.textContent=`Score: ${correct} / ${i+1} checked`;
};
document.getElementById('next').onclick=()=>{ i=(i+1)%P.length; if(i===0)correct=0; render(); };
render();
</script></body></html>