Бот-Погода: выбор города кнопками

Бот умеет присылать погоду, но только одного города, зашитого в код. Менять координаты руками каждый раз неудобно. Сделаем по-человечески: покажем города кнопками, а бот сам сходит за погодой того, что нажали. Заодно вспомним inline-кнопки из Модуля 2.

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

Иллюстрация: бот-погода — робот с облаком и солнышком, сигнал данных из интернета

Храним города в словаре

У каждого города свои координаты, широта и долгота. Это пары «название координаты», просится в словарь:

goroda = {
    "Москва": (55.75, 37.62),
    "Санкт-Петербург": (59.94, 30.31),
    "Новосибирск": (55.03, 82.92),
}

Ключ это название города, значение это пара чисел в скобках (широта, долгота). Добавить город просто: дописал строчку с координатами.

Функция, которая узнаёт погоду

def pogoda_v(shirota, dolgota):
    url = f"https://api.open-meteo.com/v1/forecast?latitude={shirota}&longitude={dolgota}&current=temperature_2m"
    data = requests.get(url).json()
    return data["current"]["temperature_2m"]

Обрати внимание на f перед адресом. Это f-строка, она подставляет координаты прямо в адрес запроса. Для Москвы получится один адрес, для Питера другой. Одна функция работает для любого города.

Собираем Бот-Погоду

import telebot
import requests
from telebot import types
from config import TOKEN

bot = telebot.TeleBot(TOKEN)

goroda = {
    "Москва": (55.75, 37.62),
    "Санкт-Петербург": (59.94, 30.31),
    "Новосибирск": (55.03, 82.92),
}

def pogoda_v(shirota, dolgota):
    url = f"https://api.open-meteo.com/v1/forecast?latitude={shirota}&longitude={dolgota}&current=temperature_2m"
    data = requests.get(url).json()
    return data["current"]["temperature_2m"]

@bot.message_handler(commands=['start'])
def start(message):
    keyboard = types.InlineKeyboardMarkup()
    for gorod in goroda:
        keyboard.add(types.InlineKeyboardButton(gorod, callback_data=gorod))
    bot.send_message(message.chat.id, "Выбери город:", reply_markup=keyboard)

@bot.callback_query_handler(func=lambda call: True)
def on_city(call):
    bot.answer_callback_query(call.id)
    gorod = call.data
    shirota, dolgota = goroda[gorod]
    temp = pogoda_v(shirota, dolgota)
    bot.send_message(call.message.chat.id, f"В городе {gorod} сейчас {temp} градусов.")

bot.infinity_polling()

В кнопку кладём название города и в метку callback_data тоже название. Когда игрок жмёт, в call.data приходит это название. По нему достаём координаты: shirota, dolgota = goroda[gorod]. Эта строчка сразу раскладывает пару из словаря по двум переменным. Дальше зовём свою функцию и шлём ответ.

Запусти, нажми /start. Появятся кнопки с городами. Жми любой, бот сходит в интернет и пришлёт реальную погоду. Три города, три кнопки, никакого копания в коде.

Контрольный вопрос. Какая буква стоит перед строкой-адресом, чтобы координаты города подставились прямо в запрос? Напиши одну букву.

Подсказка: ____»…latitude={shirota}…»

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

Задание. Сделай словарь goroda со своими городами и координатами, покажи их кнопками на /start, по нажатию присылай температуру. Прокачай ответ: добавь к температуре ещё данные (например ветер) и сделай фразу красивой. Пришли скриншот, где ты нажал город и бот прислал погоду.

Подсказка: Кнопки строй циклом по словарю. Координаты доставай распаковкой пары: shirota, dolgota = goroda[gorod].

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

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

Зачёт, если:
✅ словарь goroda со своими городами и координатами готов, города показаны кнопками на /start;
✅ по нажатию бот присылает реальную погоду выбранного города;
✅ прислан скриншот: выбор города кнопкой и ответ с погодой.

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

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