+3.5_06
This commit is contained in:
parent
046db9e827
commit
233a3e8134
186
mod_oop/3.5_06_dimensions_shopitem.py
Normal file
186
mod_oop/3.5_06_dimensions_shopitem.py
Normal 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()
|
Loading…
Reference in New Issue
Block a user