Source code for pyphi.display.numbers

"""Display-time formatting of numeric values."""

from numbers import Integral
from numbers import Real

SIG_FIGS = 6


[docs] def format_value(value, sig_figs: int = SIG_FIGS) -> str: """Format a value for display. Real (non-integer) numbers are rounded to ``sig_figs`` significant figures and always keep a decimal point (so continuous quantities read consistently). Integers — counts, indices — render without one. Everything else is rendered with ``str``. The exact numeric value remains available on the source object's attribute. """ if isinstance(value, bool): return str(value) if isinstance(value, Integral): return str(int(value)) if isinstance(value, Real): formatted = f"{float(value):.{sig_figs}g}" # Keep a decimal point on whole-valued floats (3.0 -> "3.0"); leave # exponential/inf/nan untouched. if not any(c in formatted for c in ".en"): formatted += ".0" return formatted return str(value)
[docs] def format_column(values, sig_figs: int = SIG_FIGS) -> list[str]: """Format one table column, aligning numbers on the decimal point. If every value is a real number, each formatted string is padded with spaces so that the decimal points (or the ends of integers) share a character position and all strings have equal length; in a monospace font the column then reads as decimal-aligned under any text alignment. A column containing any non-numeric value is formatted cell by cell, unpadded. """ strings = [format_value(v, sig_figs) for v in values] if not all(isinstance(v, Real) and not isinstance(v, bool) for v in values): return strings parts = [s.partition(".") for s in strings] int_w = max((len(whole) for whole, _, _ in parts), default=0) frac_w = max((len(dot + frac) for _, dot, frac in parts), default=0) return [ whole.rjust(int_w) + (dot + frac).ljust(frac_w) for whole, dot, frac in parts ]