Gonzalo Dambra
Gonzalo Dambra

Reputation: 980

Recursively append childs of tree in __str__ method

I'm learning from a data structures and algorithms course where I made my own Tree (General Tree) implementation class, which looks like this:

class TreeNode:

    def __init__(self, data: Any) -> None:
        self.data = data
        self.children = []
        self.parent = None

    def __str__(self) -> str:
        return f'<{self.data} Tree[{self.children}]>'

    def add_childs(self, *childs: List) -> None:
        for child in childs:
            self.add_child(child)

    def add_child(self, child) -> None:
        if not isinstance(child, TreeNode):
            raise TypeError('TreeNode child must be another instance of TreeNode.')
        child.parnet = self
        self.children.append(child)

    def add_parent(self, parent) -> None:
        if not isinstance(parent, TreeNode):
            raise TypeError('TreeNode parent must be another instance of TreeNode.')
        parent.add_child(self)

And I'm testing this class with this:

def build_products_tree():
    tree = TreeNode('Electronics')
    laptops = TreeNode('Laptops')
    phones = TreeNode('Phones')
    tree.add_childs(laptops, phones)
    macbook = TreeNode('MacBook')
    dell = TreeNode('Dell')
    laptops.add_childs(macbook, dell)
    samsung = TreeNode('Samsung')
    iphone = TreeNode('iPhone')
    phones.add_childs(samsung, iphone)
    print(tree)


if __name__ == '__main__':
    build_products_tree()

I want the __str__ method to recursively add the children list (and their n nested values and so on) to the string value, like this:

<Electronics Tree[<Phones Tree[<iPhone Tree[]>, <Samsung Tree[]>]>, <Laptops Tree[<Dell Tree[]>, <MacBook Tree[]>]>]>

(I'll add this just for a more human-readable explanation):

<Electronics Tree[
    <Phones Tree[
        <iPhone Tree[]>, 
        <Samsung Tree[]>
    ]>, 
    <Laptops Tree[
        <Dell Tree[]>, 
        <MacBook Tree[]>
    ]>
]>

But the current behavior of the __str__ method is returning just this:

<Electronics Tree[[<__main__.TreeNode object at 0x7f7c0b6b82e0>, <__main__.TreeNode object at 0x7f7c0b688d00>]]>

Is there any way to achieve this w/o making complex iterations inside the __str__ method? I thought the __str__ definition would apply to the nested values too since they're instances of the same class.

Upvotes: 1

Views: 94

Answers (1)

Gonzalo Dambra
Gonzalo Dambra

Reputation: 980

As @quamrana suggested, I achieved it with __repr__ like this:

def __repr__(self) -> str:
    return f'<{self.data} Tree[{self.children}]>'

And the returning value is looking as expected:

<Electronics Tree[[<Laptops Tree[[<MacBook Tree[[]]>, <Dell Tree[[]]>]]>, <Phones Tree[[<Samsung Tree[[]]>, <iPhone Tree[[]]>]]>]]>

Upvotes: 1

Related Questions