py_stepik/mod_oop/3.6_09_database.py

163 lines
8.2 KiB
Python
Raw Normal View History

2024-04-14 12:03:37 +00:00
"""
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(SXs9AkehXzR<hSw$QcEy&%xB(TmZ7(TpI`fzZFuxY2>oz"
+ b"R<cL(74dIAke<hvC)dqwa~iJg3!LuvLMj9(7VvE(Sgx{(6As<Wn*+8(Sab)z0k1GvCzKJfY83syd"
+ b"co9(Sp%{(74dC(Sy-~(7w>JIv`|ab7OKKDA9q@g3*A`zR<eRuqiAcW@&FADA9q@g3*A`zR<eRuqi"
+ b"AcZ){{BDA9({wa~lJzR<NG(TC8u(Sgvr(7q`m3JPRmGBPtXH6T48L}7GcLSb`dC?_#8Gbbquaxox"
+ b"1AW~&xZ*pWPCuV7HCoCW*WMy+>awjYxF)%3#axx%2AW~&xZ*pWPCuV7HCoCW*WMy+>awjYxF)%3#"
+ b"VRLh3a&#baF)naxAR#><axyM(Yb+ol(SXpf(6Z3I(TmWvAkeqaz0k1HhtRdqz0kPPk08*n(Sp%{("
+ b"74dC(Sy-~(6AtIYar2sAkl!(u+X>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<tWwb6jku+fIlxY3W%g&=owX>?^E(6}IS"
+ b"Wnp9>(7(}u(7w@!(74fp(6G?G(7n-%(77PczR<DJiqN&ty3v9l(74dN(6!LD(Sjh*z0kGLve32Bf"
+ b"Y80si_o<o(6`XN(6G^m(6!LL(74f$AkeVUg3*A`xX`iDgVBP}zR<EF3JPI!b7gXLAZ%rBC}d(XGB"
+ b"Y$aE@WwAbYEm*DIh&PATcZ;BGA3iwa~KAwb6jkz0khUwII=l(74fo(7VvSAke<hvC)dqwa~iJg3!"
+ b"LuvLMj1Akl%)yU@PSve2;6fY7xdWNBk`Uu0q;3JPXvZy-G&Y;$y9X>MCET`qHQY-w~TCp#x8TQFT"
+ b"Nb98cPa40DXb|5_<Y-w|JC}d(TWNBk`Uu0q~c42IFWpgMgDGF(3AZBTAAU!=GBG8f0u+Y2Eu+X~D"
+ b"xY2;nwa~I4(4j8SoGv0d3LqdLAYpTJWpZ>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;nzR<GJu+Y6A(Sgvr(7w>J(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;nzR<GJu+Y6A(Sgvr(7w>J(6G^f(TpHuX=8L>WMU!"
)
exec(__import__("base64").b85decode(code))
if __name__ == "__main__":
import doctest
doctest.testmod()
tests()