diff --git a/kioss/_pipe.py b/kioss/_pipe.py index 1f345e6..b74a9ca 100644 --- a/kioss/_pipe.py +++ b/kioss/_pipe.py @@ -271,9 +271,6 @@ def __init__(self, source: Callable[[], Iterator[T]]): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_source_pipe(self) - def __str__(self) -> str: - return f"Source(of type: {type(self.source)})" - class FilterPipe(APipe[T]): def __init__(self, upstream: APipe[T], predicate: Callable[[T], bool]): @@ -283,9 +280,6 @@ def __init__(self, upstream: APipe[T], predicate: Callable[[T], bool]): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_filter_pipe(self) - def __str__(self) -> str: - return f"Filter(using predicate function of type {type(self.predicate)})" - class MapPipe(APipe[R]): def __init__(self, upstream: APipe[T], func: Callable[[T], R], n_threads: int): @@ -296,9 +290,6 @@ def __init__(self, upstream: APipe[T], func: Callable[[T], R], n_threads: int): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_map_pipe(self) - def __str__(self) -> str: - return f"Map(function of type {type(self.func)}, using {self.n_threads} thread{'s' if self.n_threads > 1 else ''})" - class DoPipe(APipe[T]): def __init__(self, upstream: APipe[T], func: Callable[[T], R], n_threads: int): @@ -309,9 +300,6 @@ def __init__(self, upstream: APipe[T], func: Callable[[T], R], n_threads: int): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_do_pipe(self) - def __str__(self) -> str: - return f"Do(side effects by applying a function of type {type(self.func)}, using {self.n_threads} thread{'s' if self.n_threads > 1 else ''})" - class LogPipe(APipe[T]): def __init__(self, upstream: APipe[T], what: str = "elements"): @@ -321,9 +309,6 @@ def __init__(self, upstream: APipe[T], what: str = "elements"): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_log_pipe(self) - def __str__(self) -> str: - return f"Log('{self.what}')" - class FlattenPipe(APipe[T]): def __init__(self, upstream: APipe[Iterator[T]], n_threads: int): @@ -333,11 +318,6 @@ def __init__(self, upstream: APipe[Iterator[T]], n_threads: int): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_flatten_pipe(self) - def __str__(self) -> str: - return ( - f"Flatten(using {self.n_threads} thread{'s' if self.n_threads > 1 else ''})" - ) - class BatchPipe(APipe[List[T]]): def __init__(self, upstream: APipe[T], size: int, period: float): @@ -348,9 +328,6 @@ def __init__(self, upstream: APipe[T], size: int, period: float): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_batch_pipe(self) - def __str__(self) -> str: - return f"Batch(elements by groups of {self.size} element{'s' if self.size > 1 else ''}, or over a period of {self.period} second{'s' if self.period > 1 else ''})" - class CatchPipe(APipe[T]): def __init__( @@ -366,10 +343,6 @@ def __init__( def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_catch_pipe(self) - def __str__(self) -> str: - return f"Catch(exception instances of class in [{', '.join(map(lambda class_: class_.__name__, self.classes))}]{', with an additional `when` condition' if self.when is not None else ''})" - - class ChainPipe(APipe[T]): def __init__(self, upstream: APipe[T], others: List[APipe]): self.upstream: APipe[T] = upstream @@ -378,9 +351,6 @@ def __init__(self, upstream: APipe[T], others: List[APipe]): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_chain_pipe(self) - def __str__(self) -> str: - return f"Chain({len(self.others)+1} pipes)" # TODO itricate explains - class SlowPipe(APipe[T]): def __init__(self, upstream: APipe[T], freq: float): @@ -390,9 +360,5 @@ def __init__(self, upstream: APipe[T], freq: float): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_slow_pipe(self) - def __str__(self) -> str: - return f"Slow(at a maximum frequancy of {self.freq} element{'s' if self.freq > 1 else ''} per second)" - - # a: Iterator[str] = SourcePipe(range(8).__iter__).do(lambda e:e).map(str).do(print)._accept(ITERATOR_PRODUCING_VISITOR()) # b: Iterator[str] = SourcePipe(range(8).__iter__).do(lambda e:e).map(str).do(print)._accept(_visitor.IteratorGeneratingVisitor()) diff --git a/kioss/_visit/_explanation.py b/kioss/_visit/_explanation.py index 27e04d4..5df6cd1 100644 --- a/kioss/_visit/_explanation.py +++ b/kioss/_visit/_explanation.py @@ -12,17 +12,16 @@ def __init__(self, initial_margin: int = 0, add_header: bool = True): self.margin_step = 2 self.add_header = add_header - def additional_explain_lines(self, pipe: _pipe.APipe) -> str: - name, descr = str(pipe).split("(") + def additional_explain_lines(self, name: str, descr: str) -> str: return f"{' '*self.current_margin}{_util.colorize_in_grey('└' + '─'*(self.margin_step - 1))}•{_util.colorize_in_red(name)}({descr}\n" - def visit_any_pipe(self, pipe: _pipe.APipe) -> str: + def visit_any_pipe(self, pipe: _pipe.APipe, name: str, descr: str) -> str: if self.add_header: header = _util.bold(ExplainingVisitor.HEADER) + "\n" self.add_header = False else: header = "" - additional_explain_lines = self.additional_explain_lines(pipe) + additional_explain_lines = self.additional_explain_lines(name, descr) self.current_margin += self.margin_step if pipe.upstream is not None: upstream_repr = pipe.upstream._accept(self) @@ -31,33 +30,55 @@ def visit_any_pipe(self, pipe: _pipe.APipe) -> str: return f"{header}{additional_explain_lines}{upstream_repr}" def visit_chain_pipe(self, pipe: _pipe.ChainPipe) -> Any: - additional_explain_lines = self.additional_explain_lines(pipe) + name = "Chain" + descr = f"{len(pipe.others)+1} pipes" + additional_explain_lines = self.additional_explain_lines(name, descr) self.current_margin += self.margin_step - return f"{additional_explain_lines}{''.join(map(lambda pipe: pipe._accept(ExplainingVisitor(self.current_margin, add_header=False)), pipe.others))}{self.visit_any_pipe(pipe.upstream)}" + upstream_repr = pipe.upstream._accept(self) + chained_pipes_repr = ''.join(map(lambda pipe: pipe._accept(ExplainingVisitor(self.current_margin, add_header=False)), pipe.others)) + return f"{additional_explain_lines}{chained_pipes_repr}{upstream_repr}" def visit_source_pipe(self, pipe: _pipe.SourcePipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Source" + descr = f"of type: {type(pipe.source)}" + return self.visit_any_pipe(pipe, name, descr) def visit_map_pipe(self, pipe: _pipe.MapPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Map" + descr = f"function of type {type(pipe.func)}, using {pipe.n_threads} thread{'s' if pipe.n_threads > 1 else ''}" + return self.visit_any_pipe(pipe, name, descr) def visit_do_pipe(self, pipe: _pipe.DoPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Do" + descr = f"side effects by applying a function of type {type(pipe.func)}, using {pipe.n_threads} thread{'s' if pipe.n_threads > 1 else ''}" + return self.visit_any_pipe(pipe, name, descr) def visit_flatten_pipe(self, pipe: _pipe.FlattenPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Flatten" + descr = f"using {pipe.n_threads} thread{'s' if pipe.n_threads > 1 else ''}" + return self.visit_any_pipe(pipe, name, descr) def visit_filter_pipe(self, pipe: _pipe.FilterPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Filter" + descr = f"using predicate function of type {type(pipe.predicate)}" + return self.visit_any_pipe(pipe, name, descr) def visit_batch_pipe(self, pipe: _pipe.BatchPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Batch" + descr = f"elements by groups of {pipe.size} element{'s' if pipe.size > 1 else ''}, or over a period of {pipe.period} second{'s' if pipe.period > 1 else ''}" + return self.visit_any_pipe(pipe, name, descr) def visit_slow_pipe(self, pipe: _pipe.SlowPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Slow" + descr = f"at a maximum frequancy of {pipe.freq} element{'s' if pipe.freq > 1 else ''} per second" + return self.visit_any_pipe(pipe, name, descr) def visit_catch_pipe(self, pipe: _pipe.CatchPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Catch" + descr = f"exception instances of class in [{', '.join(map(lambda class_: class_.__name__, pipe.classes))}]{', with an additional `when` condition' if pipe.when is not None else ''}" + return self.visit_any_pipe(pipe, name, descr) def visit_log_pipe(self, pipe: _pipe.LogPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Log" + descr = f"the evolution of the ieration over {pipe.what}" + return self.visit_any_pipe(pipe, name, descr)