Dr. Claw
Full-stack research workspace. From idea to paper with AI agents.
Безкоштовний тренажер: інтервальні повторення FSRS, як в Anki, і пробний іспит на 20 питань. Без реклами, працює офлайн.
Translation pending
EducationJavaScript · PythonGitHub @punjetOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Anki Deck with questions from the Ukrainian driving exam. Made from official sources. Manually verified.
Taken from the repository README
Loading the full README.
Read the full README ↗Проєкт має дві частини з одним джерелом даних:
Питання й малюнки взяті з офіційної бази ГСЦ МВС (наказ № 225 від 29.10.2025, розділи 1–39 і 44–47). Кожна відповідь категорії B перевірена трьома незалежними способами.
Навчання
web/grade.js).Як на іспиті
Вибірково
Зручність
Прогрес
flowchart LR
subgraph src["Офіційні джерела"]
Q["questions.pdf<br>питання + малюнки"]
A["answers.pdf<br>скан таблиці відповідей"]
end
Q --> P["parse_official.py"]
A --> O["ocr_answers.py<br>tesseract + власний класифікатор"]
P --> D["build_dataset.py"]
O --> D
B["Brut322/pdr-test<br>незалежна звірка"] --> F["finalize_dataset.py"]
D --> F
F --> J[("data/questions.json")]
J --> DK["build_deck.py"] --> APKG["PDR_UA_category_B.apkg"]
J --> W["build_web.py + build_seo.py"] --> SITE["_site/ → GitHub Pages<br>zdaipdr.com.ua"]
AI["explain.py · similar.py · topics.py<br>(OpenAI, один раз локально)"] --> X[("explanations · similar<br>topics · keywords")]
X --> W
build_web.py копіює web/, додає questions.json, малюнки й SEO-сторінки. Збірка потребує лише стандартної бібліотеки Python, тому CI запускає її як є..github/workflows/pages.yml на кожен push у main. Після деплою indexnow.py повідомляє пошуковики про змінені сторінки.ingest(), тільки додає рядки), акаунти Google для синхронізації й тимчасові зашифровані пакети для перенесення прогресу (supabase/schema.sql).Модулі застосунку:
| Файл | Що робить |
|---|---|
web/app.js | екрани, черга FSRS, іспит, пошук, теми, налаштування, синхронізація |
web/ui.js | спільні елементи: шапка, нижня панель, діалоги, тости, перегляд малюнка з зумом |
web/grade.js | автооцінка правильної відповіді для автопереходу |
web/sync.js | вхід через Google і синхронізація (Supabase Auth + REST), вантажиться на вимогу |
web/transfer.js | перенесення прогресу за QR/посиланням з шифруванням AES-GCM |
web/telemetry.js | черга анонімної статистики, працює й офлайн |
web/sw.js | service worker: офлайн-режим і кеш малюнків |
web/vendor/ | ts-fsrs, MiniSearch, qrcode-generator |
Сайт:
python build_web.py data _site # лише стандартна бібліотека Python 3.11+
python -m http.server -d _site 8000 # http://localhost:8000
Пояснення «Чому так» потрапляють у застосунок лише зі змінною PDR_APP_EXPLAIN=1 (у CI вона ввімкнена):
PDR_APP_EXPLAIN=1 python build_web.py data _site
Колода Anki:
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
python build_deck.py data PDR_UA_category_B.apkg
Адреса сайту для канонічних посилань і sitemap — змінна SITE_URL у pages.yml. Ключі Supabase й Google (публічні) — у web/config.js; порожній SUPABASE_URL вимикає статистику й синхронізацію.
web/ веб-застосунок (вихідні файли сайту)
build_web.py збирає сайт у _site/
build_seo.py статичні сторінки для пошуковиків
build_deck.py збирає колоду Anki
deck_order.py яруси й порядок карток — спільні для колоди й сайту
parse_official.py PDF питань → JSON + малюнки
ocr_answers.py OCR скану таблиці відповідей
build_dataset.py об'єднує питання й відповіді
finalize_dataset.py звірка з Brut322/pdr-test, статус перевірки
explain.py пояснення через OpenAI Batch API
similar.py схожі питання («не сплутайте»)
topics.py теми й ключові слова для пошуку
indexnow.py повідомлення пошуковикам після деплою
data/questions.json усі 2332 питання (усі категорії) зі статусом перевірки
data/images/ малюнки до питань
data/*.json пояснення, теми, ключові слова, схожі питання, текст ПДР
answer_overrides.json відповіді, звірені вручну зі сканом
supabase/ схема бази й запити для аналізу статистики
brand/ логотип і генератор усіх його варіантів
docs/screenshots/ скриншоти для цього README
Колода є на AnkiWeb: https://ankiweb.net/shared/info/1194338664 — у Anki Огляд колод → Отримати спільні або відкрийте посилання й натисніть Download.
PDR_UA_category_B.apkg
з Releases (або зберіть самі: python build_deck.py)
і імпортуйте в Anki: Файл → Імпорт.10m 1h, бажана утримуваність FSRS 0.92.Повторний імпорт оновленої колоди зберігає прогрес: GUID нотаток стабільні.
Сайт чи Anki? Сайт не потребує встановлення, має пробний іспит, розбір помилок, теми й пошук. Anki вміє персонально оптимізувати параметри FSRS за історією відповідей (після ~1000 повторень; для 1–2 тижнів підготовки це майже нічого не змінює).
Білет складається з 10 питань ПДР, 4 — основ безпечного водіння, 4 — додаткових питань категорії та 2 — домедичної допомоги (hsc.gov.ua, 16.09.2025). Чим менший пул і більше місць у білеті, тим вища ймовірність, що конкретне питання трапиться, тому колода й сайт ідуть від найвигіднішого ярусу:
| # | Ярус | Карток | Ймовірність питання в білеті |
|---|---|---|---|
| 1 | Додаткові питання кат. B (розд. 44–47) | 65 | ~6 % |
| 2 | Домедична допомога (розд. 37) | 60 | ~3,3 % |
| 3 | Основи безпечного водіння (розд. 35) | 171 | ~2,3 % |
| 4 | Топ помилок ГСЦ: регулювальник, нерегульовані перехрестя, круговий рух, розмітка | 302 | ~0,7 % |
| 5 | Решта ПДР — ситуації з малюнком | 684 | ~0,7 % |
| 6 | Решта ПДР — текстові питання | 480 | ~0,7 % |
Ярус 4 — теми з п'ятірки найчастіших помилок за даними ГСЦ (18.12.2025). Усередині
ярусу першими йдуть складніші питання: більше варіантів, є малюнок, довший текст
(публічної статистики помилок по окремих питаннях немає). Припущення: блок
«4 питання за категорією» — це розділи 44–47. Логіка — у deck_order.py.
Поле verified у data/questions.json:
| значення | що означає | кат. B |
|---|---|---|
ocr+template+brut | tesseract, власний класифікатор цифр і незалежний датасет Brut322/pdr-test збігаються | 1646 |
template+brut | tesseract не впевнений, класифікатор і Brut322 збігаються | 111 |
manual | розбіжність, звірено очима зі сканом | 5 |
brut-only / brut-unconfirmed | відповідь лише з Brut322 (бляклий 11-й аркуш скану, розділи 53–63) | 0 (поза кат. B: 125) |
Відповіді поза категорією B (brut-only, brut-unconfirmed) вручну не перевірялися.
Потрібні Python 3.11+ і tesseract
(brew install tesseract), а також залежності з requirements.txt.
Офіційні PDF у репозиторій не входять. Їх треба скачати зі сторінки ГСЦ
«Питання та іспит з ПДР»
і покласти в data/official_pdf/ як questions.pdf (питання) та answers.pdf
(таблиця відповідей).
hsc.gov.ua стоїть за Akamai: з неукраїнського IP — «Access Denied», а з українського
звичайний curl отримує 403. Качати через curl_cffi:
from curl_cffi import requests
s = requests.Session(impersonate="chrome")
open("questions.pdf", "wb").write(s.get(URL).content)
Далі:
mkdir -p work/ans
python parse_official.py data/official_pdf/questions.pdf work/ # питання + малюнки
python -c "import pymupdf,sys; [p.get_pixmap(dpi=300).save(f'work/ans/a{i+1:02d}.png') for i,p in enumerate(pymupdf.open(sys.argv[1]))]" data/official_pdf/answers.pdf
python ocr_answers.py work/ans work/ans_ocr.json # OCR таблиці відповідей
python build_dataset.py work/questions_official.json work/ans_ocr.json work/glyphs work/dataset.json answer_overrides.json
git clone https://github.com/Brut322/pdr-test work/pdr-test # незалежна звірка
python finalize_dataset.py work/dataset.json work/pdr-test/data/questions.json answer_overrides.json data/questions.json
rm -rf data/images && cp -r work/images data/images
python build_deck.py data PDR_UA_category_B.apkg
build_dataset.py друкує розбіжності OCR і аномалії таблиці; finalize_dataset.py
завершується з помилкою, якщо хоч одна відповідь категорії B розходиться з Brut322 і
не звірена вручну. Такі питання звірте зі сканом і внесіть у answer_overrides.json
({"<розділ>-<номер>": відповідь}). Якщо в новій редакції зміниться нумерація,
Brut322 теж має бути оновлений, інакше звірка не зійдеться.
Застосунок малює все через JavaScript, тому для пошуковиків build_seo.py додає статичні сторінки без JS:
q/<id>/ — кожне питання: малюнок, варіанти, відповідь після вибору, пояснення, пункти ПДР, шанс потрапити в білет;r/<розділ>/ — розділи іспиту; pdr/<розділ>/ — текст ПДР з питаннями до кожного пункту;tema/<тема>/ — теми з data/topics.json; ispyt/ — пробний іспит; pro/ — про проєкт і перевірку відповідей;404.html, sitemap.xml з lastmod, robots.txt, CNAME.Сторінка питання індексується лише тоді, коли в data/explanations.json для нього є перевірене
пояснення ("status": "ok"); кількість живих сторінок обмежує SEO_MAX_EXPLAINED у pages.yml.
Пояснення генерує explain.py через OpenAI Batch API (вдвічі дешевше): одна модель
відповідає на питання наосліп, інша пише пояснення до офіційної відповіді; публікуються лише ті,
де обидві збігаються з таблицею ГСЦ. У запит іде не весь розділ ПДР, а 8 найближчих фрагментів
(ембединги з тим самим кешем, що й у similar.py). Усі 1762 питання коштують близько $10–15.
python explain.py submit --limit 30 # пілот: перші 30 питань у порядку колоди
python explain.py status
python explain.py collect # після завершення батчу (до 24 год)
python explain.py review # розбіжності, які треба перевірити вручну
similar.py і topics.py запускаються один раз локально (ключ OpenAI запитується прихованим вводом і не зберігається); результати комітяться, тому збірці сайту OpenAI не потрібен.
Застосунок безкоштовний і без реклами; натомість він збирає анонімну статистику навчання для відкритого дослідження про підготовку до іспиту. Збір увімкнено за замовчуванням; вимкнути можна на сторінці «Конфіденційність».
ingest(), яка лише додає рядки: публічний
ключ не може нічого прочитати, змінити чи видалити (supabase/schema.sql).
Готові запити для аналізу — supabase/analysis.sql.Щоб бачити, звідки приходять люди, додавайте до посилання свою мітку ?src=:
https://zdaipdr.com.ua/?src=reddit_ukraina
https://zdaipdr.com.ua/?src=tg_avtoshkola_kyiv
_ - ., до 40 символів (інше замінюється на _, великі літери стають малими);utm_source / utm_campaign теж працюють: ?utm_source=reddit&utm_campaign=ukraina → reddit-ukraina;first_src) і кожного наступного (src), а також
домен, з якого перейшли (ref, напр. t.me), — без повної адреси сторінки.Результати по мітках — запит 16 у supabase/analysis.sql.
Знайшли неправильну відповідь чи помилку на сайті — відкрийте issue
з номером питання (видно над текстом питання, напр. «Розділ 33 · №115»). Виправлення відповідей
вносяться в answer_overrides.json і проходять ту саму звірку.
Код, зібраний і перевірений датасет та колода — CC BY-NC-SA 4.0:
Тексти питань, відповіді й малюнки належать ГСЦ МВС України (hsc.gov.ua); автор
на них прав не заявляє — ліцензія стосується цієї збірки й власного внеску (код,
перевірка відповідей, структура ярусів). Деталі — у NOTICE, юридичний текст — у LICENSE.
Незалежна звірка — Brut322/pdr-test (MIT).
Бібліотеки в web/vendor/ — під власними ліцензіями (файли *-LICENSE.txt поруч).