CSC108/A08 Assignment 2

Buying Books for University

Due: Tuesday, March 8, 2005, 9:00 a.m.(sharp)

Introduction

This assignment will give you practise writing if statements, loops, and manipulating Strings. You will also develop a test suite.

Plan to spend a full hour reading this handout so that you thoroughly understand what we are asking for. Do this before you start programming! Take notes as you read. What classes do we want? What are the method names for each? Be sure to read all sections!
If you notice parts that are unclear, then see your instructor or your TA, or post a message to the 108 bulletin board.

The Hints and Announcements page is required reading.

Background

A student attends a university. Every year, the student must buy textbooks. The student wants to keep her costs down as much as possible: first she sells books already in her possession that are not required for the current academic year, and then she buys the required ones. All transactions take place at the university book store.

The Task

For this assignment, you are asked to produce eight classes: University, BookReference, Student, BookStore, UniversityTester, BookReferenceTester, StudentTester, and BookStoreTester. As you can see by their names, the last four exist in order to test the first four.

For University, BookReference, Student, BookStore an exact specification is given below.

For UniversityTester, BookReferenceTester, StudentTester, and BookStoreTester, we give you general guidelines. Although we don't give you exact instructions, you can read here about the general idea.

Clarification and Special Instructions

Pay close attention to the all methods described in the descriptions below! There are two crucial things to remember:

As a general rule, none of the inputs to the methods will be null, or "". Assume that all of the input strings will be provided in the correct, expected format.

Terminology

Restrictions

Class BookReference

The university provides lists of the books required for each academic year. There are four academic years, therefore there are four book-lists. As well, there is a single price list, which contains the wholesale and retail price for each book that is on a list. All of these lists are maintained and accessed in a BookReference object.

Each book-list is kept as a String consisting of the book titles, separated by the character #.
e.g.: "Introduction to Calculus#Probability#Multimedia Introduction to Programming Using Java#Introduction to Unix#Linear Algebra"

Note: The # symbol only appears between books, and not at the end of the String.

Variables

Type Description
String A book-list for the first academic year.
String A book-list for the second academic year.
String A book-list for the third academic year.
String A book-list for the fourth academic year.
String The price list for all of the books in the book-lists. The price list is a String consisting of units of information about each book. The units are separated by the character #. Within each unit is the book title, followed by the wholesale price, followed by the retail price. These fields are separated by the character :.
e.g.: "Introduction to Calculus:50.00:100.00#Probability:34.27:69.50#Linear Algebra:26.46:47.31"

Methods

BookReference supports the following methods:

Constructor Description

BookReference(String, String, String, String, String)

Constructor for the BookReference class. Takes in four book-lists, one for each academic year; and a price list. The first String represents the list for first year, the second String represents the list for second year, etc. The price list is in the last String passed. All lists are provided in the format required by the instance variable.

BookReference(String, String, String, String)

Constructor for the BookReference class. Takes in Strings representing four book-lists, one for each academic year. The first String represents the list for first year, the second String represents the list for second year, etc. These Strings have a different format from that in the first constructor: the price information is contained in each book-list String. Each String consists of units of information about each book. The units are separated by the character #. Within each unit is the book title, followed by the wholesale price, followed by the retail price. These fields are separated by the character :.
e.g.: "Introduction to Calculus:50.00:100.00#Probability:34.27:69.50#Linear Algebra:26.46:47.31"
The information must be extracted, and added, in the appropriate form, to the price list and the book-list for the corresponding year.

Method Description

bookRequired(String)

Takes the book passed in String and compares it to all of the books in all of the book-lists. Returns true if the book is in any of the book-lists; returns false otherwise. The purpose of this method is to determine whether a book is still required. If it is not, a book store will usually not purchase the book back from the student. (Hint: A helper method may be useful.)

bookFound(String, String)

