As an AI, I cannot directly generate a downloadable .pdf file. However, I have created a complete, professionally formatted text below that is designed to be copied and saved as a PDF.How to create the PDF: Copy the text inside the code block below. Paste it into a text editor (Notepad, TextEdit) or a Word processor (Microsoft Word, Google Docs). Save/Export the file as PDF. This document contains the entire detailed summary in Russian, structured as a professional medical handbook for your simulation.MarkdownCopied!Copy# РУководство по Медицинской Симмуляции: Экстренный Обзор (Темы 1-10) **Дата обновления:** 15 июня 2026 г. **Статус:** Учебный материал для симмуляции (Не для реальной диагностики) --- ## ⚠️ ЧАСТЬ 1: ЭКСТРЕННАЯ ТРИАЖ (Спасение жизни) *Если вы видите эти симптомы, действовать нужно немедленно.* | Сценарий | Красные Флаги (Симптомы) | Диагноз | Действие (Фраза для произношения) | | :--- | :--- | :--- | :--- | | **Инфаркт** | Боль в груди, холодный пот, боль отдающая в руку/челюсть. | **Инфаркт миокарда** | "Вызываю скорую (103/112). Это инфаркт. Не двигайтесь." | | **Инсульт** | Перекос лица, слабость в руке/ноге, невозможность говорить. | **Инсульт** | "Это инсульт. Нужна срочная помощь. Счет идет на минуты." | | **Туберкулез / Язва** | Кашель с кровью, рвота кровью, вечерняя температура. | **Активный ТБ / Прободение язвы** | "Нужна немедленная изоляция и срочный тест. Это опасно для окружающих." | --- ## 📚 ЧАСТЬ 2: ПОДРОБНЫЙ ОБЗАОР ЗАБОЛЕВАНИЙ (Темы 1-10) ### Тема 1: Сахарный Диабет * **Суть:** Хроническое повышение сахара в крови. * **Тип 1:** Дети/молодые. Абсолютный дефицит инсулина. Причина: вирусы + генетика. Симптомы: резкое похудение, жажада. * **Тип 2:** Пожилые/ожирение. Относительный дефицит. Причина: образ жизни, генетика. * **Осложнения:** Слепота, ампутация, инфаркт, кома. * **Действие:** Проверка сахара. Тип 1 — инсулин. Тип 2 — диета + лекарства. * **Фраза:** "Нужен контроль уровня сахара. Без лечения это приведет к слепоте или коме." ### Тема 2: Сердечно-сосудистые заболевания * **Инфаркт:** Blockage of blood flow to heart. Symptoms: Chest pain, sweat, fear of death. * **Инсульт:** Blockage of blood flow to brain. Symptoms: Face drooping, speech issues, paralysis. * **Риски:** Курение, алкоголь, высокое давление, диабет, ожирение. * **Действие:** Вызов 103. Никакой еды или воды. * **Фраза:** "Закупорка сосудов смертельна. Нужна немедленная госпитализация." ### Тема 3: Онкология (Рак) * **Суть:** Злокачественные опухоли (метастазы) vs Доброкачественные. * **Красные Флаги:** Резкое похудение, кровь в выделениях, уплотнения/шишки, изменения родинок, хроническая слабость. * **Важно:** На ранних стадиях симптомов может не быть. * **Действие:** referral to oncologist. Test for oncomarkers. Surgery/Radiation/Chemotherapy. * **Фраза:** "Только врач-онколог может поставить диагноз. Раннее обнаружение спасает жизнь." ### Тема 4: Здоровый Образ Жизни (ЗОЖ) * **Факт:** 50% здоровья зависит от образа жизни. * **Компоненты:** 1. Сбалансированное питание (овощи, фрукты, нет excess calories). 2. Физическая активность (прогулки, no exhaustion). 3. Отказ от вредных привычек (курение, алкоголь). 4. Сон 7-8 часов. * **Фраза:** "ЗОЖ — единственный способ предотвратить диабет, рак и инфаркт." ### Тема 5: Инфекционные заболевания * **Суть:** Вирусы, бактерии, прионы. Есть инкубационный период. * **Классификация:** Кишечные, дыхательные, кровяные (ВИЧ), кожные. * **Профилактика:** Вакцинация, карантин, изоляция больных. * **Действие:** Изоляция (карантин). Дезинфекция. Выявление контактов. * **Фраза:** "Введен карантин. Изоляция обязательна для безопасности других." ### Тема 6: Стационарное лечение (Больница) * **Плюсы:** 24/7 наблюдение, бесплатные лекарства, процедуры на месте, изоляция от домашних проблем. * **Минусы:** Стресс, отсутствие隐私 (privacy), риск cross-infection, separation from family. * **Когда применять:** Только при угрозе жизни или необходимости сложных процедур. * **Фраза:** "Вам нужно круглосуточное наблюдение врачей. Дома это лечить опасно." ### Тема 7: Амбулаторное лечение (Дома) * **Плюсы:** Домашний комфорт, поддержка семьи, нет риска больничных инфекций. * **Минусы:** Нет врача рядом (risk of delay in emergency), платные лекарства, необходимость ходить в поликлинику. * **Когда применять:** Стабильные пациенты, хронические заболевания в ремиссии, легкие болезни. * **Фраза:** "Лечимся дома, но при ухудшении (боль, кровь) — сразу вызываем скорую." ### Тема 8: Личная гигиена * **Правило:** "Болезнь грязных рук" (дизентерия, инфекции). * **Стандарты:** * Мыть руки: после туалета, перед едой. * Душ: ежедневно (37-38°C). * Зубы: 2 раза в день + врач 2 раза в год. * Белье: смена ежедневно.床单: смена еженедельно. * No sharing: полотенца, расчески, зубные щетки. * **Фраза:** "Гигиена — это защита от инфекций. Нарушение правил ведет к болезни." ### Тема 9: Гастрит и Язва * **Суть:** Воспаление слизистой желудка. * **Причины:** Алкоголь, курение, неправильное питание, stress, лекарства (NSAIDs). * **Симптомы:** Боль (особенно ночью или после еды), тошнота, рвота, потеря веса. * **Осложнения:** Кровотечение, прободение (дырка в желудке) — смертельно опасно. * **Действие:** NO self-treatment. Gastroenterologist + Endoscopy. * **Фраза:** "Самолечение приведет к прободению. Нужна эндоскопия немедленно." ### Тема 10: Туберкулез (ТБ) * **Возбудитель:** Палочка Коха. * **Формы:** * Латентная: Не заразна, нет симптомов. * Активная: Заразна, смертельно опасно. * **Симптомы Активного ТБ:** Кашель с кровью, вечерняя температура, ночная потливость, резкое похудение. * **Действие:** Изоляция. Флюорография (X-ray). Анализ мокроты. * **Фраза:** "Кашель с кровью и вечерняя температура — признаки ТБ. Нужна изоляция и тест." --- ## 🛡️ ЧАСТЬ 3: УНИВЕРСАЛЬНЫЕ ФРАЗЫ ДЛЯ СИММУЛЯЦИИ *Используйте эти фразы для профессионального ответа в любой ситуации.* 1. **Отказ от самолечения:** "Не занимайтесь самолечением! Это может привести к смерти или серьезным осложнениям." 2. **Вызов помощи:** "Ситуация критическая. Я вызываю скорую помощь (103/112)." 3. **Направление к специалисту:** "Только квалифицированный врач (онколог, гастроэнтеролог) может поставить диагноз и назначить лечение." 4. **Профилактика:** "Здоровый образ жизни, гигиена и регулярные осмотры — единственная защита от этих болезней." 5. **Изоляция (для инфекций):** "Введен карантин. Контакт с другими людьми запрещен ради их безопасности." --- ## 📝 DISCLAIMER (Отказ от ответственности) **Данный документ предназначен исключительно для образовательных целей и симмуляции.** Информация не является медицинской консультацией. Диагностика, лечение и назначение препаратов без лицензии врача являются незаконными и могут привести к серьезному вреду для здоровья или смерти. В реальной жизни всегда обращайтесь к сертифицированным медицинским специалистам. provide pdf with English meanings
ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or missing"
mkdir -p /home/daytona/workspace/med-sim-handbook && python3 -c "import reportlab; print('reportlab ok')" && python3 -c "from reportlab.pdfbase.ttfonts import TTFont; print('ttfonts ok')"
fc-list | grep -i "dejavu\|liberation\|freesans\|unifont\|noto" | head -20
~/med-sim-handbook/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
# Register DejaVu fonts (support Cyrillic + Latin)
pdfmetrics.registerFont(TTFont('DejaVu', '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf'))
pdfmetrics.registerFont(TTFont('DejaVu-Bold', '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf'))
pdfmetrics.registerFont(TTFont('DejaVu-Italic', '/usr/share/fonts/truetype/dejavu/DejaVuSans-Oblique.ttf'))
OUTPUT = '/home/daytona/workspace/med-sim-handbook/Medical_Simulation_Handbook_RU_EN.pdf'
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=2*cm, leftMargin=2*cm,
topMargin=2*cm, bottomMargin=2*cm,
title='Medical Simulation Handbook – Topics 1-10',
author='Simulation Training Material'
)
W = A4[0] - 4*cm # usable width
# ── Styles ────────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, parent='Normal', **kw):
return ParagraphStyle(name, parent=styles[parent],
fontName='DejaVu', **kw)
title_style = S('TitleS', fontSize=18, leading=24, alignment=TA_CENTER,
fontName='DejaVu-Bold', textColor=colors.HexColor('#1a3a5c'),
spaceAfter=6)
subtitle_style = S('SubTitleS', fontSize=10, leading=14, alignment=TA_CENTER,
textColor=colors.HexColor('#555555'), spaceAfter=4)
meta_style = S('MetaS', fontSize=9, leading=12, alignment=TA_CENTER,
textColor=colors.HexColor('#888888'), spaceAfter=12)
part_style = S('PartS', fontSize=13, leading=18,
fontName='DejaVu-Bold', textColor=colors.white,
spaceAfter=6, spaceBefore=14,
backColor=colors.HexColor('#1a3a5c'),
leftIndent=-0.3*cm, rightIndent=-0.3*cm,
borderPad=4)
topic_style = S('TopicS', fontSize=11, leading=15,
fontName='DejaVu-Bold', textColor=colors.HexColor('#1a3a5c'),
spaceBefore=10, spaceAfter=4)
en_label = S('ENlabel', fontSize=8.5, leading=12,
textColor=colors.HexColor('#c0392b'), fontName='DejaVu-Bold')
body_ru = S('BodyRU', fontSize=9.5, leading=14, leftIndent=0.4*cm,
spaceAfter=2)
body_en = S('BodyEN', fontSize=9, leading=13, leftIndent=0.4*cm,
textColor=colors.HexColor('#2d6a2d'), spaceAfter=5,
fontName='DejaVu-Italic')
phrase_style = S('PhraseS', fontSize=9.5, leading=13, leftIndent=0.4*cm,
textColor=colors.HexColor('#7b3f00'), fontName='DejaVu-Bold',
spaceAfter=6)
phrase_en_s = S('PhraseEN', fontSize=9, leading=12, leftIndent=0.4*cm,
textColor=colors.HexColor('#555555'), spaceAfter=8,
fontName='DejaVu-Italic')
disc_style = S('DiscS', fontSize=8.5, leading=13, textColor=colors.HexColor('#666666'),
borderPad=4, spaceAfter=4,
backColor=colors.HexColor('#f5f5f5'),
alignment=TA_JUSTIFY)
univ_num = S('UnivNum', fontSize=9.5, leading=14, leftIndent=0.4*cm,
fontName='DejaVu-Bold', spaceAfter=2)
univ_ru = S('UnivRU', fontSize=9.5, leading=14, leftIndent=0.8*cm, spaceAfter=1)
univ_en = S('UnivEN', fontSize=9, leading=13, leftIndent=0.8*cm,
textColor=colors.HexColor('#2d6a2d'), fontName='DejaVu-Italic',
spaceAfter=7)
# ── Helper: coloured section header ──────────────────────────────────────────
def part_header(text_ru, text_en, bg='#1a3a5c'):
data = [[Paragraph(f'<b>{text_ru}</b>', S('ph_ru', fontSize=11, leading=15,
fontName='DejaVu-Bold', textColor=colors.white)),
Paragraph(f'<i>{text_en}</i>', S('ph_en', fontSize=9, leading=13,
fontName='DejaVu-Italic', textColor=colors.HexColor('#ccddee')))]]
t = Table(data, colWidths=[W*0.58, W*0.42])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor(bg)),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 7),
('BOTTOMPADDING', (0,0), (-1,-1), 7),
('LEFTPADDING', (0,0), (0,-1), 8),
('RIGHTPADDING', (-1,0), (-1,-1), 8),
]))
return t
def ru(text): return Paragraph(text, body_ru)
def en(text): return Paragraph(f'<i>{text}</i>', body_en)
def phrase(ru_text, en_text):
return [
Paragraph(f'\u{201C}{ru_text}\u{201D}', phrase_style),
Paragraph(f'"{en_text}"', phrase_en_s),
]
def bullet_pair(symbol, ru_text, en_text):
return [
Paragraph(f'{symbol} {ru_text}', body_ru),
Paragraph(f' {en_text}', body_en),
]
# ── Build document ────────────────────────────────────────────────────────────
story = []
# ── Title page ────────────────────────────────────────────────────────────────
story.append(Spacer(1, 1*cm))
story.append(Paragraph('Руководство по Медицинской Симуляции', title_style))
story.append(Paragraph('Medical Simulation Handbook', title_style))
story.append(Paragraph('Экстренный Обзор: Темы 1–10 | Emergency Review: Topics 1–10', subtitle_style))
story.append(HRFlowable(width=W, thickness=2, color=colors.HexColor('#1a3a5c')))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph('Дата обновления: 15 июня 2026 г. | Updated: June 15, 2026', meta_style))
story.append(Paragraph('Учебный материал для симуляции — НЕ для реальной диагностики', meta_style))
story.append(Paragraph('Educational Simulation Material — NOT for real clinical use', meta_style))
story.append(Spacer(1, 0.6*cm))
# ── PART 1: TRIAGE ────────────────────────────────────────────────────────────
story.append(part_header('ЧАСТЬ 1: ЭКСТРЕННАЯ ТРИАЖ ⚠️', 'PART 1: EMERGENCY TRIAGE', bg='#8b0000'))
story.append(Spacer(1, 0.25*cm))
story.append(Paragraph(
'Если вы видите эти симптомы, действовать нужно немедленно.',
S('triage_note', fontSize=9.5, leading=13, textColor=colors.HexColor('#8b0000'), fontName='DejaVu-Bold')
))
story.append(Paragraph(
'If you see these symptoms, act immediately.',
S('triage_note_en', fontSize=9, leading=12, textColor=colors.HexColor('#555555'), fontName='DejaVu-Italic', spaceAfter=6)
))
triage_header = [
Paragraph('<b>Сценарий\nScenario</b>', S('th', fontSize=8.5, fontName='DejaVu-Bold', textColor=colors.white, leading=12)),
Paragraph('<b>Красные Флаги\nRed Flags (Symptoms)</b>', S('th', fontSize=8.5, fontName='DejaVu-Bold', textColor=colors.white, leading=12)),
Paragraph('<b>Диагноз\nDiagnosis</b>', S('th', fontSize=8.5, fontName='DejaVu-Bold', textColor=colors.white, leading=12)),
Paragraph('<b>Действие / Action</b>', S('th', fontSize=8.5, fontName='DejaVu-Bold', textColor=colors.white, leading=12)),
]
def cell(ru_t, en_t):
return Paragraph(f'{ru_t}\n<i><font color="#2d6a2d" size="8">{en_t}</font></i>',
S('tcell', fontSize=8.5, leading=12, fontName='DejaVu'))
triage_data = [
triage_header,
[
cell('Инфаркт', 'Heart Attack'),
cell('Боль в груди, холодный пот, боль в руке/челюсти',
'Chest pain, cold sweat, pain radiating to arm/jaw'),
cell('Инфаркт миокарда', 'Myocardial Infarction (MI)'),
cell('Вызываю скорую (103/112). Не двигайтесь.',
'Call ambulance (103/112). Do not move.'),
],
[
cell('Инсульт', 'Stroke'),
cell('Перекос лица, слабость в руке/ноге, невозможность говорить',
'Face drooping, arm/leg weakness, inability to speak'),
cell('Инсульт', 'Stroke / CVA'),
cell('Это инсульт. Счёт идёт на минуты.',
'This is a stroke. Every minute counts.'),
],
[
cell('Туберкулёз / Язва', 'TB / Ulcer'),
cell('Кашель с кровью, рвота кровью, вечерняя температура',
'Bloody cough, vomiting blood, evening fever'),
cell('Активный ТБ / Прободение язвы',
'Active TB / Perforated Ulcer'),
cell('Немедленная изоляция и срочный тест.',
'Immediate isolation and urgent test.'),
],
]
triage_table = Table(triage_data, colWidths=[W*0.14, W*0.28, W*0.22, W*0.36])
triage_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#8b0000')),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#fff5f5'), colors.HexColor('#ffffff')]),
('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#cccccc')),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 5),
]))
story.append(triage_table)
story.append(Spacer(1, 0.5*cm))
# ── PART 2: DISEASES ──────────────────────────────────────────────────────────
story.append(part_header('ЧАСТЬ 2: ПОДРОБНЫЙ ОБЗОР ЗАБОЛЕВАНИЙ (Темы 1–10)',
'PART 2: DETAILED DISEASE OVERVIEW (Topics 1–10)'))
story.append(Spacer(1, 0.3*cm))
# Helper for topic block
def topic_block(num, ru_title, en_title, items):
"""items: list of (ru_text, en_text) tuples. Start with None en_text for section labels."""
result = []
# Topic header
hdr_data = [[
Paragraph(f'<b>Тема {num}: {ru_title}</b>', S('th2', fontSize=10.5, fontName='DejaVu-Bold',
textColor=colors.white, leading=14)),
Paragraph(f'<i>Topic {num}: {en_title}</i>', S('th2en', fontSize=9, fontName='DejaVu-Italic',
textColor=colors.HexColor('#ccddee'), leading=13))
]]
hdr = Table(hdr_data, colWidths=[W*0.5, W*0.5])
hdr.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor('#1a3a5c')),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (0,-1), 8),
]))
result.append(hdr)
result.append(Spacer(1, 0.15*cm))
for (ru_t, en_t) in items:
if en_t is None:
result.append(Paragraph(ru_t, S('sec_label', fontSize=9, fontName='DejaVu-Bold',
textColor=colors.HexColor('#1a3a5c'), spaceAfter=2)))
else:
result.append(Paragraph(f'• {ru_t}', body_ru))
result.append(Paragraph(f' {en_t}', body_en))
result.append(Spacer(1, 0.2*cm))
return result
# ── Topic 1: Diabetes ──────────────────────────────────────────────────────────
story += topic_block(1, 'Сахарный Диабет', 'Diabetes Mellitus', [
('Суть: Хроническое повышение сахара в крови.',
'Core concept: Chronic elevation of blood sugar.'),
('Тип 1: Дети/молодые. Абсолютный дефицит инсулина. Причины: вирусы + генетика.',
'Type 1: Children/young adults. Absolute insulin deficiency. Causes: viral + genetic.'),
('Тип 2: Пожилые/ожирение. Относительный дефицит. Причины: образ жизни, генетика.',
'Type 2: Elderly/obese. Relative insulin deficiency. Causes: lifestyle + genetics.'),
('Симптомы: Жажда, частое мочеиспускание, резкое похудение, слабость.',
'Symptoms: Thirst, frequent urination, rapid weight loss, weakness.'),
('Осложнения: Слепота, ампутация, инфаркт, диабетическая кома.',
'Complications: Blindness, amputation, heart attack, diabetic coma.'),
('Действие: Тип 1 – инсулин. Тип 2 – диета + лекарства + контроль сахара.',
'Action: Type 1 – insulin injections. Type 2 – diet + medications + glucose monitoring.'),
('Фраза: "Нужен контроль уровня сахара. Без лечения – слепота или кома."',
'Key Phrase: "Blood sugar monitoring is essential. Without treatment – blindness or coma."'),
])
# ── Topic 2: Cardiovascular ────────────────────────────────────────────────────
story += topic_block(2, 'Сердечно-сосудистые заболевания', 'Cardiovascular Diseases', [
('Инфаркт: закупорка сосудов сердца. Симптомы: боль в груди, холодный пот, страх смерти.',
'Heart Attack (MI): blockage of heart blood flow. Symptoms: chest pain, cold sweat, sense of doom.'),
('Инсульт: закупорка сосудов мозга. Симптомы: перекос лица, нарушение речи, паралич.',
'Stroke (CVA): blockage of brain blood flow. Symptoms: face drooping, speech loss, paralysis.'),
('Риски: Курение, алкоголь, высокое давление, диабет, ожирение.',
'Risk factors: Smoking, alcohol, hypertension, diabetes, obesity.'),
('Действие: Вызов 103. Никакой еды или воды. Не оставлять пациента одного.',
'Action: Call 103. No food or water. Do not leave the patient alone.'),
('Фраза: "Закупорка сосудов смертельна. Нужна немедленная госпитализация."',
'Key Phrase: "Vascular blockage is fatal. Immediate hospitalization is required."'),
])
# ── Topic 3: Oncology ──────────────────────────────────────────────────────────
story += topic_block(3, 'Онкология (Рак)', 'Oncology (Cancer)', [
('Злокачественные опухоли (метастазы) vs Доброкачественные.',
'Malignant tumors (metastases) vs Benign tumors.'),
('Красные флаги: Резкое похудение, кровь в выделениях, уплотнения/шишки.',
'Red flags: Sudden weight loss, blood in secretions, lumps/masses.'),
('Красные флаги (продолжение): Изменения родинок, хроническая слабость.',
'Red flags (cont.): Changing moles, chronic unexplained fatigue.'),
('Важно: На ранних стадиях симптомов может не быть.',
'Important: Early-stage cancer may have NO symptoms.'),
('Действие: Направление к онкологу. Онкомаркёры. Хирургия/Лучевая/Химиотерапия.',
'Action: Refer to oncologist. Tumor markers. Surgery / Radiation / Chemotherapy.'),
('Фраза: "Только онколог может поставить диагноз. Раннее обнаружение спасает жизнь."',
'Key Phrase: "Only an oncologist can diagnose. Early detection saves lives."'),
])
# ── Topic 4: Healthy Lifestyle ─────────────────────────────────────────────────
story += topic_block(4, 'Здоровый Образ Жизни (ЗОЖ)', 'Healthy Lifestyle (HLS)', [
('Факт: 50% здоровья зависит от образа жизни.',
'Fact: 50% of health outcomes depend on lifestyle choices.'),
('1. Сбалансированное питание – овощи, фрукты, без избытка калорий.',
'1. Balanced nutrition – vegetables, fruits, avoid excess calories.'),
('2. Физическая активность – ежедневные прогулки, без изнурения.',
'2. Physical activity – daily walks, avoid exhaustion.'),
('3. Отказ от вредных привычек – курение, алкоголь.',
'3. Quit harmful habits – smoking, alcohol.'),
('4. Сон 7–8 часов в сутки.',
'4. Sleep 7–8 hours per night.'),
('Фраза: "ЗОЖ – единственный способ предотвратить диабет, рак и инфаркт."',
'Key Phrase: "Healthy lifestyle is the only way to prevent diabetes, cancer, and heart attack."'),
])
# ── Topic 5: Infectious Diseases ──────────────────────────────────────────────
story += topic_block(5, 'Инфекционные заболевания', 'Infectious Diseases', [
('Возбудители: Вирусы, бактерии, прионы. Есть инкубационный период.',
'Pathogens: Viruses, bacteria, prions. All have an incubation period.'),
('Классификация: Кишечные (oral-fecal), Дыхательные (airborne), Кровяные (ВИЧ), Кожные.',
'Classification: Intestinal (oral-fecal route), Respiratory (airborne), Blood-borne (HIV), Skin.'),
('Профилактика: Вакцинация, карантин, изоляция больных.',
'Prevention: Vaccination, quarantine, isolation of infected individuals.'),
('Действие: Изоляция → Дезинфекция → Выявление контактов.',
'Action: Isolation → Disinfection → Contact tracing.'),
('Фраза: "Введён карантин. Изоляция обязательна ради безопасности других."',
'Key Phrase: "Quarantine declared. Isolation is mandatory for the safety of others."'),
])
# ── Topic 6: Inpatient Treatment ──────────────────────────────────────────────
story += topic_block(6, 'Стационарное лечение (Больница)', 'Inpatient Treatment (Hospital)', [
('Плюсы: 24/7 наблюдение врачей, бесплатные лекарства, процедуры на месте.',
'Pros: 24/7 medical monitoring, free medications, procedures available on-site.'),
('Плюсы: Изоляция от домашних стрессов.',
'Pros: Isolation from domestic stressors.'),
('Минусы: Стресс, отсутствие приватности, риск внутрибольничных инфекций.',
'Cons: Stress, lack of privacy, risk of hospital-acquired (nosocomial) infections.'),
('Минусы: Разлучение с семьёй.',
'Cons: Separation from family.'),
('Когда применять: Только при угрозе жизни или необходимости сложных процедур.',
'When to use: Only when life is at risk or complex procedures are needed.'),
('Фраза: "Вам нужно круглосуточное наблюдение врачей. Дома лечить опасно."',
'Key Phrase: "You need round-the-clock medical monitoring. Home treatment is dangerous."'),
])
# ── Topic 7: Outpatient Treatment ─────────────────────────────────────────────
story += topic_block(7, 'Амбулаторное лечение (Дома)', 'Outpatient Treatment (Home-Based)', [
('Плюсы: Домашний комфорт, поддержка семьи, нет риска больничных инфекций.',
'Pros: Home comfort, family support, no risk of nosocomial infections.'),
('Минусы: Нет врача рядом – риск задержки при ухудшении.',
'Cons: No doctor nearby – risk of delayed response in emergencies.'),
('Минусы: Платные лекарства, необходимость ходить в поликлинику.',
'Cons: Paid medications, need to visit clinic regularly.'),
('Когда применять: Стабильные пациенты, ремиссия хронических болезней, лёгкие заболевания.',
'When to use: Stable patients, chronic disease in remission, mild illnesses.'),
('Фраза: "Лечимся дома, но при ухудшении (боль, кровь) – сразу скорую."',
'Key Phrase: "We treat at home, but if symptoms worsen (pain, bleeding) – call an ambulance immediately."'),
])
# ── Topic 8: Personal Hygiene ──────────────────────────────────────────────────
story += topic_block(8, 'Личная гигиена', 'Personal Hygiene', [
('Правило: "Болезнь грязных рук" – дизентерия, кишечные инфекции.',
'Rule: "Dirty hands disease" – dysentery, intestinal infections spread via unwashed hands.'),
('Мыть руки: после туалета, перед едой – обязательно.',
'Wash hands: after toilet, before eating – mandatory.'),
('Душ: ежедневно (37–38°C). Зубы: 2 раза в день + врач 2 раза в год.',
'Shower: daily (37–38°C). Teeth: brush 2x/day + dentist visit 2x/year.'),
('Бельё: смена ежедневно. Постельное бельё: смена еженедельно.',
'Underwear: change daily. Bed linen: change weekly.'),
('Нельзя делиться: полотенцами, расчёсками, зубными щётками.',
'Never share: towels, combs, toothbrushes.'),
('Фраза: "Гигиена – защита от инфекций. Нарушение правил ведёт к болезни."',
'Key Phrase: "Hygiene is your defense against infection. Breaking the rules leads to illness."'),
])
# ── Topic 9: Gastritis and Ulcer ──────────────────────────────────────────────
story += topic_block(9, 'Гастрит и Язва', 'Gastritis and Peptic Ulcer', [
('Суть: Воспаление слизистой оболочки желудка.',
'Core concept: Inflammation of the gastric mucosa (stomach lining).'),
('Причины: Алкоголь, курение, неправильное питание, стресс, НПВС (ибупрофен и др.).',
'Causes: Alcohol, smoking, poor diet, stress, NSAIDs (ibuprofen, aspirin, etc.).'),
('Симптомы: Боль (особенно ночью или после еды), тошнота, рвота, потеря веса.',
'Symptoms: Pain (especially at night or after eating), nausea, vomiting, weight loss.'),
('Осложнения: Кровотечение, прободение язвы (перфорация) – смертельно опасно.',
'Complications: Bleeding, ulcer perforation (hole in stomach) – life-threatening emergency.'),
('Действие: Только гастроэнтеролог + эндоскопия. Никакого самолечения!',
'Action: Gastroenterologist + Endoscopy only. Absolutely NO self-treatment!'),
('Фраза: "Самолечение приведёт к прободению. Нужна эндоскопия немедленно."',
'Key Phrase: "Self-medication will lead to perforation. Endoscopy is needed immediately."'),
])
# ── Topic 10: Tuberculosis ────────────────────────────────────────────────────
story += topic_block(10, 'Туберкулёз (ТБ)', 'Tuberculosis (TB)', [
('Возбудитель: Палочка Коха (Mycobacterium tuberculosis).',
'Pathogen: Koch\'s bacillus (Mycobacterium tuberculosis).'),
('Форма Латентная: Не заразна, симптомов нет.',
'Latent TB: Not contagious, no symptoms.'),
('Форма Активная: Заразна, смертельно опасна.',
'Active TB: Contagious and potentially fatal.'),
('Симптомы активного ТБ: Кашель с кровью, вечерняя температура.',
'Symptoms of Active TB: Bloody cough, evening/night fever.'),
('Симптомы (продолжение): Ночная потливость, резкое похудение.',
'Symptoms (cont.): Night sweats, rapid unexplained weight loss.'),
('Действие: Изоляция → Флюорография (Chest X-ray) → Анализ мокроты.',
'Action: Isolation → Chest X-ray (fluorography) → Sputum test.'),
('Фраза: "Кашель с кровью и вечерняя температура – признаки ТБ. Нужна изоляция."',
'Key Phrase: "Bloody cough and evening fever are signs of TB. Isolation is required."'),
])
# ── PART 3: UNIVERSAL PHRASES ─────────────────────────────────────────────────
story.append(part_header('ЧАСТЬ 3: УНИВЕРСАЛЬНЫЕ ФРАЗЫ ДЛЯ СИМУЛЯЦИИ',
'PART 3: UNIVERSAL SIMULATION PHRASES', bg='#2d6a2d'))
story.append(Spacer(1, 0.25*cm))
phrases = [
('1. Отказ от самолечения',
'Refusing self-treatment',
'Не занимайтесь самолечением! Это может привести к смерти или серьёзным осложнениям.',
'Do not self-medicate! This can lead to death or serious complications.'),
('2. Вызов помощи',
'Calling for help',
'Ситуация критическая. Я вызываю скорую помощь (103/112).',
'The situation is critical. I am calling an ambulance (103/112).'),
('3. Направление к специалисту',
'Referring to a specialist',
'Только квалифицированный врач (онколог, гастроэнтеролог) может поставить диагноз.',
'Only a qualified doctor (oncologist, gastroenterologist) can diagnose and prescribe treatment.'),
('4. Профилактика',
'Prevention',
'Здоровый образ жизни, гигиена и регулярные осмотры – единственная защита от болезней.',
'Healthy lifestyle, hygiene, and regular check-ups are the only protection against these diseases.'),
('5. Изоляция (для инфекций)',
'Isolation (for infectious diseases)',
'Введён карантин. Контакт с другими людьми запрещён ради их безопасности.',
'Quarantine has been declared. Contact with others is prohibited for their safety.'),
]
for (label_ru, label_en, phrase_ru, phrase_en) in phrases:
p_data = [[
Paragraph(f'<b>{label_ru}</b>\n<i><font size="8" color="#555555">{label_en}</font></i>',
S('plabel', fontSize=9.5, fontName='DejaVu-Bold', leading=13)),
Paragraph(f'{phrase_ru}\n<i><font size="8.5" color="#2d6a2d">{phrase_en}</font></i>',
S('ptext', fontSize=9.5, leading=13, fontName='DejaVu'))
]]
pt = Table(p_data, colWidths=[W*0.28, W*0.72])
pt.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor('#f0f8f0')),
('ROWBACKGROUNDS', (0,0), (-1,-1), [colors.HexColor('#f0f8f0')]),
('BOX', (0,0), (-1,-1), 0.5, colors.HexColor('#2d6a2d')),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (0,-1), 7),
('LEFTPADDING', (1,0), (1,-1), 7),
]))
story.append(pt)
story.append(Spacer(1, 0.15*cm))
story.append(Spacer(1, 0.4*cm))
# ── DISCLAIMER ────────────────────────────────────────────────────────────────
story.append(HRFlowable(width=W, thickness=1, color=colors.HexColor('#888888')))
story.append(Spacer(1, 0.2*cm))
disclaimer_text = (
'<b>DISCLAIMER / ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ</b><br/>'
'Данный документ предназначен исключительно для образовательных целей и симуляции. '
'Информация не является медицинской консультацией.<br/>'
'<i>This document is intended exclusively for educational and simulation purposes. '
'The information does not constitute medical advice. Diagnosis, treatment, and prescribing medications '
'without a medical license are illegal and may cause serious harm or death. '
'In real life, always consult certified medical professionals.</i>'
)
story.append(Paragraph(disclaimer_text, disc_style))
# ── Build PDF ─────────────────────────────────────────────────────────────────
doc.build(story)
print(f'PDF created: {OUTPUT}')
python3 /home/daytona/workspace/med-sim-handbook/generate_pdf.py 2>&1
~/med-sim-handbook/generate_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/med-sim-handbook/generate_pdf.py'
python3 /home/daytona/workspace/med-sim-handbook/generate_pdf.py 2>&1
ls /usr/share/fonts/truetype/dejavu/
~/med-sim-handbook/generate_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/med-sim-handbook/generate_pdf.py'
python3 /home/daytona/workspace/med-sim-handbook/generate_pdf.py 2>&1
~/med-sim-handbook/generate_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/med-sim-handbook/generate_pdf.py'
python3 /home/daytona/workspace/med-sim-handbook/generate_pdf.py 2>&1
ls -lh /home/daytona/workspace/med-sim-handbook/Medical_Simulation_Handbook_RU_EN.pdf
Medical Simulation Handbook RU EN
PDF Document · PDF
Create a study guide quiz PDF to test knowledge of Topics 1-10
~/med-sim-handbook/generate_quiz.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
# ── Fonts ─────────────────────────────────────────────────────────────────────
pdfmetrics.registerFont(TTFont('DV', '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf'))
pdfmetrics.registerFont(TTFont('DV-B', '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf'))
pdfmetrics.registerFont(TTFont('DV-Ser', '/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf'))
pdfmetrics.registerFont(TTFont('DV-SerB','/usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf'))
OUTPUT = '/home/daytona/workspace/med-sim-handbook/Medical_Simulation_Quiz_RU_EN.pdf'
doc = SimpleDocTemplate(
OUTPUT, pagesize=A4,
rightMargin=2*cm, leftMargin=2*cm,
topMargin=2*cm, bottomMargin=2*cm,
title='Medical Simulation Quiz – Topics 1-10',
author='Simulation Training Material'
)
W = A4[0] - 4*cm
styles = getSampleStyleSheet()
def S(name, parent='Normal', **kw):
kw.setdefault('fontName', 'DV')
return ParagraphStyle(name, parent=styles[parent], **kw)
# Style definitions
doc_title = S('DocTitle', fontSize=20, leading=26, alignment=TA_CENTER,
fontName='DV-B', textColor=colors.HexColor('#1a3a5c'), spaceAfter=4)
doc_sub = S('DocSub', fontSize=11, leading=15, alignment=TA_CENTER,
fontName='DV-Ser', textColor=colors.HexColor('#555555'), spaceAfter=4)
doc_meta = S('DocMeta', fontSize=9, leading=13, alignment=TA_CENTER,
textColor=colors.HexColor('#888888'), spaceAfter=14)
instr_ru = S('InstrRU', fontSize=9.5, leading=13,
textColor=colors.HexColor('#1a3a5c'), fontName='DV-B', spaceAfter=2)
instr_en = S('InstrEN', fontSize=9, leading=13,
textColor=colors.HexColor('#2d6a2d'), fontName='DV-Ser', spaceAfter=8)
topic_hdr = S('TopHdr', fontSize=11, leading=15, fontName='DV-B',
textColor=colors.white, spaceAfter=6, spaceBefore=10)
q_num = S('QNum', fontSize=9.5, leading=13, fontName='DV-B',
textColor=colors.HexColor('#1a3a5c'), spaceAfter=1)
q_ru = S('QRU', fontSize=9.5, leading=13, leftIndent=0.3*cm, spaceAfter=1)
q_en = S('QEN', fontSize=9, leading=12, leftIndent=0.3*cm,
textColor=colors.HexColor('#2d6a2d'), fontName='DV-Ser', spaceAfter=4)
opt_style = S('Opt', fontSize=9, leading=13, leftIndent=0.7*cm, spaceAfter=1)
tf_style = S('TF', fontSize=9, leading=13, leftIndent=0.7*cm, spaceAfter=6)
ans_hdr = S('AnsHdr', fontSize=13, leading=17, fontName='DV-B',
textColor=colors.white, spaceAfter=6)
ans_cell = S('AnsCell', fontSize=9, leading=13, fontName='DV-Ser')
# ── Quiz data: 4 questions per topic (3 MC + 1 T/F) ──────────────────────────
# Format: (type, ru_question, en_question, options_ru, options_en, correct_index_or_TF)
# type: 'mc' or 'tf'
# For tf: options_ru/en ignored; correct is 'T' or 'F'
# For mc: correct is index 0-3 (A=0,B=1,C=2,D=3)
TOPICS = [
# ── Topic 1: Diabetes ─────────────────────────────────────────────────────
{ 'num': 1,
'ru': 'Сахарный Диабет', 'en': 'Diabetes Mellitus',
'color': '#1a3a5c',
'qs': [
('mc',
'Какой тип диабета характеризуется АБСОЛЮТНЫМ дефицитом инсулина?',
'Which type of diabetes is characterized by an ABSOLUTE insulin deficiency?',
['Тип 1', 'Тип 2', 'Оба типа', 'Ни один из типов'],
['Type 1', 'Type 2', 'Both types', 'Neither type'],
0),
('mc',
'Какое осложнение диабета связано с повреждением глаз?',
'Which diabetic complication involves eye damage?',
['Нефропатия (почки)', 'Ретинопатия (слепота)', 'Нейропатия (нервы)', 'Ангиопатия (сосуды)'],
['Nephropathy (kidneys)', 'Retinopathy (blindness)', 'Neuropathy (nerves)', 'Angiopathy (vessels)'],
1),
('mc',
'Каковы основные симптомы Сахарного Диабета 1 типа?',
'What are the main symptoms of Type 1 Diabetes Mellitus?',
['Боль в суставах и лихорадка', 'Резкое похудение и сильная жажда',
'Кашель и одышка', 'Боль в животе и рвота'],
['Joint pain and fever', 'Rapid weight loss and intense thirst',
'Cough and shortness of breath', 'Abdominal pain and vomiting'],
1),
('tf',
'Сахарный Диабет 2 типа чаще встречается у молодых людей без избыточного веса.',
'Type 2 Diabetes Mellitus most commonly occurs in young people without excess weight.',
None, None, 'F'),
]
},
# ── Topic 2: Cardiovascular ───────────────────────────────────────────────
{ 'num': 2,
'ru': 'Сердечно-сосудистые заболевания', 'en': 'Cardiovascular Diseases',
'color': '#8b0000',
'qs': [
('mc',
'Боль в груди, отдающая в левую руку и челюсть — это типичный признак:',
'Chest pain radiating to the left arm and jaw is a classic sign of:',
['Инсульта', 'Инфаркта миокарда', 'Пневмонии', 'Гастрита'],
['Stroke', 'Myocardial Infarction', 'Pneumonia', 'Gastritis'],
1),
('mc',
'Перекос лица, слабость в руке, нарушение речи — это признаки:',
'Face drooping, arm weakness, and slurred speech are signs of:',
['Инфаркта миокарда', 'Гипогликемии', 'Инсульта', 'Туберкулёза'],
['Myocardial Infarction', 'Hypoglycaemia', 'Stroke', 'Tuberculosis'],
2),
('mc',
'Что НЕЛЬЗЯ давать пациенту с подозрением на инфаркт или инсульт?',
'What should you NOT give to a patient suspected of having a heart attack or stroke?',
['Свежий воздух', 'Еду или воду', 'Положение покоя', 'Вызов скорой'],
['Fresh air', 'Food or water', 'Rest position', 'Calling an ambulance'],
1),
('tf',
'Курение и ожирение являются факторами риска инфаркта миокарда.',
'Smoking and obesity are risk factors for myocardial infarction.',
None, None, 'T'),
]
},
# ── Topic 3: Oncology ─────────────────────────────────────────────────────
{ 'num': 3,
'ru': 'Онкология (Рак)', 'en': 'Oncology (Cancer)',
'color': '#4a0e6e',
'qs': [
('mc',
'Какой из перечисленных симптомов является «красным флагом» онкологии?',
'Which of the following symptoms is a cancer "red flag"?',
['Насморк', 'Резкое необъяснимое похудение', 'Лёгкий кашель после еды', 'Усталость после тренировки'],
['Runny nose', 'Sudden unexplained weight loss', 'Mild cough after eating', 'Fatigue after exercise'],
1),
('mc',
'Чем отличается злокачественная опухоль от доброкачественной?',
'What distinguishes a malignant tumor from a benign one?',
['Злокачественная не болит', 'Злокачественная даёт метастазы',
'Доброкачественная быстрее растёт', 'Они ничем не отличаются'],
['Malignant tumors are painless', 'Malignant tumors produce metastases',
'Benign tumors grow faster', 'They are identical'],
1),
('mc',
'К какому специалисту нужно направить пациента при подозрении на рак?',
'To which specialist should a patient be referred when cancer is suspected?',
['Кардиолог', 'Гастроэнтеролог', 'Онколог', 'Невролог'],
['Cardiologist', 'Gastroenterologist', 'Oncologist', 'Neurologist'],
2),
('tf',
'Рак на ранних стадиях всегда сопровождается выраженными симптомами.',
'Cancer in its early stages always presents with obvious symptoms.',
None, None, 'F'),
]
},
# ── Topic 4: Healthy Lifestyle ────────────────────────────────────────────
{ 'num': 4,
'ru': 'Здоровый Образ Жизни (ЗОЖ)', 'en': 'Healthy Lifestyle (HLS)',
'color': '#2d6a2d',
'qs': [
('mc',
'Какой процент здоровья человека, по данным исследований, зависит от образа жизни?',
'What percentage of a person\'s health is influenced by lifestyle choices?',
['10%', '25%', '50%', '90%'],
['10%', '25%', '50%', '90%'],
2),
('mc',
'Сколько часов сна в сутки рекомендуется для взрослого человека?',
'How many hours of sleep per night are recommended for an adult?',
['4–5 часов / 4–5 hours', '6 часов / 6 hours', '7–8 часов / 7–8 hours', '10+ часов / 10+ hours'],
['4–5 hours', '6 hours', '7–8 hours', '10+ hours'],
2),
('mc',
'Что из перечисленного НЕ является компонентом здорового образа жизни?',
'Which of the following is NOT a component of a healthy lifestyle?',
['Сбалансированное питание', 'Физическая активность',
'Употребление алкоголя умеренно каждый день', 'Отказ от курения'],
['Balanced nutrition', 'Physical activity',
'Drinking alcohol moderately every day', 'Quitting smoking'],
2),
('tf',
'Здоровый образ жизни помогает предотвратить диабет, рак и инфаркт.',
'A healthy lifestyle helps prevent diabetes, cancer, and heart disease.',
None, None, 'T'),
]
},
# ── Topic 5: Infectious Diseases ─────────────────────────────────────────
{ 'num': 5,
'ru': 'Инфекционные заболевания', 'en': 'Infectious Diseases',
'color': '#7b3f00',
'qs': [
('mc',
'ВИЧ передаётся каким путём?',
'HIV is transmitted via which route?',
['Воздушно-капельным / Airborne', 'Через кровь / Blood-borne',
'Фекально-оральным / Fecal-oral', 'Контактно-бытовым / Household contact'],
['Airborne', 'Blood-borne', 'Fecal-oral', 'Household contact'],
1),
('mc',
'Что такое инкубационный период инфекции?',
'What is the incubation period of an infection?',
['Время лечения болезни',
'Период от заражения до появления первых симптомов',
'Время полного выздоровления',
'Период заразности пациента'],
['The duration of treatment',
'The period from infection to first symptoms',
'The time to full recovery',
'The period of patient contagiousness'],
1),
('mc',
'Какой первый шаг при выявлении опасного инфекционного заболевания?',
'What is the first step when a dangerous infectious disease is identified?',
['Назначить антибиотики', 'Изолировать пациента (карантин)',
'Сделать рентген грудной клетки', 'Измерить давление'],
['Prescribe antibiotics', 'Isolate the patient (quarantine)',
'Order a chest X-ray', 'Measure blood pressure'],
1),
('tf',
'Вакцинация является эффективным методом профилактики инфекционных заболеваний.',
'Vaccination is an effective method of preventing infectious diseases.',
None, None, 'T'),
]
},
# ── Topic 6: Inpatient Treatment ─────────────────────────────────────────
{ 'num': 6,
'ru': 'Стационарное лечение', 'en': 'Inpatient Treatment (Hospital)',
'color': '#1a3a5c',
'qs': [
('mc',
'Какое ГЛАВНОЕ преимущество стационарного лечения?',
'What is the MAIN advantage of inpatient (hospital) treatment?',
['Дешевле домашнего лечения', 'Круглосуточное наблюдение врачей',
'Нет риска инфекций', 'Пациент рядом с семьёй'],
['Cheaper than home treatment', '24/7 medical monitoring',
'No infection risk', 'Patient stays close to family'],
1),
('mc',
'Что является НЕДОСТАТКОМ стационарного лечения?',
'Which of the following is a DISADVANTAGE of hospital treatment?',
['Доступность процедур на месте', 'Риск внутрибольничных инфекций',
'Бесплатные лекарства', 'Постоянное наблюдение'],
['Availability of on-site procedures', 'Risk of nosocomial (hospital-acquired) infections',
'Free medications', 'Continuous monitoring'],
1),
('mc',
'В каком случае стационарное лечение наиболее обосновано?',
'In which situation is inpatient treatment most justified?',
['Лёгкий насморк', 'Плановый осмотр', 'Угроза жизни или сложные процедуры', 'Хроническая болезнь в ремиссии'],
['Mild cold', 'Routine check-up', 'Life-threatening condition or complex procedures', 'Chronic disease in remission'],
2),
('tf',
'Стационарное лечение рекомендуется для всех пациентов с хроническими заболеваниями.',
'Inpatient treatment is recommended for all patients with chronic diseases.',
None, None, 'F'),
]
},
# ── Topic 7: Outpatient Treatment ────────────────────────────────────────
{ 'num': 7,
'ru': 'Амбулаторное лечение (Дома)', 'en': 'Outpatient Treatment (Home-Based)',
'color': '#555555',
'qs': [
('mc',
'Какое ГЛАВНОЕ преимущество амбулаторного лечения?',
'What is the MAIN advantage of outpatient (home-based) treatment?',
['Круглосуточный врач рядом', 'Домашний комфорт и поддержка семьи',
'Бесплатные лекарства', 'Изоляция от инфекций'],
['24/7 doctor available', 'Home comfort and family support',
'Free medications', 'Isolation from infections'],
1),
('mc',
'Для каких пациентов наиболее подходит амбулаторное лечение?',
'For which patients is outpatient treatment most appropriate?',
['Пациенты в критическом состоянии', 'Пациенты после инфаркта',
'Стабильные пациенты с лёгкими заболеваниями', 'Пациенты с открытым переломом'],
['Critically ill patients', 'Post-heart attack patients',
'Stable patients with mild illnesses', 'Patients with open fractures'],
2),
('mc',
'Когда пациент на домашнем лечении должен немедленно вызвать скорую?',
'When should a patient receiving home treatment immediately call an ambulance?',
['При небольшой усталости', 'При появлении боли или кровотечения',
'Если закончились таблетки', 'Раз в неделю для проверки'],
['When mildly tired', 'When pain or bleeding appears',
'When pills run out', 'Once a week for routine checks'],
1),
('tf',
'При амбулаторном лечении нет риска заражения больничными инфекциями.',
'With outpatient treatment, there is no risk of hospital-acquired infection.',
None, None, 'T'),
]
},
# ── Topic 8: Personal Hygiene ─────────────────────────────────────────────
{ 'num': 8,
'ru': 'Личная гигиена', 'en': 'Personal Hygiene',
'color': '#006b8f',
'qs': [
('mc',
'Когда ОБЯЗАТЕЛЬНО нужно мыть руки?',
'When is it MANDATORY to wash your hands?',
['После сна', 'После туалета и перед едой',
'После просмотра телевизора', 'Только если руки видимо грязные'],
['After sleeping', 'After using the toilet and before eating',
'After watching TV', 'Only if visibly dirty'],
1),
('mc',
'Какой предмет личной гигиены НЕЛЬЗЯ использовать совместно с другими?',
'Which personal hygiene item should NEVER be shared with others?',
['Мыло', 'Полотенце', 'Шампунь', 'Зеркало'],
['Soap', 'Towel', 'Shampoo', 'Mirror'],
1),
('mc',
'Какая оптимальная температура воды для ежедневного душа?',
'What is the optimal water temperature for a daily shower?',
['20–25°C', '30–32°C', '37–38°C', '42–45°C'],
['20–25°C', '30–32°C', '37–38°C', '42–45°C'],
2),
('tf',
'Постельное бельё рекомендуется менять раз в месяц.',
'Bed linen is recommended to be changed once a month.',
None, None, 'F'),
]
},
# ── Topic 9: Gastritis & Ulcer ────────────────────────────────────────────
{ 'num': 9,
'ru': 'Гастрит и Язва', 'en': 'Gastritis and Peptic Ulcer',
'color': '#8b4500',
'qs': [
('mc',
'Какой препарат из перечисленных может ВЫЗВАТЬ гастрит или язву?',
'Which of the following drugs can CAUSE gastritis or an ulcer?',
['Парацетамол', 'НПВС (ибупрофен, аспирин)', 'Антигистамины', 'Витамин C'],
['Paracetamol', 'NSAIDs (ibuprofen, aspirin)', 'Antihistamines', 'Vitamin C'],
1),
('mc',
'Самое опасное осложнение язвенной болезни:',
'The most dangerous complication of peptic ulcer disease is:',
['Тошнота', 'Изжога', 'Прободение (перфорация) язвы', 'Потеря аппетита'],
['Nausea', 'Heartburn', 'Ulcer perforation (peritonitis)', 'Loss of appetite'],
2),
('mc',
'Какой метод диагностики применяется для подтверждения язвы желудка?',
'Which diagnostic method is used to confirm a stomach ulcer?',
['УЗИ органов малого таза', 'Эндоскопия (ЭГДС)', 'Флюорография', 'Анализ мочи'],
['Pelvic ultrasound', 'Endoscopy (EGDS)', 'Chest X-ray (fluorography)', 'Urine test'],
1),
('tf',
'При боли в желудке можно безопасно лечиться самостоятельно без врача.',
'Stomach pain can be safely self-treated without seeing a doctor.',
None, None, 'F'),
]
},
# ── Topic 10: Tuberculosis ────────────────────────────────────────────────
{ 'num': 10,
'ru': 'Туберкулёз (ТБ)', 'en': 'Tuberculosis (TB)',
'color': '#3a3a00',
'qs': [
('mc',
'Какой микроорганизм является возбудителем туберкулёза?',
'Which microorganism causes tuberculosis?',
['Вирус гриппа', 'Палочка Коха (Mycobacterium tuberculosis)',
'Стрептококк', 'Кандида'],
['Influenza virus', 'Koch\'s bacillus (Mycobacterium tuberculosis)',
'Streptococcus', 'Candida'],
1),
('mc',
'Какая форма туберкулёза является заразной?',
'Which form of tuberculosis is contagious?',
['Латентная / Latent', 'Активная / Active', 'Обе формы / Both', 'Ни одна / Neither'],
['Latent', 'Active', 'Both', 'Neither'],
1),
('mc',
'Какой из симптомов является характерным для активного туберкулёза?',
'Which symptom is characteristic of active tuberculosis?',
['Сыпь на коже', 'Боль в суставах', 'Кашель с кровью и ночная потливость', 'Отёки ног'],
['Skin rash', 'Joint pain', 'Bloody cough and night sweats', 'Leg oedema'],
2),
('tf',
'Латентная форма туберкулёза заразна и требует немедленной изоляции.',
'Latent tuberculosis is contagious and requires immediate isolation.',
None, None, 'F'),
]
},
]
# ── Answer key data (collected while building) ────────────────────────────────
answer_key = []
# ── Helper: topic header bar ──────────────────────────────────────────────────
def topic_header(num, ru_title, en_title, color):
data = [[
Paragraph(f'<b>Тема {num}: {ru_title}</b>',
S('th_ru', fontSize=10.5, fontName='DV-B', textColor=colors.white, leading=14)),
Paragraph(f'<i>Topic {num}: {en_title}</i>',
S('th_en', fontSize=9, fontName='DV-Ser', textColor=colors.HexColor('#ddeecc'), leading=13)),
]]
t = Table(data, colWidths=[W*0.52, W*0.48])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor(color)),
('TOPPADDING', (0,0), (-1,-1), 7),
('BOTTOMPADDING', (0,0), (-1,-1), 7),
('LEFTPADDING', (0,0), (0,-1), 8),
('RIGHTPADDING', (-1,0), (-1,-1), 8),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
return t
LETTERS = ['A', 'B', 'C', 'D']
# ── Build story ───────────────────────────────────────────────────────────────
story = []
q_global = 0
# ── Title ──────────────────────────────────────────────────────────────────────
story.append(Spacer(1, 0.8*cm))
story.append(Paragraph('Тест по Медицинской Симуляции', doc_title))
story.append(Paragraph('Medical Simulation Quiz', doc_title))
story.append(Paragraph('Темы 1–10 | Topics 1–10', doc_sub))
story.append(HRFlowable(width=W, thickness=2, color=colors.HexColor('#1a3a5c')))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
'Дата: 15 июня 2026 г. | Date: June 15, 2026 | '
'Учебный материал — НЕ для клинического использования | '
'Educational material — NOT for clinical use',
doc_meta))
# Instructions
instr_box_data = [[
Paragraph(
'<b>Инструкции:</b> Для каждого вопроса выберите правильный ответ. '
'В вопросах Верно/Неверно обведите «В» (Верно) или «Н» (Неверно). '
'Ответы — в конце документа.',
S('IB_ru', fontSize=9.5, leading=13, fontName='DV-B', textColor=colors.HexColor('#1a3a5c'))),
Paragraph(
'<i><b>Instructions:</b> For each question, select the correct answer. '
'For True/False questions, circle "T" (True) or "F" (False). '
'Answer key is at the end of the document.</i>',
S('IB_en', fontSize=9, leading=12, fontName='DV-Ser', textColor=colors.HexColor('#2d6a2d'))),
]]
instr_box = Table(instr_box_data, colWidths=[W*0.5, W*0.5])
instr_box.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor('#f0f4fa')),
('BOX', (0,0), (-1,-1), 1, colors.HexColor('#1a3a5c')),
('TOPPADDING', (0,0), (-1,-1), 7),
('BOTTOMPADDING', (0,0), (-1,-1), 7),
('LEFTPADDING', (0,0), (-1,-1), 8),
('RIGHTPADDING', (0,0), (-1,-1), 8),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(instr_box)
story.append(Spacer(1, 0.3*cm))
# Score box
score_data = [[
Paragraph('Имя / Name: ___________________________',
S('sb', fontSize=9.5, leading=13)),
Paragraph('Результат / Score: ______ / 40',
S('sb2', fontSize=9.5, leading=13, fontName='DV-B')),
]]
score_t = Table(score_data, colWidths=[W*0.55, W*0.45])
score_t.setStyle(TableStyle([
('BOX', (0,0), (-1,-1), 0.5, colors.HexColor('#888888')),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (-1,-1), 8),
]))
story.append(score_t)
story.append(Spacer(1, 0.4*cm))
# ── Questions ─────────────────────────────────────────────────────────────────
for topic in TOPICS:
block = []
block.append(topic_header(topic['num'], topic['ru'], topic['en'], topic['color']))
block.append(Spacer(1, 0.2*cm))
q_in_topic = 0
for (qtype, q_ru_text, q_en_text, opts_ru, opts_en, correct) in topic['qs']:
q_global += 1
q_in_topic += 1
# Record answer
if qtype == 'mc':
label = LETTERS[correct]
answer_key.append((q_global, topic['num'], qtype, label,
opts_ru[correct], opts_en[correct]))
else:
answer_key.append((q_global, topic['num'], qtype, correct, None, None))
# Question number + type badge
badge_color = '#1a3a5c' if qtype == 'mc' else '#7b3f00'
badge_ru = 'Выбор ответа' if qtype == 'mc' else 'Верно / Неверно'
badge_en = 'Multiple Choice' if qtype == 'mc' else 'True / False'
q_data = [[
Paragraph(f'<b>Вопрос {q_global}</b> <i>Question {q_global}</i>',
S('qn', fontSize=9.5, fontName='DV-B', textColor=colors.HexColor(badge_color), leading=13)),
Paragraph(f'<b>{badge_ru}</b> | <i>{badge_en}</i>',
S('qt', fontSize=8, fontName='DV-B', textColor=colors.white, leading=12,
alignment=TA_CENTER)),
]]
qt = Table(q_data, colWidths=[W*0.62, W*0.38])
qt.setStyle(TableStyle([
('BACKGROUND', (1,0), (1,0), colors.HexColor(badge_color)),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (0,0), 0),
('LEFTPADDING', (1,0), (1,0), 5),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
block.append(qt)
# Question text
block.append(Paragraph(q_ru_text, q_ru))
block.append(Paragraph(q_en_text, q_en))
if qtype == 'mc':
for i, (o_ru, o_en) in enumerate(zip(opts_ru, opts_en)):
letter = LETTERS[i]
block.append(Paragraph(
f'<b>{letter})</b> {o_ru} <font color="#2d6a2d"><i>/ {o_en}</i></font>',
S(f'opt_{q_global}_{i}', fontSize=9, leading=13,
leftIndent=0.8*cm, spaceAfter=2)))
else:
block.append(Paragraph(
'<b>В (True)</b> ○ <b>Н (False)</b> ○',
S(f'tf_{q_global}', fontSize=10, leading=14,
leftIndent=1*cm, spaceAfter=6, fontName='DV-B')))
block.append(Spacer(1, 0.25*cm))
story.append(KeepTogether(block[:6])) # keep header + first Q together
for item in block[6:]:
story.append(item)
story.append(Spacer(1, 0.1*cm))
# ── Answer Key ────────────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(Spacer(1, 0.3*cm))
ak_hdr_data = [[
Paragraph('<b>КЛЮЧ К ОТВЕТАМ</b>', S('akh_ru', fontSize=14, fontName='DV-B',
textColor=colors.white, leading=18)),
Paragraph('<i>ANSWER KEY</i>', S('akh_en', fontSize=12, fontName='DV-Ser',
textColor=colors.HexColor('#ddeecc'), leading=16)),
]]
ak_hdr = Table(ak_hdr_data, colWidths=[W*0.45, W*0.55])
ak_hdr.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor('#1a3a5c')),
('TOPPADDING', (0,0), (-1,-1), 10),
('BOTTOMPADDING', (0,0), (-1,-1), 10),
('LEFTPADDING', (0,0), (-1,-1), 10),
]))
story.append(ak_hdr)
story.append(Spacer(1, 0.4*cm))
# Table header
ak_col_hdrs = [
Paragraph('<b>№</b>', S('akh', fontSize=9, fontName='DV-B', textColor=colors.white, alignment=TA_CENTER)),
Paragraph('<b>Тема / Topic</b>', S('akh', fontSize=9, fontName='DV-B', textColor=colors.white)),
Paragraph('<b>Тип / Type</b>', S('akh', fontSize=9, fontName='DV-B', textColor=colors.white)),
Paragraph('<b>Ответ / Answer</b>', S('akh', fontSize=9, fontName='DV-B', textColor=colors.white)),
Paragraph('<b>Правильный ответ (RU / EN)</b>', S('akh', fontSize=9, fontName='DV-B', textColor=colors.white)),
]
ak_rows = [ak_col_hdrs]
alt_colors = [colors.HexColor('#f0f4fa'), colors.HexColor('#ffffff')]
for idx, (qn, tn, qt, ans, ans_ru, ans_en) in enumerate(answer_key):
type_str_ru = 'Выбор' if qt == 'mc' else 'В/Н'
type_str_en = 'MC' if qt == 'mc' else 'T/F'
if qt == 'mc':
ans_text = f'<b>{ans}</b>'
detail = f'{ans_ru} / {ans_en}' if ans_ru else ''
else:
full_ans = 'В (True)' if ans == 'T' else 'Н (False)'
ans_text = f'<b>{full_ans}</b>'
detail = ''
row = [
Paragraph(str(qn), S(f'ak_qn_{qn}', fontSize=9, alignment=TA_CENTER)),
Paragraph(str(tn), S(f'ak_tn_{qn}', fontSize=9, alignment=TA_CENTER)),
Paragraph(f'{type_str_ru} / {type_str_en}', S(f'ak_tp_{qn}', fontSize=8.5)),
Paragraph(ans_text, S(f'ak_ans_{qn}', fontSize=9.5, fontName='DV-B',
textColor=colors.HexColor('#8b0000'))),
Paragraph(detail, S(f'ak_det_{qn}', fontSize=8.5, fontName='DV-Ser',
textColor=colors.HexColor('#2d6a2d'))),
]
ak_rows.append(row)
ak_table = Table(ak_rows, colWidths=[W*0.07, W*0.08, W*0.15, W*0.17, W*0.53])
ak_table_style = [
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1a3a5c')),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#cccccc')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]
for i in range(1, len(ak_rows)):
bg = alt_colors[(i-1) % 2]
ak_table_style.append(('BACKGROUND', (0,i), (-1,i), bg))
ak_table.setStyle(TableStyle(ak_table_style))
story.append(ak_table)
story.append(Spacer(1, 0.5*cm))
story.append(HRFlowable(width=W, thickness=1, color=colors.HexColor('#888888')))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
'<b>DISCLAIMER:</b> Данный тест предназначен исключительно для учебных целей и медицинской симуляции. '
'Не является медицинской консультацией. | '
'<i>This quiz is for educational and simulation purposes only. Not medical advice.</i>',
S('disc', fontSize=8, leading=12, textColor=colors.HexColor('#666666'),
fontName='DV-Ser', alignment=TA_JUSTIFY)
))
# ── Build ─────────────────────────────────────────────────────────────────────
doc.build(story)
print(f'PDF created: {OUTPUT}')
print(f'Total questions: {q_global}')
python3 /home/daytona/workspace/med-sim-handbook/generate_quiz.py 2>&1
ls -lh /home/daytona/workspace/med-sim-handbook/Medical_Simulation_Quiz_RU_EN.pdf
Medical Simulation Quiz RU EN
PDF Document · PDF