From 26dd4d81f08ad75d8260d9c2518d1b530746ea06 Mon Sep 17 00:00:00 2001 From: Niru Maheswaranathan Date: Tue, 23 May 2017 13:48:45 -0700 Subject: [PATCH 1/5] Adds Table() contextmanager for easy dynamic tables :cherry_blossom: --- tableprint.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tableprint.py b/tableprint.py index 5870e53..ee25646 100644 --- a/tableprint.py +++ b/tableprint.py @@ -14,6 +14,7 @@ from __future__ import print_function, unicode_literals from six import string_types from collections import namedtuple from numbers import Number +from contextlib import ContextDecorator import sys import re import numpy as np @@ -68,6 +69,22 @@ WIDTH = 11 FMT = '5g' +class Table(ContextDecorator): + def __init__(self, headers, width=WIDTH, style=STYLE, add_hr=True): + self.headers = header(headers, width=WIDTH, style=STYLE, add_hr=add_hr) + self.bottom = bottom(len(headers), width=WIDTH, style=STYLE) + + def __call__(self, data): + print(row(data), flush=True) + + def __enter__(self): + print(self.headers, flush=True) + return self + + def __exit__(self, *exc): + print(self.bottom, flush=True) + + def table(data, headers=None, format_spec=FMT, width=WIDTH, style=STYLE, out=sys.stdout): """Print a table with the given data From 9ba26df887ef38f87390dde401c743d8f9fee3cd Mon Sep 17 00:00:00 2001 From: Niru Maheswaranathan Date: Tue, 23 May 2017 13:59:11 -0700 Subject: [PATCH 2/5] Removes ContextDecorator (unnecessary) --- tableprint.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tableprint.py b/tableprint.py index ee25646..2c21db0 100644 --- a/tableprint.py +++ b/tableprint.py @@ -14,7 +14,6 @@ from __future__ import print_function, unicode_literals from six import string_types from collections import namedtuple from numbers import Number -from contextlib import ContextDecorator import sys import re import numpy as np @@ -69,10 +68,10 @@ WIDTH = 11 FMT = '5g' -class Table(ContextDecorator): +class Table: def __init__(self, headers, width=WIDTH, style=STYLE, add_hr=True): - self.headers = header(headers, width=WIDTH, style=STYLE, add_hr=add_hr) - self.bottom = bottom(len(headers), width=WIDTH, style=STYLE) + self.headers = header(headers, width=width, style=style, add_hr=add_hr) + self.bottom = bottom(len(headers), width=width, style=style) def __call__(self, data): print(row(data), flush=True) From 104e8d974934cf951ab85113a47eee0d5a62b9ed Mon Sep 17 00:00:00 2001 From: Niru Maheswaranathan Date: Tue, 23 May 2017 22:48:46 -0700 Subject: [PATCH 3/5] adds docstring for Table --- tableprint.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tableprint.py b/tableprint.py index 2c21db0..7735006 100644 --- a/tableprint.py +++ b/tableprint.py @@ -70,6 +70,28 @@ FMT = '5g' class Table: def __init__(self, headers, width=WIDTH, style=STYLE, add_hr=True): + """Context manager for table printing + + Parameters + ---------- + headers : array_like + A list of N strings consisting of the header of each of the N columns + + width : int, optional + The width of each column in the table (Default: 11) + + style : string or tuple, optional + A formatting style. (Default: 'round') + + add_hr : boolean, optional + Whether or not to add a horizontal rule (hr) after the headers + + Usage + ----- + >>> with Table("ABC") as t: + for k in range(10): + t.row(np.random.randn(3)) + """ self.headers = header(headers, width=width, style=style, add_hr=add_hr) self.bottom = bottom(len(headers), width=width, style=style) From b396bea5c2edafdbd3a6780507b263103558e705 Mon Sep 17 00:00:00 2001 From: Niru Maheswaranathan Date: Thu, 25 May 2017 16:12:52 -0700 Subject: [PATCH 4/5] Adds tests for contextmanager --- tableprint/printer.py | 25 +++++++++++++++---------- tests/test_io.py | 19 ++++++++++++++----- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/tableprint/printer.py b/tableprint/printer.py index 1ff16c0..240f7be 100644 --- a/tableprint/printer.py +++ b/tableprint/printer.py @@ -21,15 +21,15 @@ from six import string_types from .style import LineStyle, STYLES from .utils import ansi_len, format_line -__all__ = ('table', 'header', 'row', 'hrule', 'top', 'bottom', 'banner', 'dataframe') +__all__ = ('table', 'header', 'row', 'hrule', 'top', 'bottom', 'banner', 'dataframe', 'TableContext') STYLE = 'round' WIDTH = 11 FMT = '5g' -class Table: - def __init__(self, headers, width=WIDTH, style=STYLE, add_hr=True): +class TableContext: + def __init__(self, headers, width=WIDTH, style=STYLE, add_hr=True, out=sys.stdout): """Context manager for table printing Parameters @@ -37,7 +37,7 @@ class Table: headers : array_like A list of N strings consisting of the header of each of the N columns - width : int, optional + width : int or array_like, optional The width of each column in the table (Default: 11) style : string or tuple, optional @@ -48,22 +48,27 @@ class Table: Usage ----- - >>> with Table("ABC") as t: + >>> with TableContext("ABC") as t: for k in range(10): t.row(np.random.randn(3)) """ - self.headers = header(headers, width=width, style=style, add_hr=add_hr) - self.bottom = bottom(len(headers), width=width, style=style) + self.out = out + self.config = {'width': width, 'style': style} + self.headers = header(headers, add_hr=add_hr, **self.config) + self.bottom = bottom(len(headers), **self.config) def __call__(self, data): - print(row(data), flush=True) + self.out.write(row(data, **self.config) + '\n') + self.out.flush() def __enter__(self): - print(self.headers, flush=True) + self.out.write(self.headers + '\n') + self.out.flush() return self def __exit__(self, *exc): - print(self.bottom, flush=True) + self.out.write(self.bottom + '\n') + self.out.flush() def table(data, headers=None, format_spec=FMT, width=WIDTH, style=STYLE, out=sys.stdout): diff --git a/tests/test_io.py b/tests/test_io.py index ac7b5fd..2c2ceb9 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -1,12 +1,21 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from tableprint import table, banner, dataframe, hrule +from tableprint import table, banner, dataframe, hrule, TableContext from io import StringIO import numpy as np -def test_table(): +def test_context(): + """Tests the table context manager""" + output = StringIO() + with TableContext('ABC', style='round', width=5, out=output) as t: + t([1, 2, 3]) + t([4, 5, 6]) + assert output.getvalue() == '╭─────┬─────┬─────╮\n│ A │ B │ C │\n├─────┼─────┼─────┤\n│ 1│ 2│ 3│\n│ 4│ 5│ 6│\n╰─────┴─────┴─────╯\n' + +def test_table(): + """Tests the table function""" output = StringIO() table([[1, 2, 3], [4, 5, 6]], 'ABC', style='round', width=5, out=output) assert output.getvalue() == '╭─────┬─────┬─────╮\n│ A │ B │ C │\n├─────┼─────┼─────┤\n│ 1│ 2│ 3│\n│ 4│ 5│ 6│\n╰─────┴─────┴─────╯\n' @@ -17,7 +26,7 @@ def test_table(): def test_frame(): - + """Tests the dataframe function""" # mock of a pandas DataFrame class DataFrame: def __init__(self, data, headers): @@ -35,7 +44,7 @@ def test_frame(): def test_banner(): - + """Tests the banner function""" output = StringIO() banner('hello world', style='clean', width=11, out=output) assert output.getvalue() == ' ─────────── \n hello world \n ─────────── \n' @@ -46,7 +55,7 @@ def test_banner(): def test_hrule(): - + """Tests the hrule function""" output = hrule(1, width=11) assert len(output) == 11 assert '───────────' From 6c3a3bae6ae13d88076c8c5943a20854c603da98 Mon Sep 17 00:00:00 2001 From: Niru Maheswaranathan Date: Fri, 26 May 2017 13:33:58 -0700 Subject: [PATCH 5/5] bumping version --- README.md | 1 + tableprint/metadata.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 749b16d..b8f4349 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Hosted at Read The Docs: [tableprint.readthedocs.org](http://tableprint.readthed - `six` ## Version +- 0.7.0 (May 26 2017) Adds a TableContext context manager for easy creation of dynamic tables (tables that update periodically). Adds the ability to pass a list or tuple of widths to specify different widths for different columns - 0.6.9 (May 25 2017) Splitting the tableprint.py module into a pacakge with multiple files - 0.6.7 (May 25 2017) Fixes some bugs with ANSI escape sequences - 0.5.0 (Sept 29 2016) Better handling of ANSI escape sequences in table rows diff --git a/tableprint/metadata.py b/tableprint/metadata.py index a0a705b..9da41ee 100644 --- a/tableprint/metadata.py +++ b/tableprint/metadata.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Version info -__version__ = '0.6.9' +__version__ = '0.7.0' __license__ = 'MIT' # Project description(s)