Login

format output as table

Author:
bendavis78
Posted:
July 14, 2009
Language:
Python
Version:
1.0
Score:
4 (after 4 ratings)

Ever wished you could have pretty SQL-like output for a python object (e.g., a list of dicts) while you're debugging your code? This function will do just that. Simply pass it an object that is an iterable of dictionaries and it returns it in an easy-to-read table, similar to the output of commandline SQL.

Example:

from tablelize import tableize
from django.contrib.auth.models import User
print(tableize(User.objects.values('email', 'first_name', 'last_name')))
+------------+-----------+-------------------+
| first_name | last_name | email             |
+------------+-----------+-------------------+
| Test       | User      | [email protected]  |
| Another    | User      | [email protected] |
+------------+-----------+-------------------+
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
def tableize(obj):
    colwidths = []

    if type(obj) == list:
        obj = tuple(obj)

    #make sure we have an iterator of dicts, or a dictionary
    #import ipdb; ipdb.set_trace()
    if not(obj and isinstance(obj, dict) or (getattr(obj, '__iter__', False) \
        and not [x for x in obj if not isinstance(x,dict)])):
        raise TypeError("Object must be a dictionary or list/tuple/iterable of dictionaries")

    if type(obj) == dict:
        #convert to tuple of tuples
        obj = tuple([((('key',k),('value',v))) for k,v in obj.items()])
    
    #Convert to tuple of tuples
    obj = tuple([type(d)==dict and tuple(d.items()) or d for d in obj])

    #make sure each dict has the same keys
    keys = [k for k,v in obj[0]]
    try:
        [[dict(d)[k] for k in keys] for d in obj]
    except KeyError:
        assert False, "Dictionary keys do not match"

    #get column widths
    col_widths = dict([(k, len(k)) for k in keys])
    for row in obj:
        for k,v in row:
            if len(str(dict(row)[k])) > col_widths.get(k):
                col_widths[k] = len(str(dict(row)[k]))

    # build separator
    sep = '+'+'+'.join(['-'*(col_widths[k]+2) for k in keys])+'+'

    # print table headers
    lines = []
    lines.append(sep)
    lines.append('| '+' | '.join([k.ljust(col_widths[k]) for k in keys])+' |')
    lines.append(sep)
    
    # print table rows
    for row in obj:
        lines.append('| '+' | '.join([str(v).ljust(col_widths[k]) for k,v in row])+' |')

    lines.append(sep)

    return '\n'.join(lines)

def ptable(obj):
    print tableize(obj)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

buriy (on July 14, 2009):

colwidths = [] line is not used.

Everything else is awesome!

#

Please login first before commenting.