Source code for biocgenerics.show_as_cell
from functools import singledispatch
from typing import Any, List, Optional, Sequence
__author__ = "Aaron Lun"
__copyright__ = "LTLA"
__license__ = "MIT"
[docs]
@singledispatch
def show_as_cell(x: Any, indices: Sequence[int]) -> List[str]:
"""Show the contents of ``x`` as a cell of a table, typically for use in the ``__str__`` method of a class that
contains ``x``.
Args:
x:
Any object. By default, we assume that it can be treated as
a sequence, with a valid ``__getitem__`` method for an index.
indices:
List of indices to be extracted.
Returns:
List of strings of length equal to ``indices``, containing a
string summary of each of the specified elements of ``x``.
"""
output = []
for i in indices:
output.append(str(x[i]))
return output
def _get_max_width(col: List[str]):
width = 0
for y in col:
if len(y) > width:
width = len(y)
return width
[docs]
def format_table(
columns: List[Sequence[str]],
floating_names: Optional[Sequence[str]] = None,
sep: str = " ",
window: Optional[int] = None,
) -> str:
"""Pretty-print a table with wrapping columns.
Args:
columns: List of list of strings, where each inner list is the same length.
Strings are typically generated by :py:meth:`~show_as_cell`.
floating_names: List of strings to be added to the left of the table. This is
printed repeatedly for each set of wrapped columns.
sep: Separator between columns.
window: Size of the terminal window, in characters. We attempt to determine
this automatically, otherwise it is set to 150.
Returns:
str: String containing the pretty-printed table.
"""
if window is None:
import os
try:
window = os.get_terminal_size().columns
except Exception as _:
window = 150
if len(columns) == 0:
raise ValueError("At least one column should be supplied in 'columns'.")
n = len(columns[0])
floatwidth = 0
if floating_names is not None:
floatwidth = _get_max_width(floating_names)
new_floating_names = []
for y in floating_names:
new_floating_names.append(y.rjust(floatwidth))
floating_names = new_floating_names
output = ""
def reinitialize():
if floating_names is None:
return [""] * n
else:
return floating_names[:]
contents = reinitialize()
init = True
used = floatwidth
for col in columns:
width = _get_max_width(col)
if not init and used + width + len(sep) > window:
for line in contents:
output += line + "\n"
contents = reinitialize()
init = True
used = floatwidth
for i, y in enumerate(col):
if used > 0:
contents[i] += sep
contents[i] += y.rjust(width)
used += width + len(sep)
init = False
output += "\n".join(contents)
return output