Симулятор инсулиновой помпы в формате телеграмм бота

от автора

Не вызвавший интерес у широкой публики симулятор инсулиновой помпы в виде десктопного приложения определил необходимость поиска другого формата. В качестве нового формата был выбран телеграмм бот на Питоне. При этом пришлось пожертвовать частью функционала, но это позволило упростить процесс начала работы с симулятором. Но обо все по порядку.

Главная цель разработки — тренажер подборки настроек инсулинотерапии с обратной реакцией в виде значения глюкозы.

Для навигации в боте разработано меню, представленное ниже

Меню

Меню

Первой задачей является разработка генератора пациентов. Генерить эти данные с помощью генератора случайных чисел, идея конечно рабочая, но она отдаляет от реальности. Ведь в медицине давно сформированы соотношения всех взаимосвязанных параметров, которые характеризуют пациента: возраст, вес, суточная доза инсулина, УК (углеводный коэффициент), ФЧИ (фактор чувствительности к инсулину), БП (базальный профиль/ базальная скорость). Воспользуемся известными соотношениями и научим будущего бота генерить пациентов с «адекватными» параметрами. Ниже представлен код модуля формирования пациента.

 if call.data == "btn_new"  and chet == 0: # Обработка нажатия inline кнопки для вывода списка продуктов          users[call.from_user.id]['uk_et'] = 0         users[call.from_user.id]['phi_et'] = 0         users[call.from_user.id]['bp_et'] = 0         users[call.from_user.id]['uk'] = 0         users[call.from_user.id]['phi'] = 0         users[call.from_user.id]['bp'] = 0         users[call.from_user.id]['mode'] = 0         users[call.from_user.id]['chas'] = 0         users[call.from_user.id]['summ_gluk'] = 5.5         users[call.from_user.id]['N_gluk'] = 1         users[call.from_user.id]['gluk_tek'] = 5.5         users[call.from_user.id]['kol_xe'] = 0         users[call.from_user.id]['about'] = " "         users[call.from_user.id]['insulin'] = 0  # Сброс режима          fin_stroka = []         fin_stroka.append("Описание пациента:")         temp_vozr = random.randint(1, 69)         fin_stroka.append("1.Возраст пациента [лет]: " + str(temp_vozr))         if temp_vozr == 1:             temp_ves = 10 + random.randint(0, 2)         elif temp_vozr == 2:             temp_ves = 11 + random.randint(0, 3)         elif temp_vozr == 3:             temp_ves = 13 + random.randint(0, 2)         elif temp_vozr == 4:             temp_ves = 13 + random.randint(0, 5)         elif temp_vozr == 5:             temp_ves = 15 + random.randint(0, 7)         elif temp_vozr == 6:             temp_ves = 18 + random.randint(0, 4)         elif temp_vozr == 7:             temp_ves = 20 + random.randint(0, 8)         elif temp_vozr == 8:             temp_ves = 22 + random.randint(0, 9)         elif temp_vozr == 9:             temp_ves = 25 + random.randint(0, 10)         elif temp_vozr == 10:             temp_ves = 28 + random.randint(0, 10)         elif temp_vozr == 11:             temp_ves = 30 + random.randint(0, 11)         elif temp_vozr == 12:             temp_ves = 34 + random.randint(0, 7)         elif temp_vozr == 13:             temp_ves = 38 + random.randint(0, 15)         elif temp_vozr == 14:             temp_ves = 44 + random.randint(0, 13)         elif temp_vozr == 15:             temp_ves = 46 + random.randint(0, 23)         elif temp_vozr == 16:             temp_ves = 48 + random.randint(0, 27)         elif temp_vozr == 17:             temp_ves = 49 + random.randint(0, 30)         else:             temp_ves = 51 + random.randint(0, 48)         fin_stroka.append("2.Вес пациента [кг]: " + str(temp_ves))          if temp_vozr > 0 and temp_vozr <= 10:             temp_sdi = round(temp_ves * (7 + random.randint(0, 2)) / 10, 0)         else:             temp_sdi = round(temp_ves * (10 + random.randint(0, 9)) / 10, 0)          temp_staz = random.randint(0, 4)         if temp_staz < 2:             temp_sdi = round(temp_ves * (3 + random.randint(0, 2)) / 10, 0)             #        bot.send_message(message.chat.id, "Стаж сахарного диабета меньше 2 лет.")             fin_stroka.append("3.Стаж сахарного диабета меньше 2 лет.")          else:             fin_stroka.append("3.Стаж сахарного диабета больше 2 лет.")          fin_stroka.append("4.Суточная доза инсулина [ЕД]: " + str(temp_sdi))         temp_staz = random.randint(0, 4)         if temp_staz < 2:             temp_sdi = round(temp_sdi * 0.8)             fin_stroka.append("5.Частые гипогликемии.")         elif temp_staz > 1 and temp_staz < 4:             temp_sdi = round(temp_sdi * 0.9)             fin_stroka.append("5.Хорошие показатели глюкозы в крови, редкие гипогликемии.")         else:             fin_stroka.append("5.Высокие показатели глюкозы в крови.")          # Определение БП, УК         if temp_vozr < 7:             users[call.from_user.id]['bp_et'] = round(temp_sdi * (30 + random.randint(0, 4)) / (100 * 24), 1)          elif temp_vozr < 13 and temp_vozr > 6:             users[call.from_user.id]['bp_et'] = round(temp_sdi * (35 + random.randint(0, 4)) / (100 * 24), 1)         else:             users[call.from_user.id]['bp_et'] = round(temp_sdi * (40 + random.randint(0, 9)) / (100 * 24), 1)          users[call.from_user.id]['uk_et'] = round(temp_sdi * random.randint(12, 20) / (10 * temp_ves), 1)          users[call.from_user.id]['phi_et'] = round(random.randint(100, 110) / temp_sdi, 1)          bot.send_message(call.from_user.id, '\n'.join(fin_stroka))         users[call.from_user.id]['about'] = fin_stroka

