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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
# -*- coding: utf-8 -*-
# Copyright © 2009/2021 Andrey Vlasovskikh
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
# software and associated documentation files (the "Software"), to deal in the Software
# without restriction, including without limitation the rights to use, copy, modify,
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be included in all copies
# or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from __future__ import unicode_literals
def pretty_tree(x, kids, show):
"""Return a pseudo-graphic tree representation of the object `x` similar to the
`tree` command in Unix.
Type: `(T, Callable[[T], List[T]], Callable[[T], str]) -> str`
It applies the parameter `show` (which is a function of type `(T) -> str`) to get a
textual representation of the objects to show.
It applies the parameter `kids` (which is a function of type `(T) -> List[T]`) to
list the children of the object to show.
Examples:
```pycon
>>> print(pretty_tree(
... ["foo", ["bar", "baz"], "quux"],
... lambda obj: obj if isinstance(obj, list) else [],
... lambda obj: "[]" if isinstance(obj, list) else str(obj),
... ))
[]
|-- foo
|-- []
| |-- bar
| `-- baz
`-- quux
```
"""
(MID, END, CONT, LAST, ROOT) = ("|-- ", "`-- ", "| ", " ", "")
def rec(obj, indent, sym):
line = indent + sym + show(obj)
obj_kids = kids(obj)
if len(obj_kids) == 0:
return line
else:
if sym == MID:
next_indent = indent + CONT
elif sym == ROOT:
next_indent = indent + ROOT
else:
next_indent = indent + LAST
chars = [MID] * (len(obj_kids) - 1) + [END]
lines = [rec(kid, next_indent, sym) for kid, sym in zip(obj_kids, chars)]
return "\n".join([line] + lines)
return rec(x, "", ROOT)
|