Skip to content

Commit 13aae63

Browse files
author
Терентьев Антон Павлович
committed
initial commit
0 parents  commit 13aae63

File tree

80 files changed

+12326
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+12326
-0
lines changed

.github/workflows/ci.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
tests:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v4
12+
- uses: actions/setup-python@v5
13+
with:
14+
python-version: '3.12'
15+
- name: Install
16+
run: |
17+
python -m pip install --upgrade pip
18+
pip install -e .[dev]
19+
- name: Lint & format
20+
run: |
21+
ruff check .
22+
black --check .
23+
isort --check-only .
24+
- name: Type check
25+
run: |
26+
mypy
27+
- name: Tests
28+
run: |
29+
pytest -q
30+
31+

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.venv/
2+
__pycache__/
3+
.pytest_cache/
4+
.mypy_cache/
5+
.ruff_cache/
6+
dist/
7+
build/
8+
*.egg-info/
9+
coverage.xml
10+
*.sqlite
11+
tmp/
12+

README.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
## Учебный проект: Python 3.12 — дорожная карта задач с тестами
2+
3+
Этот репозиторий — набор практических задач, закрывающих базовые и прикладные навыки Python. Каждая задача размещена в отдельном модуле в `src/tasks/` и снабжена тестами в `tests/`. Запускайте тесты, реализуйте функции, добивайтесь зелёного статуса и покрывайте ключевую логику типами.
4+
5+
### Как начать
6+
7+
#### 1. Настройка окружения
8+
```bash
9+
# Создание виртуального окружения
10+
python -m venv .venv
11+
12+
# Активация окружения (Linux/Mac)
13+
source .venv/bin/activate
14+
15+
# Активация окружения (Windows)
16+
.venv\Scripts\activate
17+
18+
# Установка зависимостей
19+
pip install -e .[dev]
20+
```
21+
22+
#### 2. Запуск тестов
23+
```bash
24+
# Запуск всех тестов
25+
pytest -q
26+
27+
# Запуск тестов для конкретного уровня
28+
pytest tests/l1/ -v
29+
pytest tests/l2/ -v
30+
pytest tests/l3/ -v
31+
32+
# Запуск тестов с покрытием
33+
pytest --cov=src --cov-report=html
34+
```
35+
36+
#### 3. Структура проекта
37+
```
38+
src/tasks/
39+
├── l1/ # Базовый уровень (7 задач)
40+
├── l2/ # Средний уровень (10 задач)
41+
└── l3/ # Продвинутый уровень (17 задач)
42+
43+
tests/
44+
├── l1/ # Тесты для L1
45+
├── l2/ # Тесты для L2
46+
└── l3/ # Тесты для L3
47+
```
48+
49+
### Цели и навыки
50+
- Язык и стандартная библиотека: структуры данных, итераторы, исключения, файлы/пути, datetime, regex, ООП, typing/mypy.
51+
- Инструменты разработчика: формат и линт, тестирование, покрытие, логирование, CLI.
52+
- Прикладные основы: HTTP-клиент, парсинг HTML, кеширование, SQLite, Pydantic.
53+
- Асинхронность и конкурентность: asyncio, rate-limiter, планировщики.
54+
- Контейнеризация (минимум): Dockerfile (задачи класса C — опционально).
55+
56+
### Структура
57+
```
58+
.
59+
├── src/tasks/ # задачи (каждая — модуль)
60+
│ ├── l1/ # уровень L1 (база) — 7 задач
61+
│ ├── l2/ # уровень L2 (средний) — 10 задач
62+
│ └── l3/ # уровень L3 (продвинутый) — 17 задач
63+
├── tests/ # тесты к задачам
64+
│ ├── l1/ # тесты для L1
65+
│ ├── l2/ # тесты для L2
66+
│ └── l3/ # тесты для L3
67+
├── pyproject.toml # конфиги инструментов
68+
└── README.md
69+
```
70+
71+
### Полный индекс задач (1–40)
72+
1. task01_fizzbuzz — FizzBuzz без if-лестницы.
73+
2. task02_csv_normalization — Нормализация CSV с локальными числами в JSON.
74+
3. task03_word_freq — Частоты слов (unicode, топ-10).
75+
4. task04_merge_dicts — Слияние словарей с on_conflict.
76+
5. task05_lru_cache — LRU-кэш O(1).
77+
6. task06_log_parser — Парсер логов regex + группировка.
78+
7. task07_password_validator — Валидатор паролей (regex).
79+
8. task08_find_duplicates — Поиск дубликатов файлов по хешу.
80+
9. task09_timezone_convert — Конвертация расписания (zoneinfo).
81+
10. task10_retry_decorator — Декоратор retry с backoff.
82+
11. task11_pipeline_iterators — Мини-pipeline на генераторах.
83+
12. task12_config_dataclass — Конфиг на dataclass(slots,frozen).
84+
13. task13_fetch_json — HTTP-клиент с таймаутом/ретраями.
85+
14. task14_html_parser — H1..H3 и внутренние ссылки.
86+
15. task15_file_cache — Файловый кеш TTL.
87+
16. task16_sqlite_crud — SQLite CRUD без ORM.
88+
17. task17_pydantic_schemas — NoteIn/NoteOut: строгие типы, валидация тегов/длины.
89+
18. task18_rate_limiter — In-memory RPS на IP/ключ.
90+
19. task19_pagination_utils — limit/offset, сортировка.
91+
20. task20_uploader_limits — Проверка размера/мим-типа.
92+
21. task21_http_cache — Кеширование HTTP-ответов (ключ URL+параметры, TTL).
93+
22. task22_sqlalchemy_model — SQLAlchemy модель Note и пагинация.
94+
23. task23_fastapi_notes — Мини-API /notes с TestClient.
95+
24. task24_api_key_auth — X-API-Key зависимость, 401/403.
96+
25. task25_rate_limit_fastapi — Простой rate-limit middleware.
97+
26. task26_pagination_params — Валидация limit/offset.
98+
27. task27_file_upload_endpoint — POST /upload с лимитами.
99+
28. task28_token_cli — CLI выпуска API-ключей (uuid4+HMAC).
100+
29. task29_async_gatherer — Асинхронный сбор URL с Semaphore/таймаутами.
101+
30. task30_async_token_bucket — Асинхронный rate-limiter (token bucket).
102+
31. task31_thread_vs_process — Сравнение пулов CPU/I-O.
103+
32. task32_async_scheduler — Планировщик задач без наложений.
104+
33. task33_logging_config — dictConfig + ротация файлов.
105+
34. task34_cli_argparse — Подкоманды scan/report/fix.
106+
35. task35_precommit_tooling — Настройка pre-commit (black, ruff, isort).
107+
36. task36_mypy_strict — Довести мини-пакет до mypy --strict.
108+
37. task37_dockerfile_fastapi — Dockerfile (builder+runtime, non-root, healthcheck).
109+
38. task38_docker_compose — API + SQLite volume, .env.
110+
39. task39_env_settings — Pydantic Settings: обязательные/дефолты.
111+
40. task40_build_dist — Сборка wheel/sdist и консольная точка входа.
112+
113+
На каждую задачу заведён модуль-скелет с `NotImplementedError` и тесты, которые изначально падают.
114+
115+
### Уровни сложности и капстоуны
116+
117+
**L1 — Базовый уровень (7 задач):**
118+
- `task01_fizzbuzz`, `task02_csv_normalization`, `task03_word_freq`, `task04_merge_dicts`
119+
- `task07_password_validator`, `task11_pipeline_iterators`, `task12_config_dataclass`
120+
- **Цель**: Освоить базовый синтаксис Python, структуры данных, типизацию
121+
122+
**L2 — Средний уровень (10 задач):**
123+
- `task05_lru_cache`, `task06_log_parser`, `task08_find_duplicates`, `task09_timezone_convert`
124+
- `task10_retry_decorator`, `task14_html_parser`, `task15_file_cache`, `task16_sqlite_crud`
125+
- `task19_pagination_utils`, `task21_http_cache`
126+
- **Цель**: Алгоритмы, работа с файлами, базы данных, кеширование
127+
128+
**L3 — Продвинутый уровень (17 задач):**
129+
- **HTTP и API**: `task13_fetch_json`, `task17_pydantic_schemas`, `task18_rate_limiter`, `task20_uploader_limits`
130+
- **FastAPI и веб-разработка**: `task22_sqlalchemy_model`, `task23_fastapi_notes`, `task24_api_key_auth`
131+
- **Middleware и валидация**: `task25_rate_limit_fastapi`, `task26_pagination_params`, `task27_file_upload_endpoint`
132+
- **CLI и утилиты**: `task28_token_cli`
133+
- **Асинхронность**: `task29_async_gatherer`, `task30_async_token_bucket`, `task31_thread_vs_process`, `task32_async_scheduler`
134+
- **Контейнеризация**: `task37_dockerfile_fastapi`, `task38_docker_compose`
135+
- **Цель**: Создание полноценных веб-приложений, асинхронное программирование, DevOps
136+
137+
**Капстоуны (на выбор 1–2, после прохождения всех уровней):**
138+
- **REST Notes API на FastAPI**: CRUD, валидация, пагинация, auth по ключу
139+
- **Телеграм-бот «Хабит-трекер»**: напоминания, простое хранилище, рейт-лимитер
140+
- **Асинхронный сборщик URL**: gather+Semaphore, таймауты, отмена, отчёт
141+
- **CLI filesync двух директорий**: dry-run, exclude, отчёты
142+
143+
### Правила приёмки
144+
- Все тесты для выбранной задачи зелёные.
145+
- Покрытие ключевой логики по проекту ≥ 85% (`pytest --cov`).
146+
- `mypy --strict` без ошибок и без `type: ignore`.
147+
- Код проходит формат и линт: `black`, `ruff`, `isort`.
148+
149+
### Скрытые проверки
150+
В частном CI присутствуют дополнительные тесты на устойчивость и античит (например, проверка идемпотентности, корректности работы исключений путей, граничных состояний времени/таймаутов). Их описание доступно только наставникам.
151+
152+