После выполнения данного кода, пользователю представляется описание пациента. На основании описания пользователь может определить примерные коэффициенты УК, ФЧИ и БП. Данное описание доступно на любой стадии выполнения задания при клике на кнопку «О пациенте».

Вариант описания

Вариант описания

Кнопка «Инфо», код которой представлен ниже, предназначена для вывода текущей информации о состоянии симулятора. Данная информация позволяет отслеживать изменение глюкозы, просматривать текущие настройки и значение гликированного гемоглобина за период симуляции.

Информация о состоянии симулятора

Информация о состоянии симулятора
    if call.data == "btn_info"  and chet == 0:          gg = round((users[call.from_user.id]['summ_gluk']*0.6302/users[call.from_user.id]['N_gluk'])+1.584, 1)         fin_stroka = []         fin_stroka.append("Время: " + str(users[call.from_user.id]['chas'])+":00")         fin_stroka.append("                         ")         fin_stroka.append("Глюкоза [мМ/л]: " + str(round(users[call.from_user.id]['gluk_tek'],1)))         fin_stroka.append("Еда [ХЕ]: " + str(users[call.from_user.id]['kol_xe']))         fin_stroka.append("Инсулин [ЕД]: " + str(users[call.from_user.id]['insulin']))         fin_stroka.append("                         ")         fin_stroka.append("Текущие настройки:")         fin_stroka.append("БП [ЕД/ч]: " + str(users[call.from_user.id]['bp']))         fin_stroka.append("УК [ЕД/ХЕ]: " + str(users[call.from_user.id]['uk']))         fin_stroka.append("ФЧИ [мМ/л]: " + str(users[call.from_user.id]['phi']))         fin_stroka.append("                         ")         fin_stroka.append("Гликированный гемоглобин: " + str(gg))         bot.send_message(call.message.chat.id,  '\n'.join(fin_stroka))

Кнопка «Еда» позволяет симулировать прием пищи. При этом требуется указание количества ХЕ.

    if users[message.from_user.id]['mode'] == 1:         if is_number(message.text):             users[message.from_user.id]['kol_xe'] = float(message.text)             users[message.from_user.id]['mode'] = 0             menu(message)           else:             bot.send_message(message.chat.id, "Можно ввести только число")             bot.send_message(message.chat.id, "Сколько ХЕ?")

