Telegram bot for insulin therapy

In the previous article, I told you about the SugarNorm insulin therapy simulator project. This project has not yet found interest from medical schools. In my opinion, its main drawback is that it is implemented as a desktop application. Additional features of the insulin therapy simulator were a calculator for switching to pump insulin therapy and a bolus calculator. Therefore, an idea arose to eliminate the main drawback of the project by developing a telegram bot capable of implementing the following functions:

– calculator for transition to insulin pump therapy;

– bolus calculator;

– calculator for calculating the XE based on product packaging;

– table of products with translation into XE.

The format in the form of a telegram bot seemed very convenient to me – no need to install the application, no dependence on the operating system, easy upgrade by finishing the source code of the telegram bot on the server side. Python was chosen as the programming language. Now about the features of the implementation of the modules.

!!!This bot is intended solely for testing and determining the relevance of the development and cannot be used to determine pump settings or the amount of insulin without a doctor's recommendation!!!

  1. Transition calculator. The transition calculator is designed to calculate insulin therapy parameters when switching to pump insulin therapy. The calculation is based on the book Insulin pump. Help for doctor and patient for effective diabetes management. I.I. Dedov, V.A. Peterkova, T.L. Kuraeva, D.N. Laptev.

    The initial data used are: age, weight, daily insulin dose, insulin therapy features. The code for the transition calculator is presented below.

    if users[message.from_user.id]['mode'] == 1:    # Продолжение работы калькулятора перехода
        if users[message.from_user.id]['vozr'] == 0 and users[message.from_user.id]['ves'] == 0 and \
                users[message.from_user.id]['doza'] == 0 and users[message.from_user.id]['mode'] == 1:
            if is_number(message.text):
                users[message.from_user.id]['vozr'] = float(message.text)
                bot.send_message(message.chat.id, "Введите вес [кг]")
            else:
                bot.send_message(message.chat.id, "Можно ввести только число")
                bot.send_message(message.chat.id, "Введите возраст [лет]")

        elif users[message.from_user.id]['vozr'] != 0 and users[message.from_user.id]['ves'] == 0 and \
                users[message.from_user.id]['doza'] == 0 and users[message.from_user.id]['mode'] == 1:
            if is_number(message.text):
                users[message.from_user.id]['ves'] = float(message.text)
                bot.send_message(message.chat.id, "Введите суточную дозу инсулина [ед.]")
            else:
                bot.send_message(message.chat.id, "Можно ввести только число")
                bot.send_message(message.chat.id, "Введите вес [кг]")

        elif users[message.from_user.id]['vozr'] != 0 and users[message.from_user.id]['ves'] != 0 and \
                users[message.from_user.id]['doza'] == 0 and users[message.from_user.id]['mode'] == 1:
            if is_number(message.text):
                users[message.from_user.id]['doza'] = float(message.text)
                bot.send_message(message.chat.id, "Частые гипогликемии, введите 1")
                bot.send_message(message.chat.id,
                                 "Хорошие показатели глюкозы в крови, редкие или вообще отсутствующие гипогликемии, введите 2")
                bot.send_message(message.chat.id,
                                 "Высокие показатели глюкозы в крови, редкие или вообще отсутствующие гипогликемии, введите 3")
            else:
                bot.send_message(message.chat.id, "Можно ввести только число")
                bot.send_message(message.chat.id, "Введите суточную дозу инсулина [ед.]")

        elif users[message.from_user.id]['vozr'] != 0 and users[message.from_user.id]['ves'] != 0 and \
                users[message.from_user.id]['doza'] != 0 and users[message.from_user.id]['mode'] == 1:
            if message.text == "1" or message.text == "2" or message.text == "3":
                if message.text == "2":
                    users[message.from_user.id]['doza'] = users[message.from_user.id]['doza'] * 0.8
                if message.text == "3":
                    users[message.from_user.id]['doza'] = users[message.from_user.id]['doza'] * 0.9
                if users[message.from_user.id]['vozr'] <= 6.5:
                    baza = users[message.from_user.id]['doza'] * 0.33 / 24
                    UK = 1.25 * users[message.from_user.id]['doza'] / users[message.from_user.id]['ves']
                if 6.5 < users[message.from_user.id]['vozr'] <= 12.5:
                    baza = users[message.from_user.id]['doza'] * 0.37 / 24
                    UK = 1.4 * users[message.from_user.id]['doza'] / users[message.from_user.id]['ves']
                if 12.5 < users[message.from_user.id]['vozr'] <= 18.5:
                    baza = users[message.from_user.id]['doza'] * 0.45 / 24
                    UK = 2 * users[message.from_user.id]['doza'] / users[message.from_user.id]['ves']
                if users[message.from_user.id]['vozr'] > 18.5:
                    baza = users[message.from_user.id]['doza'] * 0.45 / 24
                    UK = 1.74 * users[message.from_user.id]['doza'] / users[message.from_user.id]['ves']
                if users[message.from_user.id]['vozr'] <= 17.5:
                    PHI = 110 / users[message.from_user.id]['doza']
                if users[message.from_user.id]['vozr'] > 17.5:
                    PHI = 100 / users[message.from_user.id]['doza']
                bot.send_message(message.chat.id, "Базальная профиль [ЕД/ч]: " + str(round(baza, 2)))
                bot.send_message(message.chat.id, "Углеводный коэффициент [ЕД/ХЕ]: " + str(round(UK, 2)))
                bot.send_message(message.chat.id, "Фактор чувствительности к инсулину [мМ/л]: " + str(round(PHI, 2)))

