Проверяем ответ и считаем очки

Бот показывает вопрос с кнопками, но на нажатие пока не реагирует. Сегодня научим его проверять ответ, говорить «верно» или «неверно» и копить очки. Считать счёт ты уже умеешь по угадайке, так что половина дела знакома.

После урока сможешь: объяснить тему «Проверяем ответ и считаем очки» и выполнить связанный с ней учебный шаг без подсказки.

Что нам нужно помнить

В квизе бот помнит две вещи для каждого игрока: на каком вопросе игрок сейчас и сколько у него очков. Это снова состояние в памяти, словари по chat_id, как в угадайке.

nomer = {}   # на каком вопросе игрок
ochki = {}   # сколько очков набрал

Ставим эти строки вверху, рядом со списком вопросов. На /start обнуляем оба для игрока: вопрос нулевой, очков ноль.

@bot.message_handler(commands=['start'])
def start(message):
    chat_id = message.chat.id
    nomer[chat_id] = 0
    ochki[chat_id] = 0
    poslat_vopros(chat_id)

Заметил poslat_vopros(chat_id)? Это наша своя функция, которая шлёт текущий вопрос. Сейчас её напишем, чтобы не копировать код с кнопками снова и снова.

Функция-помощник

Показывать вопрос придётся не раз: на старте и после каждого ответа. Чтобы не плодить копии, вынесем это в одну функцию.

def poslat_vopros(chat_id):
    n = nomer[chat_id]
    vopros = voprosy[n]
    keyboard = types.InlineKeyboardMarkup()
    for variant in vopros["varianty"]:
        keyboard.add(types.InlineKeyboardButton(variant, callback_data=variant))
    bot.send_message(chat_id, f"Вопрос {n + 1}: {vopros['text']}", reply_markup=keyboard)

Функция берёт номер текущего вопроса игрока, достаёт нужный словарь из списка и шлёт его с кнопками. Теперь вместо десяти строк пишем одно слово poslat_vopros(chat_id). Это и есть сила своих функций: написал раз, зовёшь сколько нужно.

Ловим ответ и считаем

@bot.callback_query_handler(func=lambda call: True)
def otvet(call):
    chat_id = call.message.chat.id
    bot.answer_callback_query(call.id)
    n = nomer[chat_id]
    if call.data == voprosy[n]["otvet"]:
        ochki[chat_id] += 1
        bot.send_message(chat_id, "Верно!")
    else:
        bot.send_message(chat_id, f"Неверно. Правильно: {voprosy[n]['otvet']}")
  • n = nomer[chat_id] это номер вопроса, на котором игрок.
  • voprosy[n]["otvet"] это правильный ответ этого вопроса, call.data это то, что игрок нажал.
  • Совпали — добавляем очко и хвалим. Нет — показываем верный ответ. answer_callback_query в начале убирает часики.

Запусти, нажми /start, ответь на первый вопрос. Бот скажет «верно» или «неверно» и под капотом изменит счёт. Пока бот застрял на первом вопросе, к следующему он не переходит. Этот шаг сделаем в финальном уроке.

Контрольный вопрос. Какой метод убирает «часики» на inline-кнопке после нажатия? Напиши имя: bot.____(call.id).

Подсказка: bot.answer_callback_query(call.id)

Онлайн-проверка ответа появится позже

Задание. Добавь словари nomer и ochki, обнуляй их на /start, напиши функцию poslat_vopros и зови её на старте. В обработчике callback проверь ответ, скажи верно/неверно и поменяй счёт. Пришли скриншот, где видно «Верно» или «Неверно».

Подсказка: Состояние — словари по chat_id. Правильный ответ текущего вопроса — voprosy[n][«otvet»], выбор игрока — call.data.

✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.

Онлайн-проверка ответа появится позже

Зачёт, если:
✅ на нажатие бот говорит «Верно» или «Неверно» и меняет счёт;
✅ состояние (номер вопроса и очки) хранится по chat_id и обнуляется на /start;
✅ прислан скриншот, где видно «Верно» или «Неверно».

Назад  ·  ↑ В начало урока  ·  ⌂ В начало курса  ·  Вперёд →

Школа Виктора Комлева