9.5. Самостоятельная работа

Примечание

При выполнении заданий используйте заготовки решений: -> Репозиторий.

Подробнее: см. Цикл выполнения и защиты заданий.

9.5.1. Комплексная задача

№9.5.1

Продолжите решение задачи № 8.5.1.

Используя результаты предыдущего решения, а также заготовку и Листинги 9.5.1-9.5.3:

  • функции сохранения и загрузки перенесите в отдельный модуль;

  • вычисления и фильтры - в отдельный модуль;

  • импортируйте новые модули, скорректируйте main.py;

  • добавьте if __name__ == "__main__" в main.py.

Листинг 9.5.1 - Модуль database.py
 1"""Комплексная задача.
 2
 3Модуль содержит функции:
 4- загрузка данных из файла;
 5- сохранение данных в файл.
 6"""
 7
 8import json
 9import csv
10
11
12def load_db(filename):
13    """Загрузить данные из json-файла 'filename'.
14
15    Функция не обрабатывает исключения.
16
17    Результат: list of dict или возбуждается исключение.
18
19    Сложность: O(1).
20    """
21    ...
22
23
24def save_db(db, filename):
25    """Сохранить данные 'db' в csv-файл 'filename'.
26
27    Функция не обрабатывает исключения.
28
29    Сложность: O(1).
30    """
31    ...
Листинг 9.5.2 - Модуль employee.py
 1"""Комплексная задача.
 2
 3Модуль содержит функции:
 4- печать объекта;
 5- фильтры и вычислительные функции.
 6"""
 7
 8
 9def print_employee(item):
10    """Вывести объект 'item' на экран со всеми атрибутами.
11
12    Сложность: O(1).
13    """
14    ...
15
16
17def employees_filter(db, lang):
18    """Вернуть отфильтрованную базу 'db' (список сотрудников), у которых
19    в качестве языка программирования имеется 'lang'.
20
21    Аргументы:
22        - db (list of dict): база данных;
23        - lang (str): язык программирования.
24
25    Результат:
26        - (list of dict): отфильтрованная база данных.
27
28    Сложность: O(N).
29    """
30    ...
31
32
33def employee_avg_height(db, younger_than):
34    """Вернуть средний рост среди сотрудников 'db', у которых
35    год рождения не менее 'younger_than'.
36
37    Аргументы:
38        - db (list of dict): база данных;
39        - younger_than (int): минимальный год рождения.
40
41    Результат:
42        - (float): если такие сотрудники есть;
43          (None): если таких сотрудников нет.
44
45    Исключения:
46        - ValueError: если кол-во найденных сотрудников равно 0.
47
48    Сложность: O(N).
49    """
50    ...
Листинг 9.5.3 - Модуль main.py
  1"""Комплексная задача.
  2
  3Главный модуль.
  4"""
  5
  6import json
  7import csv
  8import database
  9import employee
 10
 11# Это пример кода, он может быть произвольно усложнен
 12# в рамках ограничений темы
 13#
 14# Требования:
 15#
 16# - функции сохранения и загрузки перенесите в отдельный модуль;
 17# - вычисления и фильтры - в отдельный модуль;
 18# - импортируйте новые модули, скорректируйте main.py;
 19# - добавьте if __name__ == "__main__" в main.py.
 20
 21# Каждый модуль должен иметь наименование, соответствующее
 22# выбранному варианту
 23
 24
 25if __name__ == "__main__":
 26    try:
 27        db = database.load_db("data.json")
 28
 29        while True:
 30
 31            print("\n-----")
 32            print("Меню")
 33            print("-----")
 34            print("1. Список сотрудников.")
 35            print("2. Фильтр по языку программирования.")
 36            print("3. Средний рост сотрудников, моложе указанного г.р.")
 37            print("\nВыберите пункт меню или нажмите ENTER для выхода: ",
 38                  end="")
 39
 40            answer = input()
 41
 42            if answer == "1":
 43                print("Содержимое базы данных ({}):".format(len(db)))
 44                for i, item in enumerate(db, start=1):
 45                    print("{}.".format(i))
 46                    employee.print_employee(item)
 47
 48            elif answer == "2":
 49                lang = input("Введите язык программирования: ")
 50                # "Нормализация" наименования языка на случай ошибки при вводе
 51                lang = lang.capitalize()
 52
 53                res = employee.employees_filter(db, lang)
 54
 55                if len(res) > 0:
 56                    print("Список сотрудников со знанием "
 57                          "языка программирования {} ({}):".
 58                          format(lang, len(res)))
 59                    for i, item in enumerate(res, start=1):
 60                        print("{}.".format(i))
 61                        employee.print_employee(item)
 62
 63                    # Сохранение результата в файл
 64                    try:
 65                        database.save_db(res, "filter_result.csv")
 66                        print("Результат поиска сохранен в файл.")
 67                    except (IOError, csv.Error):
 68                        print("Не удалось сохранить результат поиска в файл.")
 69                else:
 70                    print("Таких сотрудников нет.")
 71
 72            elif answer == "3":
 73                try:
 74                    younger_than = int(
 75                        input("Введите год рождения сотрудника: "))
 76
 77                    try:
 78                        res = employee.employee_avg_height(db, younger_than)
 79                        print("Средний рост сотрудников, {} г.р. и моложе: "
 80                              "({:.1f}) см.".
 81                              format(younger_than, res))
 82                    except ValueError:
 83                        print("Таких сотрудников нет.")
 84                except ValueError:
 85                    print("Год рождения должен быть целым числом.")
 86
 87            else:
 88                break
 89
 90    except (IOError, json.decoder.JSONDecodeError) as err:
 91        print("Ошибка при чтении файла с данными:", err)
 92
 93    except Exception as err:
 94        print("Произошла ошибка!")
 95        print("Тип:", type(err))
 96        print("Описание:", err)
 97
 98
 99# --------------
