Giter Site home page Giter Site logo

nirum / tableprint Goto Github PK

View Code? Open in Web Editor NEW
174.0 7.0 16.0 489 KB

Pretty console printing :clipboard: of tabular data in python :snake:

Home Page: https://tableprint.readthedocs.io/

License: MIT License

Python 100.00%
terminal display print tabular-data python

tableprint's Issues

No width validation

When adding data that is wider than the tty screen, the table just breaks.

Auto-width

Love tableprint!

Since everything is monospaced, it should be easy to set the width on each column automatically based on the longest string value of each column (and its header). Could you please implement this? It would save precious horizontal space and fit more columns.

Feature request: Horizontal alignment

This is a simple, lightweight, and awesome package and exactly what I needed to print some database data in my CLI app. Any chance you could add two parameters for horizontal alignment that takes a string for the alignment of the cell data, such as "left", "center", or "right"? Something like header_align and row_align?? As it is right now I have to pad all the strings to be the same length as the longest one otherwise the table is difficult to read.

Thanks so much!

Drop Numpy as a hard requirement

Including Numpy as a necessary requirement is extremely heavy for a terminal printer. It seems like you just use it to convert a dataframe to an array and to do a floor function on a scalar(!). The latter can be easily replicated through math.floor in the stdlib, and for the former, you could attempt to import Numpy if it exists inside the dataframe function (if someone's giving you a Pandas dataframe you know there'll be Numpy).

Error executing on windows

I try this:

import tableprint as tp
tp.banner('test')

error:

Traceback (most recent call last):
  File "stats.py", line 83, in <module>
    main()
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\site-packages\click\core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\site-packages\click\core.py", line 697, in main
    rv = self.invoke(ctx)
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\site-packages\click\core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\site-packages\click\core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\site-packages\click\core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "stats.py", line 40, in dataset
    tp.banner('title_text')
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\site-packages\tableprint\printer.py", line 259, in banner
    out.write(header([message], max(width, len(message)), style) + '\n')
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\site-packages\colorama\ansitowin32.py", line 40, in write
    self.__convertor.write(text)
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\site-packages\colorama\ansitowin32.py", line 141, in write
    self.write_and_convert(text)
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\site-packages\colorama\ansitowin32.py", line 169, in write_and_convert
    self.write_plain_text(text, cursor, len(text))
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\site-packages\colorama\ansitowin32.py", line 174, in write_plain_text
    self.wrapped.write(text[start:end])
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\site-packages\colorama\ansitowin32.py", line 40, in write
    self.__convertor.write(text)
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\site-packages\colorama\ansitowin32.py", line 141, in write
    self.write_and_convert(text)
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\site-packages\colorama\ansitowin32.py", line 169, in write_and_convert
    self.write_plain_text(text, cursor, len(text))
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\site-packages\colorama\ansitowin32.py", line 174, in write_plain_text
    self.wrapped.write(text[start:end])
  File "C:\Users\acnazarejr\Anaconda3\envs\harhealth-sensors\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-31: character maps to <undefined>

Python version: 3.5.3
OS: Windows 10

feature request: print multiple items in a column (group by)

Something like:


-------------------------------
| A               | B1                   |
|                   |  B2                  |
|                   |   B3                 | 
--------------------------------

if A elements are the same, but B1 & B2 elements are different.
(in fact, table is a result of a "group by column 1" )
I can try to simulate this by inserting rows with zero value for column A, but i don't know that order will be kept.

Custom print command

It'd be useful if tableprint could accept a custom print command. In my use case, I want to progressively (print-as-I-go) print the values of TensorFlow 2 tensors in a table.

In autograph, the only way to print TensorFlow tensors is with tf.print—using print(my_tensor) doesn't print the value.

I can think of two ways to approach this:

  • accept a callable that defaults to Python's print.
    • The only problem is that there are certain options that tableprint may need to pass to tf.print; for example, output_stream. Since these arguments differ from those of Python's print, tableprint's implementation will need to use if statements to see if the callable is tf.print. This brings me to the second option:
  • accept a boolean called print_tensorflow that defaults to False. If True, print using tf.print.
    • I like this idea better since the first option implies that any callable can be used, such as click.echo, even if tableprint doesn't have click.echo's options implemented (of course, a NotImplementedError could be raised).
    • However, this would limit tableprint to only print and tf.print. If you want to add more callables in the future, you could always change this argument to a string, and use an if statement to see if the string is python, tensorflow, click, etc.

str(array) is not stable for table print

967757	2	30	14	100.00	1	[100.00]	[30, 14]
967722	2	14	6	100.00	2	[100.00, 100.00]	[30, 14, 6]
967699	2	6	2	100.00	3	[100.00, 100.00, 100.00]	[30, 14, 6, 2]
967686	2	2	0	100.00	4	[100.00, 100.00, 100.00, 100.00]	[30, 14, 6, 2, 0]
╭─────────────┬─────────────┬─────────────┬─────────────┬─────────────┬─────────────┬─────────────┬─────────────╮
│  policy_id  │  iteration  │     id      │   next_id   │ proability  │   length    │ proability_path │   id_path   │
├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
│      967757 │           2 │          30 │          14 │      100.00 │           1 │ [100.00]                         │ [30, 14]          │
│      967722 │           2 │          14 │           6 │      100.00 │           2 │ [100.00, 100.00]                 │ [30, 14, 6]       │
│      967699 │           2 │           6 │           2 │      100.00 │           3 │ [100.00, 100.00, 100.00]         │ [30, 14, 6, 2]    │
│      967686 │           2 │           2 │           0 │      100.00 │           4 │ [100.00, 100.00, 100.00, 100.00] │ [30, 14, 6, 2, 0] │
╰─────────────┴─────────────┴─────────────┴─────────────┴─────────────┴─────────────┴─────────────┴─────────────╯

ANSI escape not supported

The column size is improperly computed with the following example:

import tableprint as tp
from numpy.random import randn
from termcolor import colored

tp.table(randn(2,1), [colored('Foo', 'red')], style='fancy_grid')

It gives:

╒═══════════╕
│Foo│
╞═══════════╡
│  -0.060884│
│     -1.034│
╘═══════════╛

I think this can be corrected on header by using this:

    def format_headers(string):
        s = max(width - _ansi_len(string), 0)
        return (' ' * (s / 2)) + string + (' ' * (s - (s / 2))) if s else string

    data = map(format_headers, headers)  

Also the _ansi_len should be rewritten:

def _ansi_len(string):
    """Extra length due to any ANSI sequences in the string."""
    return len(re.sub(r'\x1b\[([0-9,A-Z]{1,2}(;[0-9]{1,2})?(;[0-9]{3})?)?[m|K]?', '', string))

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.