Pydantic — это самая популярная библиотека для валидации данных в Python, которая использует подсказки типов (type hints) для проверки и преобразования данных. Вместо того чтобы писать десятки if isinstance(...) и try/except для проверки входных данных, вы просто описываете модель данных — и библиотека делает всё остальное. Стала стандартом индустрии благодаря FastAPI, но полезна в любом проекте
from pydantic import BaseModel, ValidationError
# 1. Описываем модель (буквально 3 строки)
class User(BaseModel):
name: str
age: int
# 2. Пробуем создать пользователя
try:
# Данные приходят откуда-то извне (API, форма, файл)
user = User(name="Анна", age="25") # age пришёл как строка!
print(f"✅ {user.name}, возраст: {user.age} (тип: {type(user.age).__name__})")
# А вот неправильные данные
bad_user = User(name="Петр", age="не число")
except ValidationError as e:
print(f"❌ Ошибка: {e}")
pip install pydantic
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤2
import functools
def smart_cache(maxsize=2):
cache = {}
order = []
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
key = (args, tuple(kwargs.items()))
if key in cache:
order.remove(key)
order.append(key)
return f"Cached: {cache[key]}"
result = func(*args, **kwargs)
cache[key] = result
order.append(key)
if len(order) > maxsize:
oldest = order.pop(0)
del cache[oldest]
return f"Computed: {result}"
return wrapper
return decorator
count = 0
def tracer(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
global count
count += 1
indent = " " * count
print(f"{indent}→ {func.__name__}{args}")
result = func(*args, **kwargs)
print(f"{indent}← {result}")
count -= 1
return result
return wrapper
@smart_cache(maxsize=2)
@tracer
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)
print(fib(3))
print(fib(2))
print(fib(4))
print(f"Calls: {count}")
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5
Что делает функция zip() в Python и когда её удобно использовать?
Пример
```python
# Без zip (ручной перебор по индексу)
names = ["Анна", "Борис", "Виктор"]
scores = [85, 92, 78]
for i in range(len(names)):
print(f"{names[i]} получил {scores[i]} баллов")
# С zip (элегантная параллельная итерация)
for name, score in zip(names, scores):
print(f"{name} получил {score} баллов")
# Создание словаря одной строкой
student_scores = dict(zip(names, scores))
print(student_scores)
Ответ
Функция
zip() в Python объединяет несколько итерируемых объектов (списки, кортежи и т.д.) в один итератор кортежей. Она останавливается, когда заканчивается самая короткая последовательность.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6
Автор — ML-инженер, решивший протестировать такое явление как «вайбкодинг». Это полезно, или плохо?
В статье автор даст советы по тому, каким образом лучше всего использовать нейронки в работе, чтобы не загнать себя в глубокую-глубокую яму.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Pendulum — это элегантная замена стандартному модулю datetime, которая решает его проблемы с временными зонами, форматированием и манипуляциями. Вместо тонн boilerplate-кода вы получаете чистый, читаемый и интуитивный API.
import pendulum
# 1. Создание дат (намного проще чем datetime)
now = pendulum.now()
print(f"Сейчас: {now}")
# Создание с конкретной временной зоной
moscow_time = pendulum.now('Europe/Moscow')
ny_time = pendulum.now('America/New_York')
print(f"Москва: {moscow_time}")
print(f"Нью-Йорк: {ny_time}")
# 2. Разбор строк (парсинг)
date_str = "2024-03-15 14:30:00"
parsed = pendulum.parse(date_str)
print(f"Распарсено: {parsed}")
# Автоматическое определение формата
flexible_parse = pendulum.parse("15 марта 2024, 14:30")
print(f"Гибкий парсинг: {flexible_parse}")
# 3. Манипуляции с датами (человеко-читаемые)
tomorrow = now.add(days=1)
next_week = now.add(weeks=1)
last_month = now.subtract(months=1)
next_year_same_day = now.add(years=1)
print(f"Завтра: {tomorrow}")
print(f"Следующая неделя: {next_week}")
print(f"Прошлый месяц: {last_month}")
# 4. Разница между датами (человеко-читаемая)
birthday = pendulum.datetime(1990, 5, 15)
diff = now - birthday
print(f"Возраст: {diff.in_words()}") # → "33 года 2 месяца"
# 5. Форматирование (мощное и гибкое)
print(now.format('dddd, D MMMM YYYY HH:mm:ss'))
print(now.format('YYYY-MM-DD HH:mm', locale='ru'))
# 6. Интуитивные сравнения
event_date = pendulum.datetime(2024, 12, 31)
if event_date > now:
print(f"Событие через {now.diff_for_humans(event_date)}")
pip install pendulum
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3❤🔥2
Как работать со срезами строк в Python и чем это удобнее ручного перебора символов?
Пример
```python
# Без срезов (ручное извлечение символов)
text = "Привет, мир!"
first_char = text[0]
last_char = text[len(text)-1]
substring = ""
for i in range(3, 8):
substring += text[i]
print(first_char) # П
print(last_char) # !
print(substring) # вет,
# Со срезами (лаконичный доступ к частям строки)
text = "Привет, мир!"
first_char = text[0]
last_char = text[-1]
substring = text[3:8]
print(first_char) # П
print(last_char) # !
print(substring) # вет,
# Обратный порядок и шаг одной строкой
reversed_text = text[::-1]
every_second = text[::2]
print(reversed_text) # !рим ,тевирП
print(every_second) # Пве,и
```
Ответ
Срезы ([start:stop:step]) позволяют извлекать подстроки, копировать строки или переворачивать их без циклов и лишнего кода. Python рассматривает строки как последовательности, поэтому синтаксис срезов един для строк, списков и кортежей, делая код читаемым и выразительным.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5😱1
В статье рассказывают, что такое VRP-задачи в доставке, чем они отличаются друг от друга, какие готовые решения уже можно пробовать и на что точно не стоит тратить время.
Please open Telegram to view this post
VIEW IN TELEGRAM
from collections import OrderedDict
call_depth = 0
def trace(func):
def wrapper(*args, **kwargs):
global call_depth
call_depth += 1
indent = " " * call_depth
print(f"{indent}➡ {func.__name__}({', '.join(map(str, args))})")
result = func(*args, **kwargs)
print(f"{indent} {result}")
call_depth -= 1
return result
return wrapper
def lru_cache(maxsize=2):
cache = OrderedDict()
def decorator(func):
def wrapper(*args, **kwargs):
key = (args, tuple(sorted(kwargs.items())))
if key in cache:
cache.move_to_end(key)
return f"[CACHE] {cache[key]}"
result = func(*args, **kwargs)
cache[key] = result
if len(cache) > maxsize:
cache.popitem(last=False)
return f"[NEW] {result}"
return wrapper
return decorator
@lru_cache(maxsize=2)
@trace
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(4))
print(fibonacci(3))
print(fibonacci(5))
print(f"max depth: {call_depth}")
Please open Telegram to view this post
VIEW IN TELEGRAM