docs: def table_to_string(headers, table, align="", *, lines=("-", "-+-", " | ")):
    """Write a list of headers and a table of rows to the terminal in a nice format.
  
    Parameters:
    - headers: a list of strings that are the headers of the table
    - table: a list of lists, the actual data to be printed.
    - align: a string whose elements are in the set {'<', '^', '>'}. These define how the values
             printed in the cells will align. '<': left, '^': center, '>': right. This argument is
             optional and all unspecified columns will align as if '<' were passed for them.
    - lines: a tuple of line characters to print for the table: (row_sep, row_intersection, col_sep)
    """
    header_separator, header_junction, row_separator = lines
    align = ("{0:<<" + str(len(headers)) + "}").format(align or "")
    all_lens = [tuple(len(c) for c in r) for r in table]
  
    if headers:
      all_lens.append(tuple(len(h) for h in headers))
  
    max_lens = [max(r[i] for r in all_lens) for i in range(len(headers))]
    col_outs = ["{{{0}: {1}{2}}}".format(i, align[i], w) for i, w in enumerate(max_lens)]
    fmt_str = row_separator.join(col_outs)
    if headers:
      yield fmt_str.format(*headers)
      yield header_junction.join((header_separator * ml for ml in max_lens))
    for row in table:
      yield fmt_str.format(*row)