📝 Практические задания 15

⚡ Задания в двух словах

  1. Анализ оценок по кварталам из JSON.
  2. Поиск и нормализация немецких мобильных номеров.
  3. Извлечение email-адресов из текста.
  4. Извлечение номеров банковских карт.

Задание 1. Анализ оценок по кварталам

Условие: реализуйте программу, которая:

  • Прочитает данные из JSON-файла.
  • Для каждого ученика и предмета вычислит среднюю оценку за каждый учебный квартал:
    • 1 квартал: январь–март
    • 2 квартал: апрель–май (лето пропускается)
    • 3 квартал: сентябрь–декабрь
  • Запишет результаты в новый JSON-файл, сгруппированные по ученикам, предметам и кварталам.

Данные: файл grades.json содержит список записей следующего формата:

[
  {"name": "Bob", "subject": "Science", "grade": 86, "date": "06-09-2025"},
  {"name": "Diana", "subject": "Science", "grade": 85, "date": "31-01-2025"},
  {"name": "Bob", "subject": "Literature", "grade": 60, "date": "19-07-2025"},
  {"name": "Charlie", "subject": "Literature", "grade": 78, "date": "05-08-2025"},
  {"name": "Ethan", "subject": "Literature", "grade": 69, "date": "08-04-2025"},
  {"name": "Charlie", "subject": "Science", "grade": 63, "date": "24-10-2025"},
  {"name": "Ethan", "subject": "Math", "grade": 80, "date": "30-01-2025"},
  {"name": "Alice", "subject": "Physics", "grade": 90, "date": "15-09-2025"},
  {"name": "Ethan", "subject": "Science", "grade": 63, "date": "18-09-2025"},
  ...
]

Пример вывода: файл quarterly_report.json

{
    "Bob": {
        "Science": {
            "Q1": 86.0
        },
        "Literature": {
            "Q1": 94.0,
            "Q2": 68.0,
            "Q3": 81.0
        },
        "History": {
            "Q1": 73.67
        }
    },
    "Diana": {
        "Science": {
            "Q2": 85.0
        },
        "Physics": {
            "Q2": 92.0,
            "Q3": 72.0
        },
        ...
    },
    ...
}

Задание 2. Поиск немецких мобильных номеров

Условие: реализуйте программу, которая:

  • Находит в тексте все немецкие мобильные номера, записанные в одном из следующих форматов:
    • начинаются с +49 или 0049;
    • далее префикс мобильного оператора, начинающийся на 15, 16 или 17;
    • далее — от 7 до 9 цифр (в номере могут быть пробелы, дефисы или табуляции между блоками).
  • Очищает найденные номера от пробелов, дефисов, табов.
  • Преобразует номер в единый формат, начинающийся с +49.
  • Проверяет, что в результате (после очистки):
    • префикс после +49 должен начинаться с 15, 16 или 17;
    • и содержит 10–12 цифр после кода страны (то есть общий формат: +49XXXXXXXXXX — от 13 до 15 символов).
  • Возвращает список валидных номеров.

Данные: файл german_numbers.txt

+49 157 12345678
0049-160-9876543
+49176 2345 6789
+49 89 123456                     # <- не мобильный (городской)
0049-151-456-7890
+49 178 111-22-33
+49-152-12 34 567
0044 7700 900123                  # <- Великобритания
+49160-1234-5
...

Пример вывода:

Валидные номера:
+4917623456789
+491514567890
+491781112233
+491521234567
+49154234567890
...

Задание 3. Извлечение email-адресов

Условие: реализуйте программу, которая находит в тексте все email-адреса, соответствующие следующим критериям:

  • Перед @ допускаются буквы, цифры, точки (.) и подчёркивания (_), но адрес не начинается и не заканчивается точкой.
  • После @ следует:
    • домен второго уровня: буквы, цифры, дефисы, точки;
    • затем домен верхнего уровня (например, .com, .org, .net, .pl), от 2 до 3 букв.
  • Email не может содержать пробелы.

Данные:

text = """
Valid:
- support@mail.com
- info@company.org
- personal_email123@edu.university.net
- user.name@sub.domain.com
- contact_us123@my-site.org
- hello.world@some.place.travel
- admin@server.local
- support@company-name.de
- user@data.edu.pl

Invalid:
- user@domain,com
- name@domaincom
- name@domain.c
- user@domain.toolongtldddddd
- no@space .com
- bad@@mail.com
- missing@dotcom
"""

Пример вывода:

support@mail.com
info@company.org
personal_email123@edu.university.net
user.name@sub.domain.com
contact_us123@my-site.org
support@company-name.de
user@data.edu.pl

Задание 4. Извлечение номеров банковских карт

Условие: реализуйте программу, которая должна найти все номера карт, записанные как 16 цифр, разделённые пробелами, дефисами или без разделителей.

Данные:

text = """
Valid examples:
1234 5678 9012 3456
4321-8765-2109-6543
1234567812345678
1234-5678 9012-3456

Invalid examples:
123456781234567
1234/5678/9012/3456
1234 5678 9012
1234-5678-ABCD-3456
1234--5678--9012--3456
1234 56789 012 3456
"""

Пример вывода:

Валидные номера:
1234 5678 9012 3456
4321-8765-2109-6543
1234567812345678
1234-5678 9012-3456

Проверка понимания

Выберите один вариант ответа. После клика правильный ответ подсветится зелёным.

Вопрос 1

Что важнее всего в практическом задании?

Вопрос 2

Как безопаснее двигаться в практикуме?

Вопрос 3

Что делать, если решение не совпадает с ожидаемым результатом?

Вопрос 4

Какой стиль имён переменных обычно рекомендует PEP 8?

Вопрос 5

Зачем использовать f-strings в современном Python?

Вопрос 6

Когда полезен ранний возврат из функции?