CMSC 131 - Fall 2019 - Project #5


While we strongly suggest having this project done by October 30th, the graded assignment submission due date on the Submit Server is before 8pm on Thursday, October 31st.

Reminder: The second exam is on Friday, November 1st.

Type of project: Closed

Cubic Polynomials and Unit Testing

Objective

To practice writing a complete Java class based on a design spec, to practice writing and calling methods of all kinds, and to practice writing JUnit tests to help check that your code is implementing the tasks correctly.

Introduction

In this project you will each implement a standalone Java class that represents a cubic polynomial. We imagine that the specs have been written by a design team and that they have determined their exact needs, so be sure to read and follow this spec they've sent us carefully. They have request the class be "immutable" similar to other data types in Java, meaning that once you have an instance of a Cubic Polynomial that has been created with a specific set of coefficients, it's contents cannot be changed.

Required Reading

What you Must Implement

For this project you will be implementing one data type class; CubicPoly. However, you will also be adding tests to a file of JUnit test class to demonstrate that you know how to test that your new data structure follows the specs. Our client has not provided us with an example of a program that uses this new class, so the specs and the JUnit tests you write are all you have to go from before you submit your work, so follow the instructions below very carefully.

Of course, the submit server will be doing rigourous testing as well but you only have a limited number of release test tokens to use, so you'll want to test things out on your local machine thoroughly.

CubicPoly class

You must implement all of the data members and methods described below. You may NOT add any instance variables or static variables to this class other than those described below. You may add methods of your own, as long as they are private. The data type class you are writing is a very general class that could be of use in a wide variety of projects at our client's site, so take care in your work!

Private Instance Variables

The class will have exactly four instance variables. These variables MUST be declared private. The CubicPoly class you are implementing is a mutable class via the plusEquals and minusEquals methods, and needs to have the following instance members:

These variables represent the coefficients of the CubicPoly. That is, your class can represent any cubic polynomial of the form "a*x^3 + b*x^2 + c*x + d" given those coefficients. For example, if an instance is supposed to represent the cubic polynomial 42x^3 - 17.2x^2 + 3.7x - 5, then the value of a would be 42.0, the value of b would be -17.2, the value of c would be 3.7, and the value of d would be -5.0. Note that you do not actually store things like the strings "x^3" or "x^2" or "x" as part of the state of CubicPoly since those are implicitly there due to the semantics of the class.

Public Constructors

  1. A constructor that takes four parameters of type DoubleWithAppx representing coefficients a, b, c, d (in that order) for the CubicPoly being constructed. The data members a, b, c, and d are to be initialized with these values resulting in the cubic polynomial: "a*x^3 + b*x^2 + c*x + d". It is strongly suggested that to make your code more efficient to write and test, that you think about how all of the other constructors can make use of this one as a helper.
  2. A constructor that takes three parameters of type DoubleWithAppx representing coefficients b, c, and d (in that order) for the CubicPoly being constructed. The data members b, c, and d are to be initialized with these values and the data member a should be initialized to 0, resulting in the cubic polynomial: "b*x^2 + c*x + d".
  3. A constructor that takes two parameters of type DoubleWithAppx representing coefficients c, and d (in that order) for the CubicPoly being constructed. The data members a and b should both be set to 0 in this case, and c, and d are to be initialized with the arguments resulting in the cubic polynomial: "c*x + d".
  4. A constructor that takes one parameter of type DoubleWithAppx representing coefficient d for the CubicPoly being constructed. The data members a and b and c should all be set to 0, and d is to be initialized with the argument resulting in the cubic polynomial: "d".
  5. A constructor that takes no parameters for the CubicPoly being constructed. The data members a, b, c, and d should all be set to 0 resulting in the cubic polynomial: "0".
  6. A copy constructor.

Public Instance Getter Methods

  1. getA -- A simple "getter" for the value of the a data member.
  2. getB -- A simple "getter" for the value of the b data member.
  3. getC -- A simple "getter" for the value of the c data member.
  4. getD -- A simple "getter" for the value of the d data member.