The output of the calculator is approximate pump settings: basal profile, carbohydrate ratio, insulin sensitivity factor.

  1. Bolus calculator. The bolus calculator is designed to calculate the required insulin dose. The calculation is based on the book Insulin pump. Help for doctor and patient for effective diabetes management. I.I. Dedov, V.A. Peterkova, T.L. Kuraeva, D.N. Laptev. The bolus calculator code is provided below.

    The following data are used as initial data: carbohydrate ratio, insulin sensitivity factor, current glucose value, amount of XE consumed, target glucose value.

    if users[message.from_user.id]['mode_2'] == 1:  # Продолжение работы калькулятора болюса
        if users[message.from_user.id]['uk'] == 0 and users[message.from_user.id]['phi'] == 0 and \
                users[message.from_user.id]['gluk_tek'] == 0 and users[message.from_user.id]['kol_xe'] == 0 and \
                users[message.from_user.id]['mode_2'] == 1:
            if is_number(message.text):
                users[message.from_user.id]['uk'] = float(message.text)
                bot.send_message(message.chat.id, "Введите фактор чувствительности к инсулину [мМ/л]")
            else:
                bot.send_message(message.chat.id, "Можно ввести только число")
                bot.send_message(message.chat.id, "Введите углеводный коэффициент [ЕД/ХЕ]")

        elif users[message.from_user.id]['uk'] != 0 and users[message.from_user.id]['phi'] == 0 and \
                users[message.from_user.id]['gluk_tek'] == 0 and users[message.from_user.id]['kol_xe'] == 0 and \
                users[message.from_user.id]['mode_2'] == 1:
            if is_number(message.text):
                users[message.from_user.id]['phi'] = float(message.text)
                bot.send_message(message.chat.id, "Введите текущее значение глюкозы [мМ/л]")
            else:
                bot.send_message(message.chat.id, "Можно ввести только число")
                bot.send_message(message.chat.id, "Введите фактор чувствительности к инсулину [мМ/л]")
        elif users[message.from_user.id]['uk'] != 0 and users[message.from_user.id]['phi'] != 0 and \
                users[message.from_user.id]['gluk_tek'] == 0 and users[message.from_user.id]['kol_xe'] == 0 and \
                users[message.from_user.id]['mode_2'] == 1:
            if is_number(message.text):
                users[message.from_user.id]['gluk_tek'] = float(message.text)
                bot.send_message(message.chat.id, "Введите количество углеводов [ХЕ]")
            else:
                bot.send_message(message.chat.id, "Можно ввести только число")
                bot.send_message(message.chat.id, "Введите текущее значение глюкозы [мМ/л]")
        elif users[message.from_user.id]['uk'] != 0 and users[message.from_user.id]['phi'] != 0 and \
                users[message.from_user.id]['gluk_tek'] != 0 and users[message.from_user.id]['kol_xe'] == 0 and \
                users[message.from_user.id]['mode_2'] == 1:
            if is_number(message.text):
                users[message.from_user.id]['kol_xe'] = float(message.text)
                bot.send_message(message.chat.id, "Введите значение целевой глюкозы [мМ/л]")
            else:
                bot.send_message(message.chat.id, "Можно ввести только число")
                bot.send_message(message.chat.id, "Введите количество углеводов [ХЕ]")
        elif users[message.from_user.id]['uk'] != 0 and users[message.from_user.id]['phi'] != 0 and \
                users[message.from_user.id]['gluk_tek'] != 0 and users[message.from_user.id]['kol_xe'] != 0 and \
                users[message.from_user.id]['mode_2'] == 1:
            if is_number(message.text):
                ins = ((users[message.from_user.id]['gluk_tek'] - float(message.text)) / users[message.from_user.id]['phi']) + users[message.from_user.id]['kol_xe'] * users[message.from_user.id]['uk']
                bot.send_message(message.chat.id, "Необходимо ввести " + str(round(ins, 1)) + " ЕД")

                menu(message)  # Вызов функции меню для выхода из режима калькулятора
            else:
                bot.send_message(message.chat.id, "Можно ввести только число")
                bot.send_message(message.chat.id, "Введите значение целевой глюкозы [мМ/л]")