pyproject.toml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
[build-system]
2+
requires = ["setuptools>=68", "wheel"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "pytraining"
7+
version = "0.1.0"
8+
description = "Python 3.12 training tasks with tests"
9+
readme = "README.md"
10+
requires-python = ">=3.12,<3.13"
11+
authors = [{name = "Training", email = "[email protected]"}]
12+
dependencies = []
13+
14+
[project.optional-dependencies]
15+
dev = [
16+
"pytest>=8",
17+
"pytest-cov>=5",
18+
"hypothesis>=6",
19+
"mypy>=1.11",
20+
"ruff>=0.5",
21+
"black>=24.8",
22+
"isort>=5.13",
23+
"requests>=2.32",
24+
"pydantic>=2",
25+
"sqlalchemy>=2",
26+
]
27+
28+
[tool.pytest.ini_options]
29+
minversion = "8.0"
30+
addopts = "-q"
31+
testpaths = ["tests"]
32+
filterwarnings = [
33+
"error::DeprecationWarning",
34+
]
35+
36+
[tool.coverage.run]
37+
branch = true
38+
source = ["src"]
39+
40+
[tool.mypy]
41+
python_version = "3.12"
42+
strict = true
43+
warn_unused_configs = true
44+
warn_return_any = true
45+
warn_unreachable = true
46+
exclude = ["tests/"]
47+
48+
[tool.ruff]
49+
line-length = 100
50+
target-version = "py312"
51+
src = ["src", "tests"]
52+
lint.select = ["E", "F", "I", "N", "B", "UP", "ARG", "C90"]
53+
lint.ignore = ["E501"]
54+
55+
[tool.black]
56+
line-length = 100
57+
target-version = ["py312"]
58+
59+
[tool.isort]
60+
profile = "black"
61+
line_length = 100
62+
63+
[tool.setuptools]
64+
package-dir = {"" = "src"}
65+
66+
[tool.setuptools.packages.find]
67+
where = ["src"]
68+
include = ["tasks*"]
69+
70+

src/tasks/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""Training tasks package.
2+
3+
Each task is a standalone module `taskNN_*` exposing one or more functions.
4+
Implement functions according to their docstrings and make tests pass.
5+
"""
6+
7+

src/tasks/l1/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# L1 — базовый уровень
2+
3+
## Описание
4+
Сферы: синтаксис, структуры данных, исключения, простые итераторы, базовый typing.
5+
6+
## Задачи уровня L1
7+
8+
### Основные задачи (обязательные)
9+
1. **task01_fizzbuzz** — FizzBuzz без if-лестницы
10+
2. **task02_csv_normalization** — Нормализация CSV с локальными числами в JSON
11+
3. **task03_word_freq** — Частоты слов (unicode, топ-10)
12+
4. **task04_merge_dicts** — Слияние словарей с on_conflict
13+
5. **task05_password_validator** — Валидатор паролей (regex)
14+
6. **task06_pipeline_iterators** — Мини-pipeline на генераторах
15+
7. **task07_config_dataclass** — Конфиг на dataclass(slots,frozen)
16+
17+
## Рекомендуемый порядок выполнения
18+
1. task01_fizzbuzz — начать с простой задачи
19+
2. task02_csv_normalization — работа с файлами и JSON
20+
3. task03_word_freq — обработка текста и коллекции
21+
4. task04_merge_dicts — работа со словарями
22+
5. task05_password_validator — регулярные выражения
23+
6. task06_pipeline_iterators — генераторы и итераторы
24+
7. task07_config_dataclass — типизация и dataclass
25+
26+
## Цели обучения
27+
- Освоить базовый синтаксис Python 3.12
28+
- Понять работу со структурами данных
29+
- Научиться обрабатывать исключения
30+
- Изучить основы типизации
31+
- Понять принципы работы с файлами и JSON
32+
33+
## Критерии успешного прохождения
34+
- Все тесты для задач L1 проходят успешно
35+
- Код соответствует стандартам PEP 8
36+
- Используется типизация (type hints)
37+
- Понимание принципов работы с данными
38+

src/tasks/l1/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""Level 1 (L1): базовые задачи.
2+
3+
Импорт примеров:
4+
from tasks.l1.task01_fizzbuzz import fizzbuzz
5+
"""
6+
7+

src/tasks/l1/task01_fizzbuzz.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from tasks.task01_fizzbuzz import fizzbuzz # re-export
2+
3+
__all__ = ["fizzbuzz"]
4+
5+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from tasks.task02_csv_normalization import parse_csv_to_rows
2+
3+
__all__ = ["parse_csv_to_rows"]
4+
5+

src/tasks/l1/task03_word_freq.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from tasks.task03_word_freq import word_frequencies
2+
3+
__all__ = ["word_frequencies"]
4+
5+

0 commit comments

Comments
 (0)