#πŸ”’ help with classes/instances

90 messages Β· Page 1 of 1 (latest)

crisp comet
#

i need to do make a code that does the following:
β€’ Define a Book class with attributes for title, author, and ISBN.
β€’ Define a User class with attributes for the user's name and a list of borrowed books.
β€’ Implement methods in the User class for borrowing and returning books.
β€’ Demonstrate the system's functionality with examples of several Book and User objects in
action.

this is what i have so far:

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

class User:
    booksborrowed = []
    
    def __init__(self, username, borrowed_books=0):
        self.__username = username
        self.borrowed_books = borrowed_books
   
    def borrowBook(self, book):
        self.booksborrowed.append(book)
        

    @classmethod
    def bookCount(cls):
        return f' {cls} has these books out: {booksborrowed}.'

im trying to add a class variable under the user class to be able to output the list of the borrowed books but its not working

topaz prairieBOT
#

@crisp comet

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

late token
#

booksborrowed = [] this is assigning to the class, not the User you instantiate. That's what you want?

crisp comet
#

well i want all the users to have it

#

isnt that what class variables are for

late token
#

You don't assign it to self, therefore it assigns to the class.

crisp comet
#

right

#

i want any user i create to have the ability to use that

#

oh wait

#

that wont work

late token
#

To their own list of borrowed books, right? Not some global that counts every user's borrowed books?

crisp comet
#

because every user is gonna have a unique list of books they have borrowed

#

i see what ur trying to point out

#

so that needs to be added to each individual user

late token
#

If you want to track what each User instance has borrowed, yes.

crisp comet
#

can i add that as a list>?

late token
#

That's what your borrowbook method attempts to look for. The instance (by using self)

#

When you instantiate the object (in the init), you probably want to assign the instance a list of empty borrowedbooks

#

If you wanted to track what all User instances have borrowed, then you could also add to the Class object and that would be one place that you could easily check across all Users if a book has been borrowed. But it won't help you track what each individual User has borrowed. For that you should assign a list to self.

crisp comet
#

once someone has it

#
class User:
    booksborrowed = []
    
    def __init__(self, username, borrowed_books=0):
        self.books_borrowed = []
        self.__username = username
        self.borrowed_books = borrowed_books
#

does this look right?

#

for my list

late token
#

Where's a good place to track that, do you reckon? πŸ˜‰

crisp comet
#

in the book class?

late token
#

Yep.

#

self.borrowed_books = borrowed_books
why this?

crisp comet
#

well i added the default value

late token
#

I reckon you could init the book to know whether it is self.available

crisp comet
#

so i wanted a way to add a book at user creation if necessary

crisp comet
#

the check should happen during user creation OR during the borrowBook method or whatever thats called

late token
#
class User:
    booksborrowed = []   # <= a class variable
    
    def __init__(self, username, borrowed_books=0):
        self.books_borrowed = []  # isn't this line enough?
        self.__username = username
        self.borrowed_books = borrowed_books  # <= why do you have this? you've already got self.books_borrowed. And creating a variable to point at the class variable doesn't make much sense

#

__init__ is a function that could do anything. You aren't only limited to what args it takes.

late token
#

so i have to add an aditional positional argument to get availability?

crisp comet
#
class User:    
    def __init__(self, username, borrowed_books=0):
        self.books_borrowed = []
        self.__username = username
        self.borrowed_books = borrowed_books
late token
#

Let's just do one thing at a time. Let's come back to book availability in a sec πŸ™‚

#

self.borrowed_books = borrowed_books <= what is this to achieve?

late token
#

So what would the argument expect, a list of Book objects?

#

And is this for an assignment? Just so I know how much code I can use.

crisp comet
#

ok so

#

maybe i need to make up mind here

#

i was thinking

#

upon user creation a person would either just create their user and nothing else, or they would create the user and borrow a book

crisp comet
#

and not complicate it needlessly

late token
#
class User:    
    def __init__(self, username, borrowed_books:list[Book] = False):
        self.books_borrowed = []
        for book in borrowed_books or []:
            self.borrowBook(book)
        self.__username = username
#

I think your borrowBook method needs to tell the Book it is no longer available.

#

And check if the Book is available before borrowing it.

#

upon user creation a person would either just create their user and nothing else, or they would create the user and borrow a book
You can do both, which is what I do here.

