CIT 590 Assignment 10: Fraction Calculator
Spring 2010, David Matuszek
Implement a calculator that works with fractions. You will need three classes:
Fraction -- An object of this class represents a fraction. The class contains methods for operating on the fraction.FractionTest -- A JUnit test class for the functions defined in Fraction.FractionCalculator -- A GUI class that used the Fraction class and displays an onscreen calculator for fractions. Note: This is not a pair programming assignment, mostly because I had difficulty thinking up a project that needed two different GUIs.
| Components | Two integers, known as the numerator and the denominator. |
|---|---|
| How displayed | n/d, where n is the numerator and d
is the denominator. However, if the denominator is 1, then only the numerator n is displayed. |
| Restrictions | The denominator may not be zero. If the user enters a zero denominator, the display should show Error. |
| Normalization | The fraction is always kept in the lowest terms, that is, the Greatest
Common Divisor (GCD) of n and d is 1
(use Euclid's algorithm--you can look this up); andThe denominator is never negative. |
| Addition | a/b + c/d is (ad + bc)/bd |
| Subtraction | a/b - c/d is (ad - bc)/bd |
| Multiplication | (a/b) * (c/d) is (a*c)/(b*d) |
| Division | (a/b) / (c/d) is (a*d)/(b*c) |
| Absolute Value | Assuming that a/b is normalized: |
| Negation | -(a/b) is -a/b |
| Special | Inverse of a/b is b/a |
| Equality | If in lowest terms, numerators are equal and denominators are equal. |
| Comparison | a/b is less than c/d if ad < bc |
| Zero | Zero is represented with a numerator of zero and a denominator of one. |
class Fraction implements Comparable<Fraction> The Fraction class is an API--an Application Programmer's Interface. That is, it isn't a program in itself; it is designed to be used by programmers who, for whatever reason, need to use fractions in their programs.
The Fraction class should have three constructors:
public constructor that takes two int parameters, a numerator and a
denominator.public constructor that takes one int parameter, the numerator (the
denominator is assumed to be one)public constructor that takes a String such as "5/10", or "2"
(allow blanks in the string).
split("/") to get the two parts, then trim() both parts, then use Integer.parseInt(part) to convert each part from type String to type int. Fractions should be constructed in normalized form. For example, if the user says new Fraction(6, 8), the fraction should be created with a numerator of 3 and a denominator of 4 (not 6 and 8). Similarly, if the user says new Fraction(1, -3), the fraction should be created with a numerator of -1 and a denominator of 3 (not 1 and -3).
Constructors should throw an ArithmeticException if called with zero for a denominator.
And these public methods:
public Fraction add(Fraction f)public Fraction subtract(Fraction f)public Fraction multiply(Fraction f)public Fraction divide(Fraction f)public Fraction abs()public Fraction negate()public Fraction inverse()
0/1) should throw an ArithmeticException.private void normalize()
this" fraction. Used by constructors; should not be needed elsewhere.@Override
public boolean equals(Object o)
false if o isn't a Fraction: if (!(o instanceof Fraction)) return false; o is a Fraction, you need to cast it and save it in a variable of type Fraction: Fraction f = (Fraction)o; @Override
public int compareTo(Fraction f)
@Override
public String toString()
n/d, unless d is 1, in which case it returns just n. Fractions should be immutable, that is, there should be no way to change their components after the numbers have been created. Most of your methods simply return a new number.
Fractions should always be kept in a normalized form. Since fractions are immutable, and there is no way to normalize one from outside the Fraction class, normalization
should be done by a private method.
You probably won't use compareTo in this assignment. However, by supplying equals and compareTo methods, you make it possible to do other "numerical" things with fractions, like sorting them.
When you override equals, notice that it
requires an Object as a parameter. This means that the first thing
the method should do is make sure that its parameter is in fact a Fraction,
and return false if it is not.
When you write your JUnit tests, you may think that you need to get to the numerator and denominator of your fractions. You don't. Once you write an equals method, JUnit's assertEquals method will use your equals method, and this is all you really need.
Your goal in writing the JUnit class is to test for every possible
error. This includes making sure that the correct Exceptions are
thrown when appropriate.
class FractionTestWrite tests for all the public methods in Fraction. Remember, your goal in testing is not to "prove" that your methods are correct. Rather, it is to try to "break" your methods in every way you can think of.
Eclipse will create this class for you. See the "Advice" section below.
class FractionCalculator extends JFrameWrite a GUI that looks and acts like a "real" calculator, the kind you can buy in any drugstore. Except, your calculator will deal only with fractions. It should use a JTextField to display the fractions, and a number of JButtons to do the arithmetic. (You do not need to allow the user to type directly into the display, using the keyboard--you can tell the text field to setEnabled(false)--but if you do allow this, be sure to take care of all possible cases.)
JButtons with digits and the / character on them.+, -, ×, and ÷.
× and ÷ are not on the keyboard; use
new JButton(((char)215) + "") and
new JButton(((char)247) + ""), respectively.Good comments and good style are required, as always. Also, remember you can use SwingExamples.jar for examples of how to do various GUI things.
The Fraction class is easy--and FractionTest is longer, but not really difficult. You should get these classes done in the next day or so, in order to give yourself plenty of time to work on the FractionCalculator class.
The best way to do this is to write all the constructors and methods of the Fraction class as stubs. That is, the constructors have empty bodies, and the methods return a meaningless or intentionally wrong result (often, null). Once you have done this, use Eclipse to generate the JUnit 4 test class for you (please don't use JUnit 3, that's old style). If you step through the dialog boxes carefully, and make sure the right boxes are checked, Eclipse will generate test stub methods for all of your constructors and methods. Then all you have to do is fill in the test code.
Please use TDD--Test Driven Design. That's where you write the test first, run it to make sure it fails, then write the method, and run the test again to make sure it succeeds. Since you have to write both the method and its test anyway, you might as well do it in the correct order. To begin, test and write both a constructor and the equals method, because these are needed for everything else.
Thursday, April 8, before midnight. Zip your files and submit them via Blackboard. Do not email me your files. Do not submit .rar files.