Как создать паузу в работе бота, чтобы дать пользователю время для ответа?

Как можно сделать бота, который будет выводить расписание межгородских автобусов с различными точками отправления? У меня уже есть код, который работает с фиксированной точкой отправления, но как сделать так, чтобы это работало с разными точками отправления? Я пробовал использовать `registr`, но что-то пошло не так. Может, мне не понять, как им правильно пользоваться? Если есть возможность, помогите, пожалуйста.
  • 16 июля 2024 г. 7:32
Ответы на вопрос 2
Для создания паузы в работе бота, чтобы дать пользователю время для ответа, вы можете использовать функцию sleep из модуля time. Например, чтобы создать паузу в работе бота на 1 секунду, вы можете написать:

```python
import time

time.sleep(1)
```

Этот код заставит бота подождать 1 секунду перед тем, как продолжить выполнение программы.

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

Примерно так:

```python
from telegram import Update
from telegram.ext import Updater, CommandHandler, CallbackContext

def schedule(update: Update, context: CallbackContext):
    departure_point = context.args[0]  # принимаем точку отправления как аргумент команды
    # Ваш код, который выводит расписание автобусов для указанной точки отправления

updater = Updater("TOKEN", use_context=True)
dispatcher = updater.dispatcher

dispatcher.add_handler(CommandHandler("schedule", schedule))

updater.start_polling()
updater.idle()
```

Вызовите вашего бота с командой "/schedule Москва", где "Москва" будет вашей точкой отправления. Используйте context.args[0] для получения переданного аргумента.

Надеюсь, этот пример поможет вам доработать ваш код для работы с различными точками отправления. Если у вас возникнут дополнительные вопросы или проблемы, не стесняйтесь их задавать.
Ну для начала твоя лесенка из if-elif-elif-... - плохое решение. 
Сделай нормальную структуру данных вместо пачки переменных. Используй словарь, или ещё что. Например, такого вида:
# словарь, где ключ - строка с названием пунка отправления, а значение - ещё словарь,
#   где ключ - строка с названием пункта назначения, а значение - список,
#     где элементы - пары строк ("время отправления", "время прибытия")
# Тогда с таким словарём можно будет работать так:
bus_timetable: dict[str, dict[str, list[tuple[str, str]]]] = {
    # ты словарь заполняешь по результатам парсинга, ну и то хорошо
    # я для примера запишу прямо так
    'Владимир' : {
        'Муром': [
            ('8:00', '11:00'),
            ('9:00', '12:00'),
            ('10:00', '13:00'),
        ],
    },
}
point_from = 'Владимир'
point_to = 'Муром'
# для примера вывожу в консоль, для бота перепишешь сам
print(f'Автобус из {point_from} в {point_to}')  
for departure, arrival in bus_timetable[point_from][point_to]:
    print(f'Отходит в {departure}, прибывает в {arrival}')

Тогда тебе не потребуется делать кучу веток для разных городов, достаточно лишь определить значения point_from и point_to. Более того, ты можешь просто перечислить ключи внешнего словаря при создании кнопок:
kbd_from = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = [types.KeyboardButton(point_from) for point_from in bus_timetable]  # список кнопок
kbd_from.add(*buttons)  # если надо добавить все кнопки сразу

Похожий приём возможен и для определения кнопок для городов назначения.

А теперь по тому, как сделать выбор. Тут есть два варианта, но давай пока поговорим о ReplyKeyboardMarkup, которую ты используешь.
Если ты хочешь использовать ReplyKeyboardMarkup, то стоит помнить - её кнопки дают тот же эффект, как если бы пользователь просто ввёл текст кнопки сам. Поэтому тебе потребуется использовать register_next_step_handler(). Ты не привёл код своей попытки, но в целом идея несложная. В основном обработчике события ты проверяешь, что текст сообщения содержится в bus_timetable (оператор in в помощь) - это значит, что текст сообщения содержит название известного боту города.
Тогда ты делаешь вызов register_next_step_handler() и ставишь обработчик второго сообщения. Единственное "но": тебе нужно будет обработчику передать первый выбранный город. Это будет выглядеть как-то так:
@bot.message_handler(content_types=['text'])
def first_message_handler(message):
    if message.text in bus_timetable:  # назвали известный город? Это пункт отправления
        kbd = ...  # тут определяешь клавиатуру, опираясь на города в bus_timetable[message.text]
        response = bot.reply_to(message, "А теперь назовите пункт назначения", reply_markup=kbd)
        # обрати внимание: все параметры после указания функции second_message_handler будут
        # переданы в эту функцию при её вызове. А вызвана она будет, когда пользователь ответит.
        bot.register_next_step_handler(response, second_message_handler, message.text)
    elif ...  # нам назвали не город - тут можно проверить другие команды

def second_message_handler(message, point_from):
    # а эта функция будет вызвана только когда пользователь уже назвал пункт отправления
    # point_from будет содержать название города, отправленное пользователем.
    if message.text in bus_timetable[point_from]:  # нам назвали допустимый пункт назначения
        bus_rides = bus_timetable[point_from][point_to]  # список рейсов
        ...  # дальше перебираем список bus_rides и выводим его пользователю
    else:  # пользователь назвал что-то другое
        ...  # говорим пользователю, что он дурак
Похожие вопросы