Skip to content

Commit

Permalink
ENH: Improve short reprs (#2206)
Browse files Browse the repository at this point in the history
Improves the graphical representation of various filters, expressions, and other operations in the pipeline graph.
  • Loading branch information
jnazaren committed Jun 19, 2018
1 parent bcc31fa commit 40ba0ea
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 19 deletions.
4 changes: 2 additions & 2 deletions tests/pipeline/test_factor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1325,11 +1325,11 @@ class SomeDataSet(DataSet):

self.assertEqual(
SomeDataSet.a.latest.short_repr(),
"SomeDataSet.a.latest"
"Latest"
)
self.assertEqual(
SomeDataSet.b.latest.short_repr(),
"SomeDataSet.b.latest"
"Latest"
)


Expand Down
4 changes: 3 additions & 1 deletion tests/pipeline/test_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -1124,4 +1124,6 @@ def test_maximum_repr(self):
)

short_rep = m.short_repr()
assert_equal(short_rep, "Maximum()")
assert_equal(short_rep, "Maximum:\l "
"groupby: SomeClassifier\l "
"mask: SomeFilter\l")
5 changes: 4 additions & 1 deletion zipline/pipeline/data/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,10 @@ def __repr__(self):

def short_repr(self):
"""Short repr to use when rendering Pipeline graphs."""
return self.qualname
return "BoundColumn:\l Dataset: {}\l Column: {}\l".format(
self.dataset.__name__,
self.name
)


@total_ordering
Expand Down
15 changes: 9 additions & 6 deletions zipline/pipeline/expression.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""
NumericalExpression term.
"""
from itertools import chain
import re
from itertools import chain
from numbers import Number

import numexpr
Expand All @@ -11,11 +11,9 @@
full,
inf,
)

from zipline.pipeline.term import Term, ComputableTerm
from zipline.utils.numpy_utils import bool_dtype


_VARIABLE_NAME_RE = re.compile("^(x_)([0-9]+)$")

# Map from op symbol to equivalent Python magic method name.
Expand Down Expand Up @@ -328,7 +326,12 @@ def __repr__(self):

def short_repr(self):
"""Short repr to use when rendering Pipeline graphs."""
return "Expression: {expr}".format(
typename=type(self).__name__,
expr=self._expr,

# Replace any floating point numbers in the expression
# with their scientific notation
final = re.sub(r"[-+]?\d*\.\d+",
lambda x: format(float(x.group(0)), '.2E'),
self._expr)
return "Expression:\l {}\l".format(
final,
)
6 changes: 6 additions & 0 deletions zipline/pipeline/factors/factor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1411,6 +1411,12 @@ def __repr__(self):
mask=self.mask,
)

def short_repr(self):
return "Rank:\l method: {!r}\l mask: {}\l".format(
self._method,
type(self.mask).__name__,
)


class CustomFactor(PositiveWindowLengthMixin, CustomTermMixin, Factor):
'''
Expand Down
22 changes: 21 additions & 1 deletion zipline/pipeline/filters/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,13 @@ def _compute(self, arrays, dates, assets, mask):
)
return (lower_bounds <= data) & (data <= upper_bounds)

def short_repr(self):
return "{}:\l min: {}, max: {}\l".format(
type(self).__name__,
self._min_percentile,
self._max_percentile,
)


class CustomFilter(PositiveWindowLengthMixin, CustomTermMixin, Filter):
"""
Expand Down Expand Up @@ -481,6 +488,13 @@ def _compute(self, arrays, dates, assets, mask):
data = arrays[0]
return params['op'](data, *params['opargs']) & mask

def short_repr(self):
return "{}:\l op: {}.{}()".format(
type(self).__name__,
self.params['op'].__module__,
self.params['op'].__name__,
)


class Latest(LatestMixin, CustomFilter):
"""
Expand Down Expand Up @@ -520,6 +534,9 @@ def _compute(self, arrays, dates, assets, mask):
)
return out

def short_repr(self):
return "SingleAsset:\l asset: {!r}\l".format(self._asset)


class StaticSids(Filter):
"""
Expand Down Expand Up @@ -624,4 +641,7 @@ def __repr__(self):
)

def short_repr(self):
return "Maximum()"
return "Maximum:\l groupby: {}\l mask: {}\l".format(
type(self.inputs[1]).__name__,
type(self.mask).__name__,
)
5 changes: 3 additions & 2 deletions zipline/pipeline/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ def _compute(self, windows, dates, assets, mask):

def short_repr(self):
"""Short repr to use when rendering Pipeline graphs."""
return type(self).__name__ + '(%d)' % self.window_length
return type(self).__name__ + ':\l window_length: %d\l' % \
self.window_length


class LatestMixin(SingleInputMixin):
Expand All @@ -242,7 +243,7 @@ def _validate(self):
)

def short_repr(self):
return "{}.latest".format(self.inputs[0].short_repr())
return "Latest"


class AliasedMixin(SingleInputMixin):
Expand Down
16 changes: 10 additions & 6 deletions zipline/pipeline/term.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,8 @@ def dependencies(self):
raise NotImplementedError('dependencies')

def short_repr(self):
# Default short_repr is just the full repr.
return repr(self)
# Default short_repr is just the name of the type.
return type(self).__name__


class AssetExists(Term):
Expand Down Expand Up @@ -380,6 +380,8 @@ class AssetExists(Term):
def __repr__(self):
return "AssetExists()"

short_repr = __repr__

def _compute(self, today, assets, out):
raise NotImplementedError(
"AssetExists cannot be computed directly."
Expand All @@ -406,6 +408,8 @@ class InputDates(Term):
def __repr__(self):
return "InputDates()"

short_repr = __repr__

def _compute(self, today, assets, out):
raise NotImplementedError(
"InputDates cannot be computed directly."
Expand Down Expand Up @@ -672,10 +676,10 @@ def alias(self, name):

def __repr__(self):
return (
"{type}({inputs}, window_length={window_length})"
"{type}([{inputs}], {window_length})"
).format(
type=type(self).__name__,
inputs=self.inputs,
inputs=', '.join(i.name for i in self.inputs),
window_length=self.window_length,
)

Expand Down Expand Up @@ -710,9 +714,9 @@ def __new__(cls, term, asset):
)

def __repr__(self):
return "{type}({parent_term}, column={asset})".format(
return "{parent_term}[{asset}])".format(
type=type(self).__name__,
parent_term=type(self.inputs[0]).__name__,
parent_term=self.inputs[0].__name__,
asset=self._asset,
)

Expand Down

0 comments on commit 40ba0ea

Please sign in to comment.