Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pretty Print output in a sideways tree format in console window

I have a dictionary such as this created using Python.

d = {'a': ['Adam', 'Book', 4], 'b': ['Bill', 'TV', 6, 'Jill', 'Sports', 1, 'Bill', 'Computer', 5], 'c': ['Bill', 'Sports', 3], 'd': ['Quin', 'Computer', 3, 'Adam', 'Computer', 3], 'e': ['Quin', 'TV', 2, 'Quin', 'Book', 5], 'f': ['Adam', 'Computer', 7]}

I wanted to print this out in a sideways tree format rather on the console. I've tried pretty print but when the dictionary gets long, it becomes difficult to read.

For example, with this dictionary, it would return:

a -> Book -> Adam -> 4
b -> TV -> Bill -> 6
  -> Sports -> Jill -> 1
  -> Computer -> Bill -> 5
c -> Sports -> Bill -> 3
d -> Computer -> Quin -> 3
              -> Adam -> 3
e -> TV -> Quin -> 2
    Book -> Quin -> 5
f -> Computer -> Adam -> 7

Essentially, the pretty print is organized by the Activity, or the item in second position in the list, then by name and then by the number.

The sample output above is just an example. I tried working with Pretty print a tree but was unable to figure out how to turn that into a sideways format.

like image 797
user1530318 Avatar asked Sep 04 '12 01:09

user1530318


2 Answers

Here's how I would do it. Since the tree is only two levels deep -- despite what your desired output format might seem to imply -- there's no need to use recursion to traverse its contents, as iteration works quite well. Probably this is nothing like the #f code you referenced, since I don't know the language, but it's a lot shorter and more readable -- at least to me.

from itertools import izip

def print_tree(tree):
    for key in sorted(tree.iterkeys()):
        data = tree[key]
        previous = data[0], data[1], data[2]
        first = True
        for name, activity, value in izip(*[iter(data)]*3):  # groups of three
            activity = activity if first or activity != previous[1] else ' '*len(activity)
            print '{} ->'.format(key) if first else '    ',
            print '{} -> {} -> {}'.format(activity, name, value)
            previous = name, activity, value
            first = False

d = {'a': ['Adam', 'Book', 4],
     'b': ['Bill', 'TV', 6, 'Jill', 'Sports', 1, 'Bill', 'Computer', 5],
     'c': ['Bill', 'Sports', 3],
     'd': ['Quin', 'Computer', 3, 'Adam', 'Computer', 3],
     'e': ['Quin', 'TV', 2, 'Quin', 'Book', 5],
     'f': ['Adam', 'Computer', 7]}

print_tree(d)

Output:

a -> Book -> Adam -> 4
b -> TV -> Bill -> 6
     Sports -> Jill -> 1
     Computer -> Bill -> 5
c -> Sports -> Bill -> 3
d -> Computer -> Quin -> 3
              -> Adam -> 3
e -> TV -> Quin -> 2
     Book -> Quin -> 5
f -> Computer -> Adam -> 7

Update

To organize the output by name instead of activity you'd need to change three lines as indicated below:

from itertools import izip

def print_tree(tree):
    for key in sorted(tree.iterkeys()):
        data = tree[key]
        previous = data[0], data[1], data[2]
        first = True
        for name, activity, value in sorted(izip(*[iter(data)]*3)):  # changed
            name = name if first or name != previous[0] else ' '*len(name) # changed
            print '{} ->'.format(key) if first else '    ',
            print '{} -> {} -> {}'.format(name, activity, value) # changed
            previous = name, activity, value
            first = False

Output after modification:

a -> Adam -> Book -> 4
b -> Bill -> Computer -> 5
          -> TV -> 6
     Jill -> Sports -> 1
c -> Bill -> Sports -> 3
d -> Adam -> Computer -> 3
     Quin -> Computer -> 3
e -> Quin -> Book -> 5
          -> TV -> 2
f -> Adam -> Computer -> 7
like image 45
martineau Avatar answered Sep 17 '22 00:09

martineau


You can have a look at the code of the ETE toolkit. The function _asciiArt produces nice representations of trees even with internal node labels

from ete2 import Tree
t = Tree("(((A,B), C), D);")
print t

#               /-A
#          /---|
#     /---|     \-B
#    |    |
#----|     \-C
#    |
#     \-D
like image 148
rme Avatar answered Sep 21 '22 00:09

rme