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 шт):

Автор решения: GrAnd

У меня получилось, что ни в классе 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'
→ Ссылка