Skip to content

Commit 02b5787

Browse files
authored
fix #608 : display also non-LArray objects in Session.summary
1 parent e04d78a commit 02b5787

File tree

3 files changed

+126
-32
lines changed

3 files changed

+126
-32
lines changed

doc/source/changes/version_0_29.rst.inc

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,52 @@ Miscellaneous improvements
4848

4949
* added examples for `read_excel` and `read_hdf` functions (closes :issue:`617`).
5050

51+
* updated `Session.summary` so as to display all kinds of objects and allowed to pass a function
52+
returning a string representation of an object instead of passing a pre-defined string template
53+
(closes :issue:`608`):
54+
55+
>>> axis1 = Axis("a=a0..a2")
56+
>>> group1 = axis1['a0,a1'] >> 'a01'
57+
>>> arr1 = ndtest((2, 2), title='array 1', dtype=np.int64)
58+
>>> arr2 = ndtest(4, title='array 2', dtype=np.int64)
59+
>>> arr3 = ndtest((3, 2), title='array 3', dtype=np.int64)
60+
>>> s = Session([('axis1', axis1), ('group1', group1), ('arr1', arr1), ('arr2', arr2), ('arr3', arr3)])
61+
62+
Default template
63+
64+
>>> print(s.summary())
65+
axis1: a ['a0' 'a1' 'a2'] (3)
66+
group1: a['a0', 'a1'] >> a01 (2)
67+
arr1: a, b (2 x 2) [int64]
68+
array 1
69+
arr2: a (4) [int64]
70+
array 2
71+
arr3: a, b (3 x 2) [int64]
72+
array 3
73+
74+
Using a specific template
75+
76+
>>> def print_array(key, array):
77+
... axes_names = ', '.join(array.axes.display_names)
78+
... shape = ' x '.join(str(i) for i in array.shape)
79+
... return "{} -> {} ({})\\n title = {}\\n dtype = {}".format(key, axes_names, shape,
80+
... array.title, array.dtype)
81+
>>> template = {Axis: "{key} -> {name} [{labels}] ({length})",
82+
... Group: "{key} -> {name}: {axis_name} {labels} ({length})",
83+
... LArray: print_array}
84+
>>> print(s.summary(template))
85+
axis1 -> a ['a0' 'a1' 'a2'] (3)
86+
group1 -> a01: a ['a0', 'a1'] (2)
87+
arr1 -> a, b (2 x 2)
88+
title = array 1
89+
dtype = int64
90+
arr2 -> a (4)
91+
title = array 2
92+
dtype = int64
93+
arr3 -> a, b (3 x 2)
94+
title = array 3
95+
dtype = int64
96+
5197
5298
Fixes
5399
-----

larray/core/session.py

Lines changed: 80 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from larray.core.group import Group
1212
from larray.core.axis import Axis
1313
from larray.core.array import LArray, get_axes, ndtest, zeros, zeros_like, sequence, aslarray
14-
from larray.util.misc import float_error_handler_factory, is_interactive_interpreter, renamed_to, inverseop
14+
from larray.util.misc import float_error_handler_factory, is_interactive_interpreter, renamed_to, inverseop, basestring
1515
from larray.inout.session import ext_default_engine, get_file_handler
1616

1717

@@ -929,7 +929,7 @@ def transpose(self, *args):
929929
>>> arr2 = ndtest((2, 2))
930930
>>> sess = Session([('arr1', arr1), ('arr2', arr2)])
931931
>>> def print_summary(s):
932-
... print(s.summary("{name} -> {axes_names}"))
932+
... print(s.summary({LArray: "{key} -> {axes_names}"}))
933933
>>> print_summary(sess)
934934
arr1 -> a, b, c
935935
arr2 -> a, b
@@ -1057,44 +1057,100 @@ def apply(self, func, *args, **kwargs):
10571057

