0

I want to create a Library Management System using Python 3.10.8 and OOPs approach.

I want to make two Instance attributes:

1)listOfBooks :containing the list of books available in the Library's collection(catalogue)

2.)books : containing the list of books in the Library that have not been issued by someone else.

I made a function for borrowing a book(borrowBook) which removes the borrowed book from list stored in books. But somehow list stored in listOfBooks also gets changed which I donot want because I want the displayBooks function to display all books in library collection and not just books which have not been issued.

# Creating Library Class and the 2 attributes
    class Library:
      def __init__(self, listOfBooks):
        self.listBooks = listOfBooks
        self.books = listOfBooks

# Creating function to display books available in library collection
    def displayBooks(self):
        print('Following is the list of books in the library catalogue:')
        for index, book in enumerate(self.listBooks):
            print(index+1, book)

# Creating function to borrow books
    def borrowBook(self, bookName):
        if bookName in self.listBooks:
            if bookName in self.books:
                print(
                    f'{bookName} has been issued to you. Please keep it safe and return it within 30 days!')
       

                self.books.remove(bookName)
            else:
                print(
                    'Sorry the requested book is currently issued to someone else! Please try again later.')
        else:
            print(
                f'{bookName} is currently unavailable in our library catalogue. Sorry for the inconvenience.')
# Creating library object
    centralLibrary = Library(
    ['C', 'C++', 'Algorithms', 'The Jungle Book', 'Heidi'])
# Testing the code
    centralLibrary.displayBooks()
    centralLibrary.borrowBook('The Jungle Book')
    centralLibrary.displayBooks()

How do I change the list inside books and simultaneously keep the list inside listOfBooks as it is?

Also why is the list inside listOfBooks changing anyway?

I am using VS Code(version 1.72.2) as IDE.

1
  • because they are the same list. You are just referring to it with two different names (attributes are just names in an object's namespace!). You probably want to copy it in your constructor, so self.books = listOfBooks.copy() Commented Dec 31, 2022 at 21:20

1 Answer 1

0

Instance variables are for data unique to each instance of a class, while class variables are shared by all instances of a class.

Make listOfBooks a class variable that is init'd with a method that appends the list of books that you pass to the class when constructing the Library object (i.e. an instance of Library class), which won't update on every instance:

class Library:
    listOfBooks = []
    def __init__(self, listOfBooks):
        self.books = listOfBooks
        Library.make_class_listOfBooks(listOfBooks) # call method on init

    # update class list with the starting list of books;
    @classmethod
    def make_class_listOfBooks(cls, starting_list_of_books):
        for index, book_name in enumerate(starting_list_of_books):
            cls.listOfBooks.append(book_name)

    # Creating function to display books available in library collection
    def displayBooks(self):
        print('Following is the list of books in the library catalogue:')
        for index, book in enumerate(Library.listOfBooks):
            print(index + 1, book)
    # Creating function to borrow books
    def borrowBook(self, bookName):
        if bookName in Library.listOfBooks:
            if bookName in self.books:
                print(f'{bookName} has been issued to you. Please keep it safe and return it within 30 days!')

                self.books.remove(bookName)
            else:
                print('Sorry the requested book is currently issued to someone else! Please try again later.')
        else:
            print(f'{bookName} is currently unavailable in our library catalogue. Sorry for the inconvenience.')

Running it:

# Creating library object
centralLibrary = Library(
  ['C', 'C++', 'Algorithms', 'The Jungle Book', 'Heidi'])
# Testing the code
centralLibrary.displayBooks()
centralLibrary.borrowBook('The Jungle Book')
centralLibrary.displayBooks()
centralLibrary.borrowBook('The Jungle Book')

Output:

Following is the list of books in the library catalogue:
1 C
2 C++
3 Algorithms
4 The Jungle Book
5 Heidi
The Jungle Book has been issued to you. Please keep it safe and return it within 30 days!
Following is the list of books in the library catalogue:
1 C
2 C++
3 Algorithms
4 The Jungle Book
5 Heidi
Sorry the requested book is currently issued to someone else! Please try again later.

Though your problem is due to assigning two instance attributes to the same object which could be resolved by using a copy (i.e. self.books = listOfBooks.copy()) in the constructor as
juanpa.arrivillaga had commented. Conceptually, if you wanted to change your Library's collection(catalogue) listOfBooks you'd probably want to change it not for just a single instance but for all instances of the Library class, hence my explanation for using a class variable instead of an instance variable.

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

8 Comments

I'm sorry, but this really makes no sense. Why use a class variable here? A Library should probably just have an twi instances variables. There is no need for the listOfBooks class variable. It is part of the instance state of the Library instance.
your comment self.books = listOfBooks.copy() is definitely simpler, but a Library class having a variable which does not change across instances would in most cases be defined as a class variable. "... this really makes no sense" it does make sense, you provided a simpler answer but conceptually it should be a class variable, not an instance variable. That is an explanation with an answer.
No, conceptually it should absolutely be an instance variable, or else you can only have a single library catalogue, but what if you want to work with multiple libraries? Why do you think it shouldn't change across instances? Different libraries have different catalogues.
But that isn't the context in which the question was asked. The code they provided contained one library list for storing all books as a dataset that was supposed to remain static upon initializing the Library class and not change across instances. A dictionary could have been provided for storing other things like the users names, too, for logging more information about the user, or separate database class, etc. but that's not what the original poster was asking.
" that was supposed to remain static upon initializing the Library class and not change across instances." there is nothing in their code that implies that.
|

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.