Problem 267017 · hard · Level 02 Linear Data Structures

A Report Table with a Mean Row

py-join · py-zip · py-builtins · formatting

Write report(header, rows) that returns a plain-text table of the data, ready to print. header is a list of column names; each row in rows holds one value per column, a string, an integer or a float.

Cells. An integer is written with str, a float with exactly two decimals (3.5 becomes 3.50), and a string as it is.

Numeric columns. A column is numeric when there is at least one row and every value in it is an integer or a float. The first column always holds strings.

Mean row. When there is at least one row and at least one numeric column, a last line is added: its first cell is mean, each numeric column shows the mean of its values with two decimals, and the other cells are empty.

Layout.

  • Each column is as wide as its longest cell, counting the header and the mean row.
  • Cells in numeric columns (including their header) are padded on the left, so they line up on the right; all other cells are padded on the right.
  • Cells are separated by " | ". The second line is a rule: for each column, as many - as its width, joined by "-+-".
  • No line ends with a space, and lines are separated by "\n" with none after the last.

Examples

Input:  header = ["name", "runs", "avg"]
        rows   = [["ana", 12, 3.5], ["benedict", 7, 12.25], ["cy", 105, 0.0]]
Output (printed):
name     |  runs |   avg
---------+-------+------
ana      |    12 |  3.50
benedict |     7 | 12.25
cy       |   105 |  0.00
mean     | 41.33 |  5.25

Input:  header = ["city", "country"], rows = [["Oslo", "NO"], ["Lima", "PE"]]
Output (printed):
city | country
-----+--------
Oslo | NO
Lima | PE

Input:  header = ["item", "qty"], rows = []
Output: "item | qty\n-----+----"

In the first example the name column is 8 wide (for benedict) and the runs column 5 wide (for the mean 41.33). The second table has no numeric column, so it has no mean row.

Constraints

  • 1 <= len(header) <= 20, 0 <= len(rows) <= 5000; every row has len(header) values.
  • Strings contain no newlines; numbers are between -10**9 and 10**9.

Goals

  • Compute column widths with `max` over the columns from `zip(*rows)`
  • Align text left and numbers right with `ljust`, `rjust` and format specifications
  • Assemble the whole report from lists of pieces joined once, without `+=`
Starting Python…