Входной файл: | Стандартный вход | Ограничение времени: | 1 сек | |
Выходной файл: | Стандартный выход | Ограничение памяти: | 512 Мб | |
Максимальный балл: | 1 |
Требуется реализовать на языке Python класс Pipeline
. У класса должен быть следующий интерфейс:
from __future__ import annotations
from typing import Any
from collections.abc import Callable, Generator, Iterable, Iterator
class Pipeline:
def __init__(self,
*data: Iterable,
func: Callable[[Any, ...], Any] | None = None,
name: str | None = None):
"""Iterates over `data` applying `func` if available.
Arguments:
data: iterables to iterate over
func: callable to apply to iterables, elements of iterables are passed as positional arguments
name: name of the operation
"""
raise NotImplementedError()
@property
def name(self) -> str | None:
"""Obtains name of the operation."""
raise NotImplementedError()
def walk(self) -> Generator[Pipeline]:
"""Iterates over iterables tree depth first in the order passed during initialization returning Pipeline objects"""
raise NotImplementedError()
def __or__(self, func: Callable[[Any], Any] | tuple[Callable[[Any], Any], str]) -> Pipeline:
"""Creates a new Pipeline applying `func` to elements of `self`"""
raise NotImplementedError()
def __matmul__(self, func: Callable[[Any, ...], Any] | tuple[Callable[[Any, ...], Any], str]) -> Pipeline:
"""Creates a new Pipeline applying `func` to unpacked elements of `self`"""
raise NotImplementedError()
def __add__(self, other: Iterable) -> Pipeline:
"""Creates a new copy of `self` adding `other` to the list of iterables"""
raise NotImplementedError()
Класс должен удовлетворять Iterable
. При итерации по Pipleine
возвращаются объекты типа tuple
{ai}n − 1i = 0, где ai текущий элемент datai. При n = 1 возвращается единственный элемент a0. Если func is not None
, элементами Pipeline
являются результаты применения функции: func(a_0, a_1, ..., a_{n-1})
.
Свойство name
возвращает имя Pipeline
. Если имя не было указано при инициализации используется имя func
. Если и func
было опущено, возвращается None
.
Результатом вызова метода walk
является генератор, возвращающий элементы дерева, являющиеся объектами класса Pipeline
при обходе в глубину в порядке, указанном в data
.
Класс должен определять следующие операции
Pipeline | Callable
— создаёт новый объект типа Pipeline
, применяя Callable
к элементам исходного Pipeline
.Pipeline | (Callable, str)
— аналогично предыдущему, но передавая str
в качестве имени.Pipeline @ Callable
— создаёт новый объект типа Pipeline
, применяя Callable
к распакованным элементам исходного Pipeline
.Pipeline @ (Callable, str)
— аналогично предыдущему, но передавая str
в качестве имени.Pipeline + Iterable
— создаёт новый объект типа Pipeline
, добавляя Iterable
к data
.
Класс должен переопределять операцию repr
. Результатом должна являться строка, представляющая собой создание объекта Pipeline
, при этом вместо функции указывается её имя без кавычек, а аргументы, имеющие значение None
не указываются.
Код решения должен содержать только импортируемые модули, определение и реализацию класса.
№ | Стандартный вход | Стандартный выход |
---|---|---|
1 | a = Pipeline([1, 2, 3, 4, 5], name='data1')
b = Pipeline([5, 4, 3, 2, 1], a)
print(a)
print(b)
print(*zip(a, b))
|
|
2 | def square(x: int):
return x * x
a = Pipeline([1, 2, 3], func=square)
a = Pipeline(a, [3, 2, 1], name='zip')
a |= (lambda x: x[0] + x[1], 'sum')
print(a)
print(*a)
|
|
3 | a = Pipeline([1, 2, 3], [3, 2, 1], name='zip') @ (lambda x, y: x + y, 'sum')
print(a)
print(*a)
|
|
4 | a = Pipeline([1, 2, 3], name='data1')
a |= (lambda x: x * x, 'square')
b = Pipeline([3, 2, 1], name='data2')
b |= (lambda x: 2 * x, 'times_two')
c = Pipeline(a, b, name='zip') @ (lambda x, y: x + y, 'sum')
print(*c)
print(' -> '.join(i.name for i in c.walk()))
|
|
5 | a = Pipeline(name='data') + [1, 2, 3] + [4, 5, 6]
print(a)
print(*a)
|
|