44
44
Return a book: To return a book to the library which was issued to a member.
45
45
46
46
"""
47
+ from enum import Enum
47
48
48
49
50
+ class BookFormat (Enum ):
51
+ HARDCOVER , PAPERBACK , AUDIO_BOOK , EBOOK , NEWSPAPER , MAGAZINE , JOURNAL = 1 , 2 , 3 , 4 , 5 , 6 , 7
52
+
53
+
54
+ class BookStatus (Enum ):
55
+ AVAILABLE , RESERVED , LOANED , LOST = 1 , 2 , 3 , 4
56
+
57
+
58
+ class ReservationStatus (Enum ):
59
+ WAITING , PENDING , CANCELED , NONE = 1 , 2 , 3 , 4
60
+
61
+
62
+ class AccountStatus (Enum ):
63
+ ACTIVE , CLOSED , CANCELED , BLACKLISTED , NONE = 1 , 2 , 3 , 4 , 5
64
+
65
+
66
+ class Address :
67
+ def __init__ (self , street , city , state , zip_code , country ):
68
+ self .__street_address = street
69
+ self .__city = city
70
+ self .__state = state
71
+ self .__zip_code = zip_code
72
+ self .__country = country
73
+
74
+ from abc import ABC
75
+ class Person (ABC ):
76
+ def __init__ (self , name , address , email , phone ):
77
+ self .__name = name
78
+ self .__address = address
79
+ self .__email = email
80
+ self .__phone = phone
81
+
82
+
83
+ class Constants :
84
+ MAX_BOOKS_ISSUED_TO_A_USER = 5
85
+ MAX_LENDING_DAYS = 10
86
+
87
+ # For simplicity, we are not defining getter and setter functions. The reader can
88
+ # assume that all class attributes are private and accessed through their respective
89
+ # public getter methods and modified only through their public methods function.
90
+
91
+
92
+ from abc import ABC , abstractmethod , ABC , ABC
93
+
94
+
95
+ class Account (ABC ):
96
+ def __init__ (self , id , password , person , status = AccountStatus .Active ):
97
+ self .__id = id
98
+ self .__password = password
99
+ self .__status = status
100
+ self .__person = person
101
+
102
+ def reset_password (self ):
103
+ None
104
+
105
+
106
+ class Librarian (Account ):
107
+ def __init__ (self , id , password , person , status = AccountStatus .Active ):
108
+ super ().__init__ (id , password , person , status )
109
+
110
+ def add_book_item (self , book_item ):
111
+ None
112
+
113
+ def block_member (self , member ):
114
+ None
115
+
116
+ def un_block_member (self , member ):
117
+ None
118
+
119
+ import datetime
120
+ class Member (Account ):
121
+ def __init__ (self , id , password , person , status = AccountStatus .Active ):
122
+ super ().__init__ (id , password , person , status )
123
+ self .__date_of_membership = datetime .date .today ()
124
+ self .__total_books_checkedout = 0
125
+
126
+ def get_total_books_checkedout (self ):
127
+ return self .__total_books_checkedout
128
+
129
+ def reserve_book_item (self , book_item ):
130
+ None
131
+
132
+ def increment_total_books_checkedout (self ):
133
+ None
134
+
135
+ def renew_book_item (self , book_item ):
136
+ None
137
+
138
+ def checkout_book_item (self , book_item ):
139
+ if self .get_total_books_checked_out () >= Constants .MAX_BOOKS_ISSUED_TO_A_USER :
140
+ print ("The user has already checked-out maximum number of books" )
141
+ return False
142
+ book_reservation = BookReservation .fetch_reservation_details (
143
+ book_item .get_barcode ())
144
+ if book_reservation != None and book_reservation .get_member_id () != self .get_id ():
145
+ # book item has a pending reservation from another user
146
+ print ("self book is reserved by another member" )
147
+ return False
148
+ elif book_reservation != None :
149
+ # book item has a pending reservation from the give member, update it
150
+ book_reservation .update_status (ReservationStatus .COMPLETED )
151
+
152
+ if not book_item .checkout (self .get_id ()):
153
+ return False
154
+
155
+ self .increment_total_books_checkedout ()
156
+ return True
157
+
158
+ def check_for_fine (self , book_item_barcode ):
159
+ book_lending = BookLending .fetch_lending_details (book_item_barcode )
160
+ due_date = book_lending .get_due_date ()
161
+ today = datetime .date .today ()
162
+ # check if the book has been returned within the due date
163
+ if today > due_date :
164
+ diff = today - due_date
165
+ diff_days = diff .days
166
+ Fine .collect_fine (self .get_member_id (), diff_days )
167
+
168
+ def return_book_item (self , book_item ):
169
+ self .check_for_fine (book_item .get_barcode ())
170
+ book_reservation = BookReservation .fetch_reservation_details (
171
+ book_item .get_barcode ())
172
+ if book_reservation != None :
173
+ # book item has a pending reservation
174
+ book_item .update_book_item_status (BookStatus .RESERVED )
175
+ book_reservation .send_book_available_notification ()
176
+ book_item .update_book_item_status (BookStatus .AVAILABLE )
177
+
178
+ def renew_book_item (self , book_item ):
179
+ self .check_for_fine (book_item .get_barcode ())
180
+ book_reservation = BookReservation .fetch_reservation_details (
181
+ book_item .get_barcode ())
182
+ # check if self book item has a pending reservation from another member
183
+ if book_reservation != None and book_reservation .get_member_id () != self .get_member_id ():
184
+ print ("self book is reserved by another member" )
185
+ self .decrement_total_books_checkedout ()
186
+ book_item .update_book_item_state (BookStatus .RESERVED )
187
+ book_reservation .send_book_available_notification ()
188
+ return False
189
+ elif book_reservation != None :
190
+ # book item has a pending reservation from self member
191
+ book_reservation .update_status (ReservationStatus .COMPLETED )
192
+ BookLending .lend_book (book_item .get_bar_code (), self .get_member_id ())
193
+ book_item .update_due_date (
194
+ datetime .datetime .now ().AddDays (Constants .MAX_LENDING_DAYS ))
195
+ return True
196
+
197
+ class BookReservation :
198
+ def __init__ (self , creation_date , status , book_item_barcode , member_id ):
199
+ self .__creation_date = creation_date
200
+ self .__status = status
201
+ self .__book_item_barcode = book_item_barcode
202
+ self .__member_id = member_id
203
+
204
+ def fetch_reservation_details (self , barcode ):
205
+ None
206
+
207
+
208
+ class BookLending :
209
+ def __init__ (self , creation_date , due_date , book_item_barcode , member_id ):
210
+ self .__creation_date = creation_date
211
+ self .__due_date = due_date
212
+ self .__return_date = None
213
+ self .__book_item_barcode = book_item_barcode
214
+ self .__member_id = member_id
215
+
216
+ def lend_book (self , barcode , member_id ):
217
+ None
218
+
219
+ def fetch_lending_details (self , barcode ):
220
+ None
221
+
222
+
223
+ class Fine :
224
+ def __init__ (self , creation_date , book_item_barcode , member_id ):
225
+ self .__creation_date = creation_date
226
+ self .__book_item_barcode = book_item_barcode
227
+ self .__member_id = member_id
228
+
229
+ def collect_fine (self , member_id , days ):
230
+ None
231
+
232
+ from abc import ABC , abstractmethod
233
+
234
+ class Book (ABC ):
235
+ def __init__ (self , ISBN , title , subject , publisher , language , number_of_pages ):
236
+ self .__ISBN = ISBN
237
+ self .__title = title
238
+ self .__subject = subject
239
+ self .__publisher = publisher
240
+ self .__language = language
241
+ self .__number_of_pages = number_of_pages
242
+ self .__authors = []
243
+
244
+
245
+ class BookItem (Book ):
246
+ def __init__ (self , barcode , is_reference_only , borrowed , due_date , price , book_format , status , date_of_purchase , publication_date , placed_at ):
247
+ self .__barcode = barcode
248
+ self .__is_reference_only = is_reference_only
249
+ self .__borrowed = borrowed
250
+ self .__due_date = due_date
251
+ self .__price = price
252
+ self .__format = book_format
253
+ self .__status = status
254
+ self .__date_of_purchase = date_of_purchase
255
+ self .__publication_date = publication_date
256
+ self .__placed_at = placed_at
257
+
258
+ def checkout (self , member_id ):
259
+ if self .get_is_reference_only ():
260
+ print ("self book is Reference only and can't be issued" )
261
+ return False
262
+ if not BookLending .lend_book (self .get_bar_code (), member_id ):
263
+ return False
264
+ self .update_book_item_status (BookStatus .LOANED )
265
+ return True
266
+
267
+
268
+ class Rack :
269
+ def __init__ (self , number , location_identifier ):
270
+ self .__number = number
271
+ self .__location_identifier = location_identifier
272
+
273
+ from abc import ABC , abstractmethod
274
+
275
+ class Search (ABC ):
276
+ def search_by_title (self , title ):
277
+ None
278
+
279
+ def search_by_author (self , author ):
280
+ None
281
+
282
+ def search_by_subject (self , subject ):
283
+ None
284
+
285
+ def search_by_pub_date (self , publish_date ):
286
+ None
287
+
288
+
289
+ class Catalog (Search ):
290
+ def __init__ (self ):
291
+ self .__book_titles = {}
292
+ self .__book_authors = {}
293
+ self .__book_subjects = {}
294
+ self .__book_publication_dates = {}
295
+
296
+ def search_by_title (self , query ):
297
+ # return all books containing the string query in their title.
298
+ return self .__book_titles .get (query )
299
+
300
+ def search_by_author (self , query ):
301
+ # return all books containing the string query in their author's name.
302
+ return self .__book_authors .get (query )
0 commit comments