3

So I am making a basic directory system in python from scratch. I am pretty new to coding and am doing python as a Uni module. So I have made the functions for creating the tree from scratch, but now I have been tasked with actually just printing out the object as it is (not visually to see each step of the directory tree). So this is my code currently

class File:
    pass

class Directory(File):
    def __init__(self, name, left=None, right=None):
        self.name = name
        self.left = left
        self.right = right
        
    
    def __repr__(self):
        return f"{self.name}, {self.left}, {self.right}"
        

class PlainFile(File):
    def __init__(self, name):
        self.name = name
    
    def __str__(self):
        return self.name

When I try to print root, I want to essentially see the whole thing. But it gives me the <main.blahblah when printing the names of the classes and other parts too. I think my def__repr__ needs to be recursive in nature but for the life of me I have no clue how to do it:( Please help!

10
  • Unrelated to your direct question, but it seems like none of your directories have a right node since you've assigned a list to the left. Not sure if that's intended, but it seems a bit strange. Commented Nov 29, 2021 at 6:12
  • They do have right nodes unless they are a PlainFile (which is a leaf node). However Issac directory only has one node. Please see updated question for image of tree. Commented Nov 29, 2021 at 14:20
  • If you print root.right, you will get None. This is because the directory called "home" is the second entry in the list stored in root.left. Commented Nov 29, 2021 at 15:01
  • Ah okay, how would I change this? Commented Nov 29, 2021 at 15:58
  • 1
    I thought of something else that has simplified it all massively. Instead of using self.right and self.left I have just defined self.List_of_contents. What do you think of this? Commented Nov 29, 2021 at 17:18

1 Answer 1

1

If you make your PlainFile class implement __repr__(self) instead of __str__(self), it should work. See What is the difference between __str__ and __repr__? for more details. The good thing about your Directory class's __repr__ is that it's already recursive, since it would call the inner File's __repr__ functions when evaluating the f-string.

Edit: Adding a full solution to match the expected output.

class File:
    pass

class Directory(File):
    def __init__(self, name, left=None, right=None):
        self.name = name
        self.left = left
        self.right = right

    def __repr__(self):
        arg_str = ", ".join(
            str(arg)
            for arg in (self.name, self.left, self.right)
            if arg is not None
        )
        return f"Directory({arg_str})"


class PlainFile(File):
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return f"PlainFile({self.name})"

I use str() in the Directory implementation because it doesn't add quotes to the self.name since it's a string. By default, __str__ is implemented as __repr__, so it would also work on the File objects in left or right, and calling str() on a list will make it call repr() on its items.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much, okay so I did that and now it prints most of everything. However It prints 'none' where there is not a branch. To get rid of this none and make it exactly like the picture I linked, would I just include an if statement somewhere saying if = none print "" ? Also, the other thing I want is for it to also print where the class names have been called. In the picture I linked, it includes the whole object as originally written, including where it says Directory or PlainFile for example. How would I achieve this?
Yep you would need some if statements checking if the left or right are None when constructing your string. You can get the name of the class using type(self).__name__, or you could just hardcode it.
@BanAckerman I updated the answer with a full solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.