Skip to content

Commit

Permalink
Added utility for pretty-printing of a truncated list.
Browse files Browse the repository at this point in the history
This is equivalent to Bioconductor's coolcat function.
  • Loading branch information
LTLA committed Oct 27, 2023
1 parent 960989e commit 8ce88b6
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/biocutils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@
from .subset import subset
from .is_list_of_type import is_list_of_type
from .normalize_subscript import normalize_subscript
from .print_truncated_list import print_truncated_list
51 changes: 51 additions & 0 deletions src/biocutils/print_truncated_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from typing import Optional, Sequence, Callable


def print_truncated_list(x: Sequence, truncated_to = 3, full_threshold = 10, transform: Optional[Callable] = None, sep: str = ", ", include_brackets: bool = True) -> str:
"""
Pretty-print a truncated list, replacing the middle elements with an
ellipsis if there are too many. This provides a useful preview of an
object without spewing out all of its contents on the screen.
Args:
x: List or some other sequence to be printed.
truncated_to:
Number of elements to truncate to, at the start and end of the
sequence. This should be less than half of ``full_threshold``.
full_threshold:
Threshold on the number of elements, below which the list is
shown in its entirety.
transform:
Optional transformation to apply to the elements of ``x``
after truncation but before printing.
sep:
Separator between elements in the printed list.
include_brackets:
Whether to include the start/end brackets.
Returns:
String containing the pretty-printed truncated list.
"""
collected = []
if transform is None:
transform = lambda y : y

if len(x) > full_threshold and len(x) > truncated_to * 2:
for i in range(truncated_to):
collected.append(repr(transform(x[i])))
collected.append("...")
for i in range(truncated_to, 0, -1):
collected.append(repr(transform(x[len(x) - i])))
else:
for c in x:
collected.append(repr(transform(c)))

output = sep.join(collected)
if include_brackets:
output = "[" + output + "]"
return output
10 changes: 10 additions & 0 deletions tests/test_print_truncated_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from biocutils import print_truncated_list


def test_print_truncated_list():
assert print_truncated_list(range(6)) == repr(list(range(6)))
assert print_truncated_list(range(10)) == repr(list(range(10)))
assert print_truncated_list(range(200)) == "[0, 1, 2, ..., 197, 198, 199]"
assert print_truncated_list(["A", "B", "C", "D", "E", "F"], transform=lambda x : "foo_" + x) == "['foo_A', 'foo_B', 'foo_C', 'foo_D', 'foo_E', 'foo_F']"
assert print_truncated_list(["A", "B", "C", "D", "E", "F"], truncated_to=2, full_threshold=5, transform=lambda x : "foo_" + x) == "['foo_A', 'foo_B', ..., 'foo_E', 'foo_F']"
assert print_truncated_list(range(200), sep=" ", include_brackets=False) == "0 1 2 ... 197 198 199"

0 comments on commit 8ce88b6

Please sign in to comment.