Технология телеграм бота подкупила меня своей универсальностью. Можно использовать в телеграмм, можно просто в браузере, можно формировать любую логику работы… Сегодня рассмотрим вариант телеграм бота, представляющего собой фрагмент задачника по математике для 4 класса. Почему так все заморочено, просто ребенок учится в 4 классе и активно юзает телегу.

Начнем. В телеге запускаем бота BotFather, регистрируем новое имя бота. Имя и токен бота будут нам всегда доступны в BotFather.

Затем на комп накатываем Питон, PyCharm. Проверяем, что они видят друг друга и накатываем модуль telebot. Данные действия привожу в хронологическом порядке, более подробно можно найти данную информацию в нете.

Выбираем классическую задачу из учебника.

Из города в противоположных направлениях выехали два автомобиля. Скорость первого автомобиля составляет 57,8 км/час. Скорость второго автомобиля – 63,5 км/час. Через сколько часов расстояние между ними будет составлять 363,9 км?

Отлично. Из этой задачи можно сформулировать 4 задачи с определением различных параметров: скорость первого автомобиля, скорость второго автомобиля, время и расстояние.

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

    users[message.from_user.id]['v1'] = random.randint(50, 90)
    users[message.from_user.id]['v2'] = random.randint(50, 90)
    users[message.from_user.id]['t'] = random.randint(2, 7)
    users[message.from_user.id]['S'] = (users[message.from_user.id]['v1'] + users[message.from_user.id]['v2']) * users[message.from_user.id]['t']
    users[message.from_user.id]['mode'] = random.randint(1, 4)
    if users[message.from_user.id]['mode'] == 1:
        a = "Из города в противоположных направлениях выехали два автомобиля. Скорость первого автомобиля " + str(users[message.from_user.id]['v1']) + " км/ч. Скорость второго " + str(users[message.from_user.id]['v2']) + " км/ч. Через сколько часов расстояние между ними будет составлять " + str(users[message.from_user.id]['S']) + " км?"
    elif users[message.from_user.id]['mode'] == 2:
        a = "Из города в противоположных направлениях выехали два автомобиля. Скорость первого автомобиля " + str(users[message.from_user.id]['v1']) + " км/ч. Скорость второго " + str(users[message.from_user.id]['v2']) + " км/ч. Какое расстояние будет между ними через " + str(users[message.from_user.id]['t']) + " ч?"
    elif users[message.from_user.id]['mode'] == 3:
        a = "Из города в противоположных направлениях выехали два автомобиля. Скорость первого автомобиля " + str(users[message.from_user.id]['v1']) + " км/ч. Через " + str(users[message.from_user.id]['t']) + " ч расстояние между ними было " + str(users[message.from_user.id]['S']) + " км. Определите скорость второго автомобиля."
    else:
        a = "Из города в противоположных направлениях выехали два автомобиля. Скорость второго автомобиля " + str(users[message.from_user.id]['v2']) + " км/ч. Через " + str(users[message.from_user.id]['t']) + " ч расстояние между ними было " + str(users[message.from_user.id]['S']) + " км. Определите скорость первого автомобиля."
    bot.send_message(message.chat.id, a)
    bot.send_message(message.chat.id, "Введите ответ")

При этом в строке 5 выберим вариант вопроса.

Обработаем введенный ответ от ученика.

    if users[message.from_user.id]['mode'] > 0:
        if is_number(message.text)==True:
            if users[message.from_user.id]['mode']==1:
                if users[message.from_user.id]['t'] == int(message.text):
                    zapis(True,message.from_user.id,users[message.from_user.id]['mode'])
                else:
                    zapis(False,message.from_user.id,users[message.from_user.id]['mode'])
            elif users[message.from_user.id]['mode']==2:
                if users[message.from_user.id]['S'] == int(message.text):
                    zapis(True,message.from_user.id,users[message.from_user.id]['mode'])
                else:
                    zapis(False, message.from_user.id, users[message.from_user.id]['mode'])
            elif users[message.from_user.id]['mode']==3:
                if users[message.from_user.id]['v2'] == int(message.text):
                    zapis(True, message.from_user.id, users[message.from_user.id]['mode'])
                else:
                    zapis(False,message.from_user.id,users[message.from_user.id]['mode'])
            else:
                if users[message.from_user.id]['v1'] == int(message.text):
                    zapis(True, message.from_user.id, users[message.from_user.id]['mode'])
                else:
                    zapis(False, message.from_user.id, users[message.from_user.id]['mode'])