Кнопка «Инсулин» запускает калькулятор болюса, позволяющий рассчитать количество инсулина на коррекцию и еду. Подробный расчет доступен пользователю. При этом расчет ведется в соответствии с установленными в симуляторе значениями УК, ФЧИ и БП.

Калькулятор болюса

Калькулятор болюса
    if call.data == "btn_insulin" and chet == 0:           if users[call.from_user.id]['uk'] != 0 and users[call.from_user.id]['bp'] != 0 and users[call.from_user.id]['phi'] != 0:             fin_stroka = []             fin_stroka.append("Помощник болюса:")             eat = users[call.from_user.id]['kol_xe']*users[call.from_user.id]['uk']             fin_stroka.append("Инсулин на еду [ЕД]: " + str(users[call.from_user.id]['kol_xe'])+" * "+str(users[call.from_user.id]['uk'])+" = "+str(round(eat, 1)))             korr = (users[call.from_user.id]['gluk_tek']-7)/users[call.from_user.id]['phi']             fin_stroka.append("Инсулин на коррекц. [ЕД]: (" + str(users[call.from_user.id]['gluk_tek'])+" - 7)/ "+str(users[call.from_user.id]['phi'])+" = "+str(round(korr, 1)))             itog = eat+korr             fin_stroka.append("Итого [ЕД]:" + str(round(eat, 1))+" + "+str(round(korr, 1))+" = "+ str(round(itog, 1)))             bot.send_message(call.message.chat.id, '\n'.join(fin_stroka))              bot.send_message(call.message.chat.id, "Введите количество инсулина[ЕД]")             chet = 1  # Выбран режим работы             bot.register_next_step_handler(call.message, btn_insulin)  # Вызов функции калькулятора болюса         else : bot.send_message(call.message.chat.id, "Не введены УК, ФЧИ, БП.")

Кнопки УК, ФЧИ и БП предназначены для ввода соответствующих настроек симулятора.

Запуск шага симуляции осуществляется нажатием кнопки «Перемотка 2 часа». Соответствующий код представлен ниже.

    if call.data == "btn_peremotka" and chet == 0:          bot.send_message(call.message.chat.id, "Перемотка времени на 2 часа.")         if users[call.from_user.id]['chas']<24:             users[call.from_user.id]['chas'] +=2         else:             users[call.from_user.id]['chas'] = 0         users[call.from_user.id]['summ_gluk'] += users[call.from_user.id]['gluk_tek']         users[call.from_user.id]['N_gluk'] += 1         users[call.from_user.id]['gluk_tek'] += (users[call.from_user.id]['bp_et']-users[call.from_user.id]['bp'])*2*users[call.from_user.id]['phi_et']         users[call.from_user.id]['gluk_tek'] += ((users[call.from_user.id]['kol_xe']*users[call.from_user.id]['uk_et'])-users[call.from_user.id]['insulin'])*users[call.from_user.id]['phi_et']         users[call.from_user.id]['kol_xe'] = 0         users[call.from_user.id]['insulin'] = 0

После клика данной кнопки выполнится шаг симуляции и новое состояние симулятора будет доступно по клику на кнопку «Инфо».

!!!Данный бот предназначен исключительно для тестирования и определения актуальности разработки и не может использоваться для определения настроек помпы или количества инсулина без рекомендации врача!!!

На текущий момент данный бот доступен для тестирования

https://t.me/Sugarnorm_pomp_bot

В комментариях просьба описать Ваше видение проблематики и возможности данного формата для обучающего программного обеспечения.

В качестве направления дальнейшего исследования хочу добавить проверку правильности подбора параметров с выводом об этом информации пользователю, ведение статистики по количеству и скорости выполнения вариантов подбора параметров, аварийный вариант завершения работы симулятора в случае допущения значения глюкозы меньше 2 мМ/л или больше 20 мМ/л.


ссылка на оригинал статьи https://habr.com/ru/articles/838426/