Технология телеграм бота подкупила меня своей универсальностью. Можно использовать в телеграмм, можно просто в браузере, можно формировать любую логику работы… Сегодня ��ассмотрим вариант телеграм бота, представляющего собой фрагмент задачника по математике для 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)
