Trying to print all nodes as a string in a linked list, however it prints location instead

Book Object with attributes: Title, Author, Year

class Book():
    def __init__(self, title = "", author = "", year = None):
        self.title = title
         self.author = author
    self.year = year

def getTitle(self):
    return self.title

def getAuthor(self):
    return self.author

def getYear(self):
    return self.year

def getBookDetails(self):
    string = ("Title: {}, Author: {}, Year: {}"\
                 .format(self.title, self.author, self.year))
    return string
    

Linked List called BookCollection

class BookCollection()
    def __init__(self):
        self.head = None
    
    def insertBook(self, book)
       temp = BookCollectionNode(book)
       temp.setNext(self.head)
       self.head = temp

    def getAllBooksInCollection(self):
        node = self.head

Here is the issue below. I amUsing a while loop to print each node, however its printing the location of the node

        while node:
            print(node)
            node = node.next

Node class called BookCollectionNode

class BookCollectionNode():

    def __init__(self, data):
       self.data = data
       self.next = None

    def getData(self):
       return self.data

    def getNext(self):
        return self.next

    def setData(self, newData):
        self.data = newData
    
    def setNext(self, newNext):
        self.next = newNext

Using the functions below to print the nodes of the linked list

b0 = Book("Cujo", "King, Stephen", 1981)
b1 = Book("The Shining", "King, Stephen", 1977)
b2 = Book("Ready Player One", "Cline, Ernest", 2011)
b3 = Book("Rage", "King, Stephen", 1977)

bc = BookCollection()
bc.insertBook(b0)
bc.insertBook(b2)
bc.insertBook(b3)

print(bc.getAllBooksInCollection())

>Solution :

Fix

As node is a BookCollectionNode, you need to access it’s book attribut, then call getBookDetails() method

def getAllBooksInCollection(self):
    node = self.head
    while node:
        print(node.data.getBookDetails())
        node = node.next

And call bc.getAllBooksInCollection() without the print. As there is no return statement, it returns None that you see printed


Improvements

  1. It seems you don’t really need methods to access your properties, but If you really want them, use @property

    class Book:
        def __init__(self, title="", author="", year=None):
            self._title = title
            self._author = author
            self._year = year
        @property
        def title(self):
            return self._title
        @property
        def author(self):
            return self._author
        @property
        def year(self):
            return self._year
    
  2. Override method __str__ to get a builtin string when printing

    class BookCollectionNode:
        def __str__(self):
            return str(self.data)
    
    class Book:    
        def __str__(self):
            return f"Title: {self._title}, Author: {self._author}, Year: {self._year}"
    
  3. For BookCollectionNode getter/setter, the proper way is

    class BookCollectionNode:
        def __init__(self, data):
            self._data = data
            self._next = None
        @property
        def data(self):
            return self._data
        @property
        def next(self):
            return self._next
        @data.setter
        def data(self, newData):
            self._data = newData
        @next.setter
        def next(self, newNext):
            self._next = newNext
    

Finally the BookCollection class becomes

class BookCollection:
    def __init__(self):
        self.head = None
    def insert_book(self, book):
        temp = BookCollectionNode(book)
        temp.next = self.head
        self.head = temp
    # 'print_' and not 'get_' as you don't return anything
    def print_all_books_in_collection(self):
        node = self.head
        while node:
            print(node)
            node = node.next

Leave a Reply