Тест: quiz.html
Працюємо з тим самим журналом, що й у лекції. Він навмисно «брудний»: рядки різного формату, зайві пробіли, різний регістр рівнів. Скопіюй його до себе:
ЖУРНАЛ = """2026-03-15 09:41 INFO #1043 Олена kava@lviv.ua +380671234567 249.50 грн
2026-03-15 09:42 warn #1044 Петро petro@ua.net +380509876543 1290.00 грн
2026-03-16 11:03 ERROR #1045 Ірина iryna@mail.com +38 (063) 111-22-33 75.00 грн
2026-03-16 11:07 INFO #1046 Богдан-Тарас bt.koval+shop@ua-mail.net 0951234567 3.99 грн
непридатний рядок без жодних даних
2026-03-17 08:15 error #1047 Ґалина galyna@ukr.net +380671110099 15200.00 грн"""
рівень 1Рівень 1 — База
Витягни з журналу три списки: усі номери замовлень, усі адреси пошти, усі суми. Кожен шаблон пиши сирим рядком і поясни коментарем українською, що означає кожна його частина.
Окремо зроби четверте завдання без регулярки — порахуй, скільки рядків
починаються з 2026-03-16. Використай .startswith() і поясни в коментарі,
чому тут шаблон був би зайвий.
Зроблено, якщо:
номери == ['1043', '1044', '1045', '1046', '1047'](без решітки — саме цифри);- у списку пошти рівно пʼять адрес, серед них
bt.koval+shop@ua-mail.net(тобто твій шаблон витримує крапку, плюс і дефіс — і в імені, і в домені); - сума всіх замовлень дорівнює
16818.49; - підрахунок рядків за 16 березня зроблено методом рядка, і в коді є коментар, який пояснює чому.
рівень 2Рівень 2 — Плюс
Напиши функцію розібрати_рядок(рядок), яка повертає словник із полями
дата, час, рівень, номер, клієнт, пошта, телефон, сума —
або None, якщо рядок не підходить під формат.
Вимоги до шаблону:
- усі групи іменовані, шаблон записаний із
re.VERBOSEі коментарями; - рівень розпізнається незалежно від регістру (
INFO,info,Info), але в результаті завжди зберігається великими літерами; - імʼя клієнта може містити дефіс (
Богдан-Тарас) і українські літери, зокремаґіҐ; - телефон приймається в усіх трьох формах, що є в журналі —
+380671234567,+38 (063) 111-22-33і0951234567— і в результаті завжди зберігається як+380XXXXXXXXX; сумав словнику має бути числомfloat, а не рядком.
Далі побудуй словник сума_за_рівнем і виведи його впорядкованим за спаданням суми.
Зроблено, якщо:
розібрати_рядок("непридатний рядок без жодних даних") is None;- усі пʼять придатних рядків розібрано,
len(записи) == 5; записи[1]["рівень"] == "WARN"ізаписи[2]["телефон"] == "+380631112233";сума_за_рівнем == {"ERROR": 15275.0, "WARN": 1290.0, "INFO": 253.49};- у коді немає жодного
.group(1)— тільки імена.
рівень 3Рівень 3 — Виклик
Дослідження на дві частини.
Частина А · шаблон проти методів. Візьми задачу «розбити рядок журналу на поля».
Реалізуй її двома способами: через свій шаблон із рівня 2 і через звичайні
.split(), .strip(), зрізи. Виміряй обидва на журналі, повтореному 20 000 разів
(ЖУРНАЛ * 20000), і зроби чесний висновок: де швидше, де читабельніше і за яких
умов ти обрав би кожен варіант. Окремо виміряй скомпільований шаблон
(re.compile) проти re.search у циклі.
Частина Б · катастрофічний відкат. Для n від 12 до 23 виміряй час
re.search(r"(a+)+b", "a" * n). Побудуй таблицю «n → час → відношення до
попереднього». Потім:
- поясни, чому відношення тримається біля двійки;
- знайди шаблон, який розпізнає ту саму мову («одна або більше «a», потім «b»»), але працює лінійно, і доведи це вимірюванням;
- перевір, чи зникає проблема, якщо в тексті є літера
bу кінці, і поясни результат.
Зроблено, якщо:
- є таблиця вимірів для обох частин, а не одне число;
- для
(a+)+bвідношення сусідніх часів на великихnлежить у межах 1.7–2.5, і ти пояснив словами, звідки береться двійка; - для безпечного шаблону час на 23 символах щонайменше в тисячу разів менший за час небезпечного на тих самих 23 символах;
- у висновку сказано, за якої умови вкладений квантифікатор небезпечний (а не просто «вкладені квантифікатори погані»).
Підказки
- Українські літери не вміщаються в діапазон
[а-я]. Пиши[а-щьюяіїєґ]для малих і[А-ЩЬЮЯІЇЄҐ]для великих — або просто\w, якщо цифри й підкреслення тобі не завадять. - Щоб звести телефон до єдиного вигляду, спершу прибери все зайве
(
re.sub(r"\D", "", телефон)), а вже потім перевіряй довжину й початок. Не намагайся описати всі формати одним шаблоном — це шлях до нечитабельності. re.VERBOSEігнорує пробіли всередині шаблону. Якщо пробіл потрібен саме як символ — пиши\sабо[ ], інакше він мовчки зникне.- Вимірюючи час, повторюй вимір тричі й бери мінімум: перший запуск завжди дорожчий, бо шаблон ще не в кеші.
- Якщо результат
findallраптом складається з кортежів — у шаблоні є групи. Або зроби їх незапамʼятовними(?:...), або переходь наfinditer.