При этом не забываем проверять, что введенный ответ является цифрой.

def is_number(s):
    """ Функция проверки ввода на число """
    try:
        float(s)
        return True
    except ValueError:
        return False

Обозначенная ранее функция zapis осуществляет вывод сообщения о правильности ответа и запись в файл для учителя.

def zapis(r,id,md):
    if r==True:
        stroka="Правильно"
        bot.send_message(id, "Правильно.")
    else:
        stroka = "Неправильно"
        bot.send_message(id, "Неправильно.")
    f = open('result.txt', 'a', encoding='utf-8')
    f.write(users[id]['name'] + "  "+str(md)+"  "+stroka+'\n')
    f.close()

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

@bot.message_handler(commands=['start'])
def start_message(message):
    global chet
    users.setdefault(message.from_user.id, {'v1': 0,
                                            'v2': 0,
                                            't': 0,
                                            'name': "",
                                            'mode': 0,
                                            'S': 0})
    # Создание reply кнопки 'Меню'
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
    btn = types.KeyboardButton("Новая задача")
    markup.add(btn)
    bot.send_message(message.chat.id, "Введите имя",
                     reply_markup=markup)
    chet = 1

 if message.text!="password" and is_number(message.text)==False and chet==1:
        users[message.from_user.id]['name']=message.text
        chet=0
        bot.send_message(message.chat.id, "Нажмите 'Новая задача'")

Запускаем бот��. Вводим имя, кликаем кнопку Новая задача. Вводи неправиоьный ответ, вводим правильный ответ.

Все работает. Пробуем генерить новые задачи.

Все верно. Каждый раз новые задачи. Добавляем учителю возможность выгрузки файла с результатами и его очистку.

    if message.text =="password":
        file = open("./result.txt", "rb")
        bot.send_document(message.chat.id, file)

    if message.text =="pass_del":
        f = open('result.txt', 'w', encoding='utf-8')
        f.write("Результаты решения задач:"+'\n')
        f.close()
        bot.send_message(message.chat.id, "Данные удалены")

Пробуем.

Файл с результатами выгружается по нашему паролю.

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

import telebot  # Импортируем telebot
from secrets import secrets  # Словарь с токеном из файла secrets.py
from users import users  # Импортируем словарь для работы нескольких пользователей одновременно
from telebot import types  # для указания типов
from inline import del_inline  # для работы функции удаления предыдущего сообщения inline
import time
import random

# передаём значение переменной с кодом экземпляру бота
token = secrets.get('BOT_API_TOKEN')
bot = telebot.TeleBot(token)


def is_number(s):
    """ Функция проверки ввода на число """
    try:
        float(s)
        return True
    except ValueError:
        return False


# хендлер и функция для обработки команды /start
@bot.message_handler(commands=['start'])
def start_message(message):
    global chet
    users.setdefault(message.from_user.id, {'v1': 0,
                                            'v2': 0,
                                            't': 0,
                                            'name': "",
                                            'mode': 0,
                                            'S': 0})
    # Создание reply кнопки 'Меню'
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
    btn = types.KeyboardButton("Новая задача")
    markup.add(btn)
    bot.send_message(message.chat.id, "Введите имя",
                     reply_markup=markup)
    chet = 1

def zapis(r,id,md):
    if r==True:
        stroka="Правильно"
        bot.send_message(id, "Правильно.")
    else:
        stroka = "Неправильно"
        bot.send_message(id, "Неправильно.")
    f = open('result.txt', 'a', encoding='utf-8')
    f.write(users[id]['name'] + "  "+str(md)+"  "+stroka+'\n')
    f.close()

