Привет, друзья! С вами снова Иван, и сегодня мы погрузимся в мир веселого и интерактивного программирования на Python с помощью модуля turtle. Turtle – это практически встроенный художник для начинающих программистов. Он отлично помогает освоить базовые концепции программирования через творчество. Давайте вместе создадим несколько интерактивных проектов, которые заставят ваш код «ожить».
### Первая интерактивность: управляй черепашкой
Для начала – классика: научим пользователя управлять черепашкой при помощи клавиш. Такой подход отлично знакомит с работой событий и функцией обратного вызова (
Жмите стрелки — и наблюдайте, как черепашка послушно перемещается по экрану! Это минимальный, но очень показательный пример управления объектом.
### Рисуем, куда кликаем
А как насчёт превращения вашего кода в простейшее рисовальное приложение? Turtle позволяет реагировать на клики мышки!
Теперь каждый клик по экрану будет оставлять след — отпечаток вашей черепашки в указанном месте.
### Игра для начинающих: собираем звёзды
Давайте сделаем небольшую игру — ловим звёзды! Пусть черепашка двигается к месту клика и «собирает» звёздочку.
Теперь каждый клик — это попытка «поймать» улетающую звезду, а основа следующей игры уже готова. Такие эксперименты отлично развивают алгоритмическое мышление и интерес к Python.
### Итоги
Turtle великолепно подходит для начинающих: он дает быстрый визуальный результат и мотивацию поиграться с кодом. Советую попробовать свои идеи, меняя команды и добавляя свои фишки! Бонус — этот модуль проверенно работает даже у школьников без программного опыта. До встречи, ваш Иван!
### Первая интерактивность: управляй черепашкой
Для начала – классика: научим пользователя управлять черепашкой при помощи клавиш. Такой подход отлично знакомит с работой событий и функцией обратного вызова (
callback
).import turtle
t = turtle.Turtle()
scr = turtle.Screen()
def move_forward():
t.forward(30)
def turn_left():
t.left(45)
def turn_right():
t.right(45)
scr.listen()
scr.onkey(move_forward, "Up")
scr.onkey(turn_left, "Left")
scr.onkey(turn_right, "Right")
scr.mainloop()
Жмите стрелки — и наблюдайте, как черепашка послушно перемещается по экрану! Это минимальный, но очень показательный пример управления объектом.
### Рисуем, куда кликаем
А как насчёт превращения вашего кода в простейшее рисовальное приложение? Turtle позволяет реагировать на клики мышки!
import turtle
t = turtle.Turtle()
scr = turtle.Screen()
def draw_at(x, y):
t.penup()
t.goto(x, y)
t.pendown()
t.stamp()
scr.onscreenclick(draw_at)
scr.mainloop()
Теперь каждый клик по экрану будет оставлять след — отпечаток вашей черепашки в указанном месте.
### Игра для начинающих: собираем звёзды
Давайте сделаем небольшую игру — ловим звёзды! Пусть черепашка двигается к месту клика и «собирает» звёздочку.
import turtle
import random
player = turtle.Turtle(shape="turtle")
star = turtle.Turtle(shape="circle")
star.color("yellow")
star.penup()
star.goto(random.randint(-200, 200), random.randint(-200, 200))
def go_to_star(x, y):
player.setheading(player.towards(star))
player.goto(star.pos())
star.goto(random.randint(-200, 200), random.randint(-200, 200))
screen = turtle.Screen()
screen.onscreenclick(go_to_star)
screen.mainloop()
Теперь каждый клик — это попытка «поймать» улетающую звезду, а основа следующей игры уже готова. Такие эксперименты отлично развивают алгоритмическое мышление и интерес к Python.
### Итоги
Turtle великолепно подходит для начинающих: он дает быстрый визуальный результат и мотивацию поиграться с кодом. Советую попробовать свои идеи, меняя команды и добавляя свои фишки! Бонус — этот модуль проверенно работает даже у школьников без программного опыта. До встречи, ваш Иван!
👍3
Привет! Меня зовут Иван, и сегодня я открою вам дверь в мир геоданных на Python. Готовы к путешествию? Ведь GeoJSON — это ваш электронный компас для работы с координатами, картами и информацией о мире вокруг!
## Что такое GeoJSON?
GeoJSON — это формат для хранения и передачи данных о географических объектах. Всё, что связано с точками на карте (например, местоположения кафе, маршруты дорог или границы парков), часто хранится именно в нем.
В основе GeoJSON лежат обычные структуры JSON, что делает его простым для чтения, понимания и — самое главное для нас — обработки на Python.
## Базовая работа с GeoJSON
Для начала стоит познакомиться с модулем
Давайте разберём простой пример: у нас есть GeoJSON-файл с точками интереса (POI), и мы хотим получить координаты всех этих мест.
Теперь мы можем легко вытащить из файла всю нужную информацию!
## Создаем GeoJSON сами
Своими руками создавать такие данные тоже просто:
Этот код создаст файл с одной точкой — например, Красной площадью.
## Валидация геоданных
GeoJSON допускает ошибки — но библиотека geojson умеет валидировать объекты:
## Не только чтение, но и визуализация!
Для быстрой визуализации можно использовать folium:
Готово — у вас есть интерактивная карта на HTML!
---
GeoJSON — это отличный способ научиться работать с пространственными данными на Python. Простота формата, множество библиотек и лёгкость интеграции превращают его в швейцарский нож для начинающих геокодеров. Успехов в ваших гео-экспедициях!
## Что такое GeoJSON?
GeoJSON — это формат для хранения и передачи данных о географических объектах. Всё, что связано с точками на карте (например, местоположения кафе, маршруты дорог или границы парков), часто хранится именно в нем.
В основе GeoJSON лежат обычные структуры JSON, что делает его простым для чтения, понимания и — самое главное для нас — обработки на Python.
## Базовая работа с GeoJSON
Для начала стоит познакомиться с модулем
json
, а также с отличным помощником — библиотекой geojson
. Установить её можно через pip:pip install geojson
Давайте разберём простой пример: у нас есть GeoJSON-файл с точками интереса (POI), и мы хотим получить координаты всех этих мест.
import geojson
with open("points.geojson", "r") as file:
data = geojson.load(file)
for feature in data["features"]:
coords = feature["geometry"]["coordinates"]
name = feature["properties"].get("name")
print(f"Name: {name}, Coordinates: {coords}")
Теперь мы можем легко вытащить из файла всю нужную информацию!
## Создаем GeoJSON сами
Своими руками создавать такие данные тоже просто:
import geojson
point = geojson.Point((37.618423, 55.751244)) # (долгота, широта)
feature = geojson.Feature(geometry=point, properties={"name": "Red Square"})
feature_collection = geojson.FeatureCollection([feature])
with open("my_points.geojson", "w") as file:
geojson.dump(feature_collection, file)
Этот код создаст файл с одной точкой — например, Красной площадью.
## Валидация геоданных
GeoJSON допускает ошибки — но библиотека geojson умеет валидировать объекты:
from geojson import Point, is_valid
pt = Point((200, 100)) # неправильные координаты
print(is_valid(pt)) # Покажет, что не так
## Не только чтение, но и визуализация!
Для быстрой визуализации можно использовать folium:
import folium
map_ = folium.Map(location=[55.751244, 37.618423], zoom_start=10)
folium.GeoJson("my_points.geojson").add_to(map_)
map_.save("map.html")
Готово — у вас есть интерактивная карта на HTML!
---
GeoJSON — это отличный способ научиться работать с пространственными данными на Python. Простота формата, множество библиотек и лёгкость интеграции превращают его в швейцарский нож для начинающих геокодеров. Успехов в ваших гео-экспедициях!
👍3
Привет! Это Иван, и сегодня — интереснейшая тема для начинающих питонистов: как работает модуль signal, и зачем вообще программам нужны сигналы!
## Что такое сигналы?
Сигналы — это особый способ общения между процессами и операционной системой. Когда, например, вы нажимаете Ctrl+C во время работы скрипта, Python получает сигнал SIGINT. Представьте, что сигнал — это выстрел: его ловит программа, если знает, как это сделать, или падает, если не знает.
## Meet the signal!
В Python есть стандартный модуль
### Простейший пример
Пусть мы хотим аккуратно завершать скрипт по Ctrl+C:
Здесь мы ловим SIGINT (тот самый Ctrl+C) и обрабатываем его: печатаем сообщение и завершаемся красиво, а не резко.
### Сигналы-таймеры (SIGALRM)
Signal бывает полезен не только для Ctrl+C! Например, можно отправлять самому себе сигнал-таймер — это удобно, если хочется дать функции ограниченное время на выполнение.
Этот код выводит сообщение ровно через 3 секунды! Очень удобно для создания таймаутов.
### Важно!
- На Windows поддерживаются не все типы сигналов (например, SIGALRM не работает).
- signal работает только в главном потоке (main thread).
## Как ещё это можно использовать?
Можно ловить сигналы завершения (SIGTERM), чтобы сохранять важные данные перед смертью процесса, либо реализовать долгоживущие сервисы с аккуратным завершением.
Модуль signal — простой способ сделать свои программы более живучими и управляемыми со стороны системы. Пробуйте в своих проектах!
До новых встреч,
Иван
## Что такое сигналы?
Сигналы — это особый способ общения между процессами и операционной системой. Когда, например, вы нажимаете Ctrl+C во время работы скрипта, Python получает сигнал SIGINT. Представьте, что сигнал — это выстрел: его ловит программа, если знает, как это сделать, или падает, если не знает.
## Meet the signal!
В Python есть стандартный модуль
signal
. С его помощью ваша программа может ловить определённые сигналы (например, запрос на завершение) и реагировать на них по-своему.### Простейший пример
Пусть мы хотим аккуратно завершать скрипт по Ctrl+C:
import signal
import sys
def handle_sigint(signum, frame):
print("Received SIGINT! Exiting gracefully...")
sys.exit(0)
signal.signal(signal.SIGINT, handle_sigint)
print("Try pressing Ctrl+C!")
while True:
pass # Вечный цикл для теста
Здесь мы ловим SIGINT (тот самый Ctrl+C) и обрабатываем его: печатаем сообщение и завершаемся красиво, а не резко.
### Сигналы-таймеры (SIGALRM)
Signal бывает полезен не только для Ctrl+C! Например, можно отправлять самому себе сигнал-таймер — это удобно, если хочется дать функции ограниченное время на выполнение.
import signal
def timeout_handler(signum, frame):
print("Time's up!")
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(3) # Через 3 секунды придёт сигнал
print("Waiting for the alarm signal...")
signal.pause()
Этот код выводит сообщение ровно через 3 секунды! Очень удобно для создания таймаутов.
### Важно!
- На Windows поддерживаются не все типы сигналов (например, SIGALRM не работает).
- signal работает только в главном потоке (main thread).
## Как ещё это можно использовать?
Можно ловить сигналы завершения (SIGTERM), чтобы сохранять важные данные перед смертью процесса, либо реализовать долгоживущие сервисы с аккуратным завершением.
Модуль signal — простой способ сделать свои программы более живучими и управляемыми со стороны системы. Пробуйте в своих проектах!
До новых встреч,
Иван
👍2
Привет! С вами Иван, и сегодня мой Python-блог посвящён суперполезной фишке — автоматизации отправки email с помощью модуля smtplib. Почта — штука незаменимая: ежедневные отчёты, рассылки новостей, уведомления клиентам… Зачем делать это вручную, если можно поручить задачу питону?
## smtplib — твой email-робот
### Минимальный рабочий пример
Вот простой скрипт, который отправляет email через Gmail:
Меняем email и пароль — и письмо уже в пути! Но помни о безопасности: для временных скриптов лучше использовать отдельные почтовые аккаунты и специальные пароли приложений.
### Отправляем HTML и вложения
Текстовое письмо — это скучно. Хотите добавить форматирование или вложить файл? Вот пример с
Теперь письмо придёт с красивым вложением, что удобно для отправки отчётов.
### В чём подвох?
Автоматизация — это мощь, но есть нюансы:
- Gmail и Яндекс требуют включения паролей приложений или разрешения для сторонних приложений.
- Частая массовая отправка может привести к блокировке.
- Логи, try-except и проверки — ваши друзья при работе с отправкой email.
А теперь — создавай свои рассылки, поздравления и уведомления, ведь с
## smtplib — твой email-робот
smtplib
входит в стандартную библиотеку Python, так что ничего дополнительно устанавливать не нужно. С его помощью можно подключаться к почтовым серверам через SMTP-протокол и слать письма хоть ежедневно, хоть ежечасно.### Минимальный рабочий пример
Вот простой скрипт, который отправляет email через Gmail:
import smtplib
sender = "your_email@gmail.com"
password = "your_password"
recipient = "recipient_email@example.com"
message = "Subject: Hello from Python!\n\nThis is an automated email."
with smtplib.SMTP("smtp.gmail.com", 587) as smtp_server:
smtp_server.starttls() # Защищённое соединение
smtp_server.login(sender, password)
smtp_server.sendmail(sender, recipient, message)
Меняем email и пароль — и письмо уже в пути! Но помни о безопасности: для временных скриптов лучше использовать отдельные почтовые аккаунты и специальные пароли приложений.
### Отправляем HTML и вложения
Текстовое письмо — это скучно. Хотите добавить форматирование или вложить файл? Вот пример с
email.message.EmailMessage
:import smtplib
from email.message import EmailMessage
msg = EmailMessage()
msg["Subject"] = "Automated report"
msg["From"] = "your_email@gmail.com"
msg["To"] = "recipient_email@example.com"
msg.set_content("See attached report.")
with open("report.pdf", "rb") as file:
msg.add_attachment(file.read(), maintype="application", subtype="pdf", filename="report.pdf")
with smtplib.SMTP("smtp.gmail.com", 587) as smtp:
smtp.starttls()
smtp.login("your_email@gmail.com", "your_password")
smtp.send_message(msg)
Теперь письмо придёт с красивым вложением, что удобно для отправки отчётов.
### В чём подвох?
Автоматизация — это мощь, но есть нюансы:
- Gmail и Яндекс требуют включения паролей приложений или разрешения для сторонних приложений.
- Частая массовая отправка может привести к блокировке.
- Логи, try-except и проверки — ваши друзья при работе с отправкой email.
А теперь — создавай свои рассылки, поздравления и уведомления, ведь с
smtplib
Python справится за тебя!👍2
Привет! Иван на связи — сегодня поговорим о невероятно полезном инструменте Python для измерения производительности кода: модуле timeit. Даже самый красивый код может оказаться медленным, если не следить за временем выполнения. Timeit позволяет объективно сравнить разные реализации алгоритмов и найти узкие места.
### Почему именно timeit?
Использование
### Пример 1: Сравнение двух способов сложить список
Результаты покажут неожиданный разрыв — встроенный
### Пример 2: Как измерить время выполнения функции?
Timeit умеет работать и с реальными функциями. Например:
Передавайте функцию прямо в
### Пример 3: Сравнение list comprehension и генератора
Проверьте сами — не всегда интуиция правильна!
### Коротко: как пользоваться timeit
- Пишите тестируемый код как строку или функцию.
- Используйте параметр
- Изучайте результат — время в секундах. Меньше — лучше!
Timeit — ваш главный друг, если хотите, чтобы код работал максимально быстро. Экспериментируйте, оптимизируйте, удивляйтесь результатам!
### Почему именно timeit?
Использование
time.sleep
или обычные таймеры часто обманывают: они не учитывают влияние других процессов, кешей, а ещё добавляют погрешность. Timeit выполняет ваш код множество раз, усредняет значения и таким образом даёт честную метрику скорости работы.### Пример 1: Сравнение двух способов сложить список
import timeit
setup = "numbers = list(range(1000))"
sum_builtin = "total = sum(numbers)"
sum_loop = '''
total = 0
for num in numbers:
total += num
'''
print("Built-in sum:", timeit.timeit(stmt=sum_builtin, setup=setup, number=10000))
print("For loop sum:", timeit.timeit(stmt=sum_loop, setup=setup, number=10000))
Результаты покажут неожиданный разрыв — встроенный
sum
почти всегда быстрее ручного цикла.### Пример 2: Как измерить время выполнения функции?
Timeit умеет работать и с реальными функциями. Например:
def multiply():
result = 1
for i in range(1, 100):
result *= i
print(timeit.timeit(multiply, number=10000))
Передавайте функцию прямо в
timeit.timeit
.### Пример 3: Сравнение list comprehension и генератора
setup = "numbers = range(1000)"
list_comp = "[x * 2 for x in numbers]"
gen_expr = "list(x * 2 for x in numbers)"
print("List comprehension:", timeit.timeit(stmt=list_comp, setup=setup, number=10000))
print("Generator expression:", timeit.timeit(stmt=gen_expr, setup=setup, number=10000))
Проверьте сами — не всегда интуиция правильна!
### Коротко: как пользоваться timeit
- Пишите тестируемый код как строку или функцию.
- Используйте параметр
number
— сколько раз выполнить ваш код.- Изучайте результат — время в секундах. Меньше — лучше!
Timeit — ваш главный друг, если хотите, чтобы код работал максимально быстро. Экспериментируйте, оптимизируйте, удивляйтесь результатам!
👍1
Привет! На связи Иван, и сегодня расскажу, как модуль collections из стандартной библиотеки Python превращает скучное “списки и словари” в настоящее поле для экспериментов.
## Почему collections?
Казалось бы — зачем что-то придумывать, если уже есть list, tuple, dict? На деле, стандартные структуры не всегда удобны. Когда нужно быстро реализовать стек, очередь, счетчик, вложенный словарь или именованный кортеж, collections спасает время и нервы.
### 1.
Безумно удобно, когда к элементам можно обращаться по имени, а не по индексу:
Идеально для хранения данных с фиксированной структурой — теперь ошибки с перепутанными индексами будут реже!
### 2.
Когда хочется вложенных словарей, но надоело вручную проверять на наличие ключа:
Это настоящая магия — никаких проверок, всё создаётся "на лету".
### 3.
Считать количество элементов — привычная задача. С Counter не надо писать лишний код:
Этот инструмент помогает быстро собирать статистику и анализировать данные.
### 4.
Когда нужна быстрая вставка и удаление с обоих концов:
---
## Почему collections?
Казалось бы — зачем что-то придумывать, если уже есть list, tuple, dict? На деле, стандартные структуры не всегда удобны. Когда нужно быстро реализовать стек, очередь, счетчик, вложенный словарь или именованный кортеж, collections спасает время и нервы.
### 1.
namedtuple
: кортеж с именами, как у взрослого структуры!Безумно удобно, когда к элементам можно обращаться по имени, а не по индексу:
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(3, 5)
print(p.x, p.y) # 3 5
Идеально для хранения данных с фиксированной структурой — теперь ошибки с перепутанными индексами будут реже!
### 2.
defaultdict
: избавь себя от KeyErrorКогда хочется вложенных словарей, но надоело вручную проверять на наличие ключа:
from collections import defaultdict
tree = defaultdict(lambda: defaultdict(int))
tree['fruits']['apple'] += 1
tree['fruits']['banana'] += 2
print(dict(tree))
# {'fruits': {'apple': 1, 'banana': 2}}
Это настоящая магия — никаких проверок, всё создаётся "на лету".
### 3.
Counter
: простейший анализ данныхСчитать количество элементов — привычная задача. С Counter не надо писать лишний код:
from collections import Counter
colors = ['red', 'blue', 'red', 'green', 'blue', 'blue']
color_counts = Counter(colors)
print(color_counts)
# Counter({'blue': 3, 'red': 2, 'green': 1})
Этот инструмент помогает быстро собирать статистику и анализировать данные.
### 4.
deque
: очередь и стек в одном лицеКогда нужна быстрая вставка и удаление с обоих концов:
from collections import deque
history = deque(maxlen=3)
history.extend([1, 2, 3])
history.append(4)
print(history) # deque([2, 3, 4])
history.appendleft(0)
print(history) # deque([0, 2, 3])
deque
— must-have для реализации очередей, поиска в ширину и undo-операций.---
collections
— это не просто "очередной модуль", а настоящий швейцарский нож для работы со структурами данных. Освой эти инструменты — и твой код станет чище, понятнее и быстрее!👍2
Привет! Я — Иван, и сегодня приглашаю погрузиться в магию работы с Excel-файлами через Python с помощью библиотеки openpyxl. Excel для программиста — как волшебная тетрадь с секретами: большие таблицы, автоотчеты и автоматизация рутины. Давайте посмотрим, как легко приручить этот мощный инструмент!
1. Открываем книгу Excel и читаем данные
openpyxl позволяет читать и работать с файлами
Вот так просто можно получить первые три строки вашей таблицы и увидеть их содержимое.
2. Создаем и наполняем файл Excel
Создать новый Excel-файл — проще простого. Добавим пару строк данных «на лету»:
Здорово, правда? Таблицы с отчетами теперь можно генерировать автоматически.
3. Форматирование ячеек: цвета и стили
Рутина без красоты — скучна. В openpyxl можно добавлять стили, чтобы выделить важные данные.
Теперь ваша «шапка» таблицы засияет как положено!
4. Итог
openpyxl — это гибкий инструмент для работы с Excel внутри Python. Он экономит время, автоматизирует рутину, а возможности форматирования делают ваши отчеты по-настоящему профессиональными. Главное — не бойтесь экспериментировать! Даже если не любите таблички, с openpyxl они становятся подatливой частью ваших проектов.
До встречи в новых постах, ваш Иван!
1. Открываем книгу Excel и читаем данные
openpyxl позволяет читать и работать с файлами
.xlsx
словно они обычные списки или словари. Начнем с простого: откроем файл, заглянем на первый лист и прочитаем пару строк.from openpyxl import load_workbook
workbook = load_workbook('example.xlsx')
sheet = workbook.active # Получаем первый лист
for row in sheet.iter_rows(min_row=1, max_row=3, values_only=True):
print(row)
Вот так просто можно получить первые три строки вашей таблицы и увидеть их содержимое.
2. Создаем и наполняем файл Excel
Создать новый Excel-файл — проще простого. Добавим пару строк данных «на лету»:
from openpyxl import Workbook
workbook = Workbook()
sheet = workbook.active
sheet['A1'] = 'Name'
sheet['B1'] = 'Score'
sheet.append(['Alice', 90])
sheet.append(['Bob', 82])
workbook.save('new_report.xlsx')
Здорово, правда? Таблицы с отчетами теперь можно генерировать автоматически.
3. Форматирование ячеек: цвета и стили
Рутина без красоты — скучна. В openpyxl можно добавлять стили, чтобы выделить важные данные.
from openpyxl.styles import Font, PatternFill
sheet['A1'].font = Font(bold=True, color="FFFFFF")
sheet['A1'].fill = PatternFill(start_color="4F81BD", end_color="4F81BD", fill_type = "solid")
Теперь ваша «шапка» таблицы засияет как положено!
4. Итог
openpyxl — это гибкий инструмент для работы с Excel внутри Python. Он экономит время, автоматизирует рутину, а возможности форматирования делают ваши отчеты по-настоящему профессиональными. Главное — не бойтесь экспериментировать! Даже если не любите таблички, с openpyxl они становятся подatливой частью ваших проектов.
До встречи в новых постах, ваш Иван!
Привет! На связи Иван, и сегодня говорим о том, как держать свои сетевые операции под контролем даже тогда, когда интернет ведет себя, мягко говоря, не идеально. Представляю вам замечательный Python-модуль — backoff.
## Почему именно backoff?
Сетевые запросы — это почти всегда зона риска: сервер не ответил, интернет отвалился, ошибка тайм-аута... В такой ситуации хочется, чтобы программа не падала с криками, а спокойно попробовала еще раз и справилась сама.
Здесь-то и приходит на помощь backoff — маленький, но мощный помощник для автоматического повторения операций с задержками (и увеличением этих задержек после неудачи, если потребуется).
## Быстрое знакомство
Установить backoff можно так:
Представим, что у нас есть функция, которая тянет данные с внешнего API:
А теперь магия! С помощью backoff превращаем это в устойчивый к сбоям вызов:
Теперь при ошибке запроса будет предпринято до 5 попыток с увеличивающейся задержкой между ними (exponential backoff: 1, 2, 4, 8 сек...).
## Когда это особенно полезно?
- Интеграции с ненадежными внешними API
- Микросервисы в облаке
- Скачивание файлов
- Любые случаи, когда «падать» неудобно
## Индивидуальные настройки
Вы можете тонко управлять поведением backoff — например, отреагировать только на определённые коды ответа:
## Итог
backoff — отличный инструмент для тех, кто делает Python-программы «с характером» и не хочет бояться временных сетевых проблем. Он легко интегрируется, конфигурируется на любой вкус и просто спасает в критические моменты. Если хотите писать надежный код — попробуйте backoff в деле!
## Почему именно backoff?
Сетевые запросы — это почти всегда зона риска: сервер не ответил, интернет отвалился, ошибка тайм-аута... В такой ситуации хочется, чтобы программа не падала с криками, а спокойно попробовала еще раз и справилась сама.
Здесь-то и приходит на помощь backoff — маленький, но мощный помощник для автоматического повторения операций с задержками (и увеличением этих задержек после неудачи, если потребуется).
## Быстрое знакомство
Установить backoff можно так:
pip install backoff
Представим, что у нас есть функция, которая тянет данные с внешнего API:
import requests
def fetch_data():
response = requests.get('https://api.example.com/data')
response.raise_for_status()
return response.json()
А теперь магия! С помощью backoff превращаем это в устойчивый к сбоям вызов:
import backoff
@backoff.on_exception(backoff.expo, requests.exceptions.RequestException, max_tries=5)
def fetch_data():
response = requests.get('https://api.example.com/data')
response.raise_for_status()
return response.json()
Теперь при ошибке запроса будет предпринято до 5 попыток с увеличивающейся задержкой между ними (exponential backoff: 1, 2, 4, 8 сек...).
## Когда это особенно полезно?
- Интеграции с ненадежными внешними API
- Микросервисы в облаке
- Скачивание файлов
- Любые случаи, когда «падать» неудобно
## Индивидуальные настройки
Вы можете тонко управлять поведением backoff — например, отреагировать только на определённые коды ответа:
@backoff.on_predicate(backoff.expo, lambda r: r.status_code != 200, max_time=30)
def fetch_status():
return requests.get('https://status.example.com/check')
## Итог
backoff — отличный инструмент для тех, кто делает Python-программы «с характером» и не хочет бояться временных сетевых проблем. Он легко интегрируется, конфигурируется на любой вкус и просто спасает в критические моменты. Если хотите писать надежный код — попробуйте backoff в деле!
👍1
Привет! На связи Иван — сегодня поговорим о тестировании кода в Python с помощью библиотеки pytest. Современный программист не может позволить себе писать код без тестов — баги стоят времени, денег и, иногда, нервов. Разберёмся, что делает pytest таким удобным для модульного тестирования, и как легко организовать процесс проверки вашего кода.
Прежде всего, установка:
Представим, у нас есть простой модуль
Теперь создадим файл тестов — по традиции, его имя начинается с
Pytest автоматически найдёт функции, начинающиеся на
Вы сразу увидите лаконичный и понятный отчёт: миновала функция тест или нет, почему провалена, если что-то пошло не так. Деталь — если вы ждёте ошибку, используйте конструкцию
Pytest поддерживает параметризацию, благодаря чему можно протестировать одну функцию сразу на разных данных:
Преимущества pytest: он прост в начале, поддерживает гибкие возможности для сложных сценариев (фикстуры, плагины), а отчёты легко читать. Даже если ваш проект вырастет — pytest масштабируется без боли.
Мои лайфхаки: держите тесты в отдельной папке
Тестируйте свой Python-код, и он отблагодарит вас стабильностью!
Прежде всего, установка:
pip install pytest
Представим, у нас есть простой модуль
calculator.py
:def add(a, b):
return a + b
def divide(a, b):
return a / b
Теперь создадим файл тестов — по традиции, его имя начинается с
test_
. Пусть это будет test_calculator.py
:from calculator import add, divide
def test_add():
assert add(3, 2) == 5
def test_divide():
assert divide(10, 2) == 5
Pytest автоматически найдёт функции, начинающиеся на
test_
, и выполнит их. Запуск:pytest
Вы сразу увидите лаконичный и понятный отчёт: миновала функция тест или нет, почему провалена, если что-то пошло не так. Деталь — если вы ждёте ошибку, используйте конструкцию
pytest.raises
:import pytest
from calculator import divide
def test_divide_by_zero():
with pytest.raises(ZeroDivisionError):
divide(5, 0)
Pytest поддерживает параметризацию, благодаря чему можно протестировать одну функцию сразу на разных данных:
import pytest
from calculator import add
@pytest.mark.parametrize("a, b, expected", [
(1, 1, 2),
(5, 2, 7),
(0, -1, -1),
])
def test_add_various(a, b, expected):
assert add(a, b) == expected
Преимущества pytest: он прост в начале, поддерживает гибкие возможности для сложных сценариев (фикстуры, плагины), а отчёты легко читать. Даже если ваш проект вырастет — pytest масштабируется без боли.
Мои лайфхаки: держите тесты в отдельной папке
tests/
, запускайте их автоматом после каждого коммита, и никогда не игнорируйте красные строки — баги надо исправлять сразу.Тестируйте свой Python-код, и он отблагодарит вас стабильностью!
👍1
Привет! С вами Иван, и сегодня я расскажу о приемах управления контекстами выполнения в асинхронном Python с помощью asynccontextmanager. Если вы когда-нибудь хотели элегантно управлять ресурсами во время выполнения асинхронного кода, эта тема для вас!
## Немного о контекстах
Классический контекстный менеджер (
## asynccontextmanager — ваш друг
Модуль
### Пример: асинхронная блокировка
Рассмотрим пример, где мы хотим управлять семафором для ограничения числа одновременных задач:
В этом коде мы создали элегантный асинхронный менеджер, который гарантирует освобождение ресурса даже при ошибках.
## Как это работает?
-
- До
- После
### Асинхронные файлы
А если нам нужно работать с файлами (например, через aiofiles)? Можно обернуть открытие файла в ваш асинхронный контекст:
## Вывод
С помощью
## Немного о контекстах
Классический контекстный менеджер (
with ...:
) позволяет безопасно работать с файлами, сокетами и другими ресурсами. Казалось бы — зачем нам что-то еще? А вот зачем: когда мы ныряем в мир асинхронности (async/await), обычный with
становится бесполезен — тут требуется свой асинхронный вариант.## asynccontextmanager — ваш друг
Модуль
contextlib
из стандартной библиотеки с версии Python 3.7 предлагает декоратор @asynccontextmanager
. Он позволяет создавать асинхронные контекстные менеджеры без необходимости писать полноценные классы.### Пример: асинхронная блокировка
Рассмотрим пример, где мы хотим управлять семафором для ограничения числа одновременных задач:
import asyncio
from contextlib import asynccontextmanager
@asynccontextmanager
async def acquire_semaphore(semaphore):
await semaphore.acquire()
try:
yield
finally:
semaphore.release()
async def limited_task(semaphore):
async with acquire_semaphore(semaphore):
print("Resource acquired")
await asyncio.sleep(1)
print("Resource released")
async def main():
sem = asyncio.Semaphore(2)
await asyncio.gather(*(limited_task(sem) for _ in range(4)))
asyncio.run(main())
В этом коде мы создали элегантный асинхронный менеджер, который гарантирует освобождение ресурса даже при ошибках.
## Как это работает?
-
@asynccontextmanager
делает функцию генератором с асинхронной поддержкой.- До
yield
выполняется код инициализации (например, получение блокировки).- После
yield
— освобождение ресурса (release, закрытие файла, отключение соединения и др.).### Асинхронные файлы
А если нам нужно работать с файлами (например, через aiofiles)? Можно обернуть открытие файла в ваш асинхронный контекст:
import aiofiles
from contextlib import asynccontextmanager
@asynccontextmanager
async def open_async_file(file_path, mode):
file = await aiofiles.open(file_path, mode)
try:
yield file
finally:
await file.close()
async def read_file():
async with open_async_file("example.txt", "r") as f:
content = await f.read()
print(content)
## Вывод
С помощью
@asynccontextmanager
вы пишете лаконичный, читаемый и безопасный асинхронный код, не боясь утечек ресурсов даже при возникновении исключений. Попробуйте интегрировать его в свои проекты — и асинхронная жизнь станет проще!👍2