10581058
def summary(self, template=None):
10591059
"""
1060-
Returns a summary of the content of the session (arrays only).
1060+
Returns a summary of the content of the session.
10611061
10621062
Parameters
10631063
----------
1064-
template: str
1065-
Template describing how items are summarized (see examples).
1066-
Available arguments are 'name', 'axes_names' and 'title'
1064+
template: dict {object type: str} or dict {object type: func}
1065+
Template describing how items are summarized.
1066+
For each object type, it is possible to provide either a string template or a function taking the
1067+
the key and value of a session item as parameters and returning a string (see examples).
1068+
A string template contains specific arguments written inside brackets {}.
1069+
Available arguments are:
1070+
1071+
- for groups: 'key', 'name', 'axis_name', 'labels' and 'length',
1072+
- for axes: 'key', 'name', 'labels' and 'length',
1073+
- for arrays: 'key', 'axes_names', 'shape', 'dtype' and 'title',
1074+
- for all other types: 'key', 'value'.
10671075
10681076
Returns
10691077
-------
10701078
str
1071-
Short representation of the content of the session (arrays only).
1079+
Short representation of the content of the session.
10721080
.
10731081
Examples
10741082
--------
1075-
>>> arr1 = ndtest((2, 2), title='array 1')
1076-
>>> arr2 = ndtest(4, title='array 2')
1077-
>>> arr3 = ndtest((3, 2), title='array 3')
1078-
>>> s = Session([('arr1', arr1), ('arr2', arr2), ('arr3', arr3)])
1083+
>>> axis1 = Axis("a=a0..a2")
1084+
>>> group1 = axis1['a0,a1'] >> 'a01'
1085+
>>> arr1 = ndtest((2, 2), title='array 1', dtype=np.int64)
1086+
>>> arr2 = ndtest(4, title='array 2', dtype=np.int64)
1087+
>>> arr3 = ndtest((3, 2), title='array 3', dtype=np.int64)
1088+
>>> s = Session([('axis1', axis1), ('group1', group1), ('arr1', arr1), ('arr2', arr2), ('arr3', arr3)])
1089+
1090+
Default template
1091+
10791092
>>> print(s.summary()) # doctest: +NORMALIZE_WHITESPACE
1080-
arr1: a, b
1093+
axis1: a ['a0' 'a1' 'a2'] (3)
1094+
group1: a['a0', 'a1'] >> a01 (2)
1095+
arr1: a, b (2 x 2) [int64]
10811096
array 1
1082-
arr2: a
1097+
arr2: a (4) [int64]
10831098
array 2
1084-
arr3: a, b
1099+
arr3: a, b (3 x 2) [int64]
10851100
array 3
1086-
>>> print(s.summary("{name} -> {axes_names}"))
1087-
arr1 -> a, b
1088-
arr2 -> a
1089-
arr3 -> a, b
1101+
1102+
Using a specific template
1103+
1104+
>>> def print_array(key, array):
1105+
... axes_names = ', '.join(array.axes.display_names)
1106+
... shape = ' x '.join(str(i) for i in array.shape)
1107+
... return "{} -> {} ({})\\n title = {}\\n dtype = {}".format(key, axes_names, shape,
1108+
... array.title, array.dtype)
1109+
>>> template = {Axis: "{key} -> {name} [{labels}] ({length})",
1110+
... Group: "{key} -> {name}: {axis_name}{labels} ({length})",
1111+
... LArray: print_array}
1112+
>>> print(s.summary(template))
1113+
axis1 -> a ['a0' 'a1' 'a2'] (3)
1114+
group1 -> a01: a['a0', 'a1'] (2)
1115+
arr1 -> a, b (2 x 2)
1116+
title = array 1
1117+
dtype = int64
1118+
arr2 -> a (4)
1119+
title = array 2
1120+
dtype = int64
1121+
arr3 -> a, b (3 x 2)
1122+
title = array 3
1123+
dtype = int64
10901124
"""
10911125
if template is None:
1092-
template = "{name}: {axes_names}\n {title}\n"
1093-
templ_kwargs = [{'name': k,
1094-
'axes_names': ', '.join(v.axes.display_names),
1095-
'title': v.title}
1096-
for k, v in self.items() if isinstance(v, LArray)]
1097-
return '\n'.join(template.format(**kwargs) for kwargs in templ_kwargs)
1126+
template = {}
1127+
if Axis not in template:
1128+
template[Axis] = "{key}: {name} [{labels}] ({length})"
1129+
if Group not in template:
1130+
template[Group] = "{key}: {axis_name}{labels} >> {name} ({length})"
1131+
if LArray not in template:
1132+
template[LArray] = "{key}: {axes_names} ({shape}) [{dtype}]\n {title}"
1133+
1134+
def display(k, v):
1135+
t = Group if isinstance(v, Group) else type(v)
1136+
tmpl = template.get(t, "{key}: {value}")
1137+
if not (isinstance(tmpl, basestring) or callable(tmpl)):
1138+
raise TypeError("Expected a string template or a function for type {}. "
1139+
"Got {}".format(type(v), type(tmpl)))
1140+
if isinstance(tmpl, basestring):
1141+
if isinstance(v, Axis):
1142+
return tmpl.format(key=k, name=v.name, labels=v.labels_summary(), length=len(v))
1143+
elif isinstance(v, Group):
1144+
return tmpl.format(key=k, name=v.name, axis_name=v.axis.name, labels=v.key, length=len(v))
1145+
elif isinstance(v, LArray):
1146+
return tmpl.format(key=k, axes_names=', '.join(v.axes.display_names),
1147+
shape=' x '.join(str(i) for i in v.shape), title=v.title, dtype=v.dtype)
1148+
else:
1149+
return tmpl.format(key=k, value=str(v))
1150+
else:
1151+
return tmpl(k, v)
1152+
1153+
return '\n'.join(display(k, v) for k, v in self.items())
10981154

10991155

11001156
def _exclude_private_vars(vars_dict):

larray/tests/test_session.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -459,14 +459,6 @@ def test_rdiv(self):
459459
assert_array_nan_equal(res['e'], self.e / self.e)
460460
assert_array_nan_equal(res['f'], self.f / self.f)
461461

462-
def test_summary(self):
463-
# only arrays
464-
sess = self.session.filter(kind=LArray)
465-
assert sess.summary() == "e: a0*, a1*\n \n\ng: a0*, a1*\n \n\nf: a0*, a1*\n \n"
466-
# all objects
467-
sess = self.session
468-
assert sess.summary() == "e: a0*, a1*\n \n\ng: a0*, a1*\n \n\nf: a0*, a1*\n \n"
469-
470462
def test_pickle_roundtrip(self):
471463
original = self.session.filter(kind=LArray)
472464
s = pickle.dumps(original)

0 commit comments

Comments
 (0)