<reponame>lukasjoc/scritps
from dataclasses import dataclass


@dataclass
class Node:
    left: any
    right: any
    freq: any


def display(head):
    lines, _, _, _ = _display_aux(head)
    for line in lines:
        print(line)


def _display_aux(node):
    """Returns list of strings, width, height, and horizontal coordinate of the root. this is 
       a utility function that gets used by the <display()> method for building pretty stdout 
       visualization of the binary tree. """

    # No child exists.
    if node.right is None and node.left is None:
        line = '%s' % node.freq
        width = len(line)
        height = 1
        middle = width // 2
        return [line], width, height, middle

    # Only left child exists.
    if node.right is None:
        lines, n, p, x = _display_aux(node.left)
        s = '%s' % node.freq
        u = len(s)
        first_line = (x + 1) * ' ' + (n - x - 1) * '_' + s
        second_line = x * ' ' + '/' + (n - x - 1 + u) * ' '
        shifted_lines = [line + u * ' ' for line in lines]
        return [first_line, second_line] + shifted_lines, n + u, p + 2, n + u // 2

    # Only right child exists.
    if node.left is None:
        lines, n, p, x = _display_aux(node.right)
        s = '%s' % node.freq
        u = len(s)
        first_line = s + x * '_' + (n - x) * ' '
        second_line = (u + x) * ' ' + '\\' + (n - x - 1) * ' '
        shifted_lines = [u * ' ' + line for line in lines]
        return [first_line, second_line] + shifted_lines, n + u, p + 2, u // 2

    # Two children exist.
    left, n, p, x = _display_aux(node.left)
    right, m, q, y = _display_aux(node.right)
    s = '%s' % node.freq
    u = len(s)
    first_line = (x + 1) * ' ' + (n - x - 1) * \
        '_' + s + y * '_' + (m - y) * ' '
    second_line = x * ' ' + '/' + \
        (n - x - 1 + u + y) * ' ' + '\\' + (m - y - 1) * ' '

    if p < q:
        left += [n * ' '] * (q - p)
    elif q < p:
        right += [m * ' '] * (p - q)
    zipped_lines = zip(left, right)
    lines = [first_line, second_line] + \
        [a + u * ' ' + b for a, b in zipped_lines]
    return lines, n + m + u, max(p, q) + 2, n + u // 2


head = Node(
    left=Node(Node(None, None, freq=0.25), Node(
        None, None, freq=0.25), freq=0.5),
    right=Node(None, None, freq=0.5),
    freq=1.0
)

display(head)

from dataclasses import dataclass


@dataclass
class Node:
    left: any
    right: any
    freq: any


def display(head):
    lines, _, _, _ = _display_aux(head)
    for line in lines:
        print(line)


def _display_aux(node):
    """Returns list of strings, width, height, and horizontal coordinate of the root. this is 
       a utility function that gets used by the <display()> method for building pretty stdout 
       visualization of the binary tree. """

    # No child exists.
    if node.right is None and node.left is None:
        line = '%s' % node.freq
        width = len(line)
        height = 1
        middle = width // 2
        return [line], width, height, middle

    # Only left child exists.
    if node.right is None:
        lines, n, p, x = _display_aux(node.left)
        s = '%s' % node.freq
        u = len(s)
        first_line = (x + 1) * ' ' + (n - x - 1) * '_' + s
        second_line = x * ' ' + '/' + (n - x - 1 + u) * ' '
        shifted_lines = [line + u * ' ' for line in lines]
        return [first_line, second_line] + shifted_lines, n + u, p + 2, n + u // 2

    # Only right child exists.
    if node.left is None:
        lines, n, p, x = _display_aux(node.right)
        s = '%s' % node.freq
        u = len(s)
        first_line = s + x * '_' + (n - x) * ' '
        second_line = (u + x) * ' ' + '\\' + (n - x - 1) * ' '
        shifted_lines = [u * ' ' + line for line in lines]
        return [first_line, second_line] + shifted_lines, n + u, p + 2, u // 2

    # Two children exist.
    left, n, p, x = _display_aux(node.left)
    right, m, q, y = _display_aux(node.right)
    s = '%s' % node.freq
    u = len(s)
    first_line = (x + 1) * ' ' + (n - x - 1) * \
        '_' + s + y * '_' + (m - y) * ' '
    second_line = x * ' ' + '/' + \
        (n - x - 1 + u + y) * ' ' + '\\' + (m - y - 1) * ' '

    if p < q:
        left += [n * ' '] * (q - p)
    elif q < p:
        right += [m * ' '] * (p - q)
    zipped_lines = zip(left, right)
    lines = [first_line, second_line] + \
        [a + u * ' ' + b for a, b in zipped_lines]
    return lines, n + m + u, max(p, q) + 2, n + u // 2


head = Node(
    left=Node(Node(None, None, freq=0.25), Node(
        None, None, freq=0.25), freq=0.5),
    right=Node(None, None, freq=0.5),
    freq=1.0
)

display(head)
Returns list of strings, width, height, and horizontal coordinate of the root. this is         a utility function that gets used by the <display()> method for building pretty stdout         visualization of the binary tree. # No child exists. # Only left child exists. # Only right child exists. # Two children exist.