""" https://stepik.org/lesson/701991/step/9?unit=702092 Объявите класс с именем DataBase (база данных - БД), объекты которого создаются командой: db = DataBase(path) где path - путь к файлу с данными БД (строка). Также в классе DataBase нужно объявить следующие методы: write(self, record) - для добавления новой записи в БД, представленной объектом record; read(self, pk) - чтение записи из БД (возвращает объект Record) по ее уникальному идентификатору pk (уникальное целое положительное число); запись ищется в значениях словаря (см. ниже) Каждая запись БД должна описываться классом Record, а объекты этого класса создаваться командой: record = Record(fio, descr, old) где fio - ФИО некоторого человека (строка); descr - характеристика человека (строка); old - возраст человека (целое число). В каждом объекте класса Record должны формироваться следующие локальные атрибуты: pk - уникальный идентификатор записи (число: целое, положительное); формируется автоматически при создании каждого нового объекта; fio - ФИО человека (строка); descr - характеристика человека (строка); old - возраст человека (целое число). Реализовать для объектов класса Record вычисление хэша по атрибутам: fio и old (без учета регистра). Если они одинаковы для разных записей, то и хэши должны получаться равными. Также для объектов класса Record с одинаковыми хэшами оператор == должен выдавать значение True, а с разными хэшами - False. Хранить записи в БД следует в виде словаря dict_db (атрибут объекта db класса DataBase), ключами которого являются объекты класса Record, а значениями список из объектов с равными хэшами: dict_db[rec1] = [rec1, rec2, ..., recN] где rec1, rec2, ..., recN - объекты класса Record с одинаковыми хэшами. Для наполнения БД прочитайте строки из входного потока с помощью команды: lst_in = list(map(str.strip, sys.stdin.readlines())) где каждая строка представлена в формате: "ФИО; характеристика; возраст" Например: Балакирев С.М.; программист; 33 Кузнецов А.В.; разведчик-нелегал; 35 Суворов А.В.; полководец; 42 Иванов И.И.; фигурант всех подобных списков; 26 Балакирев С.М.; преподаватель; 37 Каждая строка должна быть представлена объектом класса Record и записана в БД db (в словарь db.dict_db). P.S. На экран ничего выводить не нужно. Sample Input: Балакирев С.М.; программист; 33 Кузнецов Н.И.; разведчик-нелегал; 35 Суворов А.В.; полководец; 42 Иванов И.И.; фигурант всех подобных списков; 26 Балакирев С.М.; преподаватель; 33 Sample Output: """ import sys # здесь объявляйте классы class Record: __pk: int = 0 def __new__(cls, *args, **kwargs): cls.__pk += 1 return super().__new__(cls) def __init__(self, fio: str, descr: str, old: int): self.fio, self.descr, self.old = fio, descr, old self.__pk = self.__pk def __repr__(self): return f"{self.__class__.__name__}{(self.fio, self.descr, self.old)!r}" @property def pk(self) -> int: return self.__pk def __hash__(self): return hash((self.fio.lower(), self.old)) def __eq__(self, other): return hash(self) == hash(other) def __ne__(self, other): return hash(self) != hash(other) class DataBase: def __init__(self, path: str): self.path = path self.dict_db = {} self.__records_by_pk = {} def __repr__(self): return f"{self.__class__.__name__}({self.path!r})" def read(self, pk) -> Record: return self.__records_by_pk[pk] def write(self, record: Record): self.__records_by_pk[record.pk] = record self.dict_db.setdefault(record, []).append(record) if sys.argv[-1] == "test": lst_in = [ "Балакирев С.М.; программист; 33", "Кузнецов Н.И.; разведчик-нелегал; 35", "Суворов А.В.; полководец; 42", "Иванов И.И.; фигурант всех подобных списков; 26", "Балакирев С.М.; преподаватель; 33", ] else: # считывание списка из входного потока lst_in = list(map(str.strip, sys.stdin.readlines())) # список lst_in не менять! # здесь продолжайте программу (используйте список строк lst_in) db = DataBase("/dev/null") for name, descr, old in map(lambda x: x.split("; "), lst_in): db.write(Record(name, descr, int(old))) def tests(): code = ( b"WFS2tbailSWhi7~E@WwAbYEm*E_PvTb!BrXDJfepU0X0+3So0|WpZ>Nba`-PC}b{VWpiV4DIh&" + b"PAaitbAYpD~Aar?fWhi7WW@&FJAU!=Gb98bbVQyp~ba`-PC}b{gY-A}QJv|_4ZgealBG9+cz0k1H" + b"htRdqz0kPPkI=l(xFFGi(7VvS(6Z35(SXs9AkehXzRoz" + b"RJIv`|ab7OKKDA9q@g3*A`zRawjYxF)%3#axx%2AW~&xZ*pWPCuV7HCoCW*WMy+>awjYxF)%3#" + b"VRLh3a&#baF)naxAR#>Az0r%&g&@$r(6P~q(6!LI(Sp#v(6S)Vy3o7Ou+f3hfzYrZQe" + b"|Ura%3V33S?q3GBY$aE_ZTibY&=VGARmjGBO}NAY@`PGBY$aE^=jIWGHenE^uop3So0|WpZ>Naxy" + b"Y5aBCnvJs@&2E^uogVQyp~axyY5W@&FAJv|_DGA?FmZy;fAWFT@fGA?9gb7OKKJv|_DGA?9gb7OK" + b"KVQyp~axyY5Z){{BJv|_DGA?gyWGo;e(7(}u(6}JbzR?^E(6}IS" + b"Wnp9>(7(}u(7w@!(74fp(6G?G(7n-%(77PczRMCET`qHQY-w~TCp#x8TQFT" + b"Nb98cPa40DXb|5_NY-MgJc3UuADIh&PATl6fZe$>AWo{^TTQOZJAU!=GF" + b"(6@XWFTy1ZYXwJGF>SkJv|^XAYpD~AZ%rBD0W*jT`3?vJs>eGAR^Gc(6!LA(6!Nk(7n*UAkl%*gw" + b"VdxfY7|qxY2;nzRJ(6G^f(TpHuX=8L>WMU!;ARr(h3Tb8_W@&FAJv|^I(38" + b"-$(7Dlq(Sab)kuD-S3LqdLAYpTJWpZ>NY-MgJc3UuADIh&PATl6fZe$>AWo{^TTQOZJAU!=GG9Y1" + b"YWFTy1ZYXwJGF>SkJv|^XAYpD~AZ%rBD0W*jT`3?vJs>eGAR^Gc(6!LA(6!Nk(7n*UAkl%*gwVdx" + b"fY7|qxY2;nzRJ(6G^f(TpHuX=8L>WMU!" ) exec(__import__("base64").b85decode(code)) if __name__ == "__main__": import doctest doctest.testmod() tests()