Question: Application: Write a Fraction API Addition [a/b + c/d]: (a*d + b*c) / b*d Subtraction [a/b - c/d]: (a*d b*c) / b*d Multiplication [a/b *
Application: Write a Fraction API
| Addition [a/b + c/d]: | (a*d + b*c) / b*d |
| Subtraction [a/b - c/d]: | (a*d b*c) / b*d |
| Multiplication [a/b * c/d]: | a*c / b*d |
| Division [(a/b) / (c/d)]: | a*d / b*c |
Before you start programming, there are a few things youll need to do:
- You will need the NetBeans IDE and the JUnit testing framework plugin. Download and install NetBeans. Download and install the JUnit4 plugin for NetBeans by performing the following steps:
Programming
NetBeans organizes Java programs as Projects. These projects are where youll write your program, and they contain all the classes, library references, and code necessary to run the program. Create a new project called Fractions. Within Fractions, create a new class called Fraction. NetBeans will supply a main method; delete this method, as you will be writing an API, not a complete program.
Before performing any operations on two fractions, you should first put them in lowest terms. For this you will also need to compute the greatest common divisor (GCD) of the numerator and denominator and then divide both by the GCD. You can compute the GCD of two numbers by using Euclid's Algorithm. If youre not familiar with this algorithm, there are a number of good definitions available on the web. (Youll find that searching the web for definitions, code snippets, and best practices is an invaluable tool for any programmer.) A Java implementation of Euclids Algorithm is included as the gcd method below.
In your Fraction class, define two private int fields; these will hold the numerator and denominator of a fraction.
Define four static methods, named add, subtract, multiply, and divide. Each of these methods should be defined to take two Fraction arguments and return a new Fraction. For now, though, each of these methods should return null.
Define a constructor that takes two int parameters, corresponding to the numerator and denominator of a fraction. For now, the constructor should do nothing with these parameters; the constructor body should be empty. You may think this odd, but the reasons will be explained shortly.
Define one more static method to compute the greatest common divisor and name it gcd. The method should take two int parameters and return an int result. A Java implementation of gcd that uses Euclids Algorithm is provided when you get to the testing portion of this assignment.
Finally, define an equals method, with exactly this signature:
@Override
public boolean equals(Object o) { ... }
It should initially return false.
Add doc comments to each of the methods above. As you may recall, a documentation (doc) comment is a comment placed immediately before a class or method, to provide information to a programmer who wants to use these methods. (Other kinds of documentation, such as how to use the program or the details of how the method does its job, do not belong here.) In NetBeans, choose Tools Analyze
Javadoc, check all relevant checkboxes, and click Fix Selected; this will write skeleton doc comments for you, but you still have to fill in words to tell what each method does, what parameters it expects, and what it returns.
The JUnit Testing Framework
Except for the fully-coded gcd method, the methods youve just defined are essentially stubs; they provide a framework for the method and show what the input and output will be, but they dont perform the actual computations. At this point, it makes sense to provide a brief explanation of why you should first write method stubs" that do nothing, or worse, return the wrong answer. It is a generally accepted truism that you should decide what a method is supposed to do before you write the method. When you have a plan, it is much easier to figure out where you are going or what you need to do. Many developers find it effective to write the tests for the methods before they write the actual code. This approach, called Test-Driven Development (TDD), turns out to have a number of benefits, including the following:
- TDD encourages the user of smaller, easily tested methods Errors are caught sooner and are more easily localized
- Long and painful debugging sessions are largely eliminated
- The tests actually get written, and are available for future use
JUnit is a testing framework that provides you with the ability to perform Test-Driven
Development within NetBeans. With JUnit, you can have NetBeans create your test methods for you. Since NetBeans doesn't know what your methods are supposed to do, the test methods it creates will also be stubs; you need to fill in the actual test code.
To install the JUnit plug-in, select your Fraction class in NetBeans, and then go to
File > New File... > JUnit > Test for Existing Class. Click Next >, and then enter the name fraction.Fraction in the Class Name: box. Click Finish, choose JUnit 4.x, and then click Select. If you have done this correctly, you will see that NetBeans has written a FractionTest class for you, with several test method stubs.
Run the tests by choosing Run > Test Project (Fraction). You will get an easy-to-read display showing that all your tests failed, as they should have since you haven't written the code yet. Notice that double-clicking on an error message will move the cursor to the failed test.
Since the TDD process requires you to navigate frequently between the code and testing, you may want to adjust NetBeans to show them side by side. To see both Fraction and FractionTest at the same time, click and hold on either of those tabs and drag it to the right or left side of the edit window. You will find it helpful to create a version of toString for the Fraction class. This will allow failed JUnit tests to print your fractions in a readable format. Here is an example:
@Override
public String toString() {
return numerator + "/" + denominator;
}
Creating and testing the methods in the Fraction Class
Usually it's best to work on one method at a time, starting with the methods that don't depend on other methods. Sometimes that's a bit tricky. In this case, if you don't have a proper constructor, you have no fractions to test; and if you don't have a working equals method, you can't test that your results are correct. As a result, you should start by going back and forth between the two.
To develop each method, follow this procedure:
- Fill in the test stub for the method with some actual tests.
- Run the tests and make sure your new test code fails.
- Fill in the method stub with actual code to do the work.
- Run the tests and make sure the new test passes (if not, debug and repeat).
- If the method should do more, return to step 1 to add more tests.
The following procedure steps you through this test-code-test-code sequence for the equals method. Afterward, youll use this same sequence for developing the other methods.
For the equals method, three cases need to be tested.
- Case 1 is when two fractions are identical and the equals method should say they are equal.
- Case 2 is when two fractions are completely different and the equals method should say they are unequal.
- Case 3 is when two fractions are equal but one or both arent in lowest terms and appear to be different at first glance.
Case 1
In the testEquals method, replace the body (all eight lines) with the following:
assertEquals(new Fraction(1, 2), new Fraction(1, 2));
Now run the tests. All of them should fail, but for now just pay attention to testEquals. It should fail, because you defined an equals method that always returns false.
Next, fill in code for the equals test. It should cast the argument to a Fraction; then test that the two numerators are equal and the two denominators are equal.
Run the tests again. This time, testFraction should pass. (If it doesn't, debug your code and try again.)
Case 2
Add the following line to testEquals:
assertFalse(new Fraction(1, 2).equals(new Fraction(1, 4)));
Run the test again. It does not pass because the default (empty) constructor just sets both the numerator and the denominator to zero. Fix the constructor to save its parameters, and run the tests again; this time testEquals should pass.
Case 3
Add the following line to testEquals:
assertEquals(new Fraction(1, 2), new Fraction(2, 4));
This really should pass because 1/2 = 2/4, but it doesn't. The best way to fix this is to keep all fractions in lowest terms, so that when you call new Fraction(2, 4), it is really saved as 1/2, not as 2/4.
To reduce a fraction to the lowest terms, divide both the numerator and the denominator by their greatest common divisor. Use the gcd method above for testing.
In the testGcd method, add one or more statements such as:
assertEquals(5, Fraction.gcd(15, 25));
Now use this Java implementation of the gcd method in your Fraction constructor:
static int gcd(int a, int b) {
a = Math.abs(a);
b = Math.abs(b);
while (a != b) {
if (a > b) a = a - b;
else b = b - a;
} return a;
}
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