Public Instance Mathematical Methods

   Remember, you do not modify the current object in any of these.
  1. evaluate -- this instance method takes one parameter (DoubleWithAppx), evaluates the cubic polynomial at the point represented by the parameter and returns a DoubleWithAppx representing the result of that evaluation.  (i.e., if your cubic polynomial is 5x^3-3x^2+2x+4, and you call evaluate(5.0), it should return 564.0)
  2. add -- this static method takes two parameters (both of type CubicPoly). It will return a new CubicPoly that is equal to the sum of the two parameters. The way this is done is by adding corresponding coefficients from the two parameters.
  3. plusEquals -- this instance method takes one parameter (CubicPoly). It will alter the object used to call it such that the object equals the sum of the value of the calling object and of the parameter object (think of it as x+=y where x was the object used to invoke the method and y was sent as the parameter).
  4. subtract -- this static method takes two parameters (both of type CubicPoly). It will return a CubicPoly that is computed by subtracting the value of the second parameter from the value of the first parameter.
  5. minusEquals -- this instance method takes one parameter (CubicPoly). It will alter the object used to call it such that the object equals the difference of the value of the calling object and of the parameter object (think of it as x-=y where x was the object used to invoke the method and y was sent as the parameter).
  6. multiply -- this instance method takes one parameter (CubicPoly). This is a bit involved and our client was quite clear that the details were critical to follow. It is not up to us to argue their logic in this method - our job is to code to their spec. If you want to multiply the cubic polynomial a*x^3 + b*x^2 + c*x + d and the cubic polynomial e*x^3 + f*x^2 + g*x + h you end up with the new cubic polynomial of (ae)x^6 + (af+be)x^5 + (ag+bf+ce)x^4 + (ah+bg+cf+de)x^3 + (bh+cg+df)x^2 + (ch+dg)x + dh as the result. This method will return a CubicPoly which is the multiply of the current object and the parameter as long as the result would NOT end up having a fourth, fifth, or sixth order term. If it would (ie: those coefficients are non-zero) then the method must return null instead. Note that you can return null by including the statement in multiply: return null;
    • Note that you can "chain" method calls provided in the DoubleWithAppx class. For example, a*b+c could be evaluated using (a.multiply(b)).add(c) by making use of the multiply and add methods in DoubleWithAppx.
  7. derivative -- this instance method takes no parameters and returns a new CubicPoly that is computed by taking the derivative of the current object. The formula for the derivative of a cubic polynomial ax^3 + bx^2 + cx + d is 3ax^2 + 2bx + c (Remember, you do not modify the current object.)
  8. compareTo -- this instance method takes one parameter (CubicPoly) and returns an int. The client specs say that:
    • Starting from the highest order term going down, if the corresponding coefficients are not equal then return +1 if the object's coefficient for the term is greater than the parameter's coefficient and -1 if it is less.
    • Return 0 if and only if all corresponding coefficients are equal.
    Read the spec on how compareTo in DoubleWithAppx works to try to make your method here as simple to read and write as possible.

Public Instance Utility Method "Challenge Problem" (save for after the exam probably)

toString -- this method takes no parameters and returns a new String representing the CubicPoly.  The string you create must have exactly the form specified here. See examples below, which illustrate correct return values for the toString() method in each case.  Note that you are allowed to use the DoubleWithAppx.toString() method for this one method. These are the requirements:
Examples:


How to test as you develop

The methods you are implementing are only exercised by the JUnit tests you will need to write (see below), and the Public and Release tests.

You should work on the class, and test things, in stages.



JUnit Tests

With this project, we have included some JUnit tests as examples in the YourTests.java file. You can run these tests yourself in Eclipse by opening the file, and from the menu selecting:  Run->Run As->JUnit Test. 

You must implement at least three additional JUnit tests that you place in the YourTests.java file that will determine if the methods you implemented (as required above) are correct. A skeleton version has been provided for each method, and you need to pick at least three to implement. We suggest you consider implementing all of them as practice and as a way to test your project before submitting. These JUnit tests are meant to individually test the public instance mathematical methods. You might also want to write JUnit tests for other things of course. They should test a variety of different situations. Make sure you are testing more than one set of values for each of the methods - one test case is often not enough to determine if a method works correctly. Look for as much variety as possible in your test cases to ensure a higher level of confidence that your code works as described.

Your JUnit tests must include a comment before each method specifying what is being tested.


Requirements


Project Submission

Submit your project from Eclipse by right-clicking the project folder and selecting "submit project".  You may submit as many times as you want -- we only grade the submission that scores the highest on the automated tests.  After you have submitted your project, you should visit the submit server.  There you can obtain limited feedback about how well your project is performing.  The number of times you can run our tests on your project (before the due date) is limited.  The earlier you begin working on the project, the more opportunities you will have to see how your project performs on our tests before the due date!


Grading

Your grade will be determined as follows:




Web Accessibility