0

I have 4 classes:

1 - Book (superclass of Paperbook and eBook) 2 - Paperbook 3 - eBook 4 - Library (this class is to create a list of books from Paperbook and eBook)

After I append myEBook and myPaperbook to self.books list, how do I return the list of books I appended? Currently I'm only getting the object reference (i.e., [<main.eBook object at 0x1023e6e80>, <main.Paperbook object at 0x1023e6eb8>])

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

    def __str__(self):
        return '"{}" by {}'.format(self.title, self.author)


class Paperbook(Book):
    def __init__(self, title, author, numPages):
        Book.__init__(self, title, author)
        self.numPages = numPages


class eBook(Book):
    def __init__(self, title, author, size):
        Book.__init__(self, title, author)
        self.size = size


class Library:
    def __init__(self):
        self.books = []

    def addBook(self, book):
        self.books.append(book)

    def getNumBooks(self):
        return len(self.books)

    def __str__(self):
        return 'The book list: {}'.format(self.books)

myEBook = eBook('The Odyssey', 'Homer', 2)
print(myEBook, myEBook.size, 'MB big')

myPaperbook = Paperbook('The Odyssey', 'Homer', 500)
print(myPaperbook, myPaperbook.numPages, 'pages long')

booksLibrary = Library()
booksLibrary.addBook(myEBook)
booksLibrary.addBook(myPaperbook)
print(booksLibrary.getNumBooks())

print(booksLibrary) 
tulipz123
  • 47
  • 2

1 Answers1

0

You specify the __repr__(self): as well. When printing a list of items python will use the output of __repr__() to represent each item of the list.

You could fix your output by defaulting the output of __repr__ to be the same as the output of __str__ like so:

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

    def __str__(self): 
        return '"{}" by {}'.format(self.title, self.author)
    def __repr__(self): return str(self)


class Paperbook(Book):
    def __init__(self, title, author, numPages):
        Book.__init__(self, title, author)
        self.numPages = numPages
    
    def __str__(self):
        return f'"{self.title}" by {self.author} ({self.numPages} pages)' 
    def __repr__(self): return str(self)


class eBook(Book):
    def __init__(self, title, author, size):
        Book.__init__(self, title, author)
        self.size = size
        
    def __str__(self): 
        return f'"{self.title}" by {self.author} ({self.size} MB)' 
    def __repr__(self): return str(self)


class Library:
    def __init__(self):
        self.books = []

    def addBook(self, book):
        self.books.append(book)

    def getNumBooks(self):
        return len(self.books)

    def __str__(self):
        return 'The book list: {}'.format(self.books)

myEBook = eBook('The Odyssey', 'Homer', 2)
print(myEBook, myEBook.size, 'MB big')

myPaperbook = Paperbook('The Odyssey', 'Homer', 500)
print(myPaperbook, myPaperbook.numPages, 'pages long')

booksLibrary = Library()
booksLibrary.addBook(myEBook)
booksLibrary.addBook(myPaperbook)
print(booksLibrary.getNumBooks())

print(booksLibrary) 

Output:

"The Odyssey" by Homer (2 MB) 2 MB big
"The Odyssey" by Homer (500 pages) 500 pages long
2 
The book list: ["The Odyssey" by Homer (2 MB), "The Odyssey" by Homer (500 pages)]

It would probably a better user experience if you did some more styling to your output instead of simply printing the list-member of your class:

class Library: # removed identical methods

    def __str__(self):
        ordered = sorted(self.books, key = lambda b: (b.author, b.title))
        max_title = 0
        max_author = 0
        for b in ordered:
            max_title = max(len(b.title), max_title)
            max_author = max(len(b.author), max_author)

        return '\n- '.join(['The book list:'] + [str(o) for o in ordered])

# create a random library 
import random

# titles 
titles = [f"A book about {x}" for x in ("cooking", "booking", "looking",
          "spooking", "crooking", "brooding","weeding","growing","mowing")]
# names from module names, inlined to remove dependency
authors = ['Michael Paul', 'Brian Torres', 'David Evans', 'Amy Kramp', 'Robert Ray', 
           'Darin Winkler', 'Mary Schoettmer', 'Sharon Evans', 'Keri Rohman']

lib = Library()

# create stocked books
for _ in range(3):
    ti = random.choices(titles, k=3)
    au = random.choices(authors, k=3)
    for a,t in zip(au,ti):
        size = random.randint(2,8)
        lib.addBook(eBook(t,a,size))
        lib.addBook(Paperbook (t,a,size*123))

# print em
print(lib)

Output:

- "A book about booking" by Amy Kramp (3 MB)
- "A book about booking" by Amy Kramp (369 pages)
- "A book about looking" by Darin Winkler (8 MB)
- "A book about looking" by Darin Winkler (984 pages)
- "A book about weeding" by Darin Winkler (2 MB)
- "A book about weeding" by Darin Winkler (246 pages)
- "A book about weeding" by Darin Winkler (3 MB)
- "A book about weeding" by Darin Winkler (369 pages)
- "A book about cooking" by Keri Rohman (7 MB)
- "A book about cooking" by Keri Rohman (861 pages)
- "A book about weeding" by Keri Rohman (2 MB)
- "A book about weeding" by Keri Rohman (246 pages)
- "A book about weeding" by Michael Paul (2 MB)
- "A book about weeding" by Michael Paul (246 pages)
- "A book about looking" by Robert Ray (3 MB)
- "A book about looking" by Robert Ray (369 pages)
- "A book about growing" by Sharon Evans (4 MB)
- "A book about growing" by Sharon Evans (492 pages)
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • thanks for your help, Patrick. What about dictionary items? Do I also use __repr__ to return the dict values? – tulipz123 Nov 09 '20 at 15:56