Skip to main content

Create simple, tastefully-formatted strings that resemble tables

Project description

Table Maker

Description

Make simple tables from rows and columns, with values separated into cells and the contents left-justified.

Initially designed for creating map marginalia in QGIS and ArcMap, as well as a substitute for the often over-engineered and clunky table wizards that are featured in word processors.

The design is data-oriented: a table is just a pair of plain values — cols (column names) and rows (same-length sequences) — and every function is a pure transformation of those values. Rendering to a string happens once, at the end, via render. Transformations that take configuration (sort_rows, head, tail, render) are factories: called with their config, they return a function of the data, so pipelines built with pipe read left to right.

Installation

pip install table_maker

Usage

Most basic use is to create a simple, cleanly-formatted table:

>>> from table_maker import pipe, render, sort_rows
>>> cols = ('athlete', 'time')
>>> rows = (('Clint', '16:04'), ('Mitch', '12:12'), ('Tommy', '22:57'), ('Zach', '27:56'))
>>> print(pipe(rows, sort_rows(col=1), render(cols)))
+---------+-------+
| athlete | time  |
+=========+=======+
| Mitch   | 12:12 |
+---------+-------+
| Clint   | 16:04 |
+---------+-------+
| Tommy   | 22:57 |
+---------+-------+
| Zach    | 27:56 |
+---------+-------+

render(cols, rows) also works directly when there's nothing to compose.

That's mostly it, but there are a few simple utilities. You can add row numbers if you like — numbered takes and returns the (cols, rows) pair, since it adds a column:

>>> import table_maker as tm
>>> cols = ('u-boat', 'commissioned', 'sunk')
>>> rows = (
...  ('u-64', '16 Dec 39', '13 Apr 40'),
...  ('u-104', '19 Aug 40', '28 Nov 40'),
...  ('u-107', '08 Oct 40', '08 Aug 44'))
>>> print(tm.render(*tm.numbered(cols, rows)))
+---+--------+--------------+-----------+
| # | u-boat | commissioned | sunk      |
+===+========+==============+===========+
| 1 | u-64   | 16 Dec 39    | 13 Apr 40 |
+---+--------+--------------+-----------+
| 2 | u-104  | 19 Aug 40    | 28 Nov 40 |
+---+--------+--------------+-----------+
| 3 | u-107  | 08 Oct 40    | 08 Aug 44 |
+---+--------+--------------+-----------+

Or you can drop the separators between rows for a more compact table, and convert items to title case:

>>> import table_maker as tm
>>> cols = ('album', 'year')
>>> rows = (('fandango!', '1975'), ('tres hombres', '1973'), ('eliminator', '1983'))
>>> x, y = tm.title_case(cols, tm.pipe(rows, tm.sort_rows(col=1)))
>>> print(tm.render(x, y, row_seps=False))
+--------------+------+
| Album        | Year |
+==============+======+
| Tres Hombres | 1973 |
| Fandango!    | 1975 |
| Eliminator   | 1983 |
+--------------+------+

There are no utilities for selecting rows beyond head and tail — since the data is plain tuples, filtering is an ordinary comprehension. For example, from this CSV string:

>>> csv = '''first,last,GOATscore
Kareem,Abdul-Jabbar,5.600
LeBron,James,5.511
Michael,Jordan,5.219
Tim,Duncan,4.273
Bill,Russell,4.066
Kobe,Bryant,4.021
Wilt,Chamberlain,3.885'''

If you only want players whose score is above 4, get them before rendering:

>>> import table_maker as tm
>>> lines = csv.split('\n')
>>> cols = lines[0].split(',')
>>> rows = [line.split(',') for line in lines[1:] if line]
>>> above_4 = [row for row in rows if float(row[2]) > 4]
>>> ranked = tm.pipe(above_4, tm.sort_rows(col=2, key=float, reverse=True))
>>> print(tm.render(*tm.numbered(cols, ranked), title='THE GREATEST OF ALL TIME'))
THE GREATEST OF ALL TIME
+---+---------+--------------+-----------+
| # | first   | last         | GOATscore |
+===+=========+==============+===========+
| 1 | Kareem  | Abdul-Jabbar | 5.600     |
+---+---------+--------------+-----------+
| 2 | LeBron  | James        | 5.511     |
+---+---------+--------------+-----------+
| 3 | Michael | Jordan       | 5.219     |
+---+---------+--------------+-----------+
| 4 | Tim     | Duncan       | 4.273     |
+---+---------+--------------+-----------+
| 5 | Bill    | Russell      | 4.066     |
+---+---------+--------------+-----------+
| 6 | Kobe    | Bryant       | 4.021     |
+---+---------+--------------+-----------+

Note that sort_rows(col=2, key=float) sorts the scores numerically — string sorting would put '10' before '2'.

Alternatively, by_col gives you the data column-wise as a dict, which is compatible with pandas.DataFrame.from_dict() if you'd rather process it that way:

>>> tm.by_col(('album', 'year'), (('Fandango!', '1975'), ('Eliminator', '1983')))
{'album': ['Fandango!', 'Eliminator'], 'year': ['1975', '1983']}

API summary

  • render(cols, rows=None, row_seps=True, title=None) — the only function that produces a string. Without rows, returns a rows -> str function for pipelines.
  • pipe(value, *fns) — thread a value through functions left to right.
  • sort_rows(col=0, key=None, reverse=False), head(n=3), tail(n=3) — factories returning rows -> rows functions.
  • numbered(cols, rows), title_case(cols, rows) — pair transforms returning (cols, rows).
  • by_col(cols, rows) — column-wise dict view.
  • chop(rows) — split rows into two halves.

Changes from 0.1.x

0.2.0 is a breaking release. The formatted string is no longer the unit of manipulation — plain data is. make_table is now render (which computes per-column widths from the data, headers included, so scaling is gone); sorting moved out of rendering into sort_rows; insert_row_numbers, capitalize_inputs, remove_seps, and insert_title became numbered, title_case, the row_seps flag, and the title argument; transform became by_col. deconstruct, maybe_table, and length were removed — they existed to recover data from a rendered string, and you still have the data.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

table_maker-0.2.0.tar.gz (6.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

table_maker-0.2.0-py3-none-any.whl (6.5 kB view details)

Uploaded Python 3

File details

Details for the file table_maker-0.2.0.tar.gz.

File metadata

  • Download URL: table_maker-0.2.0.tar.gz
  • Upload date:
  • Size: 6.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for table_maker-0.2.0.tar.gz
Algorithm Hash digest
SHA256 79a30ffe2f2640548092b64e3b2af9841d45f09df9fb0befa47a27bc9f6a8193
MD5 f31f6627e115a08279d8e441fe3b69f4
BLAKE2b-256 98f77ed56964c9aab84696194ec32b94f65d927be46392e4af35d8773681567c

See more details on using hashes here.

File details

Details for the file table_maker-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: table_maker-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 6.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for table_maker-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 faf3624098796a0aeead2cf3d38037c2bd247ab870b271aff162e75e6db8798b
MD5 8cf7d33e455b22826e3dd7a098cc1648
BLAKE2b-256 3dd67131ab8986e134661144b2ede354ed978294226e7ff81b6c3d5dbc28ae5f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page