145 lines
5.9 KiB
Python
145 lines
5.9 KiB
Python
|
"""
|
|||
|
https://stepik.org/lesson/701989/step/7?unit=702090
|
|||
|
|
|||
|
Объявите класс с именем ListMath, объекты которого можно создавать командами:
|
|||
|
|
|||
|
lst1 = ListMath() # пустой список
|
|||
|
lst2 = ListMath([1, 2, -5, 7.68]) # список с начальными значениями
|
|||
|
В качестве значений элементов списка объекты класса ListMath должны отбирать только целые и вещественные числа, остальные игнорировать (если указываются в списке). Например:
|
|||
|
|
|||
|
lst = ListMath([1, "abc", -5, 7.68, True]) # ListMath: [1, -5, 7.68]
|
|||
|
В каждом объекте класса ListMath должен быть публичный атрибут:
|
|||
|
|
|||
|
lst_math - ссылка на текущий список объекта (для каждого объекта создается свой список).
|
|||
|
|
|||
|
Также с объектами класса ListMath должны работать следующие операторы:
|
|||
|
|
|||
|
lst = lst + 76 # сложение каждого числа списка с определенным числом
|
|||
|
lst = 6.5 + lst # сложение каждого числа списка с определенным числом
|
|||
|
lst += 76.7 # сложение каждого числа списка с определенным числом
|
|||
|
lst = lst - 76 # вычитание из каждого числа списка определенного числа
|
|||
|
lst = 7.0 - lst # вычитание из числа каждого числа списка
|
|||
|
lst -= 76.3
|
|||
|
lst = lst * 5 # умножение каждого числа списка на указанное число (в данном случае на 5)
|
|||
|
lst = 5 * lst # умножение каждого числа списка на указанное число (в данном случае на 5)
|
|||
|
lst *= 5.54
|
|||
|
lst = lst / 13 # деление каждого числа списка на указанное число (в данном случае на 13)
|
|||
|
lst = 3 / lst # деление числа на каждый элемент списка
|
|||
|
lst /= 13.0
|
|||
|
При использовании бинарных операторов +, -, *, / должны формироваться новые объекты класса ListMath с новыми списками, прежние списки не меняются.
|
|||
|
|
|||
|
При использовании операторов +=, -=, *=, /= значения должны меняться внутри списка текущего объекта (новый объект не создается).
|
|||
|
|
|||
|
P.S. В программе достаточно только объявить класс. На экран ничего выводить не нужно.
|
|||
|
"""
|
|||
|
|
|||
|
from operator import add, sub, mul, truediv, floordiv, 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.lst_math = list(self.map_op(op, other))
|
|||
|
return self
|
|||
|
|
|||
|
def method_r(self, other):
|
|||
|
return self.__class__(map(lambda x: op(other, x), self.lst_math))
|
|||
|
|
|||
|
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, pow)
|
|||
|
class ListMath:
|
|||
|
def __init__(self, lst_math=None):
|
|||
|
self.lst_math = [*filter(lambda x: type(x) in (int, float), lst_math or [])]
|
|||
|
|
|||
|
def __repr__(self):
|
|||
|
return f"{self.__class__.__name__}({self.lst_math!r})"
|
|||
|
|
|||
|
def map_op(self, op, other):
|
|||
|
return map(lambda x: op(x, other), self.lst_math)
|
|||
|
|
|||
|
|
|||
|
def tests():
|
|||
|
lst1 = ListMath()
|
|||
|
lp = [1, False, 2, -5, "abc", 7]
|
|||
|
lst2 = ListMath(lp)
|
|||
|
lst3 = ListMath(lp)
|
|||
|
|
|||
|
assert id(lst2.lst_math) != id(
|
|||
|
lst3.lst_math
|
|||
|
), "внутри объектов класса ListMath должна создаваться копия списка"
|
|||
|
|
|||
|
assert lst1.lst_math == [] and lst2.lst_math == [
|
|||
|
1,
|
|||
|
2,
|
|||
|
-5,
|
|||
|
7,
|
|||
|
], "неверные значения в списке объекта класса ListMath"
|
|||
|
|
|||
|
res1 = lst2 + 76
|
|||
|
lst = ListMath([1, 2, 3])
|
|||
|
lst += 5
|
|||
|
assert lst.lst_math == [6, 7, 8] and res1.lst_math == [
|
|||
|
77,
|
|||
|
78,
|
|||
|
71,
|
|||
|
83,
|
|||
|
], "неверные значения, полученные при операциях сложения"
|
|||
|
|
|||
|
lst = ListMath([0, 1, 2])
|
|||
|
res3 = lst - 76
|
|||
|
res4 = 7 - lst
|
|||
|
assert res3.lst_math == [-76, -75, -74] and res4.lst_math == [
|
|||
|
7,
|
|||
|
6,
|
|||
|
5,
|
|||
|
], "неверные значения, полученные при операциях вычитания"
|
|||
|
|
|||
|
lst -= 3
|
|||
|
assert lst.lst_math == [
|
|||
|
-3,
|
|||
|
-2,
|
|||
|
-1,
|
|||
|
], "неверные значения, полученные при операции вычитания -="
|
|||
|
|
|||
|
lst = ListMath([1, 2, 3])
|
|||
|
res5 = lst * 5
|
|||
|
res6 = 3 * lst
|
|||
|
lst *= 4
|
|||
|
assert res5.lst_math == [5, 10, 15] and res6.lst_math == [
|
|||
|
3,
|
|||
|
6,
|
|||
|
9,
|
|||
|
], "неверные значения, полученные при операциях умножения"
|
|||
|
assert lst.lst_math == [
|
|||
|
4,
|
|||
|
8,
|
|||
|
12,
|
|||
|
], "неверные значения, полученные при операциях умножения"
|
|||
|
|
|||
|
lst = lst / 2
|
|||
|
lst /= 13.0
|
|||
|
|
|||
|
|
|||
|
if __name__ == "__main__":
|
|||
|
import doctest
|
|||
|
|
|||
|
doctest.testmod()
|
|||
|
tests()
|