Skip to main content

more options

Assignment 1 (Textbooks)

Submit on the CMS two weeks into the course
Monitoring Textbooks

Introduction

By now you have realized the important roll textbooks are going to play in your education. Almost every course you take requires you to buy some sort of textbook. The Campus Store stocks of over 6,000 titles every semester (http://www.store.cornell.edu/text/default.html), and for some courses you may want to take out addtional texts from the Cornell Library or even shop outside Cornell.

You already know how expensive textbooks can be. Shopping around for the lowest price on a book is common practice among our student body and can save you a lot of money. Consider the difference between the Campus Store and Amazon on the CS 153 textbook. You could save $12.64, or 23% of the purchase price, if you're willing to wait for the free shipping. It's usually a good idea to shop around; you never know how much you could save.

Your task in this assignment is to develop a Java class Textbook, which will maintain information about a textbook, and a JUnit class TextbookTester to maintain a suite of testcases for Textbook. This assignment will help illustrate how Java’s classes and objects can be used to maintain data about a collection of things —like textbooks.

HELP

If you don't know where to start, if you don't understand testing, if you are lost, SEE SOMEONE IMMEDIATELY —the course instructor, a TA, a consultant. Do not wait. A little one-on-one help can do wonders.

Class Textbook

An instance of class Textbook represents a single textbook. It has several fields that one might use to describe a text, as well as methods that operate on these fields.  Here are the fields, all of which should be private (you can choose the names of these fields).

  • title (a String, which holds the title of this textbook).
  • month of publication. (an int)
  • year of publication. (an int)
  • subject (a char: 'E' for engineering, 'S' for Social Sciences like history and psychology, 'L' for literature, or 'F' for foreign language).
  • first reference (a Textbook —the name on the tab of folder of a textbook object that this textbook references).
  • second reference (a second Textbook —the name on the tab of folder of a textbook object that this textbook references).
  • citations (an int: the number of textbooks that reference this one).
  • price (a double containing the best price available for this textbook, -1.0 if no shopping has been done).

Here are some details about these fields.

  • The name is a String of characters. It is okay for two textbooks to have the same name. Sometimes, this happens.
  • The month of publication is in the range 1..12, representing a month from January to December. The year of construction is something like 1953 or 2005. Do not worry about invalid dates; do not write code that checks whether dates are valid: assume they are valid.
  • The 2 references are the name of Textbook objects (manila folders) that this textbook references.  They are not Strings. A reference is null if it is either not known or if this book references no other textbooks.

Accompanying the declarations of these fields should be comments that describe what each field means —what it contains.  For example, on the declaration of the field subject, state in a comment that the field represents the subject of the textbook, ‘E’ for engineering, etc.  The collection of the comments on these fields is called the “class invariant”. The class describes all legal values for the fields together.

Whenever you write a method (see below), look through the class invariant and convince yourself that class invariant is correct when the method terminates.

Textbook Methods

Class Textbook has the following methods. Pay close attention to the parameters and return values of each method. The descriptions, while informal, are complete.

Constructor Description
Textbook(String name, int month, int year, char subject) Constructor: a new Textbook. Parameters are, in order, the book's name, the month and year of publication, and subject: 'E' for engineering, 'S' for social sciences like history and psychology, 'L' for literature, or 'F' for foreign language. No shopping has been done to find a best price, and no other textbooks reference this one. Precondition: all parameters are valid as described.
Textbook(String name, int month, int year, char subject, Textbook ref1, Textbook ref2, double price) Constructor: a new Textbook. Parameters are, in order, the name of the textbook, its month and year of publication, its subject ('E' for engineering, 'S' for social sciences, 'L' for literature, or 'F' for foreign language), two Textbook that the new Textbook references, and a best price > $0.00.
Precondition: ref1 and ref2 are not null, and all parameters are valid as described.

When you write a constructor body, be sure to set all the fields to appropriate values.

Getter Method Description
getName() = the name of this textbook. (a String)
getSubject() = the subject of this text ('E' for engineering, 'S' for social sciences, 'L' for literature, or 'F' for foreign language). (a char)
getMOP() = the month this book was published, in the range 1..12. (an int)
getYOP() = the year this book was published. (an int)
getReference1() = the name (of the folder containing) the first textbook that this one references. (a Textbook)
getReference2() = the name (of the folder containing) the second textbook that this one references. (a Textbook)
getNumberCitations() = the number of textbooks that reference this one. (an int)
getPrice() = the best price availible for this textbook. (-1.0 if unknown)
toString() = a String representation of this textbook.  Its precise specification is discussed below.
Setter Method Description
setName(String n) Set the name of this textbook to n.
setSubject(char s) Set the subject of this textbook tos. Precondition:s is one of 'E', 'S', 'L', and 'F' .
setMOP(int m) Set the month this virus was discovered to m. Precondition: m is in the range 1..12.
setYOP(int y) Set the year this virus was discovered to y.
setReference1(Textbook t) Set the first book that this one references to t.
Precondition: This book's first reference is null, and t is not null.
setReference2(Textbook t) Set the second book that this one references to t.
Precondition: This book's second reference is null, and t is not null.
setPrice(double p) Set this textbook's price to p.
Precondition: p > 0.0.
Comparison Method Description
publishedBefore(Textbook t) = "t is not null, and this textbook was published before t". (a boolean)
publishedBefore(Textbook t1,Textbook t2) Static method. = "t1 and t2 are not null, and t1 was published before t2". (a boolean)

Make sure that the names of your methods match those listed above exactly, including capitalization. The number of parameters and their order must also match. The best way to ensure this is to copy and paste our names. Our testing will expect those method names, so any mismatch will fail during our testing. Parameter names will not be tested —you can change the parameter names if you want.

Each method MUST be preceded by an appropriate specification, or "spec", as a Javadoc comment. The best way to ensure this is to copy and paste. After you have pasted, be sure to do any necessary editing. For example, the spec of a function does not have to say that the function yields a boolean or int or anything else, because that is known from the header of the method.

A precondition should not be tested by the method; it is the responsibility of the caller to ensure that the precondition is met. For example, it is a mistake to call method setReference1 with null for the text argument. However, in functions publishedBefore, the tests for t, t1, and t2 not null MUST be made (because they have no precondition).

It is possible for Textbook t1 to reference t2 and visa versa, at the same time. If two textbooks are developed concurrently, such an occurrence might actually happen, altough it would still be kind ofstrange. We do not check for such strange occurrences.

In writing methods setReference1 and setReference2, be careful! If T is becoming a reference for this textbook, then T has gained one more citation, and its field that contains the number of books citing it has to be updated accordingly.

Do not use if-statements, and you may use conditional expression (... ? ... : ...) only in function toString. Boolean expressions, using the operators && (AND), || (OR), and ! (NOT), are sufficient to implement the comparison methods.

Function toString

We illustrate the required format of the output of toString with an example and then make some comments. Here is an example of output from function toString:

"E textbook Multimededia Introduction to Programming Using Java. $79.95. Published 5/2005. Cited by 2 other textbooks."

Here are some points about this output.

  1. Exactly one blank separates each piece of information, and the periods are necessary.
  2. The E at the beginning is this textbooks subject (Engineering in this case).
  3. The name of the textbook follows the word "textbook".
  4. What books this one references are not described in this function.
  5. Do not print a negative price. If a best price has not been found, omit the price entirely (in the above example you would omit " $79.95.".
  6. If the price is $11.50, it is okay to print $11.5. In fact it is required, and printing 11.50 will result in us asking you to rewrite function toString.
  7. If the text has been cited by exactly 1 other book, the word "textbook" should appear instead of "textbooks".
  8. In writing the body of function toString, do not use if-statements or switches. Instead, use the conditional expression (condition ? expression1: expression2) This is the only place you can use the conditional expression.

Class TextbookTester

We require you to build a suite of test cases as you develop class Textbook in a JUnit class TextbookTester. Make sure that your test suite adheres to the following principles:

  • Every method in your class Textbook needs at least one test case in the test suite.
  • The more interesting or complex a method is, the more test cases you should have for it. What makes a method 'interesting' or complex can be the number of interesting combinations of inputs that method can have, the number of different results that the method can have when run several times, the different results that can arise when other methods are called before and after this method, and so on.
  • Here is one important point. If an argument of a method can be null, there should be a test case that has null for that argument.
  • Test each method (or group of methods) as soon as you finish, before moving on to the rest of the assignment.

How to do this assignment

First, remember that if-statements are not allowed. If your assignment has if-statements, you will be asked to revise the assignment and resubmit.

Second, you should develop and test the class in a methodologically sound way, which we outline below. If we detect that you did not develop it thus, we may ask you to start from scratch and write one of the other alternatives for this assignment.

  • First, start a new folder on your hard drive that will contain the files for this project. Start every new project in its own folder.
  • Second, write a class Textbook using DrJava. In it, declare the fields in class Textbook, compiling often as you proceed. Write comments that specify what these fields mean.
  • Third, after finishing the first section, start a new JUnit class, calling it TextbookTester.
  • Fourth, this assignment should properly be done in several parts. For each part, write the methods, write a test procedure in class TextbookTester and add test cases to it for all the methods you wrote, and then test the methods thoroughly. Do not go on to the next group of methods until the ones you are working on are correct. If we determine that you did not follow this way of doing things —for example, you wrote all methods and then tried to test, we may ask you to set this assignment aside and do another instead. Here are the groups of methods.
    • (1) The first constructor and all the getter methods of class Textbook.
    • (2) The second constructor.
    • (3) Function toString.
    • (4) The setter methods.
    • (5) The two comparison methods.

At each step, make sure all methods are correct before proceeding to the next step. When adding a new method, cut and paste the comment and the header from the assignment handout and then edit the comment. It must have suitable javadoc specifications as well as suitable comments on the field declarations. The assignment will not be accepted for testing until it does.

Other hints and directions

  • Do not use if statements.
  • Remember that a String literal is enclosed in double quotation marks and a char literal is enclosed in single quotation marks.
  • Be sure to create the javadoc specification and look at it carefully, to be sure that the methods are specified thoroughly and clearly.

Procedure for submission

You may submit the assignment whenever you wish. We will look at it in several steps.

1. If the field specifications and the javadoc specifications are not appropriate, we will ask you to fix them and resubmit.

2. If the field and javadoc specs are ok. We will look at your test cases. If they are inadequate, we will ask you to fix them and resubmit.

3. If the test cases are adequate, we will test your program. If there are errors, you will be asked to correct them and resubmit.

Only when the assignment passes all three categories, will it be accepted as complete.

Submitting the assignment

First, at the top of file Textbook.java, put a comment that says that you looked carefully at the specifications produced by clicking the javadoc button and checked that the specifications of methods and the class specification were OK (put this comment after doing what the comments says).

Second, upload files Textbook.java and TextbookTester.java on the CMS. You will be asked to upload Ass1.java and Ass1Tester.java. Don't worry about this; just upload files Textbook.java and TextbookTester.java.

Make sure you submit .java files. do not submit a file with the extension/suffix .java~. You can ensure that you do this by setting your preferences in your operating system so that extensions always appear.