100# Пример вывода:
101#
102# -----
103# Меню
104# -----
105# 1. Список сотрудников.
106# 2. Фильтр по языку программирования.
107# 3. Средний рост сотрудников, моложе указанного г.р.
108#
109# Выберите пункт меню или нажмите ENTER для выхода: 1
110# Содержимое базы данных (3):
111# 1.
112# Имя: Иванов Иван
113# День рождения: 01/12/2000
114# Рост (см.): 170
115# Вес (кг.): 70.5
116# Есть машина: True
117# Языки программирования: ['С++', 'Python']
118# 2.
119# Имя: Сергеев Сергей
120# День рождения: 01/06/2001
121# Рост (см.): 180
122# Вес (кг.): 110.4
123# Есть машина: False
124# Языки программирования: ['Pascal', 'Delphi']
125# 3.
126# Имя: Николаева Мария
127# День рождения: 14/07/1998
128# Рост (см.): 180
129# Вес (кг.): 66.9
130# Есть машина: True
131# Языки программирования: ['C#', 'C++', 'C']
132#
133# -----
134# Меню
135# -----
136# 1. Список сотрудников.
137# 2. Фильтр по языку программирования.
138# 3. Средний рост сотрудников, моложе указанного г.р.
139#
140# Выберите пункт меню или нажмите ENTER для выхода: 2
141# Введите язык программирования: Python
142# Список сотрудников со знанием языка программирования Python (1):
143# 1.
144# Имя: Иванов Иван
145# День рождения: 01/12/2000
146# Рост (см.): 170
147# Вес (кг.): 70.5
148# Есть машина: True
149# Языки программирования: ['С++', 'Python']
150# Результат поиска сохранен в файл.
151#
152# -----
153# Меню
154# -----
155# 1. Список сотрудников.
156# 2. Фильтр по языку программирования.
157# 3. Средний рост сотрудников, моложе указанного г.р.
158#
159# Выберите пункт меню или нажмите ENTER для выхода: 3
160# Введите год рождения сотрудника: 2000
161# Средний рост сотрудников, 2000 г.р. и моложе: (175.0) см.