Бот умеет присылать погоду, но только одного города, зашитого в код. Менять координаты руками каждый раз неудобно. Сделаем по-человечески: покажем города кнопками, а бот сам сходит за погодой того, что нажали. Заодно вспомним 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}¤t=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}¤t=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;
✅ по нажатию бот присылает реальную погоду выбранного города;
✅ прислан скриншот: выбор города кнопкой и ответ с погодой.