At the output of the model, we obtain the number of units of insulin required for food intake and correction.

  1. XE Calculator by product packaging allows you to determine the amount of insulin if the product is in the package. Let's say it's a candy bar or other treat. In this case, you need to determine how many grams of carbohydrates will be consumed and divide this value by 11 (11 grams is 1 XE). The code is below.

    The initial data for the calculator are: the weight of a serving of the product, the amount of carbohydrates in 100 grams of the product.

    if users[message.from_user.id]['mode_1'] == 1:  # Продолжение работы калькулятора XE
        if users[message.from_user.id]['ves_porc'] == 0 and users[message.from_user.id]['mode_1'] == 1:
            if is_number(message.text):
                users[message.from_user.id]['ves_porc'] = float(message.text)
                bot.send_message(message.chat.id, "Введите количество углеводов в 100 г. [г.]")
            else:
                bot.send_message(message.chat.id, "Можно ввести только число")
                bot.send_message(message.chat.id, "Введите вес порции продукта [г.]")

        elif users[message.from_user.id]['ves_porc'] != 0 and users[message.from_user.id]['mode_1'] == 1:
            if is_number(message.text):
                xe = (users[message.from_user.id]['ves_porc'] * float(message.text) / 100) / 11
                bot.send_message(message.chat.id, "В одной порции " + str(round(xe, 1)) + " ХЕ")

                menu(message)  # Вызов функции меню для выхода из режима калькулятора
            else:
                bot.send_message(message.chat.id, "Можно ввести только число")
                bot.send_message(message.chat.id, "Введите количество углеводов в 100 г. [г.]")

At the output of the module we obtain the amount of XE in one portion of the product.

  1. Table of products with translation into XE. This is a classic food chart that is handed out in some form at the hospital when type 1 diabetes is diagnosed. This chart is implemented as a separate file.

"""
        Словарь для списка продуктов
"""

