Олимпиадный тренинг

Задача . Свой мир. 08. Сундук


Задача

Темы:

Два сундука у портала надо свести в один. Хочется обращаться с сундуком как со списком: узнать, сколько занято слотов, взять предмет по номеру, проверить, есть ли внутри алмаз. Но сундук — не список, а объект.

Сложение возвращает новый сундук, исходные остаются нетронутыми. Проверка in идёт по названию предмета, а не по объекту.

Структура программы

Отправляется целая программа. Ниже — то, что в ней должно быть объявлено: имена классов, их родители и сигнатуры методов. Имена менять нельзя, проверки обращаются именно к ним.

# дано: классы из главы 6
class Item:
    def __init__(self, name, amount):
        self.name = name
        self.amount = amount

    def __str__(self):
        return f"{self.name} x{self.amount}"


class ToolItem(Item):
    def __init__(self, name, durability):
        super().__init__(name, 1)
        self.durability = durability

    def __str__(self):
        return f"{self.name} ({self.durability}%)"


class Chest:
    def __init__(self, slots=()):
        self.slots = list(slots)

    # TODO: __len__      -> сколько занято слотов
    # TODO: __getitem__  -> предмет по номеру
    # TODO: __contains__ -> есть ли предмет с таким названием
    # TODO: __add__      -> новый сундук из двух
    # TODO: __str__      -> "Сундук: Алмаз, Кирка"

Как проверяется

Проверяющая программа дописывает к твоему коду блок проверок и выполняет всё вместе. Задача засчитывается, если ни одна проверка не сработала и программа ничего не напечатала — отладочную печать перед отправкой убери.

Примеры проверок

#!requires Item: __str__
#!requires ToolItem: __str__
#!requires Chest: __len__, __getitem__, __contains__, __add__, __str__

# подготовка
left = Chest([Item("Алмаз", 3)])
right = Chest([ToolItem("Кирка", 87)])
both = left + right

# проверка
assert isinstance(both, Chest)
#!requires Item: __str__
#!requires ToolItem: __str__
#!requires Chest: __len__, __getitem__, __contains__, __add__, __str__

# подготовка
left = Chest([Item("Алмаз", 3)])
right = Chest([ToolItem("Кирка", 87)])
both = left + right

# проверка
assert len(both) == 2

Строки #!requires — служебные: по ним система убеждается, что классы и методы действительно объявлены, а не подставлены обходным путём.

Вопрос: цикл for slot in both работает, хотя __iter__ мы не писали. Какой метод его вытянул?

---


Примеры
№Входные данныеВыходные данные
1
#!requires Item: __str__
#!requires ToolItem: __str__
#!requires Chest: __len__, __getitem__, __contains__, __add__, __str__

# подготовка
left = Chest([Item("Алмаз", 3)])
right = Chest([ToolItem("Кирка", 87)])
both = left + right

# проверка
assert isinstance(both, Chest)

                         
2
#!requires Item: __str__
#!requires ToolItem: __str__
#!requires Chest: __len__, __getitem__, __contains__, __add__, __str__

# подготовка
left = Chest([Item("Алмаз", 3)])
right = Chest([ToolItem("Кирка", 87)])
both = left + right

# проверка
assert len(both) == 2

                         
Статистика успешных решений по компиляторам
Комментарий учителя