Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

project-3 You will be writing a Library simulator involving multiple classes. You will write the LibraryItem, Patron and Library classes, and the three classes that

project-3

You will be writing a Library simulator involving multiple classes. You will write the LibraryItem, Patron and Library classes, and the three classes that inherit from LibraryItem (Book, Album and Movie). All data members of each class should be marked as private and the classes should have any get or set methods that will be needed to access them.

Here are descriptions of the three classes:

LibraryItem:

  • id_code - a unique identifier for a LibraryItem - you can assume uniqueness, you don't have to enforce it
  • title - cannot be assumed to be unique
  • location - a LibraryItem can be "ON_SHELF", "ON_HOLD_SHELF", or "CHECKED_OUT"
  • checked_out_by - refers to the Patron who has it checked out (if any)
  • requested_by - refers to the Patron who has requested it (if any); a LibraryItem can only be requested by one Patron at a time
  • date_checked_out - when a LibraryItem is checked out, this will be set to the current_date of the Library
  • init method - takes an id_code, and title; checked_out_by and requested_by should be initialized to None; a new LibraryItem's location should be on the shelf
  • get and set methods

Book/Album/Movie:

  • These three classes all inherit from LibraryItem.
  • All three will need a method called get_check_out_length that returns the number of days that type of library item may be checked out for. For a Book it's 21 days, for an Album it's 14 days, and for a Movie it's 7 days.
  • All three will have an additional field. For Book, it's a string field called author. For Album, it's a string field called artist. For Movie, it's a string field called director. There will also need to be get methods to return the values of these fields.

Patron:

  • id_num - a unique identifier for a Patron - you can assume uniqueness, you don't have to enforce it
  • name - cannot be assumed to be unique
  • checked_out_items - a list of LibraryItems that a Patron currently has checked out
  • fine_amount - how much the Patron owes the Library in late fines (measured in dollars); this is allowed to go negative
  • init method - takes an idNum and name
  • get and set methods
  • add_library_item - adds the specified LibraryItem to checked_out_items
  • remove_library_item - removes the specified LibraryItem from checked_out_items
  • amend_fine - a positive argument increases the fine_amount, a negative one decreases it; this is allowed to go negative

Library:

  • holdings - a list of the LibraryItems in the Library
  • members - a list of the Patrons in the Library
  • current_date - stores the current date represented as an integer number of "days" since the Library object was created
  • a constructor that initializes the current_date to zero
  • add_library_item - adds the parameter to holdings
  • add_patron - adds the parameter to members
  • get_library_item - returns the LibraryItem corresponding to the ID parameter, or None if no such LibraryItem is in the holdings
  • get_patron - returns the Patron corresponding to the ID parameter, or None if no such Patron is a member
  • In check_out_library_item, return_library_item and request_library_item, check the listed conditions in the order given - for example, if check_out_library_item is called with an invalid LibraryItem ID and an invalid Patron ID, it should just return "item not found".
  • check_out_library_item
    • if the specified LibraryItem is not in the Library's holdings, return "item not found"
    • if the specified Patron is not in the Library's members, return "patron not found"
    • if the specified LibraryItem is already checked out, return "item already checked out"
    • if the specified LibraryItem is on hold by another Patron, return "item on hold by other patron"
    • otherwise update the LibraryItem's checkedOutBy, dateCheckedOut and Location; if the LibraryItem was on hold for this Patron, update requestedBy; update the Patron's checkedOutItems; return "check out successful"
  • return_library_item
    • if the specified LibraryItem is not in the Library's holdings, return "item not found"
    • if the LibraryItem is not checked out, return "item already in library"
    • update the Patron's checkedOutItems; update the LibraryItem's location depending on whether another Patron has requested it (if so, it should go on the hold shelf); update the LibraryItem's checkedOutBy; return "return successful"
  • request_library_item
    • if the specified LibraryItem is not in the Library's holdings, return "item not found"
    • if the specified Patron is not in the Library's members, return "patron not found"
    • if the specified LibraryItem is already requested, return "item already on hold"
    • update the LibraryItem's requestedBy; if the LibraryItem is on the shelf, update its location to on hold; return "request successful"
  • pay_fine
    • takes as a parameter the amount that is being paid (not the negative of that amount)
    • if the specified Patron is not in the Library's members, return "patron not found"
    • use amendFine to update the Patron's fine; return "payment successful"
    • increment_current_date
    • increment current date; increase each Patron's fines by 10 cents for each overdue LibraryItem they have checked out (using amendFine)

