Что делает functools.lru_cache в Python и когда его использовать?
Пример
```python
# Без lru_cache (наивная рекурсия)
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
# Вычисление 35-го числа займет несколько секунд
# print(fibonacci(35))
# С lru_cache (кэширование результатов)
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci_cached(n):
if n <= 1:
return n
return fibonacci_cached(n-1) + fibonacci_cached(n-2)
# Вычисление 100-го числа произойдет мгновенно!
print(fibonacci_cached(100))
Ответ
Декоратор @lru_cache (Least Recently Used cache) автоматически сохраняет результаты вызова функции в кэше. При повторном вызове с теми же аргументами функция не выполняется заново, а возвращает уже готовое значение из памяти.
Please open Telegram to view this post
VIEW IN TELEGRAM
Кодер-энтузиаст решил провести эксперимент, выдав 100 AI-агентам по 1000 токенов, и поставив цель максимизировать свои очки, дающиеся за выполнение заданий, которые в свою очередь стоят определенного количества токенов.
Материала всего минут на 10, но эксперимент действительно интересный. Также автор прикладывает отрывки кода, чтобы вы могли увидеть работу проекта изнутри.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
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
❤4❤🔥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