This commit is contained in:
Dmitry Belyaev 2024-04-13 15:54:27 +03:00
parent 046db9e827
commit 233a3e8134

View File

@ -0,0 +1,186 @@
"""
https://stepik.org/lesson/701990/step/6?unit=702091
Объявите класс Dimensions (габариты) с атрибутами:
MIN_DIMENSION = 10
MAX_DIMENSION = 10000
>>> Dimensions.MIN_DIMENSION, Dimensions.MAX_DIMENSION
(10, 10000)
Каждый объект класса Dimensions должен создаваться командой:
d3 = Dimensions(a, b, c) # a, b, c - габаритные размеры
Значения a, b, c должны сохраняться в локальных приватных атрибутах __a, __b, __c объектах этого класса.
>>> d3 = Dimensions(10, 20, 30)
>>> d3._Dimensions__a, d3._Dimensions__b, d3._Dimensions__c
(10, 20, 30)
Для изменения и доступа к приватным атрибутам в классе Dimensions должны быть объявлены объекты-свойства (property) с именами: a, b, c.
Причем, в момент присваивания нового значения должна выполняться проверка попадания числа в диапазон [MIN_DIMENSION; MAX_DIMENSION].
Если число не попадает, то оно игнорируется и существующее значение не меняется.
>>> d3.a, d3.b, d3.c
(10, 20, 30)
>>> d3.a = 9; d3.a
10
С объектами класса Dimensions должны выполняться следующие операторы сравнения:
dim1 >= dim2 # True, если объем dim1 больше или равен объему dim2
dim1 > dim2 # True, если объем dim1 больше объема dim2
dim1 <= dim2 # True, если объем dim1 меньше или равен объему dim2
dim1 < dim2 # True, если объем dim1 меньше объема dim2
>>> dim1, dim2, dim3 = Dimensions(10, 20, 30), Dimensions(20, 15, 20), Dimensions(10, 15, 35)
>>> dim1 > dim3, dim1 == dim2, dim2 != dim3, dim3 < dim2, dim2 >= dim3
(True, True, True, True, True)
Объявите в программе еще один класс с именем ShopItem (товар), объекты которого создаются командой:
item = ShopItem(name, price, dim)
где name - название товара (строка); price - цена товара (целое или вещественное число); dim - габариты товара (объект класса Dimensions).
>>> item = ShopItem('Кеды', 1024, Dimensions(40, 30, 120))
В каждом объекте класса ShopItem должны создаваться локальные атрибуты:
name - название товара;
price - цена товара;
dim - габариты товара (объект класса Dimensions).
>>> item.name, item.price, item.dim
('Кеды', 1024, Dimensions(40, 30, 120))
Создайте список с именем lst_shop из четырех товаров со следующими данными:
- кеды; 1024; (40, 30, 120)
- зонт; 500.24; (10, 20, 50)
- холодильник; 40000; (2000, 600, 500)
- табуретка; 2000.99; (500, 200, 200)
>>> lst_shop[:2]
[ShopItem('кеды', 1024, Dimensions(40, 30, 120)), ShopItem('зонт', 500.24, Dimensions(10, 20, 50))]
>>> lst_shop[2:]
[ShopItem('холодильник', 40000, Dimensions(2000, 600, 500)), ShopItem('табуретка', 2000.99, Dimensions(500, 200, 200))]
Сформируйте новый список lst_shop_sorted с упорядоченными по возрастанию объема (габаритов) товаров списка lst_shop,
используя стандартную функцию sorted() языка Python и ее параметр key для настройки сортировки.
Прежний список lst_shop должен оставаться без изменений.
>>> lst_shop_sorted[:2]
[ShopItem('зонт', 500.24, Dimensions(10, 20, 50)), ShopItem('кеды', 1024, Dimensions(40, 30, 120))]
>>> lst_shop_sorted[2:]
[ShopItem('табуретка', 2000.99, Dimensions(500, 200, 200)), ShopItem('холодильник', 40000, Dimensions(2000, 600, 500))]
P.S. На экран в программе ничего выводить не нужно.
"""
from functools import total_ordering
def make_properties(*names):
def decorator(cls):
def prop(private_name: str):
def getter(self):
return getattr(self, private_name)
def setter(self, value):
return setattr(self, private_name, value)
return getter, setter
for name in names:
setattr(cls, name, property(*prop(f"_{cls.__name__}__{name}")))
return cls
return decorator
@total_ordering
@make_properties(*"abc")
class Dimensions:
MIN_DIMENSION = 10
MAX_DIMENSION = 10000
def __init__(self, a, b, c):
self.a, self.b, self.c = a, b, c
def __setattr__(self, name, value):
if name in ["MIN_DIMENSION", "MAX_DIMENSION"]:
raise AttributeError(
"Менять атрибуты MIN_DIMENSION и MAX_DIMENSION запрещено."
)
if not self.MIN_DIMENSION <= value <= self.MAX_DIMENSION:
return
super().__setattr__(name, value)
@property
def volume(self):
return self.a * self.b * self.c
def __len__(self):
return self.volume
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.volume == other.volume
return NotImplemented
def __lt__(self, other):
if isinstance(other, self.__class__):
return self.volume < other.volume
return NotImplemented
def __repr__(self):
return f"{self.__class__.__name__}{(self.a, self.b, self.c)!r}"
@total_ordering
class ShopItem:
def __init__(self, name, price, dim):
self.name, self.price, self.dim = name, price, dim
def __repr__(self):
return f"{self.__class__.__name__}{(self.name, self.price, self.dim)!r}"
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.dim == other.dim
return NotImplemented
def __lt__(self, other):
if isinstance(other, self.__class__):
return self.dim < other.dim
return NotImplemented
data = [
("кеды", 1024, (40, 30, 120)),
("зонт", 500.24, (10, 20, 50)),
("холодильник", 40000, (2000, 600, 500)),
("табуретка", 2000.99, (500, 200, 200)),
]
lst_shop = [ShopItem(name, price, Dimensions(*dim)) for name, price, dim in data]
lst_shop_sorted = sorted(lst_shop)
def tests():
from base64 import b85decode
b = (
b"VRLh3a&#bUWo{^Jb97&GXm4;SAU!=GG%O$@(TC8u(Sgvr(7qtijnKQ$wa~oKwa~rMg3!LuvLMj1AZ&AVUvp@0a3IjV"
+ b"(6u1ZfY7keve3QIz92Lr3JPp<bYF9DAUz;kT?%Y-bYF9DE@5zRWo~3BQ)q8+NpxjxC@0Xm(6!LC(TgW6ATcm9G%O%QX>Db"
+ b"0b7^mGb0{=0EFd#5EFdv5Fexc13T$(9UvqFSVQ_F|Ze%D^Xm4;ybY*QQC(yUhzR<nVf+s8>H83zPGBhk8L}_hhZgXjGZgV"
+ b"IxFf1T4Ff1T7Fexc13T$(9UvqFSVQ_F|Ze%D^Xm4;ybY*QQC((t_zR<hSzR<MLxX`=NjL^N%xX`*MEFd&6FfcGIAVg_xWo"
+ b"~n6Z*FraGB7YOEFd;8Ff1T7Ffb`8DGF?JbYF9DE@5zRWo~3BQ)q8+NpxjxC@0Z^(6G?4(Sy-|(6!Nm(7MpDCoCW`FfcGKI"
+ b"XNsKL}_hhZgXjGZgVI#Ffc42GB7YKATls8DJdxm3T$(9UvqF@b8m8VWn>^dAX_KUx6r=Oz0ravEFdS)y3n=Iw9$(vEFdS*"
+ b"g3z$gvC)IkfY7zkg3!9quqP}aC((t_zR<hSzR<MLxX`=NjL^N%xX`*MT?%s`Js?|nE^c9MWgup6av*phX>K5Fb97&GXm4;"
+ b"|b8m8VWn^6nVRLh3a&#bUb97&Ga9?w8a&%>6AU!=Gb1Wbt(Sgvv(74fo(7w>RAZ&AVUvp@0a9?w8a&%>6Akl%*gwVdxfY7"
+ b"|qxY2;nzR<GJu+Y6A(7n*L(6Z3A(SXps(7qxH3S==LJs?DBZDnqAX>V?GC^RrEATuy5ATcs9DGFpVAUz;NX>Db0b7^mGb0"
+ b"{=0EFd#5EFdv5FewUTGax-6L}_hhZgXjGZgVIzFf1T4Ff1T3Ffb_!VRLh3a&#bMF(5oWAY?KuAR^Gc(6!LA(6!Nk(7n*UA"
+ b"ke<ig3*A`u+Xv4zR`lvu+Y08(7w>W(6!Nk(6G^h(7w@tAUr)H3So0|WpZ>NWHTT<Js@N<EFdD#z0kGLve32BfY80rz97)P"
+ b"(Sp%{(6G?4(7w@v(6G?EAke<hztFYOfY7kfg3!LvfFL|QA_`%1b7gXLAY?NjJRoE;EFdD#z0kGLve32BfY80rz97)P(Sp%"
+ b"{(6G?4(7w@v(6G?EAke<hztFYOfY7kfg3!LvfFL{~3JPR0E@2=&ATclsWHK&dAUz;4FbZTcE@L1)ATclsVRLh3a&#bMG9W"
+ b"x4WHBrtBGA3iwa~KAwb6jkz0kfO(7w@v(SXpf(6P|I(Sp#h(7PbezR<tWwb6jku+f6hzR`dnJRs1&(7w@u(7VvJAketbx6"
+ b"r)Mwa~rLwa~rLxY3Uw(7w>I(TdQu(7e#FAkl}=wb6jkwa~X9(7w>I(TdQu(7Mrr(Tgq7fzYzhzR<bRfzg7{ve2*~VJskGE"
+ b"Ffbd3I"
)
exec(b85decode(b))
if __name__ == "__main__":
import doctest
doctest.testmod()
tests()