Note - a LibraryItem can be on request without its location being the hold shelf (if another Patron has it checked out);

One limited example of how your classes might be used is:

 b1 = Book("123", "War and Peace", "Tolstoy") b2 = Book("234", "Moby Dick", "Melville") b3 = Book("345", "Phantom Tollbooth", "Juster") p1 = Patron("abc", "Felicity") p2 = Patron("bcd", "Waldo") lib = Library() lib.add_library_item(b1) lib.add_library_item(b2) lib.add_library_item(b3) lib.add_patron(p1) lib.add_patron(p2) lib.check_out_library_item("bcd", "234") for i in range(7): lib.increment_current_date() lib.check_out_library_item("bcd", "123") lib.check_out_library_item("abc", "345") for i in range(24): lib.increment_current_date() lib.pay_fine("bcd", 0.4) p1Fine = p1.get_fine_amount() p2Fine = p2.get_fine_amount() 

This example obviously doesn't include all of the functions described above. You are responsible for testing all of the required functions to make sure they operate as specified.

Your file must be named: Library.py

Just to think about: Since there are three possible locations for a LibraryItem, there are six hypothetical changes in location. Are all six possible according to these specifications?

My Code: class LibraryItem: checked_out_by = None requested_by = None date_checked_out = None def __init__(self, id_code, title): self._id_code = id_code """Unique identifier for library item""" self._title = title #cannot be unique??? """Non-unique name for library item""" self._location = "ON_SHELF" """Can be ON_SHELF, ON_HOLD_SHELF, or CHECKED_OUT""" self._checked_out_by = None """Refers to Patron who checked out item, if any""" self._requested_by = None """Refers to Patron who requested item, if any. Can be requested by one Patron at a time""" self._date_checked_out = 0 """When LibraryItem is checked out, this will be set to current_date of the Library""" def get_id_code(self): return self._id_code def set_id_code(self, id_code): self._id_code = id_code def get_title(self): return self._title def set_title(self, title): self._title = title def get_location(self): return self._location def set_location(self, location): self._location = location def get_checked_out_by(self): return self._checked_out_by def set_checked_out_by(self, name): self._checked_out_by = name def get_requested_by(self): return self._requested_by def set_requested_by(self, name): self._requested_by = name def get_date_checked_out(self): return self._date_checked_out def set_date_checked_out(self, date): self._date_checked_out = date class Book(LibraryItem): def __init__(self, id_code, title, author): super().__init__(id_code, title) self._author = author def get_check_out_length(self): return 21 def get_author(self): return self._author def set_author(self, author): self._author = author class Album(LibraryItem): def __init__(self, id_code, title, artist): super().__init__(id_code, title) self._artist = artist def get_check_out_length(self): return 14 def get_artist(self): return self._artist def set_artist(self, artist): self._artist = artist class Movie(LibraryItem): def __init__(self, id_code, title, director): super().__init__(id_code, title) self._director = director def get_check_out_length(self): return 7 def get_director(self): return self._director def set_director(self, director): self._set_director = director class Patron: def __init__(self, id_num, name): self._id_num = id_num self._name = name self._checked_out_items = [] self._fine_amount = 0.00 def add_library_item(self, library_item): """Adds input library item to the checked_out_items list""" self._checked_out_items.append(library_item) def remove_library_item(self, library_item): """Removes input library item from the checked_out_items list""" self._checked_out_items.remove(library_item) def amend_fine(self, amount): """When Called, changes the fine total""" self._fine_amount = self._fine_amount + amount def get_id_num(self): return self._id_num def set_id_num(self, id_num): self._id_num = id_num def get_name(self): return self._name def set_name(self, name): self._name = name def get_fine_amount(self): return self._fine_amount def set_fine_amount(self, fine_amount): self._fine_amount = fine_amount class Library: def __init__(self): self._holdings = [] self._members = [] self._current_date = 0 def get_current_date(self, day): return self._current_date def set_current_date(self, day): self._current_date = day def add_library_item(self, library_item): """Adds parameter to holdings""" self._holdings.append(library_item) def add_patron(self, patron): """Adds parameter to members""" self._members.append(patron) def get_library_item(self, library_item): """Returns the LibraryItem corresponding to the ID parameter""" for x in self._holdings: if library_item == self._holdings: return x else: return None def get_patron(self, patron_name): for x in self._members: if patron_name == x.get_id_num(): return x else: return None def check_out_library_item(self, id_num, id_code): library_item = self.get_library_item(id_code) patron_id = self.get_patron(id_num) if library_item == None: print("item not found") elif patron_id == None: print("item not found") if library_item == "CHECKED_OUT": return "item already checked out" if library_item.get_location() == "CHECKED_OUT": print("item already checked out") if library_item == "ON_HOLD_SHELF" and library_item.get_requested_by != id_num: return("item on hold by other patron") library_item.set_checked_out(id_num) library_item.set_date_checked_out(self._current_date) library_item.set_location("CHECKED_OUT") if library_item.get_requested_by() == id_num: library_item.set_requested_by(None) patron_id.add_library_item(self, id_code) print("check out successful") def return_library_item(self, id_code): library_item_id_test = self.get_library_item(id_code) patron_id_test = self.get_patron(id_code) if library_item_id_test == None: print("item not found") elif patron_id_test == None: print("item not found") else: if (library_item_id_test.get_location() != "CHECKED_OUT"): print("item already in library") patron_id_test.remove_library_item(id_code) if (library_item_id_test.get_requested_by != None): library_item_id_test.set_location("ON_HOLD_SHELF") else: library_item_id_test.set_location("ON_SHELF") library_item_id_test.set_checked_out(None) print("return successful") def request_library_item(self, id_num, id_code): library_item_id_test = self.get_library_item(id_code) patron_id_test = self.get_patron(id_num) if library_item_id_test == None: print("item not found") elif patron_id_test == None: print("item not found") else: if (library_item_id_test.get_location() == "ON_HOLD_SHELF"): print("item already on hold") else: library_item_id_test.set_requested_by(id_num) if (library_item_id_test.get_location() == "ON_SHELF"): library_item_id_test.set_location("ON_HOLD_SHELF") print("request successful") def increment_current_date(self): self._current_date = self._current_date + 1 def pay_fine(self, id_num, fine_total): patron = self.get_patron(id_num) if patron is None: print("patron not found") patron.amend_fine(fine_total) print("payment successful") b1 = Book("345", "Phantom Tollbooth", "Juster") #id_code, title, author a1 = Album("456", "...And His Orchestra", "The Fastbacks") #id_code, title, artist m1 = Movie("567", "Laputa", "Miyazaki") #id_code, title, director print(b1.get_author()) print(a1.get_artist()) print(m1.get_director()) p1 = Patron("abc", "Felicity") p2 = Patron("bcd", "Waldo") lib = Library() lib.add_library_item(b1) lib.add_library_item(a1) lib.add_patron(p1) lib.add_patron(p2) lib.check_out_library_item("bcd", "456") lib.request_library_item("abc", "456") for i in range(57): lib.increment_current_date() # 57 days pass p2_fine = p2.get_fine_amount() lib.pay_fine("bcd", p2_fine) lib.return_library_item("456")

I'm getting close, but it is not compiling correctly.

Traceback (most recent call last): File "C:/Users/Library.py", line 260, in lib.check_out_library_item("bcd", "456") File "C:/Users/Library.py", line 183, in check_out_library_item if library_item.get_location() == "CHECKED_OUT": AttributeError: 'NoneType' object has no attribute 'get_location'

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Database And Expert Systems Applications 19th International Conference Dexa 2008 Turin Italy September 2008 Proceedings Lncs 5181

Authors: Sourav S. Bhowmick ,Josef Kung ,Roland Wagner

2008th Edition

3540856536, 978-3540856535

More Books

Students also viewed these Databases questions