You are going to implement software for your local library. The user of the software will be the librarian, who uses your program to issue library cards, check books out to patrons, check books back in, send out overdue notices, and open and close the library.
In a number of methods, we will make a distinction between what the program appears to do (its behavior), and what it actually does (its implementation). For example, when we "issue a library card" to a patron, we don't create some kind of a "library_card object" and give it to a patron object; the implementation will achieve the same result by simply recording the patron's name in a dictionary. The visible behavior is the same: A person who has been "issued a library card" will be able to check out books. Don't let yourself be confused by the terminology.
You should not need any additional classes, but if you would like additional methods, feel free to write (and test!) them.
Create the following classes. Each class should be on a separate file, named after the class but lowercase: The All classes should be defined in a file named Calendar class should be on a file named calendar.py, the Patron class on a file named patron.py, etc. Test classes should be named TestCalendar, TestPatron, etc., and should be on files named test_calendar.py, test_patron.py, etc.library.py, and all test classes should be on a separate file named library_test.py.
class Calendar(object)date class, but to keep
things simple, we will just use an integer to keep
track of how many days have passed. This class needs only a couple of methods:
__init__(self)get_date(self)advance(self)class Book(object)id, title, author (only one author
per book), and due_date.
The due date is None if the book is not checked
out.
__init__(self, id, title, author)get_id(self)get_title(self)get_author(self)get_due_date(self)check_out(self, due_date)check_in(self)None. Doesn't return anything.__str__(self)"id: title, by
author".class Patron(object)__init__(self, name, library)get_name(self)check_out(self, book)give_back(self, book)return, but I hope you can see why I can't do that.) get_books(self)Book objects checked out to this patron (may be the
empty set, set([])).send_overdue_notice(self, notice)class Library(object)__init__(self)collection.txt, a list of (title, author) tuples,
Create a Book from each tuple, and save these books in some
appropriate data structure of your choice. Give each book a unique id number (starting from 1, not 0). You may have many copies of the "same" book (same title and author), but each will have its own id.Noneopen(self)Exception with the message "The library is already open!". Otherwise, starts the day by advancing the Calendar, and setting the flag to indicate that the library is open. ()."Today is day n."find_all_overdue_books(self)"No books are overdue.".issue_card(self, name_of_patron)"Library card issued to name_of_patron." or "name_of_patron already has a library card.".Exception: "The library is not open.". serve(self, name_of_patron)"Now serving name_of_patron." or "name_of_patron does not have a library card.". Exception: "The library is not open."find_overdue_books(self)__str__ method), of the books that have been checked out by the patron currently being served, and which are overdue. If the patron has no overdue books, the value None (not the string "None") is returned. the string "None" is printed. Exception with an appropriate message:
"The library is not open.""No patron is currently being served."check_in(self, *book_numbers)book_numbers are taken from the list printed by the
serve search command. Checking in a Book will involve
both telling the Book that it is checked in and
returning the Book to this library's collection of available
Books."name_of_patron has returned n books.".Exception with an appropriate message:
"The library is not open.""No patron is currently being served.""The patron does not have book id."search(self, string)Books whose title or author (or both)
contains this string. For example, the string "tact" might
return, among other things, the book Contact, by Carl Sagan.
The search should be case-insensitive; that is, "saga"
would also return this book. Only books which are currently available
(not checked out) will be found. If there is more than one copy of a book (with the same title and same author), only one will be found. In addition, to keep from returning
too many books, require that the search string be at least 4 characters
long."No books found.""Search string must contain at least four characters."__str__ method.) check_out(self, *book_ids)book_ids could have been found by a recent call to the search method.
Checking out a book will involve both telling the book that it
is checked out and removing the book from this library's
collection of available books. "n books have been checked out to name_of_patron.".Exception with an appropriate message:
"The library is not open.""No patron is currently being served.""The library does not have book id."renew(self, *book_ids)"n books have been renewed for name_of_patron.".Exception with an appropriate message:
"The library is not open.""No patron is currently being served.""The patron does not have book id."close(self)quit) can be used when the library is
closed."Good night.".Exception with the message "The library is not open." quit(self)"The library is now closed for renovations.".serve the patron. This will print a numbered list of books
checked out to that patron.check_in the books by the
numbers given above.serve the patron. You can ignore the list of books that this
will print out.search for a book wanted by
the patron (unless you already know its id).check_out zero or more books
by the numbers returned from the search command.search.Instance variables are variables that belong to an object, and instance methods are methods that are defined for an object. Instance variables and methods must be prefixed with self. , when used by the object itself. Local variables (including parameters) and global variables should not be prefixed with self. When an object uses the methods of another object, those methods must be prefixed by a variable that refers to the object; for example, book.get_title().
Three of the methods above, check_out,
check_in, and renew, have an asterisk in front of the last parameter. That
asterisk is new syntax--it means that, when you call the
method, you can give as many book numbers as you please; you don't have to
give just one. Inside the method, the parameter
book_ids is a tuple of all the numbers
(zero or more) that you gave it.
Zip together and turn in two files: library.py, containing all of the above classes, and library_test.py, containing all the unit tests.
It would be a good idea to read How Assignments Are Graded, but here's a summary: Do exactly what the assignment says to do, use good programming style, test your program carefully, zip up your program (if it's more than a single file), and turn it in via Blackboard. Late programs will lose points.
Your program is due before