+ 3.6_09
This commit is contained in:
parent
e9a4f02399
commit
6ce82afa41
162
mod_oop/3.6_09_database.py
Normal file
162
mod_oop/3.6_09_database.py
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
"""
|
||||||
|
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()
|
Loading…
Reference in New Issue
Block a user