-2

How would I find a book in the "self.book_list" using the book_id and then return the book object?

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

book_id = int(input("Enter Book ID: "))

class Inventory:
    book_list = []
    def __init__(self):
        self.book_list.append(Book('Science: A Visual Encyclopedia', 1000))
        self.book_list.append(Book('My First Human Body Book', 1001))
        self.book_list.append(Book('The Runaway Children', 1002))
        self.book_list.append(Book('The Tuscan Child', 1003))
        self.book_list.append(Book('Learning Python', 1004))

    def display_books_in_inventory(self):
        for x in self.book_list:
            print (x)

    def find_book_in_inventory(self, book_id):
Turing85
  • 18,217
  • 7
  • 33
  • 58
  • 2
    What is `Book`? – Aplet123 Dec 18 '20 at 14:13
  • This is a section of the code, I have another `book` class. –  Dec 18 '20 at 14:15
  • How do you get the id of a `Book`? Can you include the `Book` class? – Aplet123 Dec 18 '20 at 14:15
  • 1
    The `Book` class you included is nothing like the `Book` you use in your `Inventory` constructor. The `Book` in `Inventory` should take a title and an id, in that order, but your constructor for `Book` takes a number, a title, an author, a genre, and a price, which you don't supply half of. I doubt this code can even run with the code you included. – Aplet123 Dec 18 '20 at 14:18
  • The id would be the numbers at the end of each line (1000,1001,etc.) The user will enter the id and it would print out the corresponding book info. –  Dec 18 '20 at 14:18
  • 2
    Your `Book` constructor doesn't seem to match up with your instantiations. Are you sure this is the correct version you're working with? – costaparas Dec 18 '20 at 14:19
  • This should give you a broader perspective for finding items in list. https://stackoverflow.com/questions/9542738/python-find-in-list – suvigyavijay Dec 18 '20 at 14:23
  • 1
    in your book constructur you have your `book_id` and your `title` in a different order. Also you got more non optional parameters you are not using. This constructor would match your instantiations: `def __init__(self, title, number, author=None, genre=None, price=None)` – SyntaxError Dec 18 '20 at 14:27
  • 3
    Please don't make more work for other people by vandalizing your posts. By posting on the Stack Exchange network, you've granted a non-revocable right, under the [CC BY-SA 4.0 license](//creativecommons.org/licenses/by-sa/4.0/), for Stack Exchange to distribute that content (i.e. regardless of your future choices). By Stack Exchange policy, the non-vandalized version of the post is the one which is distributed. Thus, any vandalism will be reverted. If you want to know more about deleting a post please see: [How does deleting work?](//meta.stackexchange.com/q/5221) – rene Dec 24 '20 at 17:23

2 Answers2

1

Assuming a Book() will have an attribute called .number with its identifier:

    def find_book_in_inventory(self, book_id):
        return next(book for book in self.book_list if book.number == book_id)

In the comments, people were asking for the definition of Book() because it was unclear what the identifier attribute would be called exactly.

The Book class you included is still clearly not the same you're using in the construction of the list, as Book('Science: A Visual Encyclopedia', 1000) only has two parameters, while Book.__init__() has 5 required parameters, where we can only assume number is the identifier.

Grismar
  • 27,561
  • 4
  • 31
  • 54
0

You need to fill the other required args in Book as they do not have a value. Parameters without a default value are required, if you don't define them while calling the class, you will get an error. Secondly, for the number arg in Book, you gave it a string instead, and for the title arg in Book you put an int. I'm pretty sure these were mistakes and you mixed up title and number. Thirdly, as the Book class is, putting it into a list isn't going to get you any good information about the Book class and its params, it's just going to give you the default string representation of the class, which is <__main__.Book object at [idk what this is]>. To fix this, you will have to put __str__() or __repr__() in your book class. Fourthly, there are no variables in the class Inventory other than book_list, you can't access anything else, in this case, it would be very useful to use variables for the books you are putting into the book_list list to access attributes of the books. Fifthly, there is no book id anywhere, you need that to get your book object. Finally, to answer your original question, you can't, you can only do that using dictionaries ({<book-id>: <book-object>}), not lists. However, one way to achieve what you are trying to do is to have the number arg as an index for book_list to get the book object you are trying to access. Final code:

class Book:
    def __init__(self, title, book_id, author=None, genre=None, price=None):
        self.book_id = book_id
        self.title = title
        self.author = author
        self.genre = genre
        self.price = price


class Inventory:
    def __init__(self, Book: Book):
        self.book_dict = {}
        self.book = Book
        self.book_dict.update({str(Book.id) : Book.title})

    def display_books(self):
        for x in self.book_dict:
            print(self.book_dict[x])

    def find_book_by_id(self, book_id):
        return self.book_dict[str(book_id)]
        
nonimportant
  • 406
  • 4
  • 15