Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
48
Task/Visualize-a-tree/Python/visualize-a-tree-1.py
Normal file
48
Task/Visualize-a-tree/Python/visualize-a-tree-1.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
Python 3.2.3 (default, May 3 2012, 15:54:42)
|
||||
[GCC 4.6.3] on linux2
|
||||
Type "copyright", "credits" or "license()" for more information.
|
||||
>>> help('pprint.pprint')
|
||||
Help on function pprint in pprint:
|
||||
|
||||
pprint.pprint = pprint(object, stream=None, indent=1, width=80, depth=None)
|
||||
Pretty-print a Python object to a stream [default is sys.stdout].
|
||||
|
||||
>>> from pprint import pprint
|
||||
>>> for tree in [ (1, 2, 3, 4, 5, 6, 7, 8),
|
||||
(1, (( 2, 3 ), (4, (5, ((6, 7), 8))))),
|
||||
((((1, 2), 3), 4), 5, 6, 7, 8) ]:
|
||||
print("\nTree %r can be pprint'd as:" % (tree, ))
|
||||
pprint(tree, indent=1, width=1)
|
||||
|
||||
|
||||
|
||||
Tree (1, 2, 3, 4, 5, 6, 7, 8) can be pprint'd as:
|
||||
(1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8)
|
||||
|
||||
Tree (1, ((2, 3), (4, (5, ((6, 7), 8))))) can be pprint'd as:
|
||||
(1,
|
||||
((2,
|
||||
3),
|
||||
(4,
|
||||
(5,
|
||||
((6,
|
||||
7),
|
||||
8)))))
|
||||
|
||||
Tree ((((1, 2), 3), 4), 5, 6, 7, 8) can be pprint'd as:
|
||||
((((1,
|
||||
2),
|
||||
3),
|
||||
4),
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8)
|
||||
>>>
|
||||
51
Task/Visualize-a-tree/Python/visualize-a-tree-2.py
Normal file
51
Task/Visualize-a-tree/Python/visualize-a-tree-2.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
>>> tree = "a",("b0",("c1","c2",("d",("ef","gh")),"c3",("i1","i2","i3",("jj"),"i4",("kk","m"))),"b1",("C1","C2",("D1",("E"),"D2","D3"),"C3"))
|
||||
>>> pprint(tree, width=1)
|
||||
('a',
|
||||
('b0',
|
||||
('c1',
|
||||
'c2',
|
||||
('d',
|
||||
('ef',
|
||||
'gh')),
|
||||
'c3',
|
||||
('i1',
|
||||
'i2',
|
||||
'i3',
|
||||
'jj',
|
||||
'i4',
|
||||
('kk',
|
||||
'm'))),
|
||||
'b1',
|
||||
('C1',
|
||||
'C2',
|
||||
('D1',
|
||||
'E',
|
||||
'D2',
|
||||
'D3'),
|
||||
'C3')))
|
||||
>>> copypasteoutput = ('a',
|
||||
... ('b0',
|
||||
... ('c1',
|
||||
... 'c2',
|
||||
... ('d',
|
||||
... ('ef',
|
||||
... 'gh')),
|
||||
... 'c3',
|
||||
... ('i1',
|
||||
... 'i2',
|
||||
... 'i3',
|
||||
... 'jj',
|
||||
... 'i4',
|
||||
... ('kk',
|
||||
... 'm'))),
|
||||
... 'b1',
|
||||
... ('C1',
|
||||
... 'C2',
|
||||
... ('D1',
|
||||
... 'E',
|
||||
... 'D2',
|
||||
... 'D3'),
|
||||
... 'C3')))
|
||||
>>> tree == copypasteoutput
|
||||
True
|
||||
>>>
|
||||
11
Task/Visualize-a-tree/Python/visualize-a-tree-3.py
Normal file
11
Task/Visualize-a-tree/Python/visualize-a-tree-3.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
>>> pprint(tree, width=60)
|
||||
('a',
|
||||
('b0',
|
||||
('c1',
|
||||
'c2',
|
||||
('d', ('ef', 'gh')),
|
||||
'c3',
|
||||
('i1', 'i2', 'i3', 'jj', 'i4', ('kk', 'm'))),
|
||||
'b1',
|
||||
('C1', 'C2', ('D1', 'E', 'D2', 'D3'), 'C3')))
|
||||
>>>
|
||||
38
Task/Visualize-a-tree/Python/visualize-a-tree-4.py
Normal file
38
Task/Visualize-a-tree/Python/visualize-a-tree-4.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
>>> mixedtree = ['a', ('b0', ('c1', 'c2', ['d', ('ef', 'gh')], 'c3', ('i1', 'i2',
|
||||
... 'i3', 'jj', 'i4', ['kk', 'm'])), 'b1', ('C1', 'C2', ('D1', 'E',
|
||||
... 'D2', 'D3'), 'C3'))]
|
||||
>>> pprint(mixedtree, width=1)
|
||||
['a',
|
||||
('b0',
|
||||
('c1',
|
||||
'c2',
|
||||
['d',
|
||||
('ef',
|
||||
'gh')],
|
||||
'c3',
|
||||
('i1',
|
||||
'i2',
|
||||
'i3',
|
||||
'jj',
|
||||
'i4',
|
||||
['kk',
|
||||
'm'])),
|
||||
'b1',
|
||||
('C1',
|
||||
'C2',
|
||||
('D1',
|
||||
'E',
|
||||
'D2',
|
||||
'D3'),
|
||||
'C3'))]
|
||||
>>> pprint(mixedtree, width=60)
|
||||
['a',
|
||||
('b0',
|
||||
('c1',
|
||||
'c2',
|
||||
['d', ('ef', 'gh')],
|
||||
'c3',
|
||||
('i1', 'i2', 'i3', 'jj', 'i4', ['kk', 'm'])),
|
||||
'b1',
|
||||
('C1', 'C2', ('D1', 'E', 'D2', 'D3'), 'C3'))]
|
||||
>>>
|
||||
331
Task/Visualize-a-tree/Python/visualize-a-tree-5.py
Normal file
331
Task/Visualize-a-tree/Python/visualize-a-tree-5.py
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
'''Textually visualized tree, with vertically-centered parent nodes'''
|
||||
|
||||
from functools import reduce
|
||||
from itertools import (chain, takewhile)
|
||||
|
||||
'''
|
||||
┌ Epsilon
|
||||
├─── Zeta
|
||||
┌─ Beta ┼──── Eta
|
||||
│ │ ┌───── Mu
|
||||
│ └── Theta ┤
|
||||
Alpha ┤ └───── Nu
|
||||
├ Gamma ────── Xi ─ Omicron
|
||||
│ ┌─── Iota
|
||||
└ Delta ┼── Kappa
|
||||
└─ Lambda
|
||||
'''
|
||||
# Tree style and algorithm inspired by the Haskell snippet at:
|
||||
# https://doisinkidney.com/snippets/drawing-trees.html
|
||||
|
||||
|
||||
# drawTree2 :: Bool -> Bool -> Tree a -> String
|
||||
def drawTree2(blnCompact):
|
||||
'''Monospaced UTF8 left-to-right text tree in a
|
||||
compact or expanded format, with any lines
|
||||
containing no nodes optionally pruned out.
|
||||
'''
|
||||
def go(blnPruned, tree):
|
||||
# measured :: a -> (Int, String)
|
||||
def measured(x):
|
||||
'''Value of a tree node
|
||||
tupled with string length.
|
||||
'''
|
||||
s = ' ' + str(x) + ' '
|
||||
return len(s), s
|
||||
|
||||
# lmrFromStrings :: [String] -> ([String], String, [String])
|
||||
def lmrFromStrings(xs):
|
||||
'''Lefts, Mid, Rights.'''
|
||||
i = len(xs) // 2
|
||||
ls, rs = xs[0:i], xs[i:]
|
||||
return ls, rs[0], rs[1:]
|
||||
|
||||
# stringsFromLMR :: ([String], String, [String]) -> [String]
|
||||
def stringsFromLMR(lmr):
|
||||
ls, m, rs = lmr
|
||||
return ls + [m] + rs
|
||||
|
||||
# fghOverLMR
|
||||
# :: (String -> String)
|
||||
# -> (String -> String)
|
||||
# -> (String -> String)
|
||||
# -> ([String], String, [String])
|
||||
# -> ([String], String, [String])
|
||||
def fghOverLMR(f, g, h):
|
||||
def go(lmr):
|
||||
ls, m, rs = lmr
|
||||
return (
|
||||
[f(x) for x in ls],
|
||||
g(m),
|
||||
[h(x) for x in rs]
|
||||
)
|
||||
return lambda lmr: go(lmr)
|
||||
|
||||
# leftPad :: Int -> String -> String
|
||||
def leftPad(n):
|
||||
return lambda s: (' ' * n) + s
|
||||
|
||||
# treeFix :: (Char, Char, Char) -> ([String], String, [String])
|
||||
# -> [String]
|
||||
def treeFix(l, m, r):
|
||||
def cfix(x):
|
||||
return lambda xs: x + xs
|
||||
return compose(stringsFromLMR)(
|
||||
fghOverLMR(cfix(l), cfix(m), cfix(r))
|
||||
)
|
||||
|
||||
def lmrBuild(w, f):
|
||||
def go(wsTree):
|
||||
nChars, x = wsTree['root']
|
||||
_x = ('─' * (w - nChars)) + x
|
||||
xs = wsTree['nest']
|
||||
lng = len(xs)
|
||||
|
||||
# linked :: String -> String
|
||||
def linked(s):
|
||||
c = s[0]
|
||||
t = s[1:]
|
||||
return _x + '┬' + t if '┌' == c else (
|
||||
_x + '┤' + t if '│' == c else (
|
||||
_x + '┼' + t if '├' == c else (
|
||||
_x + '┴' + t
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# LEAF ------------------------------------
|
||||
if 0 == lng:
|
||||
return ([], _x, [])
|
||||
|
||||
# SINGLE CHILD ----------------------------
|
||||
elif 1 == lng:
|
||||
def lineLinked(z):
|
||||
return _x + '─' + z
|
||||
rightAligned = leftPad(1 + w)
|
||||
return fghOverLMR(
|
||||
rightAligned,
|
||||
lineLinked,
|
||||
rightAligned
|
||||
)(f(xs[0]))
|
||||
|
||||
# CHILDREN --------------------------------
|
||||
else:
|
||||
rightAligned = leftPad(w)
|
||||
lmrs = [f(x) for x in xs]
|
||||
return fghOverLMR(
|
||||
rightAligned,
|
||||
linked,
|
||||
rightAligned
|
||||
)(
|
||||
lmrFromStrings(
|
||||
intercalate([] if blnCompact else ['│'])(
|
||||
[treeFix(' ', '┌', '│')(lmrs[0])] + [
|
||||
treeFix('│', '├', '│')(x) for x
|
||||
in lmrs[1:-1]
|
||||
] + [treeFix('│', '└', ' ')(lmrs[-1])]
|
||||
)
|
||||
)
|
||||
)
|
||||
return lambda wsTree: go(wsTree)
|
||||
|
||||
measuredTree = fmapTree(measured)(tree)
|
||||
levelWidths = reduce(
|
||||
lambda a, xs: a + [max(x[0] for x in xs)],
|
||||
levels(measuredTree),
|
||||
[]
|
||||
)
|
||||
treeLines = stringsFromLMR(
|
||||
foldr(lmrBuild)(None)(levelWidths)(
|
||||
measuredTree
|
||||
)
|
||||
)
|
||||
return [
|
||||
s for s in treeLines
|
||||
if any(c not in '│ ' for c in s)
|
||||
] if (not blnCompact and blnPruned) else treeLines
|
||||
|
||||
return lambda blnPruned: (
|
||||
lambda tree: '\n'.join(go(blnPruned, tree))
|
||||
)
|
||||
|
||||
|
||||
# TEST ----------------------------------------------------
|
||||
# main :: IO ()
|
||||
def main():
|
||||
'''Trees drawn in varying formats'''
|
||||
|
||||
# tree1 :: Tree Int
|
||||
tree1 = Node(1)([
|
||||
Node(2)([
|
||||
Node(4)([
|
||||
Node(7)([])
|
||||
]),
|
||||
Node(5)([])
|
||||
]),
|
||||
Node(3)([
|
||||
Node(6)([
|
||||
Node(8)([]),
|
||||
Node(9)([])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
# tree :: Tree String
|
||||
tree2 = Node('Alpha')([
|
||||
Node('Beta')([
|
||||
Node('Epsilon')([]),
|
||||
Node('Zeta')([]),
|
||||
Node('Eta')([]),
|
||||
Node('Theta')([
|
||||
Node('Mu')([]),
|
||||
Node('Nu')([])
|
||||
])
|
||||
]),
|
||||
Node('Gamma')([
|
||||
Node('Xi')([Node('Omicron')([])])
|
||||
]),
|
||||
Node('Delta')([
|
||||
Node('Iota')([]),
|
||||
Node('Kappa')([]),
|
||||
Node('Lambda')([])
|
||||
])
|
||||
])
|
||||
|
||||
print(
|
||||
'\n\n'.join([
|
||||
'Fully compacted (parents not all centered):',
|
||||
drawTree2(True)(False)(
|
||||
tree1
|
||||
),
|
||||
'Expanded with vertically centered parents:',
|
||||
drawTree2(False)(False)(
|
||||
tree2
|
||||
),
|
||||
'Centered parents with nodeless lines pruned out:',
|
||||
drawTree2(False)(True)(
|
||||
tree2
|
||||
)
|
||||
])
|
||||
)
|
||||
|
||||
|
||||
# GENERIC -------------------------------------------------
|
||||
|
||||
# Node :: a -> [Tree a] -> Tree a
|
||||
def Node(v):
|
||||
'''Contructor for a Tree node which connects a
|
||||
value of some kind to a list of zero or
|
||||
more child trees.
|
||||
'''
|
||||
return lambda xs: {'type': 'Tree', 'root': v, 'nest': xs}
|
||||
|
||||
|
||||
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
|
||||
def compose(g):
|
||||
'''Right to left function composition.'''
|
||||
return lambda f: lambda x: g(f(x))
|
||||
|
||||
|
||||
# concatMap :: (a -> [b]) -> [a] -> [b]
|
||||
def concatMap(f):
|
||||
'''A concatenated list over which a function has been mapped.
|
||||
The list monad can be derived by using a function f which
|
||||
wraps its output in a list,
|
||||
(using an empty list to represent computational failure).
|
||||
'''
|
||||
return lambda xs: list(
|
||||
chain.from_iterable(map(f, xs))
|
||||
)
|
||||
|
||||
|
||||
# fmapTree :: (a -> b) -> Tree a -> Tree b
|
||||
def fmapTree(f):
|
||||
'''A new tree holding the results of
|
||||
applying f to each root in
|
||||
the existing tree.
|
||||
'''
|
||||
def go(x):
|
||||
return Node(f(x['root']))(
|
||||
[go(v) for v in x['nest']]
|
||||
)
|
||||
return lambda tree: go(tree)
|
||||
|
||||
|
||||
# foldr :: (a -> b -> b) -> b -> [a] -> b
|
||||
def foldr(f):
|
||||
'''Right to left reduction of a list,
|
||||
using the binary operator f, and
|
||||
starting with an initial accumulator value.
|
||||
'''
|
||||
def g(x, a):
|
||||
return f(a, x)
|
||||
return lambda acc: lambda xs: reduce(
|
||||
g, xs[::-1], acc
|
||||
)
|
||||
|
||||
|
||||
# intercalate :: [a] -> [[a]] -> [a]
|
||||
# intercalate :: String -> [String] -> String
|
||||
def intercalate(x):
|
||||
'''The concatenation of xs
|
||||
interspersed with copies of x.
|
||||
'''
|
||||
return lambda xs: x.join(xs) if isinstance(x, str) else list(
|
||||
chain.from_iterable(
|
||||
reduce(lambda a, v: a + [x, v], xs[1:], [xs[0]])
|
||||
)
|
||||
) if xs else []
|
||||
|
||||
|
||||
# iterate :: (a -> a) -> a -> Gen [a]
|
||||
def iterate(f):
|
||||
'''An infinite list of repeated
|
||||
applications of f to x.
|
||||
'''
|
||||
def go(x):
|
||||
v = x
|
||||
while True:
|
||||
yield v
|
||||
v = f(v)
|
||||
return lambda x: go(x)
|
||||
|
||||
|
||||
# levels :: Tree a -> [[a]]
|
||||
def levels(tree):
|
||||
'''A list of the nodes at each level of the tree.'''
|
||||
return list(
|
||||
map_(map_(root))(
|
||||
takewhile(
|
||||
bool,
|
||||
iterate(concatMap(nest))(
|
||||
[tree]
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# map :: (a -> b) -> [a] -> [b]
|
||||
def map_(f):
|
||||
'''The list obtained by applying f
|
||||
to each element of xs.
|
||||
'''
|
||||
return lambda xs: list(map(f, xs))
|
||||
|
||||
|
||||
# nest :: Tree a -> [Tree a]
|
||||
def nest(t):
|
||||
'''Accessor function for children of tree node.'''
|
||||
return t['nest'] if 'nest' in t else None
|
||||
|
||||
|
||||
# root :: Tree a -> a
|
||||
def root(t):
|
||||
'''Accessor function for data of tree node.'''
|
||||
return t['root'] if 'root' in t else None
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
91
Task/Visualize-a-tree/Python/visualize-a-tree-6.py
Normal file
91
Task/Visualize-a-tree/Python/visualize-a-tree-6.py
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
'''Visualize a tree'''
|
||||
|
||||
from itertools import (chain, repeat, starmap)
|
||||
from operator import (add)
|
||||
|
||||
|
||||
# drawTree :: Tree a -> String
|
||||
def drawTree(tree):
|
||||
'''ASCII diagram of a tree.'''
|
||||
return '\n'.join(draw(tree))
|
||||
|
||||
|
||||
# draw :: Tree a -> [String]
|
||||
def draw(node):
|
||||
'''List of the lines of an ASCII
|
||||
diagram of a tree.'''
|
||||
def shift(first, other, xs):
|
||||
return list(starmap(
|
||||
add,
|
||||
zip(
|
||||
chain([first], repeat(other, len(xs) - 1)),
|
||||
xs
|
||||
)
|
||||
))
|
||||
|
||||
def drawSubTrees(xs):
|
||||
return (
|
||||
(
|
||||
['│'] + shift(
|
||||
'├─ ', '│ ', draw(xs[0])
|
||||
) + drawSubTrees(xs[1:])
|
||||
) if 1 < len(xs) else ['│'] + shift(
|
||||
'└─ ', ' ', draw(xs[0])
|
||||
)
|
||||
) if xs else []
|
||||
|
||||
return (str(root(node))).splitlines() + (
|
||||
drawSubTrees(nest(node))
|
||||
)
|
||||
|
||||
|
||||
# TEST ----------------------------------------------------
|
||||
# main :: IO ()
|
||||
def main():
|
||||
'''Test'''
|
||||
|
||||
# tree :: Tree Int
|
||||
tree = Node(1)([
|
||||
Node(2)([
|
||||
Node(4)([
|
||||
Node(7)([])
|
||||
]),
|
||||
Node(5)([])
|
||||
]),
|
||||
Node(3)([
|
||||
Node(6)([
|
||||
Node(8)([]),
|
||||
Node(9)([])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
print(drawTree(tree))
|
||||
|
||||
|
||||
# GENERIC -------------------------------------------------
|
||||
|
||||
|
||||
# Node :: a -> [Tree a] -> Tree a
|
||||
def Node(v):
|
||||
'''Contructor for a Tree node which connects a
|
||||
value of some kind to a list of zero or
|
||||
more child trees.'''
|
||||
return lambda xs: {'root': v, 'nest': xs}
|
||||
|
||||
|
||||
# nest :: Tree a -> [Tree a]
|
||||
def nest(tree):
|
||||
'''Accessor function for children of tree node.'''
|
||||
return tree['nest'] if 'nest' in tree else None
|
||||
|
||||
|
||||
# root :: Dict -> a
|
||||
def root(dct):
|
||||
'''Accessor function for data of tree node.'''
|
||||
return dct['root'] if 'root' in dct else None
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue