RE на 7 тесте. ООП
Такое условие: Вас попросили написать 2 класса, CustomList и CustomDict, оба эти класса имеют атрибут data, в котором хранится ссылка на список или словарь соответственно. В конструкторе класса передается список или словарь, также атрибут data можно изменять в процессе работы с классами, то есть:
my_list = CustomList([1, 2, 3])
my_list.data = [1, 2]
Оба эти класса имеют одни и те же свойства:
- size - размер списка или словаря,
- max_value - максимальный элемент списка или максимальный ключ словаря
- min_value - минимальный элемент списка или минимальный ключ словаря
Также печать экземпляров обоих классов должна возвращать строку в формате:
My CustomList data [1, 2, 3]
My CustomDict data {1:1, 2:2, 3:3}
Общие свойства и методы этих двух классов должны реализованы в классе CommonProperties, от которого будут наследоваться классы CustomList и CustomDict.
max_value и min_value для словаря нужно считать не только по ключам, но и по значениям. В случае, если вы пытаетесь сравнить несравнимые объекты, нужно попытаться посчитать max_value и min_value только по ключам, если и это невалидно, нужно выкинуть исключение TypeError. Для этого функционала реализуйте класс DictProperties, от которого будет наследоваться класс CustomDict.
Если же вы пытаетесь сравнить несравнимые для списка объекты (например, строки и числа), нужно выкинуть исключение TypeError.
import sys
class CommonProperties():
def __init__(self, nums):
self.nums = nums
@property
def size(self):
return str(len(self.nums))
@property
def min_value(self):
if isinstance(self, CustomList):
return min(self.nums)
else:
return DictProperties.find_min(self)
@property
def max_value(self):
if isinstance(self, CustomList):
return max(self.nums)
else:
return DictProperties.find_max(self)
class CustomList (CommonProperties):
def __str__(self):
return 'My CustomList data ' + str(self.nums)
@property
def data(self):
return str(self.nums)
@data.setter
def data(self, nums):
self.nums = nums
class DictProperties(CommonProperties):
def find_max(self):
skey, svalue = set(), set()
lkey, lvalue = [], []
for k, v in self.nums.items():
skey.add(type(k))
svalue.add(type(k))
lkey.append(k)
lvalue.append(v)
if len(skey) == 1 and len(svalue) == 1:
return max(max(lkey, lvalue))
elif len(skey) == 1:
return max(lkey)
elif len(svalue) == 1:
return max(lvalue)
else:
raise TypeError
def find_min(self):
skey, svalue = set(), set()
lkey, lvalue = [], []
for k, v in self.nums.items():
skey.add(type(k))
svalue.add(type(k))
lkey.append(k)
lvalue.append(v)
if len(skey) == 1 and len(svalue) == 1:
return min(min(lkey, lvalue))
elif len(skey) == 1:
return min(lkey)
elif len(svalue) == 1:
return min(lvalue)
else:
raise TypeError
class CustomDict(DictProperties):
def __str__(self):
return 'My CustomDict data ' + str(self.nums)
@property
def data(self):
return str(self.nums)
@data.setter
def data(self, nums):
self.nums = nums
exec(sys.stdin.read())
Еще в этом коде явно вызываю метод класса DictProperties таким образом DictProperties.find_max(self). Хотя должно быть так просто find_max(). Понимаю, что нужно наследовать какой то класс. пробовал, не получается)) Может Вы поможете?
Ответы (1 шт):
У меня получилось, что ни в классе CustomDict, ни в CustomList даже имплементировать нечего. :)
Смотрите:
- data хранится в базовом классе
CommonProperties, т.к. она есть и уCustomListи уCustomDict. find_min/find_maxтоже можно реализовать в базовом классе. Для списка их переопределять не надо, они и так работать будут. Для словаря они будут работать наполовину (искать только по ключам), так что там придётся переопределять.__repr__(формат вывода на печать) тоже можно переопределить в базовом классе, т.к. имя класса можно достать из self.- Для
CustomDictпереопределяемfind_min/find_max. Для поиска по ключам используется аналогичная функция предка (базового класса), хотя можно и напрямую min/max вызвать (но через вызов метода предка интереснее же ;). Ну и аккуратно обрабатываем exceptions (даже самому их генерировать нет надобности, функции min/max и так их генерят).
class CommonProperties():
def __init__(self, data):
self.data = data
def __repr__(self):
return f'My {self.__class__.__name__} data {self.data}'
@property
def size(self):
return len(self.data)
def find_min(self):
return min(self.data)
@property
def min_value(self):
return self.find_min()
def find_max(self):
return max(self.data)
@property
def max_value(self):
return self.find_max()
class CustomList (CommonProperties):
pass
class DictProperties(CommonProperties):
def find_max(self):
max_key = super().find_max()
try:
max_value = max(self.data.values())
return max(max_key, max_value)
except TypeError:
return max_key
def find_min(self):
min_key = super().find_min()
try:
min_value = min(self.data.values())
return min(min_key, min_value)
except TypeError:
return min_key
class CustomDict(DictProperties):
pass
l = CustomList([1,3,6,99,-18.5,-3])
print(l, f"size={l.size} min={l.min_value} max={l.max_value}")
# l.data = [7, 15, "a", True] # для того чтобы вызвать TypeError exception
# print(l, f"size={l.size} min={l.min_value} max={l.max_value}")
d = CustomDict({-3:33, 15:321})
print(d, f"size={d.size} min={d.min_value} max={d.max_value}")
d.data = {"a":2, "b":1}
print(d, f"size={d.size} min={d.min_value} max={d.max_value}")
d.data = {"a":2, 7:"z"} # для того чтобы вызвать TypeError exception
print(d, f"size={d.size} min={d.min_value} max={d.max_value}")
My CustomList data [1, 3, 6, 99, -18.5, -3] size=6 min=-18.5 max=99
My CustomDict data {-3: 33, 15: 321} size=2 min=-3 max=321
My CustomDict data {'a': 2, 'b': 1} size=2 min=a max=b
Traceback (most recent call last):
...
TypeError: '<' not supported between instances of 'int' and 'str'