122 lines
4.9 KiB
Python
122 lines
4.9 KiB
Python
|
"""
|
|||
|
https://stepik.org/lesson/701989/step/11?unit=702090
|
|||
|
|
|||
|
Объявите класс Box3D для представления прямоугольного параллелепипеда (бруска), объекты которого создаются командой:
|
|||
|
|
|||
|
box = Box3D(width, height, depth)
|
|||
|
где width, height, depth - ширина, высота и глубина соответственно (числа: целые или вещественные)
|
|||
|
|
|||
|
В каждом объекте класса Box3D должны создаваться публичные атрибуты:
|
|||
|
|
|||
|
width, height, depth - ширина, высота и глубина соответственно.
|
|||
|
|
|||
|
С объектами класса Box3D должны выполняться следующие операторы:
|
|||
|
|
|||
|
box1 = Box3D(1, 2, 3)
|
|||
|
box2 = Box3D(2, 4, 6)
|
|||
|
|
|||
|
box = box1 + box2 # Box3D: width=3, height=6, depth=9 (соответствующие размерности складываются)
|
|||
|
box = box1 * 2 # Box3D: width=2, height=4, depth=6 (каждая размерность умножается на 2)
|
|||
|
box = 3 * box2 # Box3D: width=6, height=12, depth=18
|
|||
|
box = box2 - box1 # Box3D: width=1, height=2, depth=3 (соответствующие размерности вычитаются)
|
|||
|
box = box1 // 2 # Box3D: width=0, height=1, depth=1 (соответствующие размерности целочисленно делятся на 2)
|
|||
|
box = box2 % 3 # Box3D: width=2, height=1, depth=0
|
|||
|
При каждой арифметической операции следует создавать новый объект класса Box3D с соответствующими значениями локальных атрибутов.
|
|||
|
|
|||
|
P.S. В программе достаточно только объявить класс Box3D. На экран ничего выводить не нужно.
|
|||
|
|
|||
|
"""
|
|||
|
|
|||
|
from operator import add, sub, mul, truediv, floordiv, mod, xor
|
|||
|
|
|||
|
|
|||
|
def add_ops(*ops):
|
|||
|
def decorator(cls):
|
|||
|
def make_methods(op):
|
|||
|
def method_new(self, other):
|
|||
|
return self.__class__(*self.map_op(op, other))
|
|||
|
|
|||
|
def method_ip(self, other):
|
|||
|
self.values = self.map_op(op, other)
|
|||
|
return self
|
|||
|
|
|||
|
def method_r(self, other):
|
|||
|
if isinstance(other, (int, float)):
|
|||
|
return self.__class__(*map(lambda x: op(other, x), self.values))
|
|||
|
return self.__class__(*map(op, other.values, self.values))
|
|||
|
|
|||
|
return {
|
|||
|
f"__{op.__name__}__": method_new,
|
|||
|
f"__i{op.__name__}__": method_ip,
|
|||
|
f"__r{op.__name__}__": method_r,
|
|||
|
}
|
|||
|
|
|||
|
for op in ops:
|
|||
|
for name, method in make_methods(op).items():
|
|||
|
setattr(cls, name, method)
|
|||
|
return cls
|
|||
|
|
|||
|
return decorator
|
|||
|
|
|||
|
|
|||
|
@add_ops(add, sub, mul, truediv, floordiv, xor, mod, pow)
|
|||
|
class Box3D:
|
|||
|
def __init__(self, width, height, depth):
|
|||
|
self.width, self.height, self.depth = width, height, depth
|
|||
|
|
|||
|
@property
|
|||
|
def values(self):
|
|||
|
return self.width, self.height, self.depth
|
|||
|
|
|||
|
@values.setter
|
|||
|
def values(self, values):
|
|||
|
self.width, self.height, self.depth = values
|
|||
|
|
|||
|
def __repr__(self):
|
|||
|
return f"{self.__class__.__name__}{self.values!r}"
|
|||
|
|
|||
|
def map_op(self, op, other):
|
|||
|
if isinstance(other, (int, float)):
|
|||
|
return map(lambda x: op(x, other), self.values)
|
|||
|
return map(op, self.values, other.values)
|
|||
|
|
|||
|
|
|||
|
def tests():
|
|||
|
box1 = Box3D(1, 2, 3)
|
|||
|
box2 = Box3D(2, 4, 6)
|
|||
|
assert (
|
|||
|
hasattr(box1, "depth") and hasattr(box1, "height") and hasattr(box1, "width")
|
|||
|
), "ошибка в атрибутах"
|
|||
|
box = box1 + box2
|
|||
|
assert (
|
|||
|
box.depth == 9 and box.height == 6 and box.width == 3
|
|||
|
), "ошибка при операции Box3D(1, 2, 3) + Box3D(2, 4, 6)"
|
|||
|
box1 = Box3D(1, 2, 3)
|
|||
|
box = box1 * 2
|
|||
|
assert (
|
|||
|
box.depth == 6 and box.height == 4 and box.width == 2
|
|||
|
), "ошибка при операции box1 * 2 (каждая размерность умножается на 2)"
|
|||
|
box = 3 * box2
|
|||
|
assert (
|
|||
|
box.depth == 18 and box.height == 12 and box.width == 6
|
|||
|
), "ошибка при операции 3 * box2"
|
|||
|
box = box2 - box1
|
|||
|
assert (
|
|||
|
box.depth == 3 and box.height == 2 and box.width == 1
|
|||
|
), "ошибка при операции box2 - box1"
|
|||
|
box = box1 // 2
|
|||
|
assert (
|
|||
|
box.depth == 1 and box.height == 1 and box.width == 0
|
|||
|
), "ошибка при операции box1 // 2"
|
|||
|
box = box2 % 3
|
|||
|
assert (
|
|||
|
box.depth == 0 and box.height == 1 and box.width == 2
|
|||
|
), "ошибка при операции box2 % 3"
|
|||
|
|
|||
|
|
|||
|
if __name__ == "__main__":
|
|||
|
import doctest
|
|||
|
|
|||
|
doctest.testmod()
|
|||
|
tests()
|