crisp comet
#

how does that look?

late token
#

what is books_borrowed?

#

Why don't you just ask the book directly if it is available?

crisp comet
#

ah sorry im being messy

#

books_borrowed is my empty list

#

thats gonna hold the books

#
class User:    
    def __init__(self, username):
        self.__username = username
           
    def borrowBook(self, book):
        self.books_borrowed = []
        if book not in books_borrowed:
            self.books_borrowed.append(book)
        else:
            return f'This book is not available.'
#

is this better?

crisp comet
late token
#

No... each time you go to borrow a book you wipe the list of books you've borrowed

crisp comet
#

how do i ask the book directly

late token
#
class User:    
    def __init__(self, username):
        self.books_borrowed = []
        self.__username = username
           
    def borrowBook(self, book):
        if book.available:
            book.check_out(self)
            self.books_borrowed.append(book)

class Book:
    def __init__(self, title, author, ISBN):
        self.title = title
        self.author = author
        self.ISBN = ISBN
        self.available = True
        self.checked_out_by = None

    def check_out(self, user):
        if self.available:
            self.checked_out_by = user
            self.available = False
        else:
            raise Exception() # this is unlikely to ever be hit as our User.borrowBook method checks before checking out
#

wait how?

def borrowBook(self, book):
        self.books_borrowed = []  # <= you wipe the list here
        if book not in books_borrowed:
            self.books_borrowed.append(book)
        else:
            return f'This book is not available.'
crisp comet
#

whats the .available

#

is that something u made or is that a conditional thing in python

late token
#

It's a boolean value set in the Book's init

#

ie When the book is created, it is available

#

It's nothing particular, just a variable called available with a boolean value

crisp comet
#

or thats just to be able to say which user?

late token
#

If you want to ask a book who it is checked out by, you do.
If you want to know if the book is available so 2 Users can't both check it out, you do.

late token
#

For eg you could use it in this way:

class Book:
    def __init__(self, title, author, ISBN):
        self.title = title
        self.author = author
        self.ISBN = ISBN
        self.available = True
        self.checked_out_by = None

    def check_out(self, user):
        if self.available:
            self.checked_out_by = user
            self.available = False
        else:
            raise Exception(f"The book is already checked out by {self.checked_out_by}")

    def get_checked_out_by(self):
      if self.available:
        return None
      return self.checked_out_by
crisp comet
#

i think a confusion i was having is thinking that

#

all the stuff under the init had to be a position arg

#

but apparentely it doesnt

#

what does raise do?>

late token
#

Yeah, that's why I said:

init is a function that could do anything. You aren't only limited to what args it takes.

late token
late token
#

It kinda comes together like this:

class Book:
    def __init__(self, title, author, ISBN):
        self.title = title
        self.author = author
        self.ISBN = ISBN
        self.available = True
        self.checked_out_by = None

    def check_out(self, user):
        if self.available:
            self.checked_out_by = user
            self.available = False
        else:
            raise Exception(f"The book is already checked out by {self.checked_out_by}")

    def get_checked_out_by(self):
      if self.available:
        return None
      return self.checked_out_by
    
class User:    
    def __init__(self, username):
        self.books_borrowed = []
        self.__username = username
           
    def borrowBook(self, book):
        if book.available:
            book.check_out(self)
            self.books_borrowed.append(book)

    def __repr__(self):
        return self.__username
        
user1 = User("daryl")
user2 = User("sleep")

book1 = Book("Eye of the World", "Robert Jordan", 123456789)

print(f"'{book1.title}' checked out by: {book1.get_checked_out_by()}")

user1.borrowBook(book1)
print(f"'{book1.title}' checked out by: {book1.get_checked_out_by()}")

user2.borrowBook(book1)
print(f"'{book1.title}' checked out by: {book1.get_checked_out_by()}")

print(f"\nBooks checked out by {user1}:")
for book in user1.books_borrowed:
    print(f" - '{book.title}' by {book.author}")
#

output:

'Eye of the World' checked out by: None
'Eye of the World' checked out by: daryl
'Eye of the World' checked out by: daryl

Books checked out by daryl:
 - 'Eye of the World' by Robert Jordan
#

book not checked out
user1 checks it out
user2 tries to check it out
user1 still has it, not user2

topaz prairieBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.