mirror of
				https://github.com/KevinMidboe/tableprint.git
				synced 2025-10-29 18:00:16 +00:00 
			
		
		
		
	merging v0.6.8
This commit is contained in:
		| @@ -3,6 +3,7 @@ python: | |||||||
|   - "2.7" |   - "2.7" | ||||||
|   - "3.4" |   - "3.4" | ||||||
|   - "3.5" |   - "3.5" | ||||||
|  |   - "3.6" | ||||||
| install: | install: | ||||||
|   - sudo apt-get update |   - sudo apt-get update | ||||||
|   - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then |   - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
								
							| @@ -14,6 +14,6 @@ test: | |||||||
| 	nosetests -v --with-coverage --cover-package=tableprint --logging-level=INFO | 	nosetests -v --with-coverage --cover-package=tableprint --logging-level=INFO | ||||||
|  |  | ||||||
| clean: | clean: | ||||||
| 	rm -rf tableprint.egg-info | 	rm -R tableprint.egg-info | ||||||
| 	rm -f *.pyc | 	rm -f tableprint/*.pyc | ||||||
| 	rm -rf __pycache__ | 	rm -R tableprint/__pycache__/ | ||||||
|   | |||||||
| @@ -49,6 +49,7 @@ Hosted at Read The Docs: [tableprint.readthedocs.org](http://tableprint.readthed | |||||||
| - `six` | - `six` | ||||||
|  |  | ||||||
| ## Version | ## Version | ||||||
|  | - 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 | - 0.5.0 (Sept 29 2016) Better handling of ANSI escape sequences in table rows | ||||||
| - 0.4.0 (May 3 2016) Adds a 'block' style | - 0.4.0 (May 3 2016) Adds a 'block' style | ||||||
| - 0.3.2 (May 3 2016) Adds a test suite | - 0.3.2 (May 3 2016) Adds a test suite | ||||||
|   | |||||||
							
								
								
									
										34
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								setup.py
									
									
									
									
									
								
							| @@ -1,29 +1,28 @@ | |||||||
|  | import re | ||||||
|  | import os | ||||||
| from setuptools import setup | from setuptools import setup | ||||||
|  |  | ||||||
|  |  | ||||||
|  | __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) | ||||||
|  | with open(os.path.join(__location__, 'tableprint/metadata.py'), 'r') as f: | ||||||
|  |     metadata = dict(re.findall("__([a-z_]+)__\s*=\s*'([^']+)'", f.read())) | ||||||
|  |  | ||||||
|  |  | ||||||
| setup( | setup( | ||||||
|     name='tableprint', |     name='tableprint', | ||||||
|  |     url=metadata['url'], | ||||||
|  |     version=metadata['version'], | ||||||
|  |  | ||||||
|     # Versions should comply with PEP440.  For a discussion on single-sourcing |     author=metadata['author'], | ||||||
|     # the version across setup.py and the project code, see |     author_email=metadata['author_email'], | ||||||
|     # https://packaging.python.org/en/latest/single_source_version.html |  | ||||||
|     version='0.7.0', |  | ||||||
|  |  | ||||||
|     description='Pretty console printing of tabular data', |     license=metadata['license'], | ||||||
|  |     description=metadata['description'], | ||||||
|     long_description='''Formatted console printing of tabular data. |     long_description='''Formatted console printing of tabular data. | ||||||
|                         tableprint lets you easily print formatted tables of data. |                         tableprint lets you easily print formatted tables of data. | ||||||
|                         Unlike other modules, you can print single rows of data at a time |                         Unlike other modules, you can print single rows of data at a time | ||||||
|                         (useful for printing ongoing computation results).''', |                         (useful for printing ongoing computation results).''', | ||||||
|  |  | ||||||
|     # The project's main homepage. |  | ||||||
|     url='https://github.com/nirum/tableprint', |  | ||||||
|  |  | ||||||
|     # Author details |  | ||||||
|     author='Niru Maheswaranathan', |  | ||||||
|     author_email='niru@fastmail.com', |  | ||||||
|  |  | ||||||
|     # Choose your license |  | ||||||
|     license='MIT', |  | ||||||
|  |  | ||||||
|     # See https://pypi.python.org/pypi?%3Aaction=list_classifiers |     # See https://pypi.python.org/pypi?%3Aaction=list_classifiers | ||||||
|     classifiers=[ |     classifiers=[ | ||||||
|         # How mature is this project? Common values are |         # How mature is this project? Common values are | ||||||
| @@ -44,6 +43,7 @@ setup( | |||||||
|         'Programming Language :: Python :: 2.7', |         'Programming Language :: Python :: 2.7', | ||||||
|         'Programming Language :: Python :: 3.4', |         'Programming Language :: Python :: 3.4', | ||||||
|         'Programming Language :: Python :: 3.5', |         'Programming Language :: Python :: 3.5', | ||||||
|  |         'Programming Language :: Python :: 3.6', | ||||||
|     ], |     ], | ||||||
|  |  | ||||||
|     # What does your project relate to? |     # What does your project relate to? | ||||||
| @@ -51,8 +51,7 @@ setup( | |||||||
|  |  | ||||||
|     # You can just specify the packages manually here if your project is |     # You can just specify the packages manually here if your project is | ||||||
|     # simple. Or you can use find_packages(). |     # simple. Or you can use find_packages(). | ||||||
|     packages=[], |     packages=['tableprint'], | ||||||
|     py_modules=['tableprint'], |  | ||||||
|  |  | ||||||
|     # List run-time dependencies here.  These will be installed by pip when your |     # List run-time dependencies here.  These will be installed by pip when your | ||||||
|     # project is installed. For an analysis of "install_requires" vs pip's |     # project is installed. For an analysis of "install_requires" vs pip's | ||||||
| @@ -67,5 +66,4 @@ setup( | |||||||
|         'dev': [], |         'dev': [], | ||||||
|         'test': ['pytest', 'coverage'], |         'test': ['pytest', 'coverage'], | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
| ) | ) | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								tableprint/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								tableprint/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  | Tableprint | ||||||
|  | """ | ||||||
|  | from .metadata import __author__, __version__ | ||||||
|  | from .printer import * | ||||||
|  | from .style import * | ||||||
|  | from .utils import * | ||||||
							
								
								
									
										15
									
								
								tableprint/metadata.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tableprint/metadata.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  |  | ||||||
|  | # Version info | ||||||
|  | __version__ = '0.6.8' | ||||||
|  | __license__ = 'MIT' | ||||||
|  |  | ||||||
|  | # Project description(s) | ||||||
|  | __description__ = 'Pretty console printing of tabular data' | ||||||
|  |  | ||||||
|  | # The project's main homepage. | ||||||
|  | __url__ = 'https://github.com/nirum/tableprint' | ||||||
|  |  | ||||||
|  | # Author details | ||||||
|  | __author__ = 'Niru Maheswaranathan' | ||||||
|  | __author_email__ = 'niru@fastmail.com' | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||||
| """ | """ | ||||||
| Tableprint | Table printing | ||||||
| 
 | 
 | ||||||
| A module to print and display formatted tables of data | A module to print and display formatted tables of data | ||||||
| 
 | 
 | ||||||
| @@ -11,58 +11,18 @@ Usage | |||||||
| >>> tableprint.table(data, headers) | >>> tableprint.table(data, headers) | ||||||
| """ | """ | ||||||
| from __future__ import print_function, unicode_literals | from __future__ import print_function, unicode_literals | ||||||
| from six import string_types | 
 | ||||||
| from collections import namedtuple |  | ||||||
| from numbers import Number |  | ||||||
| import sys | import sys | ||||||
| import re | from numbers import Number | ||||||
|  | 
 | ||||||
| import numpy as np | import numpy as np | ||||||
|  | from six import string_types | ||||||
| 
 | 
 | ||||||
| __all__ = ('table', 'header', 'row', 'hr', 'top', 'bottom', | from .style import LineStyle, STYLES | ||||||
|            'banner', 'dataframe', 'humantime', 'styles') | from .utils import ansi_len, format_line | ||||||
| __version__ = '0.7.0' | 
 | ||||||
|  | __all__ = ('table', 'header', 'row', 'hrule', 'top', 'bottom', 'banner', 'dataframe') | ||||||
| 
 | 
 | ||||||
| # set up table styles |  | ||||||
| LineStyle = namedtuple('LineStyle', ('begin', 'hline', 'sep', 'end')) |  | ||||||
| TableStyle = namedtuple('TableStyle', ('top', 'below_header', 'bottom', 'row')) |  | ||||||
| styles = { |  | ||||||
|     'grid': TableStyle( |  | ||||||
|         top=LineStyle('+', '-', '+', '+'), |  | ||||||
|         below_header=LineStyle('+', '-', '+', '+'), |  | ||||||
|         bottom=LineStyle('+', '-', '+', '+'), |  | ||||||
|         row=LineStyle('|', '', '|', '|'), |  | ||||||
|     ), |  | ||||||
|     'fancy_grid': TableStyle( |  | ||||||
|         top=LineStyle('╒', '═', '╤', '╕'), |  | ||||||
|         below_header=LineStyle('╞', '═', '╪', '╡'), |  | ||||||
|         bottom=LineStyle("╘", "═", "╧", "╛"), |  | ||||||
|         row=LineStyle('│', '', '│', '│'), |  | ||||||
|     ), |  | ||||||
|     'clean': TableStyle( |  | ||||||
|         top=LineStyle(' ', '─', ' ', ' '), |  | ||||||
|         below_header=LineStyle(' ', '─', ' ', ' '), |  | ||||||
|         bottom=LineStyle(" ", "─", " ", " "), |  | ||||||
|         row=LineStyle(' ', '', ' ', ' '), |  | ||||||
|     ), |  | ||||||
|     'round': TableStyle( |  | ||||||
|         top=LineStyle('╭', '─', '┬', '╮'), |  | ||||||
|         below_header=LineStyle('├', '─', '┼', '┤'), |  | ||||||
|         bottom=LineStyle('╰', '─', '┴', '╯'), |  | ||||||
|         row=LineStyle('│', '', '│', '│'), |  | ||||||
|     ), |  | ||||||
|     'banner': TableStyle( |  | ||||||
|         top=LineStyle('╒', '═', '╤', '╕'), |  | ||||||
|         below_header=LineStyle("╘", "═", "╧", "╛"), |  | ||||||
|         bottom=LineStyle("╘", "═", "╧", "╛"), |  | ||||||
|         row=LineStyle('│', '', '│', '│'), |  | ||||||
|     ), |  | ||||||
|     'block': TableStyle( |  | ||||||
|         top=LineStyle('◢', '■', '■', '◣'), |  | ||||||
|         below_header=LineStyle(' ', '━', '━', ' '), |  | ||||||
|         bottom=LineStyle('◥', '■', '■', '◤'), |  | ||||||
|         row=LineStyle(' ', '', ' ', ' '), |  | ||||||
|     ), |  | ||||||
| } |  | ||||||
| STYLE = 'round' | STYLE = 'round' | ||||||
| WIDTH = 11 | WIDTH = 11 | ||||||
| FMT = '5g' | FMT = '5g' | ||||||
| @@ -92,10 +52,10 @@ def table(data, headers=None, format_spec=FMT, width=WIDTH, style=STYLE, out=sys | |||||||
|         A file handle or object that has write() and flush() methods (Default: sys.stdout) |         A file handle or object that has write() and flush() methods (Default: sys.stdout) | ||||||
|     """ |     """ | ||||||
|     ncols = len(data[0]) if headers is None else len(headers) |     ncols = len(data[0]) if headers is None else len(headers) | ||||||
|     tablestyle = styles[style] |     tablestyle = STYLES[style] | ||||||
| 
 | 
 | ||||||
|     # Initialize with a hr or the header |     # Initialize with a hr or the header | ||||||
|     tablestr = [hr(ncols, width, tablestyle.top)] \ |     tablestr = [hrule(ncols, width, tablestyle.top)] \ | ||||||
|         if headers is None else [header(headers, width, style)] |         if headers is None else [header(headers, width, style)] | ||||||
| 
 | 
 | ||||||
|     # parse each row |     # parse each row | ||||||
| @@ -103,7 +63,7 @@ def table(data, headers=None, format_spec=FMT, width=WIDTH, style=STYLE, out=sys | |||||||
| 
 | 
 | ||||||
|     # only add the final border if there was data in the table |     # only add the final border if there was data in the table | ||||||
|     if len(data) > 0: |     if len(data) > 0: | ||||||
|         tablestr += [hr(ncols, width, tablestyle.bottom)] |         tablestr += [hrule(ncols, width, tablestyle.bottom)] | ||||||
| 
 | 
 | ||||||
|     # print the table |     # print the table | ||||||
|     out.write('\n'.join(tablestr) + '\n') |     out.write('\n'.join(tablestr) + '\n') | ||||||
| @@ -122,14 +82,14 @@ def header(headers, width=WIDTH, style=STYLE, add_hr=True): | |||||||
|         The width of each column (Default: 11) |         The width of each column (Default: 11) | ||||||
| 
 | 
 | ||||||
|     style : string or tuple, optional |     style : string or tuple, optional | ||||||
|         A formatting style (see styles) |         A formatting style (see STYLES) | ||||||
| 
 | 
 | ||||||
|     Returns |     Returns | ||||||
|     ------- |     ------- | ||||||
|     headerstr : string |     headerstr : string | ||||||
|         A string consisting of the full header row to print |         A string consisting of the full header row to print | ||||||
|     """ |     """ | ||||||
|     tablestyle = styles[style] |     tablestyle = STYLES[style] | ||||||
| 
 | 
 | ||||||
|     # parse width |     # parse width | ||||||
|     if isinstance(width, int): |     if isinstance(width, int): | ||||||
| @@ -142,11 +102,11 @@ def header(headers, width=WIDTH, style=STYLE, add_hr=True): | |||||||
|     data = map(lambda x: ('{:^%d}' % (x[0] + _ansi_len(x[1]))).format(x[1]), zip(widths, headers)) |     data = map(lambda x: ('{:^%d}' % (x[0] + _ansi_len(x[1]))).format(x[1]), zip(widths, headers)) | ||||||
| 
 | 
 | ||||||
|     # build the formatted str |     # build the formatted str | ||||||
|     headerstr = _format_line(data, tablestyle.row) |     headerstr = format_line(data, tablestyle.row) | ||||||
| 
 | 
 | ||||||
|     if add_hr: |     if add_hr: | ||||||
|         upper = hr(len(headers), widths, tablestyle.top) |         upper = hrule(len(headers), widths, tablestyle.top) | ||||||
|         lower = hr(len(headers), widths, tablestyle.below_header) |         lower = hrule(len(headers), widths, tablestyle.below_header) | ||||||
|         headerstr = '\n'.join([upper, headerstr, lower]) |         headerstr = '\n'.join([upper, headerstr, lower]) | ||||||
| 
 | 
 | ||||||
|     return headerstr |     return headerstr | ||||||
| @@ -174,7 +134,7 @@ def row(values, width=WIDTH, format_spec=FMT, style=STYLE): | |||||||
|     rowstr : string |     rowstr : string | ||||||
|         A string consisting of the full row of data to print |         A string consisting of the full row of data to print | ||||||
|     """ |     """ | ||||||
|     tablestyle = styles[style] |     tablestyle = STYLES[style] | ||||||
| 
 | 
 | ||||||
|     # parse width |     # parse width | ||||||
|     if isinstance(width, int): |     if isinstance(width, int): | ||||||
| @@ -183,7 +143,7 @@ def row(values, width=WIDTH, format_spec=FMT, style=STYLE): | |||||||
|         assert len(width) == len(values), "Width and values must have the same length" |         assert len(width) == len(values), "Width and values must have the same length" | ||||||
|         widths = width |         widths = width | ||||||
| 
 | 
 | ||||||
|     assert isinstance(format_spec, string_types) | (type(format_spec) is list), \ |     assert isinstance(format_spec, string_types) | isinstance(format_spec, list), \ | ||||||
|         "format_spec must be a string or list of strings" |         "format_spec must be a string or list of strings" | ||||||
| 
 | 
 | ||||||
|     if isinstance(format_spec, string_types): |     if isinstance(format_spec, string_types): | ||||||
| @@ -196,7 +156,7 @@ def row(values, width=WIDTH, format_spec=FMT, style=STYLE): | |||||||
|         width, datum, prec = val |         width, datum, prec = val | ||||||
| 
 | 
 | ||||||
|         if isinstance(datum, string_types): |         if isinstance(datum, string_types): | ||||||
|             return ('{:>%i}' % (width + _ansi_len(datum))).format(datum) |             return ('{:>%i}' % (width + ansi_len(datum))).format(datum) | ||||||
| 
 | 
 | ||||||
|         elif isinstance(datum, Number): |         elif isinstance(datum, Number): | ||||||
|             return ('{:>%i.%s}' % (width, prec)).format(datum) |             return ('{:>%i.%s}' % (width, prec)).format(datum) | ||||||
| @@ -208,10 +168,10 @@ def row(values, width=WIDTH, format_spec=FMT, style=STYLE): | |||||||
|     data = map(mapdata, zip(widths, values, format_spec)) |     data = map(mapdata, zip(widths, values, format_spec)) | ||||||
| 
 | 
 | ||||||
|     # build the row string |     # build the row string | ||||||
|     return _format_line(data, tablestyle.row) |     return format_line(data, tablestyle.row) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def hr(n, width=WIDTH, linestyle=LineStyle('', '─', '─', '')): | def hrule(n=1, width=WIDTH, linestyle=LineStyle('', '─', '─', '')): | ||||||
|     """Returns a formatted string used as a border between table rows |     """Returns a formatted string used as a border between table rows | ||||||
| 
 | 
 | ||||||
|     Parameters |     Parameters | ||||||
| @@ -244,12 +204,12 @@ def hr(n, width=WIDTH, linestyle=LineStyle('', '─', '─', '')): | |||||||
| 
 | 
 | ||||||
| def top(n, width=WIDTH, style=STYLE): | def top(n, width=WIDTH, style=STYLE): | ||||||
|     """Prints the top row of a table""" |     """Prints the top row of a table""" | ||||||
|     return hr(n, width, linestyle=styles[style].top) |     return hrule(n, width, linestyle=STYLES[style].top) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def bottom(n, width=WIDTH, style=STYLE): | def bottom(n, width=WIDTH, style=STYLE): | ||||||
|     """Prints the top row of a table""" |     """Prints the top row of a table""" | ||||||
|     return hr(n, width, linestyle=styles[style].bottom) |     return hrule(n, width, linestyle=STYLES[style].bottom) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def banner(message, width=30, style='banner', out=sys.stdout): | def banner(message, width=30, style='banner', out=sys.stdout): | ||||||
| @@ -282,70 +242,3 @@ def dataframe(df, **kwargs): | |||||||
|         A pandas DataFrame with the table to print |         A pandas DataFrame with the table to print | ||||||
|     """ |     """ | ||||||
|     table(np.array(df), list(df.columns), **kwargs) |     table(np.array(df), list(df.columns), **kwargs) | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def humantime(t): |  | ||||||
|     """Converts a time in seconds to a reasonable human readable time |  | ||||||
| 
 |  | ||||||
|     Parameters |  | ||||||
|     ---------- |  | ||||||
|     t : float |  | ||||||
|         The number of seconds |  | ||||||
| 
 |  | ||||||
|     Returns |  | ||||||
|     ------- |  | ||||||
|     time : string |  | ||||||
|         The human readable formatted value of the given time |  | ||||||
|     """ |  | ||||||
|     try: |  | ||||||
|         t = float(t) |  | ||||||
|     except (ValueError, TypeError): |  | ||||||
|         raise ValueError("Input must be numeric") |  | ||||||
| 
 |  | ||||||
|     # weeks |  | ||||||
|     if t >= 7 * 60 * 60 * 24: |  | ||||||
|         weeks = np.floor(t / (7 * 60 * 60 * 24)) |  | ||||||
|         timestr = "{:g} weeks, ".format(weeks) + humantime(t % (7 * 60 * 60 * 24)) |  | ||||||
| 
 |  | ||||||
|     # days |  | ||||||
|     elif t >= 60 * 60 * 24: |  | ||||||
|         days = np.floor(t / (60 * 60 * 24)) |  | ||||||
|         timestr = "{:g} days, ".format(days) + humantime(t % (60 * 60 * 24)) |  | ||||||
| 
 |  | ||||||
|     # hours |  | ||||||
|     elif t >= 60 * 60: |  | ||||||
|         hours = np.floor(t / (60 * 60)) |  | ||||||
|         timestr = "{:g} hours, ".format(hours) + humantime(t % (60 * 60)) |  | ||||||
| 
 |  | ||||||
|     # minutes |  | ||||||
|     elif t >= 60: |  | ||||||
|         minutes = np.floor(t / 60.) |  | ||||||
|         timestr = "{:g} min., ".format(minutes) + humantime(t % 60) |  | ||||||
| 
 |  | ||||||
|     # seconds |  | ||||||
|     elif (t >= 1) | (t == 0): |  | ||||||
|         timestr = "{:g} s".format(t) |  | ||||||
| 
 |  | ||||||
|     # milliseconds |  | ||||||
|     elif t >= 1e-3: |  | ||||||
|         timestr = "{:g} ms".format(t * 1e3) |  | ||||||
| 
 |  | ||||||
|     # microseconds |  | ||||||
|     elif t >= 1e-6: |  | ||||||
|         timestr = "{:g} \u03BCs".format(t * 1e6) |  | ||||||
| 
 |  | ||||||
|     # nanoseconds or smaller |  | ||||||
|     else: |  | ||||||
|         timestr = "{:g} ns".format(t * 1e9) |  | ||||||
| 
 |  | ||||||
|     return timestr |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def _ansi_len(string): |  | ||||||
|     """Extra length due to any ANSI sequences in the string.""" |  | ||||||
|     return len(string) - len(re.compile(r'\x1b[^m]*m').sub('', string)) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def _format_line(data, linestyle): |  | ||||||
|     """Formats a list of elements using the given line style""" |  | ||||||
|     return linestyle.begin + linestyle.sep.join(data) + linestyle.end |  | ||||||
							
								
								
									
										48
									
								
								tableprint/style.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								tableprint/style.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  | Table styles | ||||||
|  | """ | ||||||
|  | from collections import namedtuple | ||||||
|  |  | ||||||
|  | __all__ = ('STYLES', 'LineStyle', 'TableStyle') | ||||||
|  |  | ||||||
|  | LineStyle = namedtuple('LineStyle', ('begin', 'hline', 'sep', 'end')) | ||||||
|  | TableStyle = namedtuple('TableStyle', ('top', 'below_header', 'bottom', 'row')) | ||||||
|  | STYLES = { | ||||||
|  |     'grid': TableStyle( | ||||||
|  |         top=LineStyle('+', '-', '+', '+'), | ||||||
|  |         below_header=LineStyle('+', '-', '+', '+'), | ||||||
|  |         bottom=LineStyle('+', '-', '+', '+'), | ||||||
|  |         row=LineStyle('|', '', '|', '|'), | ||||||
|  |     ), | ||||||
|  |     'fancy_grid': TableStyle( | ||||||
|  |         top=LineStyle('╒', '═', '╤', '╕'), | ||||||
|  |         below_header=LineStyle('╞', '═', '╪', '╡'), | ||||||
|  |         bottom=LineStyle("╘", "═", "╧", "╛"), | ||||||
|  |         row=LineStyle('│', '', '│', '│'), | ||||||
|  |     ), | ||||||
|  |     'clean': TableStyle( | ||||||
|  |         top=LineStyle(' ', '─', ' ', ' '), | ||||||
|  |         below_header=LineStyle(' ', '─', ' ', ' '), | ||||||
|  |         bottom=LineStyle(" ", "─", " ", " "), | ||||||
|  |         row=LineStyle(' ', '', ' ', ' '), | ||||||
|  |     ), | ||||||
|  |     'round': TableStyle( | ||||||
|  |         top=LineStyle('╭', '─', '┬', '╮'), | ||||||
|  |         below_header=LineStyle('├', '─', '┼', '┤'), | ||||||
|  |         bottom=LineStyle('╰', '─', '┴', '╯'), | ||||||
|  |         row=LineStyle('│', '', '│', '│'), | ||||||
|  |     ), | ||||||
|  |     'banner': TableStyle( | ||||||
|  |         top=LineStyle('╒', '═', '╤', '╕'), | ||||||
|  |         below_header=LineStyle("╘", "═", "╧", "╛"), | ||||||
|  |         bottom=LineStyle("╘", "═", "╧", "╛"), | ||||||
|  |         row=LineStyle('│', '', '│', '│'), | ||||||
|  |     ), | ||||||
|  |     'block': TableStyle( | ||||||
|  |         top=LineStyle('◢', '■', '■', '◣'), | ||||||
|  |         below_header=LineStyle(' ', '━', '━', ' '), | ||||||
|  |         bottom=LineStyle('◥', '■', '■', '◤'), | ||||||
|  |         row=LineStyle(' ', '', ' ', ' '), | ||||||
|  |     ), | ||||||
|  | } | ||||||
							
								
								
									
										75
									
								
								tableprint/utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								tableprint/utils.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | |||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  | Tableprint utilities | ||||||
|  | """ | ||||||
|  | import re | ||||||
|  | import numpy as np | ||||||
|  |  | ||||||
|  | __all__ = ('humantime',) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def humantime(time): | ||||||
|  |     """Converts a time in seconds to a reasonable human readable time | ||||||
|  |  | ||||||
|  |     Parameters | ||||||
|  |     ---------- | ||||||
|  |     t : float | ||||||
|  |         The number of seconds | ||||||
|  |  | ||||||
|  |     Returns | ||||||
|  |     ------- | ||||||
|  |     time : string | ||||||
|  |         The human readable formatted value of the given time | ||||||
|  |     """ | ||||||
|  |     try: | ||||||
|  |         time = float(time) | ||||||
|  |     except (ValueError, TypeError): | ||||||
|  |         raise ValueError("Input must be numeric") | ||||||
|  |  | ||||||
|  |     # weeks | ||||||
|  |     if time >= 7 * 60 * 60 * 24: | ||||||
|  |         weeks = np.floor(time / (7 * 60 * 60 * 24)) | ||||||
|  |         timestr = "{:g} weeks, ".format(weeks) + humantime(time % (7 * 60 * 60 * 24)) | ||||||
|  |  | ||||||
|  |     # days | ||||||
|  |     elif time >= 60 * 60 * 24: | ||||||
|  |         days = np.floor(time / (60 * 60 * 24)) | ||||||
|  |         timestr = "{:g} days, ".format(days) + humantime(time % (60 * 60 * 24)) | ||||||
|  |  | ||||||
|  |     # hours | ||||||
|  |     elif time >= 60 * 60: | ||||||
|  |         hours = np.floor(time / (60 * 60)) | ||||||
|  |         timestr = "{:g} hours, ".format(hours) + humantime(time % (60 * 60)) | ||||||
|  |  | ||||||
|  |     # minutes | ||||||
|  |     elif time >= 60: | ||||||
|  |         minutes = np.floor(time / 60.) | ||||||
|  |         timestr = "{:g} min., ".format(minutes) + humantime(time % 60) | ||||||
|  |  | ||||||
|  |     # seconds | ||||||
|  |     elif (time >= 1) | (time == 0): | ||||||
|  |         timestr = "{:g} s".format(time) | ||||||
|  |  | ||||||
|  |     # milliseconds | ||||||
|  |     elif time >= 1e-3: | ||||||
|  |         timestr = "{:g} ms".format(time * 1e3) | ||||||
|  |  | ||||||
|  |     # microseconds | ||||||
|  |     elif time >= 1e-6: | ||||||
|  |         timestr = "{:g} \u03BCs".format(time * 1e6) | ||||||
|  |  | ||||||
|  |     # nanoseconds or smaller | ||||||
|  |     else: | ||||||
|  |         timestr = "{:g} ns".format(time * 1e9) | ||||||
|  |  | ||||||
|  |     return timestr | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def ansi_len(string): | ||||||
|  |     """Extra length due to any ANSI sequences in the string.""" | ||||||
|  |     return len(string) - len(re.compile(r'\x1b[^m]*m').sub('', string)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def format_line(data, linestyle): | ||||||
|  |     """Formats a list of elements using the given line style""" | ||||||
|  |     return linestyle.begin + linestyle.sep.join(data) + linestyle.end | ||||||
| @@ -5,6 +5,7 @@ import pytest | |||||||
|  |  | ||||||
|  |  | ||||||
| def test_borders(): | def test_borders(): | ||||||
|  |     """Tests printing of the top and bottom borders""" | ||||||
|  |  | ||||||
|     # top |     # top | ||||||
|     assert top(5, width=2, style='round') == '╭──┬──┬──┬──┬──╮' |     assert top(5, width=2, style='round') == '╭──┬──┬──┬──┬──╮' | ||||||
| @@ -16,6 +17,7 @@ def test_borders(): | |||||||
|  |  | ||||||
|  |  | ||||||
| def test_row(): | def test_row(): | ||||||
|  |     """Tests printing of a single row of data""" | ||||||
|  |  | ||||||
|     # valid |     # valid | ||||||
|     assert row("abc", width=3, style='round') == '│  a│  b│  c│' |     assert row("abc", width=3, style='round') == '│  a│  b│  c│' | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| from tableprint import table, banner, dataframe, hr | from tableprint import table, banner, dataframe, hrule | ||||||
| from io import StringIO | from io import StringIO | ||||||
| import numpy as np | import numpy as np | ||||||
|  |  | ||||||
| @@ -23,6 +23,7 @@ def test_frame(): | |||||||
|         def __init__(self, data, headers): |         def __init__(self, data, headers): | ||||||
|             self.data = data |             self.data = data | ||||||
|             self.columns = headers |             self.columns = headers | ||||||
|  |  | ||||||
|         def __array__(self): |         def __array__(self): | ||||||
|             return self.data |             return self.data | ||||||
|  |  | ||||||
| @@ -44,8 +45,8 @@ def test_banner(): | |||||||
|     assert output.getvalue() == '╒═╕\n│!│\n╘═╛\n' |     assert output.getvalue() == '╒═╕\n│!│\n╘═╛\n' | ||||||
|  |  | ||||||
|  |  | ||||||
| def test_hr(): | def test_hrule(): | ||||||
|  |  | ||||||
|     output = hr(1, width=11) |     output = hrule(1, width=11) | ||||||
|     assert len(output) == 11 |     assert len(output) == 11 | ||||||
|     assert '───────────' |     assert '───────────' | ||||||
|   | |||||||
| @@ -1,20 +1,21 @@ | |||||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| from tableprint import humantime, _format_line, LineStyle | from tableprint import humantime, LineStyle | ||||||
|  | from tableprint.utils import format_line | ||||||
| import pytest | import pytest | ||||||
|  |  | ||||||
|  |  | ||||||
| def test_format_line(): | def test_format_line(): | ||||||
|  |  | ||||||
|     # using ASCII |     # using ASCII | ||||||
|     assert _format_line(['foo', 'bar'], LineStyle('(', '_', '+', ')')) == '(foo+bar)' |     assert format_line(['foo', 'bar'], LineStyle('(', '_', '+', ')')) == '(foo+bar)' | ||||||
|     assert _format_line("abc", LineStyle('[', '*', '.', ']')) == '[a.b.c]' |     assert format_line("abc", LineStyle('[', '*', '.', ']')) == '[a.b.c]' | ||||||
|     assert _format_line(["_"], LineStyle('o', '', '!', 'o')) == 'o_o' |     assert format_line(["_"], LineStyle('o', '', '!', 'o')) == 'o_o' | ||||||
|     assert _format_line([], LineStyle(':', '', '', ')')) == ':)' |     assert format_line([], LineStyle(':', '', '', ')')) == ':)' | ||||||
|  |  | ||||||
|     # using unicode |     # using unicode | ||||||
|     assert _format_line(['.', '.', '.'], LineStyle('★', '_', '╳', '☆')) == '★.╳.╳.☆' |     assert format_line(['.', '.', '.'], LineStyle('★', '_', '╳', '☆')) == '★.╳.╳.☆' | ||||||
|     assert _format_line("☚☛", LineStyle('♪', '*', '♩', '♫')) == '♪☚♩☛♫' |     assert format_line("☚☛", LineStyle('♪', '*', '♩', '♫')) == '♪☚♩☛♫' | ||||||
|  |  | ||||||
|  |  | ||||||
| def test_humantime(): | def test_humantime(): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user