Построение простой системы рекомендаций на основе покупок
Представим, что у нас есть небольшой онлайн‑магазин, и мы хотим показывать покупателю блок «С этим товаром часто покупают». Звучит как магия, но на базовом уровне это можно сделать несколькими строками кода на Python.
Базовая идея:
если товары A и B часто встречаются в одной корзине, то покупателям товара A можно рекомендовать B (и наоборот).
### Данные
Допустим, у нас есть список заказов, и каждый заказ — это набор купленных товаров:
### Считаем совместные покупки
Используем
Так мы получаем «рейтинг дружбы» товаров: чем больше счётчик, тем чаще товары покупают вместе.
### Строим простые рекомендации
Сделаем функцию, которая по товару отдаёт список рекомендаций:
Теперь для любого товара мы можем быстро получить список «часто покупаемых вместе».
### Что можно улучшить
1. Учесть частоту самого товара — нормировать по общему числу покупок товара (меры вроде lift, confidence).
2. Фильтровать редкие пары с помощью
3. Сохранить модель (словарь
Это ещё не «умный» AI, но уже рабочая рекомендательная система, которую легко встроить в учебный проект интернет‑магазина и постепенно усложнять: добавлять веса, категории, сезонность и, конечно, больше данных.
Представим, что у нас есть небольшой онлайн‑магазин, и мы хотим показывать покупателю блок «С этим товаром часто покупают». Звучит как магия, но на базовом уровне это можно сделать несколькими строками кода на Python.
Базовая идея:
если товары A и B часто встречаются в одной корзине, то покупателям товара A можно рекомендовать B (и наоборот).
### Данные
Допустим, у нас есть список заказов, и каждый заказ — это набор купленных товаров:
transactions = [
["milk", "bread", "eggs"],
["bread", "butter"],
["milk", "bread"],
["beer", "chips"],
["beer", "chips", "nuts"],
["milk", "eggs"],
]
### Считаем совместные покупки
Используем
collections.Counter, чтобы посчитать, какие пары товаров встречаются вместе чаще всего:from collections import Counter
from itertools import combinations
pair_counter = Counter()
for basket in transactions:
# все уникальные пары товаров из одной корзины
for item1, item2 in combinations(sorted(set(basket)), 2):
pair_counter[(item1, item2)] += 1
print(pair_counter.most_common(5))
Так мы получаем «рейтинг дружбы» товаров: чем больше счётчик, тем чаще товары покупают вместе.
### Строим простые рекомендации
Сделаем функцию, которая по товару отдаёт список рекомендаций:
from collections import defaultdict
def build_recommendations(pair_counter, min_support=1):
related = defaultdict(list)
for (item1, item2), count in pair_counter.items():
if count < min_support:
continue
related[item1].append((item2, count))
related[item2].append((item1, count))
# сортируем по популярности совместной покупки
for item in related:
related[item].sort(key=lambda x: x[1], reverse=True)
return related
recommendations = build_recommendations(pair_counter, min_support=1)
def recommend_for(item, top_n=3):
return [x for x, _ in recommendations.get(item, [])[:top_n]]
print("For 'milk':", recommend_for("milk"))
print("For 'beer':", recommend_for("beer"))
Теперь для любого товара мы можем быстро получить список «часто покупаемых вместе».
### Что можно улучшить
1. Учесть частоту самого товара — нормировать по общему числу покупок товара (меры вроде lift, confidence).
2. Фильтровать редкие пары с помощью
min_support, чтобы не советовать то, что встретилось один раз случайно.3. Сохранить модель (словарь
recommendations) в файл через json или pickle и подгружать в вашем веб‑приложении.Это ещё не «умный» AI, но уже рабочая рекомендательная система, которую легко встроить в учебный проект интернет‑магазина и постепенно усложнять: добавлять веса, категории, сезонность и, конечно, больше данных.
👍4❤1
Python для начинающих: перевод и интернационализация с модулем
Когда приложение начинает жить дольше пары недель, внезапно выясняется: пользователи не обязаны знать английский. А переписывать все строки под каждый язык — боль. Для этого в Python есть стандартный модуль
---
## Базовая идея
Вы пишете код один раз, помечая фразы для перевода. Реальные тексты для разных языков хранятся в отдельных файлах. Программа выбирает нужный язык «на лету».
Классический паттерн:
Если есть перевод, на экране окажется что-то вроде
---
## Структура проекта
Сделаем минимальный каркас:
---
## Подготовка шаблона переводов
В коде достаточно помечать строки через
Далее нужно сгенерировать список фраз. Обычно это делается внешней утилитой
1. Собираем все строки внутри
2. Для каждого языка создаём
3. Компилируем
Пример содержимого
После компиляции (через
---
## Плюс форматирования: не ломаем код
Важно не «убивать» форматирование строк. Вы можете смело использовать
В переводе:
---
## Переключение языка на лету
Вы можете дать пользователю выбор:
Таким образом, ваш код не «привязан» к конкретному языку — он зависит только от файлов перевода.
---
gettextКогда приложение начинает жить дольше пары недель, внезапно выясняется: пользователи не обязаны знать английский. А переписывать все строки под каждый язык — боль. Для этого в Python есть стандартный модуль
gettext, который превращает ваш код в многоязычную машину.---
## Базовая идея
Вы пишете код один раз, помечая фразы для перевода. Реальные тексты для разных языков хранятся в отдельных файлах. Программа выбирает нужный язык «на лету».
Классический паттерн:
import gettext
lang = gettext.translation(
domain="messages",
localedir="locale",
languages=["es"], # например, испанский
fallback=True
)
lang.install()
_ = lang.gettext # сокращение
print(_("Hello, world!"))
Если есть перевод, на экране окажется что-то вроде
Hola, mundo!. Если нет — исходная фраза.---
## Структура проекта
Сделаем минимальный каркас:
project/
app.py
locale/
es/
LC_MESSAGES/
messages.po
messages.mo
domain="messages" → имя файла переводов messages.po/.mo. localedir="locale" → корневая папка с переводами. languages=["es"] → нужный язык (ISO-код).---
## Подготовка шаблона переводов
В коде достаточно помечать строки через
_():# app.py
import gettext
gettext.bindtextdomain("messages", "locale")
gettext.textdomain("messages")
_ = gettext.gettext
user_name = "Alex"
print(_("Welcome, {user}!").format(user=user_name))
print(_("Exit"))
Далее нужно сгенерировать список фраз. Обычно это делается внешней утилитой
xgettext, но принцип такой:1. Собираем все строки внутри
_("") в шаблон .pot.2. Для каждого языка создаём
.po.3. Компилируем
.po в .mo.Пример содержимого
messages.po (упрощённо):msgid "Welcome, {user}!"
msgstr "¡Bienvenido, {user}!"
msgid "Exit"
msgstr "Salir"
После компиляции (через
msgfmt или инструменты IDE) появится messages.mo, который читает gettext.---
## Плюс форматирования: не ломаем код
Важно не «убивать» форматирование строк. Вы можете смело использовать
format() или f-строки, главное — сохранять имена плейсхолдеров:msg = _("You have {count} new message(s).").format(count=5)
print(msg)
В переводе:
msgid "You have {count} new message(s)."
msgstr "У вас {count} новых сообщений."
---
## Переключение языка на лету
Вы можете дать пользователю выбор:
import gettext
def get_translator(lang_code):
translation = gettext.translation(
"messages",
localedir="locale",
languages=[lang_code],
fallback=True
)
return translation.gettext
lang_code = "es" # например, пришло из настроек
_ = get_translator(lang_code)
print(_("Settings"))
print(_("Profile"))
Таким образом, ваш код не «привязан» к конкретному языку — он зависит только от файлов перевода.
---
gettext — это не магия, а аккуратное разделение текста и логики. Один раз настроили структуру и процесс генерации .po/.mo — и дальше добавление нового языка сводится к переводу строк, без переписывания кода.👍6
Простое создание QR-кодов с помощью
QR-коды давно вышли из мира маркетинга и стали удобным способом быстро передавать ссылки, Wi‑Fi‑пароли, визитки и любую короткую текстовую информацию. А с Python сделать свой QR-код можно буквально в несколько строк.
---
## Установка библиотеки
Для начала установим библиотеку:
---
## Самый простой QR-код
Сделаем QR-код с ссылкой:
Готово:
---
## Больше контроля: размер, цвет, ошибка
Для тонкой настройки используем класс
Параметр
---
## Закодируем виртуальную визитку
QR-код может содержать не только ссылки, но и, например, vCard:
Смартфон при сканировании предложит сохранить контакт сразу в адресную книгу.
---
## Идеи для применения
- Быстрый доступ к документации проекта.
- Генерация бэджей участников мероприятия.
- Маркировка оборудования: QR-код с номером и ссылкой на карточку в системе учёта.
- Генерация временных ссылок и токенов в админ-интерфейсе.
QR-коды — отличный пример того, как несколько строк Python превращаются в инструмент, который можно применить и в проектах, и в реальной «офлайновой» жизни.
qrcode: как закодировать информациюQR-коды давно вышли из мира маркетинга и стали удобным способом быстро передавать ссылки, Wi‑Fi‑пароли, визитки и любую короткую текстовую информацию. А с Python сделать свой QR-код можно буквально в несколько строк.
---
## Установка библиотеки
Для начала установим библиотеку:
pip install qrcode[pil]
[pil] добавляет поддержку изображений через Pillow, чтобы сразу сохранять QR-код в PNG/JPEG.---
## Самый простой QR-код
Сделаем QR-код с ссылкой:
import qrcode
data = "https://python.org"
img = qrcode.make(data)
img.save("python_org_qr.png")
Готово:
python_org_qr.png можно открыть, распечатать или вставить в презентацию.---
## Больше контроля: размер, цвет, ошибка
Для тонкой настройки используем класс
QRCode:import qrcode
from qrcode.constants import ERROR_CORRECT_H
qr = qrcode.QRCode(
version=2, # размер: 1–40 (чем больше, тем больше данных)
error_correction=ERROR_CORRECT_H, # до ~30% восстановления
box_size=8, # размер "квадратика" в пикселях
border=4, # рамка (минимум 4)
)
qr.add_data("WiFi password: MySecretPass123")
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
img.save("wifi_qr.png")
Параметр
error_correction важен, если QR-код будут печатать маленьким или частично закрывать (наклейка, логотип). Уровень ERROR_CORRECT_H даст максимальный шанс всё равно считать код.---
## Закодируем виртуальную визитку
QR-код может содержать не только ссылки, но и, например, vCard:
import qrcode
vcard = """BEGIN:VCARD
VERSION:3.0
N:Smith;John;;;
FN:John Smith
EMAIL:john@example.com
TEL:+123456789
END:VCARD
"""
img = qrcode.make(vcard)
img.save("vcard_qr.png")
Смартфон при сканировании предложит сохранить контакт сразу в адресную книгу.
---
## Идеи для применения
- Быстрый доступ к документации проекта.
- Генерация бэджей участников мероприятия.
- Маркировка оборудования: QR-код с номером и ссылкой на карточку в системе учёта.
- Генерация временных ссылок и токенов в админ-интерфейсе.
QR-коды — отличный пример того, как несколько строк Python превращаются в инструмент, который можно применить и в проектах, и в реальной «офлайновой» жизни.
👍3
Модуль
Если вы всё ещё склеиваете пути к файлам через
---
### Зачем нужен
- Не нужно думать о слэше:
- Пути становятся объектами, а не строками.
- Методы для чтения/записи файлов встроены прямо в объект пути.
Подключение модуля:
---
### Создание и комбинирование путей
Оператор
---
### Поиск файлов по маске
Найдем все
---
### Чтение и запись файлов
Необязательно открывать файл через
Есть и бинарные варианты:
---
### Создание директорий и безопасная работа
---
### Абсолютные пути и нормализация
---
pathlib: современная работа с файловой системойЕсли вы всё ещё склеиваете пути к файлам через
os.path и плюсики — самое время познакомиться с pathlib. Это «современный» способ работы с путями в Python: объектно-ориентированный, удобный и кроссплатформенный.---
### Зачем нужен
pathlibpathlib решает несколько болезненных мест:- Не нужно думать о слэше:
/ под Linux и \ под Windows. - Пути становятся объектами, а не строками.
- Методы для чтения/записи файлов встроены прямо в объект пути.
Подключение модуля:
from pathlib import Path
---
### Создание и комбинирование путей
from pathlib import Path
base_dir = Path.home() # Домашняя папка пользователя
project_dir = base_dir / "my_project" / "data" # Склеивание через /
print(project_dir)
print(project_dir.exists()) # Проверяем, существует ли путь
print(project_dir.is_dir()) # Это папка?
Оператор
/ перегружен и безопасно соединяет части пути с учётом ОС.---
### Поиск файлов по маске
Найдем все
.txt в директории:data_dir = Path("data")
for txt_file in data_dir.glob("*.txt"):
print(txt_file.name, txt_file.stat().st_size, "bytes")
glob() поддерживает маски (*, **) и позволяет быстро обходить дерево каталогов.---
### Чтение и запись файлов
Необязательно открывать файл через
open:file_path = Path("data") / "notes.txt"
# Запись текста
file_path.write_text("Hello, pathlib!\nSecond line.")
# Чтение текста
content = file_path.read_text()
print(content)
Есть и бинарные варианты:
write_bytes() и read_bytes().---
### Создание директорий и безопасная работа
logs_dir = Path("logs")
logs_dir.mkdir(exist_ok=True, parents=True) # Создаст все недостающие папки
log_file = logs_dir / "app.log"
if not log_file.exists():
log_file.write_text("Log start\n")
else:
with log_file.open("a", encoding="utf-8") as f:
f.write("New log line\n")
parents=True создаст всю цепочку директорий, а exist_ok=True не вызовет ошибку, если папка уже есть.---
### Абсолютные пути и нормализация
p = Path("data") / ".." / "data" / "file.txt"
print(p) # Относительный "кривой" путь
print(p.resolve()) # Нормализованный абсолютный путь
resolve() приводит путь к каноничному виду и показывает, куда он реально ведет.---
pathlib хорошо ложится на мышление «объект пути + действия с ним», избавляя от ручной возни со строками. Если вы начинаете с Python сегодня — имеет смысл сразу привыкать именно к такому стилю работы с файловой системой.👍3
Как использовать модуль
Когда вы считаете средние оценки, анализируете продажи или смотрите на результаты эксперимента — без базовой статистики далеко не уедешь. В Python для этого есть готовый инструмент — модуль
---
## Подготовка
Модуль встроен в стандартную библиотеку, поэтому никаких установок не нужно:
Для примеров возьмём список чисел:
---
## Среднее (mean)
Среднее арифметическое — сумма всех значений, делённая на их количество. В
Круто то, что модуль сам обрабатывает
---
## Медиана (median)
Медиана — это «середина» отсортированных данных. Она устойчивее к выбросам. Если в выборке внезапно появится «сумасшедшее» значение, среднее уедет, а медиана — почти нет.
Медиана сразу показывает, что «нормальные» значения всё ещё где-то около 12–13, а не 258.75.
---
## Мода (mode)
Мода — самое часто встречающееся значение. Полезно, когда нужно найти «типичный» элемент: самый популярный рейтинг, любимый номер, частый результат.
Важно: если в данных несколько значений с одинаковой максимальной частотой,
---
## Быстрый мини-анализ набора данных
Соберём всё вместе:
Всего несколько строк — и вы уже видите «портрет» своих данных: где центр, где разброс и какое значение встречается чаще всего.
Модуль
statistics: среднее, медиана и мода без боли в мозгеКогда вы считаете средние оценки, анализируете продажи или смотрите на результаты эксперимента — без базовой статистики далеко не уедешь. В Python для этого есть готовый инструмент — модуль
statistics. Он избавляет от самописных циклов и формул и помогает считать всё в одну строку.---
## Подготовка
Модуль встроен в стандартную библиотеку, поэтому никаких установок не нужно:
import statistics as stats
Для примеров возьмём список чисел:
data = [10, 12, 13, 15, 15, 17, 18]
---
## Среднее (mean)
Среднее арифметическое — сумма всех значений, делённая на их количество. В
statistics это делается так:import statistics as stats
data = [10, 12, 13, 15, 15, 17, 18]
avg = stats.mean(data)
print(avg) # 14.285714285714286
Круто то, что модуль сам обрабатывает
int и float, не нужно думать о типах.---
## Медиана (median)
Медиана — это «середина» отсортированных данных. Она устойчивее к выбросам. Если в выборке внезапно появится «сумасшедшее» значение, среднее уедет, а медиана — почти нет.
import statistics as stats
data = [10, 12, 13, 1000] # явный выброс
mean_value = stats.mean(data)
median_value = stats.median(data)
print(mean_value) # 258.75
print(median_value) # 12.5
Медиана сразу показывает, что «нормальные» значения всё ещё где-то около 12–13, а не 258.75.
---
## Мода (mode)
Мода — самое часто встречающееся значение. Полезно, когда нужно найти «типичный» элемент: самый популярный рейтинг, любимый номер, частый результат.
import statistics as stats
grades = [5, 4, 5, 3, 4, 5, 5, 4]
most_common = stats.mode(grades)
print(most_common) # 5
Важно: если в данных несколько значений с одинаковой максимальной частотой,
mode() в некоторых версиях Python может выбросить StatisticsError. Для таких случаев есть более гибкая функция multimode():import statistics as stats
values = [1, 2, 2, 3, 3]
modes = stats.multimode(values)
print(modes) # [2, 3]
---
## Быстрый мини-анализ набора данных
Соберём всё вместе:
import statistics as stats
data = [12, 15, 17, 15, 19, 21, 15, 18]
summary = {
"mean": stats.mean(data),
"median": stats.median(data),
"mode": stats.mode(data),
"min": min(data),
"max": max(data)
}
print(summary)
# Пример вывода:
# {'mean': 16.5, 'median': 16.0, 'mode': 15, 'min': 12, 'max': 21}
Всего несколько строк — и вы уже видите «портрет» своих данных: где центр, где разброс и какое значение встречается чаще всего.
Модуль
statistics — отличный первый шаг в сторону анализа данных, без pandas и сложной математики. Идеален для учебных задач, прототипов и маленьких утилит.👍3
### Создание простого HTTP‑клиента с помощью
Большинство начинающих знакомятся с веб‑запросами через библиотеку
---
## Первый запрос: GET к публичному API
Сделаем простой GET‑запрос к публичному API и разберём шаги.
Что тут важно:
-
-
-
-
---
## Отправка данных: простой POST
Теперь отправим JSON‑данные методом POST. Здесь уже нужны заголовки и тело запроса:
Ключевые моменты:
- Тело запроса мы сериализуем через
- Обязательно указываем
-
---
## Обработка ошибок и таймаут
Реальный клиент должен быть готов к сетевым ошибкам:
Тут:
-
- исключения
---
Зная
http.clientБольшинство начинающих знакомятся с веб‑запросами через библиотеку
requests. Удобно, но иногда полезно заглянуть на «низкий уровень» и понять, как все работает внутри. Для этого в стандартной библиотеке Python есть модуль http.client.---
## Первый запрос: GET к публичному API
Сделаем простой GET‑запрос к публичному API и разберём шаги.
import http.client
import json
conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com")
conn.request("GET", "/posts/1")
response = conn.getresponse()
print("Status:", response.status, response.reason)
data = response.read()
text = data.decode("utf-8")
post = json.loads(text)
print("Title:", post["title"])
conn.close()
Что тут важно:
-
HTTPSConnection — шифрованное соединение (для http:// был бы HTTPConnection);-
request(method, url, body=None, headers={}) — отправка запроса;-
getresponse() — получение объекта ответа;-
read() — сырые байты, которые обычно нужно декодировать (decode) и парсить (JSON, HTML и т.д.).---
## Отправка данных: простой POST
Теперь отправим JSON‑данные методом POST. Здесь уже нужны заголовки и тело запроса:
import http.client
import json
conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com")
payload = {"title": "foo", "body": "bar", "userId": 1}
body = json.dumps(payload)
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
}
conn.request("POST", "/posts", body=body, headers=headers)
response = conn.getresponse()
print("Status:", response.status)
print("Headers:", dict(response.getheaders()))
data = response.read().decode("utf-8")
created_post = json.loads(data)
print("Created ID:", created_post["id"])
conn.close()
Ключевые моменты:
- Тело запроса мы сериализуем через
json.dumps;- Обязательно указываем
Content-Type;-
getheaders() возвращает список пар заголовков.---
## Обработка ошибок и таймаут
Реальный клиент должен быть готов к сетевым ошибкам:
import http.client
import socket
try:
conn = http.client.HTTPSConnection("example.com", timeout=3)
conn.request("GET", "/")
response = conn.getresponse()
print("Status:", response.status)
conn.close()
except (http.client.HTTPException, socket.timeout) as exc:
print("Request failed:", exc)
Тут:
-
timeout защищает от «вечного ожидания»;- исключения
HTTPException и socket.timeout помогают корректно отреагировать на проблемы сети.---
Зная
http.client, легче понимать, что делает любая высокоуровневая библиотека: устанавливает соединение, формирует запрос, отправляет тело, читает статус, заголовки и содержимое. Это отличный шаг к более глубокому пониманию сетевого кода в Python.👍1
### Изучаем
Если вы хоть раз вручную писали вложенные циклы, чтобы перебрать все пары, тройки или варианты, — модуль
---
## Комбинации: выбираем без повторов
Комбинация — это выбор элементов без учета порядка. Из
- не повторяет элементы;
-
- всё генерируется лениво (по мере запроса).
Полезно, когда перебираете возможные команды, наборы опций или подсеты признаков в задаче машинного обучения.
---
## Комбинации с повторениями
Иногда элемент можно брать несколько раз: монеты, кубики, вкусы мороженого.
---
## Декартово произведение: все возможные варианты
Результат:
-
-
-
- и т.д.
Можно задать повторения:
Это уже все возможные броски двух кубиков.
---
## Комбинации против продукта: что когда использовать?
- Нужен выбор из одного набора без повторов →
- Нужен выбор из одного набора с возможными повторами →
- Нужны все сочетания из нескольких наборов →
- Хотите сымитировать несколько одинаковых наборов (кубики, пароли фиксированной длины) →
---
itertools: комбинации и декартовы произведенияЕсли вы хоть раз вручную писали вложенные циклы, чтобы перебрать все пары, тройки или варианты, — модуль
itertools создан для вас. Он умеет генерировать комбинации и продукты «на лету», не занимая лишнюю память.---
## Комбинации: выбираем без повторов
Комбинация — это выбор элементов без учета порядка. Из
[1, 2, 3] пары такие: (1, 2), (1, 3), (2, 3).from itertools import combinations
items = ['a', 'b', 'c', 'd']
for pair in combinations(items, 2):
print(pair)
combinations(iterable, r):- не повторяет элементы;
-
(a, b) и (b, a) считаются одним вариантом;- всё генерируется лениво (по мере запроса).
Полезно, когда перебираете возможные команды, наборы опций или подсеты признаков в задаче машинного обучения.
---
## Комбинации с повторениями
Иногда элемент можно брать несколько раз: монеты, кубики, вкусы мороженого.
from itertools import combinations_with_replacement
flavors = ['vanilla', 'chocolate', 'strawberry']
for combo in combinations_with_replacement(flavors, 2):
print(combo)
('vanilla', 'vanilla') здесь вполне допустим.---
## Декартово произведение: все возможные варианты
product — это как вложенные циклы, только в одну строку. Идеален для генерации всех комбинаций параметров.from itertools import product
sizes = ['S', 'M', 'L']
colors = ['black', 'white']
for item in product(sizes, colors):
print(item)
Результат:
-
('S', 'black')-
('S', 'white')-
('M', 'black')- и т.д.
Можно задать повторения:
for roll in product(range(1, 7), repeat=2):
print(roll)
Это уже все возможные броски двух кубиков.
---
## Комбинации против продукта: что когда использовать?
- Нужен выбор из одного набора без повторов →
combinations- Нужен выбор из одного набора с возможными повторами →
combinations_with_replacement- Нужны все сочетания из нескольких наборов →
product- Хотите сымитировать несколько одинаковых наборов (кубики, пароли фиксированной длины) →
product(..., repeat=n)---
itertools экономит память и время разработки: вы получаете мощный генератор вариантов без километров вложенных циклов. Как только ловите себя на мысли «сейчас напишу ещё один for внутри for», сначала загляните в этот модуль.👍4
Модуль
Когда нужно что-то «уникальное» — многие программисты тянутся к времени, счётчикам или даже случайным числам. Проблема в том, что всё это легко пересекается, особенно в распределённых системах. Здесь в игру вступает модуль
UUID (Universally Unique Identifier) — это 128-битное число, обычно записываемое как строка вроде:
Вероятность коллизии настолько мала, что их смело используют в базах данных, API, токенах и временных файлах.
---
### Базовая генерация UUID
---
### Разные версии UUID
Модуль поддерживает несколько схем:
Где это полезно:
-
-
-
---
### UUID как строки и обратно
Чаще всего UUID хранят как строки (например, в базе):
Можно работать и с байтами:
---
### Практический мини-пример: генерация ключей для API
Метод
---
Модуль
uuid: генерация уникальных идентификаторов без боли и коллизийКогда нужно что-то «уникальное» — многие программисты тянутся к времени, счётчикам или даже случайным числам. Проблема в том, что всё это легко пересекается, особенно в распределённых системах. Здесь в игру вступает модуль
uuid — стандартный способ генерировать уникальные идентификаторы в Python.UUID (Universally Unique Identifier) — это 128-битное число, обычно записываемое как строка вроде:
550e8400-e29b-41d4-a716-446655440000Вероятность коллизии настолько мала, что их смело используют в базах данных, API, токенах и временных файлах.
---
### Базовая генерация UUID
import uuid
user_id = uuid.uuid4()
print(user_id) # например: 3e7c0e78-9a8e-4b52-9780-4e1c23f57abc
print(type(user_id)) # <class 'uuid.UUID'>
uuid4() генерирует UUID на основе криптографически стойкого генератора случайных чисел. Это самый популярный вариант.---
### Разные версии UUID
Модуль поддерживает несколько схем:
import uuid
# v1 — на основе MAC-адреса и времени
session_id = uuid.uuid1()
# v3 — хеш MD5 (детерминированный)
name_based_v3 = uuid.uuid3(uuid.NAMESPACE_DNS, "example.com")
# v5 — хеш SHA-1 (детерминированный, предпочтительнее v3)
name_based_v5 = uuid.uuid5(uuid.NAMESPACE_URL, "https://example.com")
print(session_id)
print(name_based_v3)
print(name_based_v5)
Где это полезно:
-
uuid4() — когда нужна просто уникальность.-
uuid1() — когда порядок по времени важен (но может раскрывать MAC-адрес и время).-
uuid3() / uuid5() — когда один и тот же «вход» должен давать один и тот же UUID (идентификатор по имени, URL и т.п.).---
### UUID как строки и обратно
Чаще всего UUID хранят как строки (например, в базе):
import uuid
order_id = uuid.uuid4()
order_str = str(order_id) # в строку
print(order_str)
restored = uuid.UUID(order_str) # обратно в объект UUID
print(restored == order_id) # True
Можно работать и с байтами:
token = uuid.uuid4()
token_bytes = token.bytes
restored_token = uuid.UUID(bytes=token_bytes)
---
### Практический мини-пример: генерация ключей для API
import uuid
def generate_api_key() -> str:
return uuid.uuid4().hex # без дефисов, 32 символа
keys = [generate_api_key() for _ in range(3)]
for k in keys:
print(k)
Метод
.hex возвращает компактное шестнадцатеричное представление, удобное для токенов.---
Модуль
uuid снимает головную боль с уникальностью: вместо придумывания схем и «умных» счётчиков достаточно вызвать одну функцию — и получить идентификатор, с которым комфортно работать и локально, и в распределённых системах.🔥2👍1
Использование
Когда файл «чуть-чуть поменяли», глазами искать отличия — то еще удовольствие. Python-модуль
---
### 1. Быстро сравнить две строки
Начнем с простого: найти различия между двумя строками посимвольно.
Результат покажет строки с префиксами:
-
-
-
Это удобно, когда нужно понять, почему строки «почти одинаковы», но сравнение
---
### 2. Похожесть строк в процентах
Иногда важно не чем строки отличаются, а насколько они похожи. Для этого есть
Значение от 0 до 1 — коэффициент похожести. Можно использовать для:
- поиска опечаток,
- подсказки «Вы имели в виду…»,
- фильтрации «почти одинаковых» записей.
---
### 3. HTML-отчет о различиях
Хотите красивый, наглядный diff в браузере?
Откройте
---
### 4. Сравнение файлов построчно
Классический сценарий — сравнить два текстовых файла:
Формат
---
difflib: как Python видит отличия лучше насКогда файл «чуть-чуть поменяли», глазами искать отличия — то еще удовольствие. Python-модуль
difflib умеет делать это аккуратно, наглядно и… очень гибко. Разберёмся, как сравнивать строки и файлы, будто у нас встроен мини-Git.---
### 1. Быстро сравнить две строки
Начнем с простого: найти различия между двумя строками посимвольно.
import difflib
s1 = "Python is awesome!"
s2 = "Python is awesom?"
diff = difflib.ndiff(s1, s2)
print("\n".join(diff))
Результат покажет строки с префиксами:
-
- — удалено-
+ — добавлено-
? — подсказка, какие именно символы отличаютсяЭто удобно, когда нужно понять, почему строки «почти одинаковы», но сравнение
== возвращает False.---
### 2. Похожесть строк в процентах
Иногда важно не чем строки отличаются, а насколько они похожи. Для этого есть
SequenceMatcher.from difflib import SequenceMatcher
a = "color"
b = "colour"
ratio = SequenceMatcher(None, a, b).ratio()
print(ratio) # например, 0.91...
Значение от 0 до 1 — коэффициент похожести. Можно использовать для:
- поиска опечаток,
- подсказки «Вы имели в виду…»,
- фильтрации «почти одинаковых» записей.
---
### 3. HTML-отчет о различиях
Хотите красивый, наглядный diff в браузере?
difflib.HtmlDiff как раз для этого:import difflib
old_lines = [
"def add(a, b):\n",
" return a + b\n",
]
new_lines = [
"def add(a, b):\n",
" result = a + b\n",
" return result\n",
]
html = difflib.HtmlDiff().make_file(old_lines, new_lines,
fromdesc="Old version",
todesc="New version")
with open("diff.html", "w", encoding="utf-8") as f:
f.write(html)
Откройте
diff.html в браузере — увидите таблицу с подсветкой добавленных/удалённых строк. Мини-система контроля версий прямо в одном файле.---
### 4. Сравнение файлов построчно
Классический сценарий — сравнить два текстовых файла:
import difflib
with open("old.txt", encoding="utf-8") as f:
old = f.readlines()
with open("new.txt", encoding="utf-8") as f:
new = f.readlines()
for line in difflib.unified_diff(old, new,
fromfile="old.txt",
tofile="new.txt"):
print(line.rstrip())
Формат
unified diff знаком всем, кто работал с Git: строки с +, - и контекстом вокруг изменений. Удобно для логов, конфигов, автопроверок.---
difflib часто недооценивают, а зря. Это готовый швейцарский нож для работы с похожими текстами: от проверки орфографии до построения собственных дифф-отчетов. И всё это — в стандартной библиотеке, без единого pip install.🔥3
Создание локального веб-сервера с помощью встроенного
Когда слышишь «веб‑сервер», в голове всплывают сложные штуки вроде Nginx, Apache или хотя бы Flask. Но в Python уже есть крошечный сервер «из коробки» — модуль
---
### Запускаем самый простой сервер
Перейдите в папку с файлами, которые хотите раздавать, и запустите:
Теперь в браузере откройте
Порт можно не указывать, тогда по умолчанию будет
---
### Минимальный сервер своим скриптом
Можно сделать то же самое из Python‑файла:
---
### Свой обработчик запросов
Хотите кастомный ответ вместо списка файлов? Наследуемся от
Теперь при открытии
---
### Когда это полезно
- Быстро показать HTML/CSS/JS без настройки больших серверов.
- Локально протестировать AJAX‑запросы.
- Написать минимальный API‑мок для отладки клиента.
http.serverКогда слышишь «веб‑сервер», в голове всплывают сложные штуки вроде Nginx, Apache или хотя бы Flask. Но в Python уже есть крошечный сервер «из коробки» — модуль
http.server. Он идеален для экспериментов, отладки и быстрых демо.---
### Запускаем самый простой сервер
Перейдите в папку с файлами, которые хотите раздавать, и запустите:
python -m http.server 8000
Теперь в браузере откройте
http://localhost:8000 — вы уже подняли сервер, который раздает текущую директорию. Порт можно не указывать, тогда по умолчанию будет
8000.---
### Минимальный сервер своим скриптом
Можно сделать то же самое из Python‑файла:
from http.server import HTTPServer, SimpleHTTPRequestHandler
def run_server(port: int = 8000):
server_address = ("", port) # "" означает слушать на всех интерфейсах
httpd = HTTPServer(server_address, SimpleHTTPRequestHandler)
print(f"Serving on port {port}...")
httpd.serve_forever()
if __name__ == "__main__":
run_server()
SimpleHTTPRequestHandler умеет раздавать файлы из текущей папки и показывает простую HTML‑страницу со списком файлов.---
### Свой обработчик запросов
Хотите кастомный ответ вместо списка файлов? Наследуемся от
BaseHTTPRequestHandler:from http.server import HTTPServer, BaseHTTPRequestHandler
class HelloHandler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == "/":
message = "Hello, Python beginner!"
else:
message = f"Unknown path: {self.path}"
data = message.encode("utf-8")
self.send_response(200)
self.send_header("Content-Type", "text/plain; charset=utf-8")
self.send_header("Content-Length", str(len(data)))
self.end_headers()
self.wfile.write(data)
def run_server(port: int = 8080):
server_address = ("", port)
httpd = HTTPServer(server_address, HelloHandler)
print(f"Custom server on port {port}...")
httpd.serve_forever()
if __name__ == "__main__":
run_server()
Теперь при открытии
http://localhost:8080/ вы получите текстовый ответ, а при переходе по другому пути — сообщение с этим путем.---
### Когда это полезно
- Быстро показать HTML/CSS/JS без настройки больших серверов.
- Локально протестировать AJAX‑запросы.
- Написать минимальный API‑мок для отладки клиента.
http.server не для продакшена: нет защиты, логики масштабирования, нормального логирования. Но для обучения он идеально показывает, как HTTP‑запрос превращается в ответ, и помогает почувствовать «скелет» любого веб‑фреймворка.👍2