@bot.message_handler(content_types=["text"])
def text(message):
    global chet     # Для работы возможности выбора только одной операции в один момент времени (Калькулятор или список продуктов)
    if message.text == "Новая задача":  # При поступлении сообщения 'Меню' в чат
        menu(message)   # Вызов функции меню

    if message.text!="password" and is_number(message.text)==False and chet==1:
        users[message.from_user.id]['name']=message.text
        chet=0
        bot.send_message(message.chat.id, "Нажмите 'Новая задача'")

    if message.text =="password":
        file = open("./result.txt", "rb")
        bot.send_document(message.chat.id, file)

    if message.text =="pass_del":
        f = open('result.txt', 'w', encoding='utf-8')
        f.write("Результаты решения задач:"+'\n')
        f.close()
        bot.send_message(message.chat.id, "Данные удалены")

    if users[message.from_user.id]['mode'] > 0:
        if is_number(message.text)==True:
            if users[message.from_user.id]['mode']==1:
                if users[message.from_user.id]['t'] == int(message.text):
                    zapis(True,message.from_user.id,users[message.from_user.id]['mode'])
                else:
                    zapis(False,message.from_user.id,users[message.from_user.id]['mode'])
            elif users[message.from_user.id]['mode']==2:
                if users[message.from_user.id]['S'] == int(message.text):
                    zapis(True,message.from_user.id,users[message.from_user.id]['mode'])
                else:
                    zapis(False, message.from_user.id, users[message.from_user.id]['mode'])
            elif users[message.from_user.id]['mode']==3:
                if users[message.from_user.id]['v2'] == int(message.text):
                    zapis(True, message.from_user.id, users[message.from_user.id]['mode'])
                else:
                    zapis(False,message.from_user.id,users[message.from_user.id]['mode'])
            else:
                if users[message.from_user.id]['v1'] == int(message.text):
                    zapis(True, message.from_user.id, users[message.from_user.id]['mode'])
                else:
                    zapis(False, message.from_user.id, users[message.from_user.id]['mode'])
@bot.message_handler(content_types=["text"])
def menu(message):
    """
    Функция вызова меню с выбором inline кнопок
    """
    users[message.from_user.id]['v1'] = random.randint(50, 90)
    users[message.from_user.id]['v2'] = random.randint(50, 90)
    users[message.from_user.id]['t'] = random.randint(2, 7)
    users[message.from_user.id]['S'] = (users[message.from_user.id]['v1'] + users[message.from_user.id]['v2']) * users[message.from_user.id]['t']
    users[message.from_user.id]['mode'] = random.randint(1, 4)
    if users[message.from_user.id]['mode'] == 1:
        a = "Из города в противоположных направлениях выехали два автомобиля. Скорость первого автомобиля " + str(users[message.from_user.id]['v1']) + " км/ч. Скорость второго " + str(users[message.from_user.id]['v2']) + " км/ч. Через сколько часов расстояние между ними будет составлять " + str(users[message.from_user.id]['S']) + " км?"
    elif users[message.from_user.id]['mode'] == 2:
        a = "Из города в противоположных направлениях выехали два автомобиля. Скорость первого автомобиля " + str(users[message.from_user.id]['v1']) + " км/ч. Скорость второго " + str(users[message.from_user.id]['v2']) + " км/ч. Какое расстояние будет между ними через " + str(users[message.from_user.id]['t']) + " ч?"
    elif users[message.from_user.id]['mode'] == 3:
        a = "Из города в противоположных направлениях выехали два автомобиля. Скорость первого автомобиля " + str(users[message.from_user.id]['v1']) + " км/ч. Через " + str(users[message.from_user.id]['t']) + " ч расстояние между ними было " + str(users[message.from_user.id]['S']) + " км. Определите скорость второго автомобиля."
    else:
        a = "Из города в противоположных направлениях выехали два автомобиля. Скорость второго автомобиля " + str(users[message.from_user.id]['v2']) + " км/ч. Через " + str(users[message.from_user.id]['t']) + " ч расстояние между ними было " + str(users[message.from_user.id]['S']) + " км. Определите скорость первого автомобиля."
    bot.send_message(message.chat.id, a)
    bot.send_message(message.chat.id, "Введите ответ")

# бесконечное выполнение кода
while True:
    try:
      bot.polling(none_stop=True, interval=0)
    except:
      continue
#bot.polling(none_stop=True, interval=0)