This static method accepts String book name and a String list of books (in the format of the yearly book-list variable: book titles separated by a #). This method returns true if the book name is found in the list, otherwise it returns false.

getBookList(int)

Accepts an int representing the year of study, and returns the String book-list for that year. This method is usually used by the student to obtain the list of books that they will need to buy for their academic year. You may assume that only 1, 2, 3 or 4 will be entered (you do not need to do any error checking).

getWholesalePrice(String)

Accepts a String representing the name of a book, and returns the double wholesale price for that book. If the book is not in the price list, this method returns 0.0. All books in the book-list must also be found in the price-list.

getRetailPrice(String)

Accepts a String representing the name of a book, and returns the double retail price for that book. If the book is not in the price list, this method returns 0.0. All books in the book-list must also be found in the price-list.

removeBooks(String, String)

This static method accepts String listA and String listB. The book titles in each list are separated with a # character. It returns a #-delimited String: a list containing all the book titles in listB minus those that occur in listA.

Class BookStore

The BookStore class represents a book store. It has a number of fields containing information essential to running a book store, and methods to manipulate the fields.

The BookStore class has the following fields:

Variables

Type Description
double

Cost Multiplier: The percentage of the listed wholesale price that this book store pays when purchasing books. Represented as a double with a value 0 < cost multiplier ≤ 1.0. This cost multiplier is applied to all book purchases.

double

Sale Multiplier: The percentage of the listed retail price that this book store sells its books for. Represented as a double with a value 0 < sale multiplier ≤ 1.0. This sale multiplier is applied to all book sales.

double The total sales income for this store.
double The total costs for purchasing books for this store.
String The inventory of books on hand in this store.
Inventory format: The books on hand are kept in a contiguous String. The name of the book and the quantity are stored for each title and are joined by the character :. Each block of information (for a single book) is separated from the next by a # character.
eg:"Programming Using Java:30#Systems Analysis with UML:45# ..."
BookReference The book-lists used to identify books used by the local university, as well as the publisher's retail and wholesale prices for the books.

Methods

The BookStore class supports the following methods:

Constructor Description

BookStore(BookReference, double, double)

Constructor for the BookStore class. Takes the BookReference for the local university book-lists, the double cost multiplier, and the double sale multiplier.

BookStore(BookReference, double, double, String)

Constructor for the BookStore class. Takes the BookReference for the local university book-lists, the double cost multiplier, the double sale multiplier, and the String list of books to be added to the books on hand inventory. The books are separated from each other by a # character.
Example of list of books to be added: "Algebra II#Programming for all#Java Swing#Algebra II"
The books are added to the inventory one at a time. For each book added: the cost for that book must be calculated and added to the total store costs; and the book must be added to the inventory of books on hand in a way that preserves the strict format of the inventory variable (described in variables above). When adding a book to the inventory, if the book title is already present, increase the quantity by one, otherwise, add the book to the inventory with an initial quantity of one. The book titles in the String parameter are all required books already in the BookReference parameter. Remember that the wholesale cost of these books must be reflected in the double instance variable representing total costs.

Method Name Description

getCosts()

Return total costs for purchasing books for this store (as a double).

getSales()

Return total sales income for this store (as a double).

addCosts(String)

Add the cost of the book (with title given as a String) to the total costs for this book store. Return the book cost (as a double). If the book does not exist on the price list, return 0.0. (Hint: This can be used as a helper method.)

addSales(String)

Get the retail price of the String book; calculate the sale value for the book store by multiplying the retail price by the sale multiplier; and add the sale value to the total sales for the store. Return the sale value for this book (as a double). If the book does not exist on the price list, return 0.0.

bookAvailable(String)

Verifies if the String book is available in the inventory of books on hand in the store. Returns true if at least one copy is available; otherwise returns false.

buyBook(String)

Purchase String book for the book store. The purchase is only made if the book is on one of the book-lists. Add the cost of the book (calculated using the wholesale price times the cost multiplier) to the total costs, and update the inventory adding this book to the books on hand. Return the cost of this book (as a double) if a purchase is made, otherwise return 0.0.

sellBook(String)

Determine if String book is available in the books on hand, and if it is add the sale value of the book to the store sales. Reduce the inventory by one to reflect the book sale; and return the value of the sale price (as a double). Otherwise, return 0.0. (hint: use existing methods as helpers)

inventoryBooks()

Conduct an inventory of the books in the book store. Create a line of detail for each book in the store giving: the name of the book, the number of copies on hand,the cost per book for this store, the total cost for all copies of this book for this store, the sale price per book for this store, and the total sale amount if the current number of copies were all sold. Terminate each detail line with a \n.
e.g., "Linear Algebra, 5, 25.0, 125.0, 50.5, 250.25\n"
After reporting details for all books on hand, provide a total line containing "Total: number of books: x, cost: y, sale price: z" where x is the total number of books, y is the total cost for all the books in the store, and x is the total sale price if the current inventory of books were all sold.
The inventory report is returned as a String.

addInventory(String)

A single book is added to inventory. Add the book with the title given as a String to the inventory of books on hand.

reduceInventory(String)

Remove one copy of the String book from the inventory of books on hand. If the quantity of a book is reduced to zero, remove it from the list of books on hand entirely. (Hint: Can this be used as a helper method for other methods?)

Class University

The University class represents a university. The book reference information and the local book store is maintained at the university. Fields are used to store this information. As well, there are methods to get this information.

The University class has the following fields:

Variables

Type Description
BookStore The university book store on the university campus.
BookReference The book and price list information for books for this university.

Methods

The University class supports the following methods:

Constructor Description

University(BookReference, BookStore)

Constructor for the University class. Takes the BookReference for the local university book-lists, and the local on-campus BookStore.

Method Name Description

getBookLists()

Return the book and price lists for this university (as a BookReference.)

getBookStore()

Return the on-campus book store for this university (as a BookStore.)

As a general rule, none of the inputs to these methods will be null.

Class Student

The Student class represents a university student. The student name,number, current year of study, University attended, list of books owned, and total book costs are maintained.

Variables

Type Description
String The student name.
String The student number.
int The current academic year of study for this student.
String The list of books currently in the student's possession. Stored in a #-separated list.
double The total amount spent on books through all the years of school.
University The university that the student is attending.

Methods

The Student class supports the following methods. Again ...Pay close attention to the table below!

Constructor Description

Student(String, String, int, University)

Constructs a student using the String student name, the String student number, the int current academic year of study, and the University currently attended by the student.

Method Name Description

changeSchools(University)

Replace the current university attended with the University given.

changeYear()

The student has moved forward a year and the year of study is incremented . The number is never incremented past four, since that is the last year of study at the university.

buyBooks()

Buy the books for the academic year. In order to conserve money, the student first sells back to the book store, those books that she doesn't require for this year, and reduces her total costs (reflected in the total amount spent on books) by the amount that she makes. She then buys the books she needs from the book store. (Notice: she does not need books that she already possesses.)The total amount spent on books is incremented to reflect the cost of the books bought. The list of books in the student's possession is updated to reflect both the books sold and those that were bought.. This method returns the list of books that are still needed (as a #-separated String. (Hint: call existing methods as helpers)

sellBooks()

Sell all books not required for the current academic year to the book store, if they will accept them. If the book is no longer on any book-lists, the book store will not purchase it. Update the costs to show the money saved. Update the books owned to reflect any books no longer owned.

getBookCosts()

Returns the total amount this student has spent on books (as a double.)

getBooks()

Return a list of all books currently in the student's possession. Each book on the list must be followed by a \n (a newline character). The list is returned as a String.

As a general rule, none of the inputs to these methods will be null.

Class BookReferenceTester.java, Class BookStoreTester.java, Class UniversityTester.java and Class StudentTester.java

How do you know whether the BookReference, BookStore, University and Student classes you're designing are correct or not? The only way you can be sure is if you test them, to see if they do what they are supposed to do:

For each new method that you add to BookReference, BookStore, University and Student, you are expected to write one or more test methods in ,BookReferenceTester, BookStoreTester, UniversityTester and StudentTester, respectively. In these methods, you usually create at least one new object and test your method on it.

The BookReferenceTester, BookStoreTester, UniversityTester and StudentTester are the JUnit test suites you'll design, which perform these testing tasks for you.You can also get more detail by following the links on the course main web-site's Java links page.

Make sure that your test suites adhere to the following principles:

Remember that if you change static variables in an early test, they will retain their values in later tests. Important: the tests in a JUnit test suite are not necessarily run in the order in which you list them in your suite. So when testing static variables, record their initial value at the beginning of the test, and test that the change in the value is what you expect.

Marking

What is important? Several things. While we do not hand out a marking scheme, you need to know what counts for good marks:

What to Hand In

Your tutorial or your campus-specific information page describes how you hand in your assignment. This section tells you what to hand in:

Hand in the following eight files: BookReference.java, BookReferenceTester.java, BookStore.java, BookStoreTester.java, University.java, UniversityTester.java, Student.java, StudentTester.java.

Remember that spelling, including case, count in Java: your files must be named exactly as above.

NOTE: Only hand in the files that end with the .java suffix. Be careful about this, because in the same place as your .java files you may also have files with the extension .class (that is, they end with the .class suffix), but otherwise have the same name. Two particular pitfalls:

Since .class files cannot be read by TAs or run with our testing programs, submitting the wrong files might cause you to fail the assignment. Every year, a half-dozen students submit the wrong file; we simply cannot do anything to fix this mistake.