spisok=[["Абрикос", "средний 1 шт.", 120],
        ["Ананас", "1 ломтик с кожурой поперечный срез", 140],
        ["Апельсин", "с кожурой маленький 1 шт.", 130],
        ["Арбуз", "один ломтик с кожурой", 270],
        ["Банан", "средний 1/2 шт.", 70],
        ["Блин тонкий", "1 большой", 30],
        ["Виноград", "средний 10 шт.", 70],
        ["Грейпфрут", "крупный 1/2 шт.", 170],
        ["Грецкие орехи (очищенные)", "б.л. с горкой", 90],
        ["Груша", "средняя 1 шт.",  100],
        ["Дыня", "один ломтик с кожурой", 100],
        ["Карт. жар.", "1.5-2 ст. ложки в зависимости от нарезки",  35],
        ["Карт. пюре.", "2 ст. ложки", 75],
        ["Карт. чипсы", "1 маленький пакетик", 25],
        ["Карт. Фри.", "12 ломтиков", 35],
        ["Каша", "2 ст. ложки с горкой", 50],
        ["Кефир", "1 стакан", 250],
        ["Компот", "1 стакан", 250],
        ["Крекеры крупные", "2 шт.", 20],
        ["Кукуруза (початок)", "0.5 шт.", 100],
        ["Кукур. хлопья", "4 ст. ложки", 15],
        ["Макароны", "в зависимости от формы от 2 до 4 ст. ложек", 50],
        ["Мандарины", "мелкие 3 шт. с кожурой", 150],
        ["Мармелад", "-", 20],
        ["Мед", "1 ст. ложка", 11],
        ["Молоко", "1 стакан", 200],
        ["Мороженое", "-", 65],
        ["Морож. (глаз.)", "-", 50],
        ["Нектарин", "средний", 120],
        ["Оладьи", "1 средний", 30],
        ["Персик", "средний", 120],
        ["Пицца", "-", 50],
        ["Пряник", "1/2 шт.", 40],
        ["Сдобная булка", "-", 20],
        ["Сок", "0.5 стакана", 125],
        ["Сырник средний (с сахаром)", "1 штука", 75],
        ["Фундук", "3/4 стакана", 90],
        ["Хлеб белый", "1 кусок толщиной 1.5 см.", 20],
        ["Хлеб черный", "1 кусок толщиной 1 см.", 25],
        ["Хурма", "средняя 1 шт.",  70],
        ["Черешня", "10 шт. (или 1 стакан)", 100],
        ["Черника", "7 ст. ложек (или 1 стакан)", 140],
        ["Шоколад", "1/5 плитки", 20],
        ["Яблоко", "среднее 1 шт.", 90]]

And in the output module itself, a search by the first letter of the product name has been added.

@bot.message_handler(content_types=["text"])
def gr_list(message):
    """
        Функция для вывода списка продуктов (Полноcтью реализована в данной функции)
    """

    fin_stroka = []
    for i in range(len(spisok)):
        stroka = spisok[i][0]
        if stroka[0] == message.text.upper() or message.text == "*":
            fin_stroka.append(' '.join([spisok[i][0], " || ", str(spisok[i][1]), " || ", str(spisok[i][2]), "г."]))

    if fin_stroka != []:
        bot.send_message(message.chat.id, "Название || количество на 1 ХЕ || вес на 1 ХЕ:")
        bot.send_message(message.chat.id, '\n'.join(fin_stroka))
    else:
        bot.send_message(message.chat.id, "Продукты не найдены")

    menu(message)   # Вызов функции меню для выхода из режима вывода списка продуктов

I would really like to get the opinion of people interested in this development. At the moment, the bot is deployed only on a local server, so it is available intermittently. @Sugarnorm_bot

!!!This bot is intended solely for testing and determining the relevance of the development and cannot be used to determine pump settings or the amount of insulin without a doctor's recommendation!!!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *