In: Computer Science
In this homework you will implement a Library class that uses your Book and Person class from homework 2, with slight modifications. The Library class will keep track of people with membership and the books that they have checked out.
Book.java
You will need to modify your Book.java from homework 2 in the following ways:
field: dueDate (private)
A String containing the date book is due. Dates are given in the format "DD MM YYYY", such as "01 02 2017" (Feb. 1, 2017.) This will help when calculating the number of days a book is overdue.
Field: checkedOut (private)
A Boolean that is true if the book is checked out and false otherwise.
Field: bookId (private)
An int that holds the unique Id for the book. Because it is unique it will not be changed so you can declare it as final. This will be used to distinguish separate copies of the same book (with the same title and author).
Field: bookValue (private)
A double that holds the current value of the book in dollars.
Replace the old constructor with one that has the following method hearder
public Book(String title, String author, int bookId, double bookValue)
Add accessors and mutators for each of the new fields except for a mutator for bookId. Note that getters for boolean fields use "is" instead of the normal "get". For example the getter for checkedOut in the book class should be called isCheckedOut(). Update the equals method to only use the bookId since it is unique for each book. We do this because it is possiblie to have multiple copies of the same book (same title and author) and in this set up they would not be equal. Also, update the toString method.
Person.java
You will need to modify your Person.java from homework 2 in the following ways:
Field: address (private)
A String that contains the address for the person, e.g. "101 Main St." For simplicity, do not worry about including the city, state, or zip code.
Field: libraryCardNum (private)
An int that is the unique library id number for the person. Note that this replaces the id field from homework 2. Once this is set it will never change, so you can make if final if you would like.
Change the old constructor so that it has the following header and sets the correct fields:
public Person(String name, String address, int libraryCardNum)
Create accessors for the fields and mutators for the address field. Update equals method and toString. The ArrayList<Book> will now be called checkedOut and be a list of books the Person has checked out from the library. The addBook method will change slightly (see below). You can update the other methods as needed but they will not be used for this assignment and they will not be tested.
public boolean addBook(Book b)
Add the Book b to the list of the current object's checked out books if and only if it was not already in that list. Return true if the Book was added; return false if it was not added.
Library
Field: libraryBooks (private)
An ArrayList<Book> that holds all books for the library. Note that the library may have multiple copies of the same book (same title and author) but the bookId for each copy must be unique.
Field: patrons (private)
An ArrayList<Person> that holds all the people who are patrons of the library.
Field: name (private)
A String that holds the name of the library
Field: numBooks (private)
An int that keeps track of the number of books that are currently available to be checked out. A book that is checked out is not included in this count.
Field: numPeople (private)
An int that keeps the number of patrons to the library.
Field: currentDate (private)
A String that represents the current date. Dates are given in the format "DD MM YYYY", such as "01 10 2016" (Oct. 1, 2016) just like the due date.
Constructor
Write a constructor that takes in a String for the name of the library.
Accessors
Write accessors for each of the fields.
Mutators
Write a mutator for each field except for numBooks and numPeople as these depend on the other fields and should only be updated when the fields are updated or accessed.
Public int checkNumCopies( String title, String author)
A method that takes in a string for the title and author of a book and returns the number of copies of this book in the library (both checked out and available)
Public int totalNumBooks()
Returns the number of books in the library (either checked out or not)
Public boolean checkOut(Person p, Book b, String dueDate)
A method that checks out the book to the given person only if the person is a patron and the book is in the library and not currently checked out. Note that the book object being passed in may be equal to a book in the library but not the actual book in the library. That means you need to be sure to update the book in the library not the book being passed into the method. It will also update the due date for the book object. It will return true if the book is successfully checked out and false otherwise.
Public ArrayList<Book> booksDueOnDate(String date)
A method that returns an Array List of books due on the given date.
Public double lateFee(Person p)
This method will calculate the late fee the person owes. The late fee is based on the value of the book and the number of days the book is overdue. The fee is 1% of the book value for every day the book is overdue. For example if a book is worth $20 and is nine days late the late fee will be $1.80. If the Person has multiple books overdue then the late fees are simply added together.
To calculate the number of days between the current date and the date the book is due, we recommend that you look at the GregorianCalendar class. Google the API for help. If you want to use/write another method to calculate the number of days between the current date and the due date you are welcome to do so! If you get ideas from online, please remember to site your sources at the top of your .java file(s).
Testing
You will need to write at least two JUnit tests for each of the following methods in the Library class:
checkNumCopies
checkOut
booksDueOnDate and
lateFee
You are encouraged to write tests for the other methods but we will not require it. You will need to submit these to Web-CAT along with the rest of your code. Use standard naming conventions for these JUnit tests (include the word 'test' in the name somewhere - such as "testCheckOut"), otherwise we do not mind what you call them. Remember, it would be best if you do not have more than one assert statement per JUnit test case (method). There is no upper limit on how many JUnit test cases you write. Place all your JUnit test cases in one single file ("JUnit Test Case") - you do not need separate files to test Book.java, Person.java, and Library.java.
Constraints
Each .java file must have the assignment name (Homework 3)
Do not put your classes into a package - leave it as default. (If you don't know what this means, don't worry about it.)
Observe the basic naming conventions you've been shown in class.
Your code must be correctly indented. Most code editors have a way of doing this for you. In Eclipse, select all text with CTRL-A (Command-A on the Mac), and then do Source->Correct Indentation (which is CTRL-I on Windows and Command-I on the Mac).
If two methods share identical logic, you should factor that out into a separate method (a helper method).
Program Screenshots:
Sample output:
JunitTestCase:
Code to be copied:
Book.java
//Declare the class Book
public class Book
{
//Declare required variables variables
private String title;
private String author;
private String dueDate;
private boolean checkedOut;
private int bookId;
private double bookValue;
//constructor
public Book(String title, String author, int bookId, double bookValue )
{
this.title = title;
this.author = author;
this.bookId = bookId;
this.bookValue = bookValue;
}
//Accessor and mutator methodss
public String getTitle()
{
return this.title;
}
public String getAuthor()
{
return this.author;
}
public String getDueDate()
{
return this.dueDate;
}
public void setDueDate(String dueDate)
{
this.dueDate = dueDate;
}
public boolean isCheckedOut()
{
return checkedOut;
}
public void setCheckedOut(boolean checkedOut)
{
this.checkedOut = checkedOut;
}
public double getBookValue()
{
return bookValue;
}
public void setBookValue(double bookValue)
{
this.bookValue = bookValue;
}
public int getBookId()
{
return bookId;
}
//Implement the methods
public boolean equals(Object o)
{
if(o instanceof Book)
{
Book newObj = (Book) o;
return this.bookId == newObj.bookId;
}
return false;
}
//toString method
public String toString()
{
return "\nTitle: " + this.title + " " + "Author: " + this.author + " " + "ID #:" +
this.bookId + " " + "Price: " + this.bookValue + " ";
}
}
Person.java
//import reqyired packages
import java.util.ArrayList;
//Declare class
public class Person
{
//Declare variables
private String name;
private ArrayList<Book> getCheckedOut = new ArrayList<Book>();
private String address;
final private int libraryCardNum;
//Constructor
public Person(String name, String address, int libraryCardNum){
this.name = name;
this.address = address;
this.libraryCardNum = libraryCardNum;
}
//accessor and mutator methods
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getLibraryCardNum() {
return this.libraryCardNum;
}
public ArrayList<Book> getCheckedOut() {
return this.getCheckedOut;
}
public String getAddress(){
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
//Implement the methods
public boolean addBook(Book b)
{
if (getCheckedOut.contains(b)){
return false;
}
else{
getCheckedOut.add(b);
return true;
}
}
//implement method has read
public boolean hasRead(Book b){
if (getCheckedOut.contains(b)){
return true;
}
return false;
}
//check whether the book is there or not
//if the book is there then remove the book
public boolean removeBook(Book b)
{
if (getCheckedOut.contains(b))
{
getCheckedOut.remove(b);
return true;
}
return false;
}
//implement number of books to read
public int numBooksRead()
{
return getCheckedOut.size();
}
public boolean equals(Object o)
{
Person newPerson = (Person) o;
return this.libraryCardNum == newPerson.libraryCardNum;
}
//toString method
public String toString(){
return "Name: " + this.name + "\n" + "Address: "
+ this.address + "\n" + "Id:" + this.libraryCardNum + "\n" + "Books read: "
+ getCheckedOut.toString();
}
//Implement the method commonBooks
public static ArrayList<Book> commonBooksPersons(Person a, Person b)
{
//declare arraylist
ArrayList<Book> listOfCommonBooks = new ArrayList<Book>();
//Using for-loop to repeat the checked books
for(Book i : a.getCheckedOut){
for(Book j : b.getCheckedOut){
if(i.equals(j))
{
listOfCommonBooks.add(i);
}
}
}
return listOfCommonBooks;
}
//Implement the method silimarity with two person objects
public static double similaritymeasure(Person p1, Person p2)
{
double commonvalue = commonBooksPersons(p1, p2).size();
double total_checked = (p1.getCheckedOut.size() + p2.getCheckedOut.size());
return commonvalue / total_checked;
}
}
Library.java
//Import required classes
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
//Declare class Library
public class Library
{
//Declare arraylist of Books
private ArrayList<Book> libraryBooks = new ArrayList<Book>();
private ArrayList<Person> patrons = new ArrayList<Person>();
private int numBooks = getNumBooks();
private String currentDate = "02 22 2017";
private String name;
private int numPeople=patrons.size();
//Construtor
public Library(String name)
{
this.name = name;
}
//mutator and accessor methods
public ArrayList<Book> getLibraryBooks()
{
return this.libraryBooks;
}
public void setLibraryBooks(ArrayList<Book> libraryBooks) {
this.libraryBooks = libraryBooks;
}
public ArrayList<Person> getPatrons()
{
return patrons;
}
public void setPatrons(ArrayList<Person> patrons)
{
this.patrons = patrons;
}
public String getCurrentDate()
{
return currentDate;
}
public void setCurrentDate(String currentDate)
{
this.currentDate = currentDate;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNumBooks() {
this.numBooks = 0;
for(Book i: getLibraryBooks()){
this.numBooks ++;
if(i.isCheckedOut()){
this.numBooks --;
}
}
return numBooks;
}
public int getNumPeople()
{
return patrons.size();
}
//Implement the method checkNumCopies
public int checkNumCopies(String title, String author)
{
int copies = 0;
for(Book i: getLibraryBooks()){
if (i.getTitle().equals(title) && i.getAuthor().equals(author))
{
copies += 1;
}
}
return copies;
}
//Implement the method totalNumBooks
public int totalNumBooks()
{
int num = 0;
for(@SuppressWarnings("unused") Book i: getLibraryBooks())
{
num += 1;
}
return num;
}
//Implement the method checkout
public boolean checkOut(Person p, Book b, String dueDate)
{
if(patrons.contains(p) && libraryBooks.contains(b)){
int index = libraryBooks.indexOf(b);
if (!libraryBooks.get(index).isCheckedOut()){
libraryBooks.get(index).setCheckedOut(true);
libraryBooks.get(index).setDueDate(dueDate);
p.addBook(libraryBooks.get(index));
return true;
}
}
return false;
}
//Implement the method booksDueOnDate
public ArrayList<Book> booksDueOnDate(String tilldate)
{
ArrayList<Book> remainBooks = new ArrayList<Book>();
for(Book obj: libraryBooks){
if (obj.getDueDate() == tilldate){
remainBooks.add(obj);
}
}
return remainBooks;
}
//Implement the method lateFee
public double lateFee (Person personObj)
{
int remainDays = 0;
double lateFee = 0.0;
double totalValue = 0.0;
ArrayList<Book> listofBooks = new ArrayList<Book>();
for (Book i: personObj.getCheckedOut()){
if(Integer.parseInt(i.getDueDate().substring(6,10)) <= Integer.parseInt(currentDate.substring(6,10)))
{
if(!listofBooks.contains(i)) {listofBooks.add(i);};
remainDays += ((Integer.parseInt(currentDate.substring(6,10))) - (Integer.parseInt(i.getDueDate().substring(6,10)))) * 365.24;
if(Integer.parseInt(i.getDueDate().substring(3,5)) <= Integer.parseInt(currentDate.substring(3,5))){
if(!listofBooks.contains(i)) {listofBooks.add(i);};
remainDays += (Integer.parseInt(currentDate.substring(3,5)) - (Integer.parseInt(i.getDueDate().substring(3,5)))) * 30.42;
if (Integer.parseInt(i.getDueDate().substring(0,2)) <= Integer.parseInt(currentDate.substring(0,2))){
if(!listofBooks.contains(i)) {listofBooks.add(i);};
remainDays += Integer.parseInt(currentDate.substring(0,2)) - (Integer.parseInt(i.getDueDate().substring(0,2)));
}
}
}
else
{
remainDays += 0;
}
}
for (Book j: listofBooks)
{
totalValue = 0.01 * j.getBookValue();
}
lateFee += (totalValue) * remainDays;
return lateFee;
}
//implement the method getDate
public static String getDate()
{
String[] ids = TimeZone.getAvailableIDs(-5 * 60 * 60 * 1000);
SimpleTimeZone easternStndrd = new SimpleTimeZone(-5 * 60 * 60 * 1000, ids[0]);
easternStndrd.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
easternStndrd.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
Calendar dateBook = new GregorianCalendar(easternStndrd);
Date time = new Date();
dateBook.setTime(time);
String date = dateToString(dateBook.get(Calendar.DATE), dateBook.get(Calendar.MONTH),
dateBook.get(Calendar.YEAR) );
return date;
}
//implement the method to convert date as string
public static String dateToString(int days, int month, int year)
{
month += 1;
if (month > 9)
{
return days + " " + month + " " + year;
}
return days + " 0" + month + " " + year;
}
//main method
public static void main(String[] args)
{
//define the library object
final Library libraryObject = new Library("RoyalLibrary");
//define objects
final Book B1 = new Book("The Catcher in the Rye", "J.D.SAlingley", 1059810, 15.00);
final Book B2 = new Book("The Great Gatsby", "F. Scott Fitzgerald", 101985, 7.00);
final Book B3 = new Book("Animal Farm", "George Orwell", 9095483, 9.00);
final Book B4 = new Book("Molloy", "Samuel Beckett", 1029594, 8.50);
final Book B5 = new Book("The Man Who Was Thursday", "G.K. Chesterton", 10951898, 8.50);
final Book B6 = new Book("To kill a Mocking Bird", "Harper Lee", 3509483, 15.25);
final Book B7 = new Book("The Lion, The Witch, and The Wardrobe", "C.S. Lewis", 35099903, 15.25);
final Book B8 = new Book("To kill a Mocking Bird", "Harper Lee", 109554898, 17.20);
final Book B9 = new Book("Pride and Prejudice", "Jane Austin", 10961898, 9.50);
B1.setDueDate("02 01 1910");
B2.setDueDate("02 01 1915");
B3.setDueDate("02 01 1900");
B4.setDueDate("02 01 1900");
B5.setDueDate("17 02 2017");
B6.setDueDate("02 01 2000");
B7.setDueDate("02 01 2000");
B8.setDueDate("02 01 2010");
B9.setDueDate("02 01 2010");
final Person PERSON1 = new Person("George Orward", "Orward St.", 13825);
final Person PERSON2 = new Person("Mark Twait", "Denalwart St. ", 52831 );
final ArrayList<Person> people = new ArrayList<Person>();
people.add(PERSON1);
people.add(PERSON2);
libraryObject.setPatrons(people);
PERSON1.addBook(B9);
PERSON2.addBook(B1);
//define array list
final ArrayList<Book> listOfbooks = new ArrayList<Book>();
//add books in the list
listOfbooks.add(B1);
listOfbooks.add(B2);
listOfbooks.add(B3);
listOfbooks.add(B4);
listOfbooks.add(B5);
listOfbooks.add(B6);
listOfbooks.add(B7);
listOfbooks.add(B8);
listOfbooks.add(B9);
libraryObject.setLibraryBooks(listOfbooks);
//call the methods with the library object
System.out.println("Late Fee for Person 1: "+libraryObject.lateFee(PERSON1));
System.out.println("Late Fee for Person 2: "+libraryObject.lateFee(PERSON2));
System.out.println("Number of Copies: "+libraryObject.checkNumCopies("To kill a Mocking Bird", "Harper Lee"));
System.out.println("Books On Due Date: "+libraryObject.booksDueOnDate("02 01 1900"));
System.out.println("Books get Due Date: "+B4.getDueDate());
System.out.println("Number of People in library: "+libraryObject.getNumPeople());
}
}
LibraryTest.java
import static org.junit.Assert.*;
import java.util.ArrayList;
import org.junit.Test;
//Declare the class
public class LibraryTest
{
//Declare the String name
String LibraryName="OxFord";
//instantiate the class
Library obj=new Library(LibraryName);
//crare instances for the clases Person and Book
Person p = new Person("Will Temple", "Wertland St.", 13825);
Book b = new Book("The Wizard of Oz", "L. Frank Baum", 1059810, 15.00);
//JUnit testcase for the method testCheckNumCopies()
@Test
public void testCheckNumCopies()
{
assertEquals(obj.checkNumCopies("The Man Who Was Thursday", "G.K. Chesterton"),0);
assertEquals(obj.checkNumCopies("The Lion, The Witch, and The Wardrobe", "C.S. Lewis"),0);
}
//JUnit testcase for the method testCheckOut()
public void testCheckOut()
{
assertFalse(obj.checkOut(p, b, "01 12 2017"));
}
//JUnit testcase for the method testBooksDueOnDate()
public void testBooksDueOnDate()
{
ArrayList<String> ar = new ArrayList<>();
assertEquals(ar,obj.booksDueOnDate("02 01 1900"));
}
//JUnit testcase for the method testLateFee()
public void testLateFee()
{
assertFalse(obj.checkOut(p, b, "01 12 2017"));
//assertEquals(0, obj.lateFee(p));
}
}
Note: This Junit testcase is for Library class only.