Tables

A Table holds data in columns, and renders it as text or HTML.

Creating a table

Pass a dictionary that maps each column name to a list of values. All the columns must have the same length:

from tinytab import Table

menu = Table(
    {
        "item": ["coffee", "bagel", "croissant"],
        "price": [3.5, 2.25, 4.0],
        "sold": [120, 45, None],
    }
)

menu.columns, menu.n_rows
(['item', 'price', 'sold'], 3)

In a notebook, or on a page like this one, a table displays as HTML. Missing values (None) show as empty cells:

menu
itempricesold
coffee3.5120
bagel2.2545
croissant4.0

Formatting columns

Table.fmt() attaches a formatting function to a column. Any function that takes a value and returns a string works, including tinytab’s own formatters:

from tinytab import fmt_currency

menu.fmt("price", fmt_currency)
itempricesold
coffee$3.50120
bagel$2.2545
croissant$4.00

fmt() returns a new table and leaves the original unchanged, so calls can be chained, one per column:

from tinytab import fmt_number

menu.fmt("price", fmt_currency).fmt("sold", lambda x: fmt_number(x, decimals=0))
itempricesold
coffee$3.50120
bagel$2.2545
croissant$4.00

Formatters are never given missing values, so a formatter doesn’t need to handle None.

Rendering as text

Table.as_text() renders a Markdown-style text table, ready to print or paste into a Markdown document:

print(menu.fmt("price", fmt_currency).as_text())
| item      | price | sold |
|-----------|-------|------|
| coffee    | $3.50 | 120  |
| bagel     | $2.25 | 45   |
| croissant | $4.00 |      |

Rendering as HTML

Table.as_html() returns the HTML as a string, for use in a web page or report:

print(menu.fmt("price", fmt_currency).as_html())
<table class="tinytab">
  <thead>
    <tr><th>item</th><th>price</th><th>sold</th></tr>
  </thead>
  <tbody>
    <tr><td>coffee</td><td>$3.50</td><td>120</td></tr>
    <tr><td>bagel</td><td>$2.25</td><td>45</td></tr>
    <tr><td>croissant</td><td>$4.00</td><td></td></tr>
  </tbody>
</table>

Every value is HTML-escaped, so text in the data can never be mistaken for markup:

Table({"name": ["<b>bold</b>", "Tom & Jerry"]})
name
<b>bold</b>
Tom & Jerry

Saving and loading

Table.to_csv() writes the table’s values to a CSV file, and Table.from_csv() reads one back:

import tempfile
from pathlib import Path

path = Path(tempfile.mkdtemp()) / "menu.csv"
menu.to_csv(path)

Table.from_csv(path)
itempricesold
coffee3.5120
bagel2.2545
croissant4.0

Two things to know about CSV files:

  • Formatting isn’t saved. to_csv() writes the original values, not the formatted ones.
  • CSV files don’t record types, so from_csv() reads every value as a string.