#!/usr/bin/env python3 from typing import Sequence, Optional __author__ = "David Blume" __copyright__ = "Copyright 2016-2023, David Blume" __license__ = "MIT" __version__ = "1.0" __status__ = "Development" def print_table(rows: Sequence[Sequence[str]], underline_header: str='-', col_delimiter: str="\t", header_delimiter: Optional[str]=None, outside_delimiters: bool=False): """Prints rows with consistent column widths.""" cols = zip(*rows) # Compute column widths by taking maximum length of values per column col_widths = [max(len(value) for value in col) for col in cols] # Create a suitable format string for nice table output fmt = col_delimiter.join(["{:<%d}" % i for i in col_widths]) if outside_delimiters: fmt = f"{col_delimiter.lstrip()}{fmt}{col_delimiter.rstrip()}" # Print each row using the computed format if header_delimiter is not None: width_diff = len(header_delimiter) - len(col_delimiter) header_fmt = header_delimiter.join(["{:<%d}" % (i - width_diff) for i in col_widths]) if outside_delimiters: header_fmt = f"{header_delimiter.lstrip()}{header_fmt}{header_delimiter.rstrip()}" else: header_fmt = fmt print(header_fmt.format(*rows[0])) if underline_header: if outside_delimiters: print(col_delimiter.lstrip() + col_delimiter.join([(underline_header * i) for i in col_widths]) + col_delimiter.rstrip()) else: print(col_delimiter.join([(underline_header * i) for i in col_widths])) for row in rows[1:]: print(fmt.format(*row)) if __name__ == '__main__': t = (("Header 1", "Header 2", "Header 3"), ("Row one", "Row one, longer cell", "R1.3"), ("Row two, long cell", "Row two", "R2.3")) print_table(t, None) print() print_table(t) print() print_table(t, col_delimiter=" | ", outside_delimiters=True) print() print_table(t, None, col_delimiter=" | ", header_delimiter=" || ", outside_delimiters=True)