Перейти до змісту

Бонус. CV розробника: HTML → PDF

Курс закінчується фінальним проєктом (уроки 52–53), а після нього — пошук роботи чи стажування. Перше, що побачить рекрутер, — не код, а CV. Цей бонус-урок (поза нумерацією 1–52) — про дві речі:

  1. що писати: як з «я робив» зробити «я створив цінність» — туторіал;
  2. як робити CV інженерно: зміст і дизайн у HTML, PDF — однією командою, версії — у Git.

Стартовий код — CV_maker: HTML-резюме викладача, скрипт generate_cv_pdf.py (pdfkit → wkhtmltopdf), README з інструкціями і туторіал.

Крок Матеріал Що там
1 довідник «Сильне CV» Professional Summary, формула пункту, сильні дієслова, чесні метрики, порядок проєктів, Skills, розриви сторінок, адаптація під вакансію, ATS
2 cv_maker/ cv_template.html — шаблон для свого CV; generate_cv_pdf.py і generate_cv_pdf_chromium.py; README
3 Відкрити вправи в Colab Переглянути розв’язки 6 вправ: перевірка пунктів CV, лише чесні числа, CV як дані → HTML з екрануванням, PDF

Після уроку ти зможеш:

  • написати пункт CV за формулою «дієслово + що + чим + яка цінність» про свої проєкти курсу;
  • відрізнити чесну метрику від вигаданої;
  • зібрати CV з HTML-шаблону в PDF і тримати версії під різні вакансії.

Як це працює

flowchart TD
    classDef step     fill:#eceff1,stroke:#546e7a,stroke-width:1px,color:#1a1a1a;
    classDef decision fill:#e3f2fd,stroke:#1565c0,stroke-width:2px,color:#1a1a1a;
    classDef success  fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px,color:#1a1a1a;
    classDef error    fill:#ffebee,stroke:#c62828,stroke-width:3px,color:#1a1a1a;
    classDef warning  fill:#fff8e1,stroke:#e65100,stroke-width:2px,color:#1a1a1a;

    subgraph S1["зміст і дизайн"]
        direction LR
        A1["cv_template.html<br>текст + CSS"] --> A2["перевірка<br>у браузері"]
    end
    subgraph S2["генерація"]
        direction LR
        B1["generate_cv_pdf.py"] --> B2["pdfkit"] --> B3["wkhtmltopdf<br>(QtWebKit)"]
    end
    subgraph S3["альтернатива"]
        direction LR
        C1["generate_cv_pdf_chromium.py"] --> C2["Playwright<br>Chromium"]
    end
    subgraph S4["результат"]
        direction LR
        D1["CV_Name_Surname.pdf"] --> D2["Git: версія<br>під вакансію"]
    end
    S1 --> S2 --> S4
    S1 --> S3 --> S4

    class A1,A2,B1,B2,C1 step
    class B3 warning
    class C2 success
    class D1,D2 success
cd module_6/bonus/cv_maker
pip install pdfkit                               # + wkhtmltopdf (README: Windows, macOS, Linux)
python generate_cv_pdf.py                        # CV викладача
python generate_cv_pdf.py cv_template.html CV_Name_Surname.pdf
PDF created: …/module_6/bonus/cv_maker/CV_Viktor_Nikoriak_GeoAI.pdf     ← 5 сторінок
PDF created: /tmp/CV_Template.pdf                                          ← шаблон: 1 сторінка

Шаблон cv_template.html — той самий CSS, що в CV викладача (кольори, розриви сторінок, keep-together), а замість змісту — поля в [дужках] і підказка з формулою пункту. Розділ, для якого нічого написати, видаляй цілком: порожній розділ гірший за відсутній.

wkhtmltopdf чи Chromium

wkhtmltopdf рендерить HTML старим рушієм QtWebKit, а сам проєкт архівований і більше не розвивається. Тому поруч — generate_cv_pdf_chromium.py: той самий HTML через Chromium (Playwright), тобто так, як сторінку бачить Chrome.

                         wkhtmltopdf 0.12.6   wkhtmltopdf --disable-smart-shrinking   Chromium (Playwright)
CV викладача             5 сторінок            6 сторінок                               6 сторінок
cv_template.html         1 сторінка            2 сторінки                               2 сторінки

Різниця — не помилка: wkhtmltopdf за замовчуванням трохи зменшує вміст, щоб він вмістився (smart shrinking). Без цього він дає ті самі сторінки, що Chromium. Для CV на одну сторінку в Chromium — скороти текст або зменш font-size у CSS, а не покладайся на стиснення.

flowchart TD
    classDef step     fill:#eceff1,stroke:#546e7a,stroke-width:1px,color:#1a1a1a;
    classDef decision fill:#e3f2fd,stroke:#1565c0,stroke-width:2px,color:#1a1a1a;
    classDef success  fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px,color:#1a1a1a;
    classDef error    fill:#ffebee,stroke:#c62828,stroke-width:3px,color:#1a1a1a;
    classDef warning  fill:#fff8e1,stroke:#e65100,stroke-width:2px,color:#1a1a1a;

    Q0["потрібен PDF з HTML"]
    Q1{"wkhtmltopdf уже<br>встановлений?"}
    Q2{"сучасний CSS:<br>flex, grid, змінні?"}
    W["generate_cv_pdf.py<br>(pdfkit + wkhtmltopdf)"]
    C["generate_cv_pdf_chromium.py<br>(Playwright)"]
    Q0 --> Q1
    Q1 -->|так| Q2
    Q1 -->|ні| C
    Q2 -->|ні| W
    Q2 -->|так| C

    class Q0 step
    class Q1,Q2 decision
    class W,C success

Що писати: коротко з туторіалу

Повний туторіал — у довіднику. Головне:

Слабко Сильно
перелік ролей у Summary роль + досвід + спеціалізація + доказ + технології
«Responsible for…», «Worked on…» сильне дієслово + що + чим + яка цінність
«improved by 70%» без вимірювання лише числа, які можеш пояснити на співбесіді
список з 30 технологій карта компетенцій: Backend, Data, Infrastructure, Quality

Проєкти курсу — готовий матеріал. Приклад пунктів, що спираються лише на справжні факти з уроків 37–51:

Built a news aggregator API with FastAPI, PostgreSQL and Redis, covered by 343 pytest tests.
Containerized a FastAPI news aggregator with Docker and Compose: nginx, PostgreSQL, Redis and one-shot Alembic migrations.
Automated testing with GitHub Actions: 6 jobs per pull request, including pytest on 2 Python versions and mypy --strict.

Практика

Спробуй самостійно: своє CV

Скопіюй cv_template.html у cv_<ім'я>.html і заповни.

Критерії перевірки:

  • кожен пункт проходить weak_reasons з ноутбука (дієслово дії, інструменти, до 30 слів);
  • кожне число — з твого коду чи вимірювання (unverified_numbers порожній для твоїх фактів);
  • щонайменше два пункти — про проєкти курсу або фінальний проєкт, з посиланням на репозиторій;
  • PDF з generate_cv_pdf.py або generate_cv_pdf_chromium.py — 1–2 сторінки.

Знайди помилку

CV генерується з даних Python-функцією, яка вставляє текст у HTML «як є». У Skills записано C++ & Rust <basics>. PDF виглядає акуратно — але що саме в ньому написано?

Відповідь

<basics> браузер сприймає як тег і не показує: у PDF лише «C++ & Rust ». Ноутбук відтворює це на html.parser, як браузер. Текст, що вставляється в HTML, — через html.escape (так само, як ім'я користувача в боті уроку 48).

Документація і джерела