🎯 Python + Погода: как получить данные с OpenWeatherMap API
Когда на улице пасмурно, дождливо, и хочется остаться дома с Python — самое время научиться получать метеоданные из реального мира. Сегодня разберем, как добыть и обработать погоду с помощью API OpenWeatherMap. Следить за капризами атмосферы мы будем с помощью библиотеки requests.
📌 Что нам понадобится?
- Аккаунт на https://openweathermap.org/
- API-ключ (его можно получить бесплатно после регистрации)
- Библиотека requests (если не установлена — pip install requests)
🚀 Стартуем!
Допустим, мы хотим узнать текущую погоду в Москве. OpenWeatherMap предоставляет различные API — мы воспользуемся самым простым, Current Weather Data.
Пример запроса:
Обратите внимание: параметр
🎯 Теперь — извлечем нужную информацию:
💡 Что дальше?
- Преобразовать это в функцию: удобно использовать в разных частях программы.
- Добавить ввод города от пользователя.
- Расширить: подключить прогноз погоды на неделю (One Call API).
📦 Функция для повторного использования:
Затем можно красиво оформить вывод:
🌤 Заключение
Работа с реальными API — отличный способ оживить свои знания Python. OpenWeatherMap позволяет не только вытягивать погодные данные, но и анализировать их, строить приложения прогнозов, отправлять уведомления. Все начинается с простого запроса. Следующий шаг — автоматизация или визуализация этих данных.
Пусть код всегда будет тёплым, а погода за окном — предсказуемой 😎
— Иван, программист
Когда на улице пасмурно, дождливо, и хочется остаться дома с Python — самое время научиться получать метеоданные из реального мира. Сегодня разберем, как добыть и обработать погоду с помощью API OpenWeatherMap. Следить за капризами атмосферы мы будем с помощью библиотеки requests.
📌 Что нам понадобится?
- Аккаунт на https://openweathermap.org/
- API-ключ (его можно получить бесплатно после регистрации)
- Библиотека requests (если не установлена — pip install requests)
🚀 Стартуем!
Допустим, мы хотим узнать текущую погоду в Москве. OpenWeatherMap предоставляет различные API — мы воспользуемся самым простым, Current Weather Data.
Пример запроса:
import requests
API_KEY = 'your_api_key_here'
CITY = 'Moscow'
URL = f'https://api.openweathermap.org/data/2.5/weather?q={CITY}&appid={API_KEY}&units=metric&lang=en'
response = requests.get(URL)
data = response.json()
print(data)
Обратите внимание: параметр
units=metric
отвечает за метрическую систему (°C вместо °K), а lang=en
— за язык описания погоды. Можно попробовать lang=ru
, если хочется интернациональности :)🎯 Теперь — извлечем нужную информацию:
if response.status_code == 200:
weather = data['weather'][0]['description']
temp = data['main']['temp']
feels = data['main']['feels_like']
humidity = data['main']['humidity']
wind = data['wind']['speed']
print(f"Погода в {CITY}: {weather}")
print(f"Температура: {temp}°C (ощущается как {feels}°C)")
print(f"Влажность: {humidity}%")
print(f"Скорость ветра: {wind} м/с")
else:
print(f"Ошибка получения данных: {response.status_code}")
💡 Что дальше?
- Преобразовать это в функцию: удобно использовать в разных частях программы.
- Добавить ввод города от пользователя.
- Расширить: подключить прогноз погоды на неделю (One Call API).
📦 Функция для повторного использования:
def get_current_weather(city, api_key):
url = f'https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric&lang=ru'
response = requests.get(url)
if response.status_code != 200:
return f"Ошибка: {response.status_code}"
data = response.json()
weather_info = {
'city': city,
'description': data['weather'][0]['description'],
'temp': data['main']['temp'],
'feels_like': data['main']['feels_like'],
'humidity': data['main']['humidity'],
'wind_speed': data['wind']['speed']
}
return weather_info
Затем можно красиво оформить вывод:
report = get_current_weather('Kazan', API_KEY)
if isinstance(report, dict):
print(f"{report['city']}: {report['description'].capitalize()}, {report['temp']}°C, ощущается как {report['feels_like']}°C")
else:
print(report)
🌤 Заключение
Работа с реальными API — отличный способ оживить свои знания Python. OpenWeatherMap позволяет не только вытягивать погодные данные, но и анализировать их, строить приложения прогнозов, отправлять уведомления. Все начинается с простого запроса. Следующий шаг — автоматизация или визуализация этих данных.
Пусть код всегда будет тёплым, а погода за окном — предсказуемой 😎
— Иван, программист
openweathermap.org
Current weather and forecast
OpenWeather provides comprehensive weather data services, including current, forecast, and historical
weather information. Explore a wide range of APIs for solar radiation, road risk assessment, solar energy prediction,
and more, with global coverage and…
weather information. Explore a wide range of APIs for solar radiation, road risk assessment, solar energy prediction,
and more, with global coverage and…
👍1
Привет! Сегодня мы поговорим о настоящей находке для любого Python-разработчика — defaultdict из модуля collections. Если вы хоть раз работали с подсчетом повторов, группировкой по ключам, вложенными структурами — этот инструмент спасет вам не один вечер.
Обычный словарь в Python хорош, но порой слишком суров. Попробуйте обратиться к несуществующему ключу — получите KeyError. Конечно, можно делать проверки или использовать get(), но есть и более изящный путь.
Знакомьтесь: defaultdict.
defaultdict — это подкласс стандартного dict, в который нужно передать функцию, возвращающую значение по умолчанию для новых ключей. Больше никаких проверок на наличие ключа — вы просто используете его, и если такого ключа не было, он автоматически создается с нужным значением.
Начнем с простого примера: подсчет частоты символов в строке.
Пара строк, и у нас мощный инструмент для статистики. Без get(), без if-ов — всё автоматически.
Теперь чуть интереснее. Группировка элементов по признаку. Например, сгруппируем слова по их первой букве:
Здесь defaultdict(list) творит магию: новые ключи создаются с пустым списком, и мы можем сразу .append() к ним.
Вы можете использовать любую callable в качестве фабрики значений. Например, создадим словарь словарей:
Без defaultdict такой код превращается в бой с инициализацией: проверяй ключи, создавай промежуточные словари вручную. А тут — элегантно и понятно.
Когда использовать defaultdict?
- Подсчет чего-либо (символов, слов, чисел, объектов)
- Группировка по ключам
- Вложенные структуры
- Кэширование и маппинг с дефолтными значениями
Когда не стоит:
- Если нужно понимание, существует ли ключ (defaultdict может скрыть ошибки)
- Если значения по умолчанию не универсальны
В целом, defaultdict — это шикарный способ сделать код компактнее, читаемее и устойчивее. Он буквально отключает необходимость думать о ключах — и даёт возможность сосредоточиться на сути задачи.
До встречи в следующем посте!
— Иван.
Обычный словарь в Python хорош, но порой слишком суров. Попробуйте обратиться к несуществующему ключу — получите KeyError. Конечно, можно делать проверки или использовать get(), но есть и более изящный путь.
Знакомьтесь: defaultdict.
defaultdict — это подкласс стандартного dict, в который нужно передать функцию, возвращающую значение по умолчанию для новых ключей. Больше никаких проверок на наличие ключа — вы просто используете его, и если такого ключа не было, он автоматически создается с нужным значением.
Начнем с простого примера: подсчет частоты символов в строке.
from collections import defaultdict
def count_characters(text):
char_count = defaultdict(int)
for char in text:
char_count[char] += 1
return char_count
text = "hello world"
print(count_characters(text))
Пара строк, и у нас мощный инструмент для статистики. Без get(), без if-ов — всё автоматически.
Теперь чуть интереснее. Группировка элементов по признаку. Например, сгруппируем слова по их первой букве:
from collections import defaultdict
words = ['apple', 'banana', 'avocado', 'blueberry', 'apricot', 'blackberry']
grouped = defaultdict(list)
for word in words:
grouped[word[0]].append(word)
print(dict(grouped))
Здесь defaultdict(list) творит магию: новые ключи создаются с пустым списком, и мы можем сразу .append() к ним.
Вы можете использовать любую callable в качестве фабрики значений. Например, создадим словарь словарей:
from collections import defaultdict
nested = defaultdict(lambda: defaultdict(int))
nested['user1']['clicks'] += 1
nested['user2']['views'] += 5
print(dict(nested))
Без defaultdict такой код превращается в бой с инициализацией: проверяй ключи, создавай промежуточные словари вручную. А тут — элегантно и понятно.
Когда использовать defaultdict?
- Подсчет чего-либо (символов, слов, чисел, объектов)
- Группировка по ключам
- Вложенные структуры
- Кэширование и маппинг с дефолтными значениями
Когда не стоит:
- Если нужно понимание, существует ли ключ (defaultdict может скрыть ошибки)
- Если значения по умолчанию не универсальны
В целом, defaultdict — это шикарный способ сделать код компактнее, читаемее и устойчивее. Он буквально отключает необходимость думать о ключах — и даёт возможность сосредоточиться на сути задачи.
До встречи в следующем посте!
— Иван.
👍3❤1
💾 Конфигурационные файлы с configparser: сохраняем настройки по-взрослому
Когда ваш Python-скрипт перестаёт быть одноразовой поделкой, в нём быстро появляется необходимость в настройках: база данных, логгирование, параметры подключения, пути, флаги… Всё это хочется вынести из кода и спрятать где-нибудь в конфиге, чтобы не пересобирать всё при каждом изменении одного IP-адреса. И тут на сцену выходит модуль configparser.
Встроенный в стандартную библиотеку, configparser позволяет удобно работать с INI-файлами — старым, но до сих пор живым форматом конфигураций. И это потрясающе удобно.
🌟 Пример 1: создаём конфиг
Начнём с сохранения простой конфигурации:
После выполнения этого кода появится файл
👌 Просто, наглядно – и читается как человеком, так и машиной.
🔎 Пример 2: читаем конфиг
Теперь прочитаем его и используем настройки в коде:
Бонус: методы вроде
🎯 Несколько полезных штук:
- Значения в секции
- Можно использовать
- Интуитивный синтаксис: если вы знакомы с INI-файлами — вы уже наполовину освоили configparser.
💡 А когда не стоит использовать configparser?
Если вы работаете со структурой, где важен порядок ключей, вложенность или поддержка сложных типов данных (например, список в списке) — возможно, лучше подойдёт JSON, YAML или TOML. Но для простых и среднесложных проектов configparser — лёгкий и надёжный выбор.
Вместо того чтобы хардкодить параметры в скрипте или передавать их через кучу аргументов, дайте своим скриптам читать из конфигов — и жить станет проще. Настройки вне кода — это шаг к более гибкому и поддерживаемому софту.
👨💻 С вами был Иван, до встречи в следующих постах по Python!
Когда ваш Python-скрипт перестаёт быть одноразовой поделкой, в нём быстро появляется необходимость в настройках: база данных, логгирование, параметры подключения, пути, флаги… Всё это хочется вынести из кода и спрятать где-нибудь в конфиге, чтобы не пересобирать всё при каждом изменении одного IP-адреса. И тут на сцену выходит модуль configparser.
Встроенный в стандартную библиотеку, configparser позволяет удобно работать с INI-файлами — старым, но до сих пор живым форматом конфигураций. И это потрясающе удобно.
🌟 Пример 1: создаём конфиг
Начнём с сохранения простой конфигурации:
import configparser
config = configparser.ConfigParser()
config['DEFAULT'] = {
'Server': 'localhost',
'Port': '8080',
'UseSSL': 'yes'
}
config['database'] = {
'User': 'admin',
'Password': 'secret',
'Host': '127.0.0.1'
}
with open('config.ini', 'w') as configfile:
config.write(configfile)
После выполнения этого кода появится файл
config.ini
примерно с таким содержимым:[DEFAULT]
Server = localhost
Port = 8080
UseSSL = yes
[database]
User = admin
Password = secret
Host = 127.0.0.1
👌 Просто, наглядно – и читается как человеком, так и машиной.
🔎 Пример 2: читаем конфиг
Теперь прочитаем его и используем настройки в коде:
import configparser
config = configparser.ConfigParser()
config.read('config.ini')
server = config['DEFAULT']['Server']
port = int(config['DEFAULT']['Port'])
use_ssl = config.getboolean('DEFAULT', 'UseSSL')
db_user = config['database']['User']
db_pass = config['database']['Password']
print(f"Connecting to {server}:{port} (SSL: {use_ssl}) as {db_user}")
Бонус: методы вроде
getboolean()
автоматически приводят значения к нужному типу. Вам не нужно вручную проверять 'yes'
или 'no'
— всё уже предусмотрено.🎯 Несколько полезных штук:
- Значения в секции
[DEFAULT]
наследуются всеми другими секциями.- Можно использовать
.get(section, option, fallback=value)
— если нет значения, вернёт значение по умолчанию вместо того, чтобы бросать исключение.- Интуитивный синтаксис: если вы знакомы с INI-файлами — вы уже наполовину освоили configparser.
💡 А когда не стоит использовать configparser?
Если вы работаете со структурой, где важен порядок ключей, вложенность или поддержка сложных типов данных (например, список в списке) — возможно, лучше подойдёт JSON, YAML или TOML. Но для простых и среднесложных проектов configparser — лёгкий и надёжный выбор.
Вместо того чтобы хардкодить параметры в скрипте или передавать их через кучу аргументов, дайте своим скриптам читать из конфигов — и жить станет проще. Настройки вне кода — это шаг к более гибкому и поддерживаемому софту.
👨💻 С вами был Иван, до встречи в следующих постах по Python!
👍2
Привет! Сегодня поговорим о безопасности — потому что никакой "Hello, World!" не стоит XSS-уязвимости. Если ты работаешь с пользовательским контентом, особенно HTML, будь готов встретиться с потенциальными атаками. Но к счастью, в Python есть модуль, который позволяет легко и эффективно очистить HTML от всего лишнего. Знакомься, bleach.
Модуль bleach — это простая, но мощная библиотека, которая позволяет фильтровать HTML-контент, оставляя только безопасные и разрешённые теги, атрибуты и стили. Под капотом bleach использует html5lib и поддерживает белый список (whitelist) — ты сам указываешь, какие HTML-элементы допустимы.
Зачем это нужно? Представь, что твое приложение отображает текст, введённый пользователем. Без фильтрации туда можно внедрить вредоносный скрипт, например:
Даже если ты любишь острые ощущения, пользователь твоего чата — вряд ли. Посмотрим, как bleach спасает положение.
Начнем с простого:
Результат:
Как видно, опасный тег
Теперь допустим, ты хочешь разрешить пользователю использовать только ограниченный набор тегов, скажем,
Все убойные
Страшно? Не бойся, bleach срежет опасные протоколы. Выход будет чист:
Want to allow safe links only? Используй
Наконец, можно “отбеливать” не просто строки, а делать это правильно в потоке данных. Bleach поддерживает
И ты получишь:
Вот так легко защитить свои Python-приложения от XSS и порадовать пользователей безопасным интерфейсом. Bleach — небольшой, но мощный инструмент, без которого сложно представить обработку HTML в веб-приложениях.
Оставайтесь чистыми 😉
— Иван
Модуль bleach — это простая, но мощная библиотека, которая позволяет фильтровать HTML-контент, оставляя только безопасные и разрешённые теги, атрибуты и стили. Под капотом bleach использует html5lib и поддерживает белый список (whitelist) — ты сам указываешь, какие HTML-элементы допустимы.
Зачем это нужно? Представь, что твое приложение отображает текст, введённый пользователем. Без фильтрации туда можно внедрить вредоносный скрипт, например:
<script>alert('Hacked!');</script>
Даже если ты любишь острые ощущения, пользователь твоего чата — вряд ли. Посмотрим, как bleach спасает положение.
Начнем с простого:
import bleach
raw_html = '<h1>Hello</h1><script>alert("XSS")</script><p>Welcome!</p>'
clean_html = bleach.clean(raw_html)
print(clean_html)
Результат:
<h1>Hello</h1><script>alert("XSS")</script><p>Welcome!</p>
Как видно, опасный тег
<script>
был автоматически экранирован.Теперь допустим, ты хочешь разрешить пользователю использовать только ограниченный набор тегов, скажем,
<p>
, <strong>
и <a>
. На помощь приходит параметр tags
:allowed_tags = ['p', 'strong', 'a']
clean_html = bleach.clean(raw_html, tags=allowed_tags)
print(clean_html)
Все убойные
<script>
, <style>
и прочий "ядерный арсенал" будут выброшены. Bleach также заботится об атрибутах. По умолчанию разрешены только безопасные, но ты можешь настроить список разрешенных атрибутов:raw_html = '<a href="javascript:alert(1)">Click me</a>'
clean_html = bleach.clean(raw_html, tags=['a'], attributes={'a': ['href']})
print(clean_html)
Страшно? Не бойся, bleach срежет опасные протоколы. Выход будет чист:
<a>Click me</a>
Want to allow safe links only? Используй
bleach.sanitizer.ALLOWED_PROTOCOLS
— он фильтрует небезопасные схемы вроде javascript:
.Наконец, можно “отбеливать” не просто строки, а делать это правильно в потоке данных. Bleach поддерживает
linkify()
— магию для превращения URL в ссылки:text = "Visit https://python.org!"
linked_text = bleach.linkify(text)
print(linked_text)
И ты получишь:
Visit <a href="https://python.org">https://python.org</a>!
Вот так легко защитить свои Python-приложения от XSS и порадовать пользователей безопасным интерфейсом. Bleach — небольшой, но мощный инструмент, без которого сложно представить обработку HTML в веб-приложениях.
Оставайтесь чистыми 😉
— Иван
👍1
Когда Python пишет в память: как измерять и оптимизировать использование памяти
Представьте, что у вас в рюкзаке лежат книги. Если у вас всего пара книжек — проблем нет. Но если вы случайно запихнули туда энциклопедию в 10 томах, да ещё на каждой странице – картинка, быть беде: рюкзак рвётся. Так же и с памятью в Python — можно писать лёгкий код, а можно незаметно нагрузить память до отказа. Сегодня поговорим о том, как следить за объёмом используемой памяти и как её оптимизировать.
📏 Измеряем: кто сколько ест?
Python по умолчанию не показывает, сколько памяти занял тот или иной объект. К счастью, у нас есть модуль
Начнём с простого:
Но
Заметка: установите
☝️ Проверь себя: строки и множества
Некоторые стандартные структуры данных в Python могут неожиданно потреблять много памяти. Например, множества
📉 Оптимизируем: меньше, но лучше
- Используйте генераторы вместо списков там, где это возможно. Они не хранят все элементы в памяти одновременно:
- Замените большие словари с повторяющимися значениями на
- Не держите в памяти то, что уже не нужно. Иногда достаточно просто удалить переменные:
- Используйте
🚀 Вывод
Python — не самый «худенький» язык, когда речь заходит о памяти. Но понимание того, как и где расходуются ресурсы, творит чудеса. Используя простые приёмы и правильные инструменты, даже «тяжёлый» код можно привести в форму. А значит — приложение работает быстрее, а сервер не падает при каждом запуске анализа данных.
Представьте, что у вас в рюкзаке лежат книги. Если у вас всего пара книжек — проблем нет. Но если вы случайно запихнули туда энциклопедию в 10 томах, да ещё на каждой странице – картинка, быть беде: рюкзак рвётся. Так же и с памятью в Python — можно писать лёгкий код, а можно незаметно нагрузить память до отказа. Сегодня поговорим о том, как следить за объёмом используемой памяти и как её оптимизировать.
📏 Измеряем: кто сколько ест?
Python по умолчанию не показывает, сколько памяти занял тот или иной объект. К счастью, у нас есть модуль
sys
и отличная библиотека pympler
.Начнём с простого:
import sys
data = [i for i in range(10000)]
print(sys.getsizeof(data)) # Размер самого списка
print(sys.getsizeof(data[0])) # Размер одного элемента
Но
sys.getsizeof()
возвращает только «голый» размер объекта, без вложенных данных. Например, список из 10 000 строк займёт гораздо больше, чем просто «список». Для глубокого анализа лучше использовать pympler
.from pympler import asizeof
data = [str(i) for i in range(10000)]
print(asizeof.asizeof(data))
Заметка: установите
pympler
через pip install pympler
, если он ещё не установлен.☝️ Проверь себя: строки и множества
Некоторые стандартные структуры данных в Python могут неожиданно потреблять много памяти. Например, множества
set
занимают больше памяти, чем списки, а строки — иногда ведут себя не так, как ожидаешь:a = 'hello' * 1000
b = ['hello'] * 1000
print(sys.getsizeof(a), 'vs', sys.getsizeof(b))
📉 Оптимизируем: меньше, но лучше
- Используйте генераторы вместо списков там, где это возможно. Они не хранят все элементы в памяти одновременно:
sum_gen = sum(i for i in range(10**7)) # Генератор
sum_list = sum([i for i in range(10**7)]) # Список, занимает в разы больше памяти
- Замените большие словари с повторяющимися значениями на
collections.defaultdict
или array
/struct
, особенно в случае числовых данных.- Не держите в памяти то, что уже не нужно. Иногда достаточно просто удалить переменные:
import gc
del large_data
gc.collect()
- Используйте
__slots__
в ваших классах, если количество атрибутов фиксировано. Это сокращает накладные расходы на хранение объектов:class Lightweight:
__slots__ = ['name', 'value']
def __init__(self, name, value):
self.name = name
self.value = value
🚀 Вывод
Python — не самый «худенький» язык, когда речь заходит о памяти. Но понимание того, как и где расходуются ресурсы, творит чудеса. Используя простые приёмы и правильные инструменты, даже «тяжёлый» код можно привести в форму. А значит — приложение работает быстрее, а сервер не падает при каждом запуске анализа данных.
👍2
🕹️ Как создать простую текстовую игру с помощью модуля curses в Python
Привет! С вами Иван, и сегодня мы окунёмся в мир текстовых интерфейсов на чистом Python. Игры — отличный способ попрактиковаться в программировании. А текстовые игры — это минимум графики, максимум фантазии. Но даже текст можно приукрасить: анимацией, управлением клавишами и взаимодействием в реальном времени. Всё это даёт модуль curses.
Что такое curses?
Модуль curses — это оболочка для работы с терминалом. Он позволяет рисовать "на лету", обрабатывать нажатия клавиш без ENTER'а, управлять цветами и позициями текста, и всё это — удобно, не покидая консолей. Работает из коробки на Linux и macOS. На Windows потребуется установить windows-curses:
Создаём простую игру: уклоняйся от падающих звёзд 🌠
Представьте: звёзды падают сверху вниз, а вы — смайлик 🙂, который бегает внизу и старается не попасть под удар.
Давайте напишем минимальную, но полностью работающую аркаду на curses:
📦 Что мы здесь используем:
-
-
-
-
-
🔥 Игра проста, но в ней уже есть движение, случайность, управление и счёт. На этой базе можно развивать игру: добавить жизни, уровни или спецэффекты.
Если вы устали от обычных input/print — попробуйте curses. Он идеален для создания собственных мини-игр, TUI-интерфейсов, и просто для фана.
До встречи в следующем посте. Будем учиться строить терминальное меню и прокачаем наши игрушки! 👾
Привет! С вами Иван, и сегодня мы окунёмся в мир текстовых интерфейсов на чистом Python. Игры — отличный способ попрактиковаться в программировании. А текстовые игры — это минимум графики, максимум фантазии. Но даже текст можно приукрасить: анимацией, управлением клавишами и взаимодействием в реальном времени. Всё это даёт модуль curses.
Что такое curses?
Модуль curses — это оболочка для работы с терминалом. Он позволяет рисовать "на лету", обрабатывать нажатия клавиш без ENTER'а, управлять цветами и позициями текста, и всё это — удобно, не покидая консолей. Работает из коробки на Linux и macOS. На Windows потребуется установить windows-curses:
pip install windows-curses
Создаём простую игру: уклоняйся от падающих звёзд 🌠
Представьте: звёзды падают сверху вниз, а вы — смайлик 🙂, который бегает внизу и старается не попасть под удар.
Давайте напишем минимальную, но полностью работающую аркаду на curses:
import curses
import random
import time
def main(stdscr):
curses.curs_set(0)
stdscr.nodelay(True)
stdscr.timeout(100)
sh, sw = stdscr.getmaxyx()
player_x = sw // 2
player = "🙂"
stars = []
score = 0
while True:
stdscr.clear()
# Рисуем игрока
stdscr.addstr(sh - 1, player_x, player)
# Генерация новых звезд
if random.randint(1, 10) == 1:
star_x = random.randint(0, sw - 1)
stars.append([0, star_x])
# Обновляем позиции звезд
for star in stars:
star[0] += 1
if star[0] < sh:
stdscr.addstr(star[0], star[1], "*")
# Проверка на столкновение
for star in stars:
if star[0] == sh - 1 and star[1] == player_x:
msg = f"Game Over! Score: {score}"
stdscr.addstr(sh // 2, sw // 2 - len(msg) // 2, msg)
stdscr.refresh()
time.sleep(2)
return
# Удаляем вышедшие за границу звезды и увеличиваем счёт
stars = [star for star in stars if star[0] < sh]
score += 1
# Управление
key = stdscr.getch()
if key == curses.KEY_LEFT and player_x > 0:
player_x -= 1
elif key == curses.KEY_RIGHT and player_x < sw - 1:
player_x += 1
elif key == ord('q'):
break
stdscr.refresh()
curses.wrapper(main)
📦 Что мы здесь используем:
-
nodelay(True)
и timeout(100)
— для плавного обновления экрана;-
curs_set(0)
— отключение мигающего курсора;-
getch()
— для чтения нажатий клавиш без ENTER'а;-
addstr(y, x, text)
— вывод текста в нужную позицию;-
getmaxyx()
— узнаем размеры терминала;🔥 Игра проста, но в ней уже есть движение, случайность, управление и счёт. На этой базе можно развивать игру: добавить жизни, уровни или спецэффекты.
Если вы устали от обычных input/print — попробуйте curses. Он идеален для создания собственных мини-игр, TUI-интерфейсов, и просто для фана.
До встречи в следующем посте. Будем учиться строить терминальное меню и прокачаем наши игрушки! 👾
Когда кортеж — хорошо, но читаемость важнее: знакомимся с namedtuple
Когда-то каждый из нас начинал с простых структур данных в Python: списков, словарей и кортежей. Но вот беда — кортежи хоть и компактны, но напрочь забывают об удобстве чтения. Спустя пару недель ты смотришь на что-то вроде tuple2 и пытаешься вспомнить, был ли это адрес, возраст или погрешность измерения.
А теперь представь — можно оставить легковесность, но добавить читаемость. Волшебство? Почти. Это namedtuple.
📦 Что такое namedtuple?
Это тот самый кортеж, только с возможностью обращаться к полям по имени. Импортируется он из стандартного модуля collections:
Выглядит как класс, работает как кортеж. Удобно, быстро и читаемо.
🚀 Создаем первый namedtuple
Допустим, мы пишем GPS-трекер. Точка на карте содержит имя координаты, широту и долготу. Можно сделать это так:
Уже лучше, чем tuple0, правда? А еще у такого объекта сохраняется понятная структура при выводе и его можно распаковывать как обычный кортеж:
✨ Не только красиво, но и полезно
Из коробки namedtuple дает такие плюшки:
- Легковесность как у tuple (namedtuple неизменяем);
- Поддержка всех tuple-операций: индексация, распаковка, сравнение;
- Метод asdict() — для превращения в словарь;
- Метод replace() — для создания новой копии с измененными полями.
Пример:
А вот превращение в словарь удобно, если нужно, скажем, сериализовать:
🧩 Когда использовать?
Используй namedtuple, когда:
1. У объекта фиксированное количество атрибутов;
2. Ты хочешь неизменяемые структуры;
3. Нужна читаемость при минимальных затратах памяти.
Для mutable-объектов лучше подойдет dataclass, но это уже другая история.
🤹 Чуть больше магии
namedtuple позволяет указывать значения по умолчанию (не напрямую, но можно немного схитрить):
Эта фича доступна, начиная с Python 3.7.
🔚 Итоги
Если тебе нужно структурировать данные, но не хочется писать полноценный класс — namedtuple будет твоим лучшим другом. Он компактен, читаем и быстр. Маленький герой большого кода.
Используй силу именованных кортежей и пиши код, который не только работает, но и радует глаз.
Когда-то каждый из нас начинал с простых структур данных в Python: списков, словарей и кортежей. Но вот беда — кортежи хоть и компактны, но напрочь забывают об удобстве чтения. Спустя пару недель ты смотришь на что-то вроде tuple2 и пытаешься вспомнить, был ли это адрес, возраст или погрешность измерения.
А теперь представь — можно оставить легковесность, но добавить читаемость. Волшебство? Почти. Это namedtuple.
📦 Что такое namedtuple?
Это тот самый кортеж, только с возможностью обращаться к полям по имени. Импортируется он из стандартного модуля collections:
from collections import namedtuple
Выглядит как класс, работает как кортеж. Удобно, быстро и читаемо.
🚀 Создаем первый namedtuple
Допустим, мы пишем GPS-трекер. Точка на карте содержит имя координаты, широту и долготу. Можно сделать это так:
from collections import namedtuple
Location = namedtuple('Location', ['name', 'latitude', 'longitude'])
place = Location(name='Home', latitude=55.750446, longitude=37.617494)
print(place)
print(place.name) # 'Home'
print(place.latitude) # 55.750446
Уже лучше, чем tuple0, правда? А еще у такого объекта сохраняется понятная структура при выводе и его можно распаковывать как обычный кортеж:
name, lat, lon = place
✨ Не только красиво, но и полезно
Из коробки namedtuple дает такие плюшки:
- Легковесность как у tuple (namedtuple неизменяем);
- Поддержка всех tuple-операций: индексация, распаковка, сравнение;
- Метод asdict() — для превращения в словарь;
- Метод replace() — для создания новой копии с измененными полями.
Пример:
updated_place = place._replace(name='Office')
print(place.name) # 'Home'
print(updated_place.name) # 'Office'
А вот превращение в словарь удобно, если нужно, скажем, сериализовать:
print(place._asdict())
# {'name': 'Home', 'latitude': 55.750446, 'longitude': 37.617494}
🧩 Когда использовать?
Используй namedtuple, когда:
1. У объекта фиксированное количество атрибутов;
2. Ты хочешь неизменяемые структуры;
3. Нужна читаемость при минимальных затратах памяти.
Для mutable-объектов лучше подойдет dataclass, но это уже другая история.
🤹 Чуть больше магии
namedtuple позволяет указывать значения по умолчанию (не напрямую, но можно немного схитрить):
Color = namedtuple('Color', ['r', 'g', 'b'], defaults=[0, 0, 0])
gray = Color()
print(gray) # Color(r=0, g=0, b=0)
Эта фича доступна, начиная с Python 3.7.
🔚 Итоги
Если тебе нужно структурировать данные, но не хочется писать полноценный класс — namedtuple будет твоим лучшим другом. Он компактен, читаем и быстр. Маленький герой большого кода.
Используй силу именованных кортежей и пиши код, который не только работает, но и радует глаз.
👍1
Привет! Сегодня мы поговорим о модуле ftplib — простом, но полезном инструменте Python для работы с FTP. Вы сможете подключиться к удалённому серверу, скачать или загрузить файлы — и всё это всего за пару строк кода. Поехали!
Модуль ftplib входит в стандартную библиотеку Python, так что ничего дополнительно устанавливать не нужно. Давайте сразу начнем с базового подключения.
## Подключаемся к FTP-серверу
Для начала, создадим соединение и получим список файлов:
Метод
## Скачиваем файл
Хотите скачать файл — скажем,
Метод
## Загружаем файл
Теперь — наоборот: загрузим файл на сервер.
Метод
## Полезные фишки
-
-
-
-
Пример: создадим папку и загрузим туда файл.
## Немного безопасности
FTP — это не самый защищённый протокол. Данные передаются в открытом виде, без шифрования. Если работаете с чувствительной информацией — рассмотрите
## В заключение
Модуль ftplib — это отличный способ автоматизировать работу с файлами на удалённых серверах. Он незаменим, если вы, например, хотите написать скрипт, который каждый день сохраняет бэкапы или забирает отчеты с FTP-серверов. Всё просто: минимум кода, максимум полезности.
До встречи в следующих постах!
Ваш Иван 🐍
Модуль ftplib входит в стандартную библиотеку Python, так что ничего дополнительно устанавливать не нужно. Давайте сразу начнем с базового подключения.
## Подключаемся к FTP-серверу
Для начала, создадим соединение и получим список файлов:
from ftplib import FTP
ftp = FTP('ftp.example.com') # Адрес сервера
ftp.login(user='username', passwd='password')
ftp.cwd('/path/to/directory') # Переход в нужную директорию
files = ftp.nlst() # Получаем список файлов
print(files)
ftp.quit()
Метод
login()
используется для авторизации. Если сервер поддерживает анонимный доступ, просто вызовите ftp.login()
без параметров. Метод nlst()
возвращает список имен файлов в текущей директории.## Скачиваем файл
Хотите скачать файл — скажем,
data.txt
? Легко:with open('data.txt', 'wb') as f:
ftp.retrbinary('RETR data.txt', f.write)
Метод
retrbinary()
хорош для двоичных данных (например, изображений). Если вы уверены, что работаете с текстом, можно использовать retrlines()
:ftp.retrlines('RETR readme.txt', lambda line: print(">>", line))
## Загружаем файл
Теперь — наоборот: загрузим файл на сервер.
with open('upload.txt', 'rb') as f:
ftp.storbinary('STOR upload.txt', f)
Метод
storbinary()
отправляет двоичный файл на сервер. Если нужно передать файл построчно, используйте storlines()
.## Полезные фишки
-
ftp.cwd(path)
— смена директории на сервере.-
ftp.mkd(dirname)
и ftp.rmd(dirname)
— создать и удалить директорию.-
ftp.delete(filename)
— удалить файл.-
ftp.rename(old, new)
— переименовать файл или переместить.Пример: создадим папку и загрузим туда файл.
ftp.mkd('new_folder')
ftp.cwd('new_folder')
with open('photo.jpg', 'rb') as f:
ftp.storbinary('STOR photo.jpg', f)
## Немного безопасности
FTP — это не самый защищённый протокол. Данные передаются в открытом виде, без шифрования. Если работаете с чувствительной информацией — рассмотрите
ftplib.FTP_TLS
, чтобы использовать FTPS.from ftplib import FTP_TLS
ftp = FTP_TLS('secure.example.com')
ftp.login('user', 'password')
ftp.prot_p() # Включаем защиту данных
## В заключение
Модуль ftplib — это отличный способ автоматизировать работу с файлами на удалённых серверах. Он незаменим, если вы, например, хотите написать скрипт, который каждый день сохраняет бэкапы или забирает отчеты с FTP-серверов. Всё просто: минимум кода, максимум полезности.
До встречи в следующих постах!
Ваш Иван 🐍
Привет! На связи Иван, и сегодня поговорим о том, как научить свои скрипты понимать команды из терминала. Представь: ты написал крутую утилиту, и теперь хочешь запускать её с разными параметрами, а не каждый раз менять код или жонглировать input(). На помощь приходит модуль argparse — встроенный в Python инструмент для парсинга аргументов командной строки.
Никакой магии, только понятный и мощный API. Давайте разберёмся, как он работает на практике.
Начнем с мини-примера:
Попробуй теперь вызвать скрипт из консоли так:
И получишь:
Что здесь происходит?
-
-
-
Теперь усилим пример. Добавим обязательный аргумент и флаг:
Команды:
Здесь
Тебе не нужно писать код для проверки: есть ли аргументы, правильно ли указаны — за это отвечает argparse. Даже help-меню (да, оно генерируется само!) можно получить так:
Вы получите подробную справку автоматически. Удобно? Очень.
👀 А теперь пример посложнее — калькулятор с операцией и числами:
Вызов:
А если указать что-то кроме
Вот за что я люблю этот модуль — минимум кода, максимум пользы. У него есть и более продвинутые возможности: группы аргументов, парсинг вложенных команд, типы вроде float или datetime. Для больших CLI-добавлений можно использовать argparse в связке с модулями subparsers или даже перейти на click, но это уже другая история.
Если ты хочешь превратить свой скрипт в полноценный инструмент командной строки — начинай с argparse. Он встроен, прост и отлично масштабируется.
До встречи в следующем посте!
Никакой магии, только понятный и мощный API. Давайте разберёмся, как он работает на практике.
Начнем с мини-примера:
import argparse
parser = argparse.ArgumentParser(description='Simple greeting script')
parser.add_argument('--name', type=str, help='Name of the person')
args = parser.parse_args()
print(f"Hello, {args.name}!")
Попробуй теперь вызвать скрипт из консоли так:
python script.py --name Alice
И получишь:
Hello, Alice!
Что здесь происходит?
-
ArgumentParser
запускает “приёмную кампанию” для аргументов.-
add_argument()
указывает, что мы ждём аргумент --name
, и какого он типа.-
parse_args()
превращает пользовательский ввод в объект с атрибутами.Теперь усилим пример. Добавим обязательный аргумент и флаг:
parser.add_argument('filename', type=str, help='Path to the input file')
parser.add_argument('--verbose', action='store_true', help='Enable verbose mode')
Команды:
python script.py data.txt --verbose
Здесь
filename
— позиционный аргумент (обязателен), а --verbose
— флаг (включается, если указан).Тебе не нужно писать код для проверки: есть ли аргументы, правильно ли указаны — за это отвечает argparse. Даже help-меню (да, оно генерируется само!) можно получить так:
python script.py --help
Вы получите подробную справку автоматически. Удобно? Очень.
👀 А теперь пример посложнее — калькулятор с операцией и числами:
parser = argparse.ArgumentParser(description='Simple calculator')
parser.add_argument('operation', choices=['add', 'sub'], help='Operation to perform')
parser.add_argument('x', type=int, help='First number')
parser.add_argument('y', type=int, help='Second number')
args = parser.parse_args()
if args.operation == 'add':
result = args.x + args.y
else:
result = args.x - args.y
print(f"Result: {result}")
Вызов:
python calc.py add 3 7
# Выведет: Result: 10
А если указать что-то кроме
add
или sub
— argparse не даст запустить скрипт.Вот за что я люблю этот модуль — минимум кода, максимум пользы. У него есть и более продвинутые возможности: группы аргументов, парсинг вложенных команд, типы вроде float или datetime. Для больших CLI-добавлений можно использовать argparse в связке с модулями subparsers или даже перейти на click, но это уже другая история.
Если ты хочешь превратить свой скрипт в полноценный инструмент командной строки — начинай с argparse. Он встроен, прост и отлично масштабируется.
До встречи в следующем посте!
Привет, друзья! Сегодня поговорим о том, как удобно и понятно управлять состоянием приложения с помощью обычных Python-классов. Ведь даже в самом простом проекте нам часто нужно отслеживать, где находится пользователь, какие данные он ввёл, открыт ли файл, активна ли сессия и много чего ещё. Давайте разберёмся, как сделать это грамотно.
Когда мы говорим «состояние приложения», мы подразумеваем набор параметров, описывающих его текущую "жизнь". Если подходить к этому хаотично — создавая глобальные переменные или передавая «состояние» вручную в каждую функцию, — приложение быстро превратится в кошмар для сопровождения.
Вот тут и приходят на помощь классы.
Посмотрим на простой пример. Допустим, мы разрабатываем текстовый редактор:
Теперь у нас есть полноценный контейнер состояния редактора. Всё, что может происходить: загрузка файла, изменения, сохранение — оформлено методами класса. И главное, состояние (
Но зачем вообще класс, если можно просто передавать словарь?
Во-первых, классы позволяют инкапсулировать поведение: вы определяете не только данные, но и то, как с ними можно работать. Во-вторых — читаемость, масштабируемость, интеграция с типизацией. Это особенно ценно, когда приложение растёт.
Давайте усложним задачу. Создадим что-нибудь вроде простого игрового состояния:
Теперь GameState знает, как себя "вести", когда игра запускается, когда игрок переходит на следующий уровень или завершает сессию. Такой подход прекрасно масштабируется: можно добавить сохранение/загрузку в JSON, можно сделать отдельные состояния для игрока, врагов, меню — и всё это будет изолировано и логично.
Небольшой бонус — использование dataclass:
Идеально для хранения данных без лишнего кода. Если вам не нужно особое поведение, а просто нужно "держать" состояние — отличный и лаконичный способ.
Итак, если вы только начинаете с Python и ваш проект постепенно обрастает логикой и данными — начинайте формировать привычку описывать состояниe через классы. Это помогает избежать хаоса, делает код чище, тесты — проще, а вас — спокойнее.
До встречи!
– Иван 👨💻
Когда мы говорим «состояние приложения», мы подразумеваем набор параметров, описывающих его текущую "жизнь". Если подходить к этому хаотично — создавая глобальные переменные или передавая «состояние» вручную в каждую функцию, — приложение быстро превратится в кошмар для сопровождения.
Вот тут и приходят на помощь классы.
Посмотрим на простой пример. Допустим, мы разрабатываем текстовый редактор:
class TextEditorState:
def __init__(self):
self.filename = None
self.content = ""
self.modified = False
def load_file(self, filename):
with open(filename, "r", encoding="utf-8") as f:
self.content = f.read()
self.filename = filename
self.modified = False
def update_content(self, new_content):
self.content = new_content
self.modified = True
def save(self):
if self.filename:
with open(self.filename, "w", encoding="utf-8") as f:
f.write(self.content)
self.modified = False
Теперь у нас есть полноценный контейнер состояния редактора. Всё, что может происходить: загрузка файла, изменения, сохранение — оформлено методами класса. И главное, состояние (
content
, filename
, modified
) всегда у нас под контролем и в одном месте.Но зачем вообще класс, если можно просто передавать словарь?
Во-первых, классы позволяют инкапсулировать поведение: вы определяете не только данные, но и то, как с ними можно работать. Во-вторых — читаемость, масштабируемость, интеграция с типизацией. Это особенно ценно, когда приложение растёт.
Давайте усложним задачу. Создадим что-нибудь вроде простого игрового состояния:
class GameState:
def __init__(self):
self.level = 1
self.score = 0
self.inventory = []
def next_level(self):
self.level += 1
def add_score(self, points):
self.score += points
def add_item(self, item):
self.inventory.append(item)
def reset(self):
self.level = 1
self.score = 0
self.inventory.clear()
Теперь GameState знает, как себя "вести", когда игра запускается, когда игрок переходит на следующий уровень или завершает сессию. Такой подход прекрасно масштабируется: можно добавить сохранение/загрузку в JSON, можно сделать отдельные состояния для игрока, врагов, меню — и всё это будет изолировано и логично.
Небольшой бонус — использование dataclass:
from dataclasses import dataclass, field
@dataclass
class SessionState:
user_id: int
is_authenticated: bool = False
preferences: dict = field(default_factory=dict)
Идеально для хранения данных без лишнего кода. Если вам не нужно особое поведение, а просто нужно "держать" состояние — отличный и лаконичный способ.
Итак, если вы только начинаете с Python и ваш проект постепенно обрастает логикой и данными — начинайте формировать привычку описывать состояниe через классы. Это помогает избежать хаоса, делает код чище, тесты — проще, а вас — спокойнее.
До встречи!
– Иван 👨💻
🔥3