PA - Final
CS 149: Programming Fundamentals
James Madison University, Fall 2021 Semester
PA Final: Dukes Library (Classes + Objects)


Objectives
- Implement a specific design from UML diagrams.
- Validate the arguments before updating an object.
- Write toString methods that use string formatting.
- Search for given values within an array of objects.
- Solve problems using object-oriented techniques.
Honor Code
This assignment must be completed individually. Your submission must conform to the JMU Honor Code. Authorized help is limited to general discussion on Piazza, the lab assistants assigned to CS149, and the instructor. Copying work from another student or the Internet is an honor code violation and will be grounds for a reduced or failing grade in the course.
Background
This assignment is inspired by the Little Free Library organization which has managed to charter small "libraries" like the one shown above all across the world. Each "library" encourages patrons to take a book or leave a book to promote accessibility of books and reading in general. They are community spaces, many with benches or seats nearby and all are maintained by volunteers. There are eight in Harrisonburg. The one at Thomas Harrison Middle School was built by the JMU Art Department. The one shown above is the Elizabeth Street Little Free Library, and the data file you will be using in the assignment is based on the books available in 2015 at the Elizabeth Street box.
Requirements
In this assignment, imagine that the Little Free Library organization has contracted with the JMU Computer Science department to track how much money they could earn if they were a commercial organization that charged late fees for overdue books. This information will then be used for local Little Free Library librarians to apply for funding from other non-profit foundations or the government. Each book and patron will be modeled by classes with relevant data and methods as outlined in the UML diagram and descriptions shown below. The Library class will then have arrays of books and patrons along with methods that allow for books to be checked in, checked out, and found in addition to determining fines. Your program will be based on the following files:
- DateUtils.java - This utility class is provided for you. Do not submit to Autolab.
- Driver.java - This example class is provided for you. Do not submit to Autolab.
- lflbooks.txt - Example books; based on Elizabeth St in Harrisonburg.
- patrons.txt - Example patrons; feel free to add yourself to this file!
- Book.java - You must write this class from scratch.
- Patron.java - You must write this class from scratch.
- Library.java - You must write this class from scratch.
You don't actually need the Driver to complete the assignment; it is simply provided to show how your classes might be used in a larger application. The following UML diagram illustrates the relationship of the classes to one another(Click the image for a larger pdf).
Book.java
-
The Book
constructor
will be used to initialize all attributes of the Book object. The initial status of the book should be AVAILABLE, and the patron and due date should be null. -
Like the constructor, the
checkin
method should set the book's status to AVAILABLE and assign null to both patron and due date. -
The
checkout
method should make the book UNAVAILABLE and save the given patron and due date in the object. -
The
equals
method checks whether two books have the same isbn. If the given object is a Book, compare this.isbn with the other book's isbn. If the given object is a String, compare this.isbn with the string. -
In the UML diagram, there are eight methods that start with get: one accessor method for each of the eight attributes. These return the value of the indicated attribute. Note that the class should have no "setX" methods.
-
The
toString
method should return a String representation of the book. If a book is initialized with the following parameters ("aaa", "bbb", "1234BBBBBBBBB", 2013, 10), it should return a String exactly as follows: "Title: aaa, Author: bbb, ISBN: 1234BBBBBBBBB, Year: 2013, Pages: 10."
Patron.java
-
The Patron
constructor
will be used to initialize all attributes of the Patron object. -
The
adjustBalance
will update the current balance of the patron. For example if the current balance of a Patron is 2.0 and the amount is 4.5, this method should assign 6.50 to this.balance and return 6.50. -
The
equals
method checks whether two patrons have the same id number. If the given object is a Patron, compare this.idNumber with the other patron's idNumber. If the given object is an Integer, compare this.idNumber with the Integer. -
The
toString
method should return a String representation of the Patron. If a patron is initialized with the following parameters ("bob", "eee", 2, 5.5), it should return a String exactly as follows: "Name: bob, Email: eee, ID: 2, Balance: $5.50."
Library.java
-
The Library
constructor
will initialize an array of Book and Patron objects using the book and patron array parameters. -
The
checkin
method will check in a book upon return. If the returned book belongs in the Library, and it is currently checked out, this method should update the status of the book, reset its patron and due date, determine the fine for this book (if any), and update the patron's balance. The return value indicates success or failure. For example, if the book is not in the library, checkin should return false. -
The
checkout
method will let a patron checkout a book that is available in the Library. If the book belongs to the library and is available, this method will update it's status and patron, and set the due date to ten days from today's date. The return value indicates success or failure. For example, if the book is not in the library, checkout should return false. -
The
determineFine
method will compute the fine currently due for a book that is checked out. For this method, the fine rate is $0.50 per day for each day after the due date. -
The
searchBooks
method searches for books, depending on the key and type, and returns an array of the books found. If no books are found, the resulting array will have a length of zero.- When type is TITLE_SEARCH, key will be a string containing the title to search. The method should return all books with that title.
- When type is AUTHOR_SEARCH, key will be a String containing the author's name. The method should return all books for that author.
- When type is PATRON_SEARCH, key will either be a Patron object or an Integer with the Patron's id. The method should return all books checked out to that patron.
- When type is OVERDUE_SEARCH, key will be a Date object. The method should return all books that will be overdue on that date (if not checked in before then).
Hints and Tips
-
Do not implement any other methods than what you see in the UML diagram. For example, you should not have a Patron.getBalance()method, even for testing purposes.
-
Do not use any static/instance variables in your test classes. JUnit will run your test methods in a random order, so it's best to use all local variables to avoid corrupting test data.
-
Make sure you're using the required constants Book.AVAILABLE, Library.TITLE_SEARCH, etc. Your test code should not use magic numbers like 1 or 2, or magic characters like 'A' or 'T'.
-
JUnit's assertEquals method automatically calls the object's equals method. So instead of writing assertTrue(book1.equals(book2)), you should just write assertEquals(book1, book2).
-
To implement the equals methods (in both Book and Patron), you'll need to use the instanceof operator. For example:
if (other instanceof Book) { Book b = (Book) other; ... }
-
You'll need to import the java.util.Date class. When you construct a new Date(), it will automatically contain today's date. If you want a relative date in the past, call DateUtils.addDays with a negative number of days.
-
The provided DateUtils class has all the methods you'll need for adding and subtracting dates. There's no need to reinvent the wheel! You should not be using any Date methods that are deprecated.
-
In searchBooks, you'll need to search the books array twice: once to count the number of books that will match the search, and a second time to build the resulting array.
-
Don't wait until the last day to finish this assignment! You'll need some time to prepare for the final exam and ask questions about anything you don't understand.
Submission
See your Canvas section for submission details and deadlines.
Part A: Readiness Quiz
- Read this specification, take notes. Ask questions about the specification. When you're ready, take the corresponding Canvas quiz for your section by its deadline.
For the last two parts, try to practice Test-Driven Development (TDD). With the understanding you have from Part A, write tests first, then develop your implementation to satisfy your tests.
Part B: Books and Patrons
- Create a new class called BookTest, and write your tests for the Book class in it.
- Develop your Book class to pass your tests in BookTest.
- Create a new class called PatronTest, and write your tests for the Patron class in it.
- Develop your Patron class to pass your tests in PatronTest.
- Submit a zip file (e.g. pa-finalb.zip) containing Book.java, BookTest.java, Patron.java, and PatronTest.java
Part C:
- Create a new class called LibraryTest, and write your tests for the Library class in it.
- Develop your Library class to pass your tests in LibraryTest.
- Update your BookTest, Book, Patron, and PatronTest as needed if you realize they don't work well now that you're adding Library.
- Submit a zip file (e.g. pa-finalc.zip) containing Book.java, BookTest.java, Patron.java, PatronTest.java, Library.java, and LibraryTest.java