from __builtin__ import print as _builtin_print
from functools import partial
+from itertools import islice
+from type_helpers import isstr
+
+
+def shortened(iterable, n_head=20, n_tail=20, n_elems=None,
+ skip_elem="...(skipping {n_skipped} elements)..."):
+ """ convenient way to shorten a possibly very long iterable before printing
+
+ Will not modify short iterables, but for longer lists/tuples/... will only
+ yield first few, then a message how many were skipped and the last few
+
+ The iterable does not even have to have a `len(..)` method if argument
+ `n_elems` is given. Only needs a `next(..)` method. However, for very long
+ iterables this will be faster if radnom element access is provided via []
+
+ :param iterable: an iterable
+ :param int n_head: number of starting elements to yield (optional)
+ :param int n_tail: number of ending elements to yield (optional)
+ :param int n_elems: number of elements in iterable; give this to avoid a
+ call to `len(iterable)` (optional)
+ :param skip_elem: element to replace bulge of skipped elements; yielded
+ once at most; None to not yield a skip replacement; if str
+ then it will be formatted; optional, defaults to string
+ with number of skipped elems
+
+ ..seealso: :py:func:`slice`, py:func:`itertools.islice`
+ """
+
+ if n_elems is None:
+ n_elems = len(iterable)
+
+ # yield first n_head elems
+ index = 0
+ for elem in iterable:
+ index += 1
+ if index > n_head:
+ break
+ yield elem
+
+ # yield skip element
+ if n_elems > n_head + n_tail:
+ if skip_elem is not None:
+ if (isstr(skip_elem)):
+ yield skip_elem.format(n_skipped=n_elems-n_head-n_tail)
+ else:
+ yield skip_elem
+ elif n_elems <= n_head:
+ raise StopIteration()
+
+ # yield end
+ try:
+ # try to access end directly
+ for elem in iterable[n_elems-n_tail:]:
+ yield elem
+ except TypeError:
+ # if this did not work, then need to iterate through whole thing
+ # do this as in itertool recipe for consume():
+ n_skip = n_elems - n_head - n_tail - 1
+ next(islice(iterable, n_skip, n_skip), None)
+ for elem in iterable:
+ yield elem
+
+
+###############################################################################
+# TEXT FORMATTING/COLORING
+###############################################################################
COLOR_BLACK = 'black'
COLOR_RED = 'red'