CS 161 Homework 3 - Fraction Calculator
Due Mon Feb 16 at 11:59pm
Overview
Lots of young math students struggle when doing math with fractions. For this assignment, you'll help them out by making a simple Fraction Calculator programs that work through the BlueJ terminal. Your program will support two pieces of functinoality:
-
The ability to add three (3) different fractions (these can be proper or improper):
Enter first fraction: 1/2 Enter second fraction: 17/9 Enter third fraction: -3/4 1/2 + 17/9 + -3/4 = 118/72 (1 46/72)
Note that I typed in the fractions in red.
-
The ability to multiply two mixed numbers (a proper fraction with an additional whole number part):
Enter first mixed: 1 1/2 Enter second mixed: 3 2/5 1 1/2 * 3 2/5 = 5 1/10
Notice that you will not need to reduce or simplify the fractions in any way (we'll talk about how to do that later), other than converting them to a mixed number format.
To do this, you will be creating two new classes: one that represents a Fraction
(a number with a numerator and a denominator: either a proper or improper fraction), and one that represents a Mixed
number (a proper fraction with an additional whole number part). You will also be making a FractionCalculator
to allow aspiring mathematicians to use your classes to do math,
This assignment should be completed individually.
Warning: This can be a very difficult assignment! It involves thinking about very "abstract" objects, rather than something more physical or graphical, as well as working with new methods and classes. Be sure and get started early, and if you get stuck or have any questions, feel free to ask for help!
Objectives
- To practice designing and implementing classes from scratch
- To practice using objects: instantiating and using them as parameters and return values
- To practice with String manipulation and methods
- To practice working with objects as abstractions of data
- To practice with user input and output
Necessary Files
You will need a copy of the
Hwk3.zip file.
The BlueJ project in this file includes a provided FractionTester
class that can use to help test some of your code as you are working (but you'll need to make any testers you want for the Mixed class!). The project also contains the README.txt that you will need to fill out and turn in along with your assignment.
Remember to extract the files from the zip folder before proceeding!
Assignment Details
For this assignment you will be making 3 classes: Fraction
, Mixed
, and FractionCalculator
. Each class is described in more detail below.
As you write your classes, think about how you can use the various templates and recipes we've talked about in class.
- Helpful hint: there are lots of parts to this assignment. Some of them may require content we won't have gone over until later in the week. If you hit such a point, try working on a different piece! Part of creating new programs from scratch involves figuring out the steps (the algorithm!) for implementing the program.
Fraction
Fraction
represents a fraction
(technically a rational number),
which is a number that has two integer parts: a numerator and a denominator. A fraction expresses the ratio of the numerator to the denominator. For example, the fraction 1/2 expresses the ratio of 1 to 2, while the fraction 3/2 expresses the ratio of 3 to 2. While you can think of these as improper fractions, you will need to represent them as two numbers (the numerator and the denominator), rather than as a decimal number.
-
Think about what attributes a
Fraction
has. What instance variables will you need to declare? What data type will these instance variables have?- Think about how we defined a fraction in the preceding paragraph!
-
You will need to create one constructor for the
Fraction
class that takes in twoint
s (a numerator and a denominator) and assigns them to the instance variables as appropriate. Thus your constructor's method signature will look like:public Fraction(int numerator, int denominator)
-
You will also need to create a second constuctor for the
Fraction
class. This constructor should take a singleString
as a parameter, representing the String version of a fraction (for example"1/2"
).-
For this constructor, you will need to extract the numerator and denominator from the String parameter and store them in the instance variables. For example, if the value in the parameter is
"7/10"
, you will need to break this apart into"7"
and"10"
Strings, convert those Strings into numbers, and then store the numbers as attributes. -
Remember that you can use the
.substring()
method to fetch a piece of a String, the.indexOf()
method to figure out the index of a particular character (such as the"/"
in the fraction), and theInteger.parseInt()
method to convert a String into an integer. If you have trouble with any of these methods, please check in with me!-
Optional: it is also possible to use a
Scanner
built on a String (using the String as the parameter to the constructor) andnextInt()
to get a number from a String! This is generally more complicated though.
-
Optional: it is also possible to use a
-
For this constructor, you will need to extract the numerator and denominator from the String parameter and store them in the instance variables. For example, if the value in the parameter is
- Your class should have a getter and setter for each attribute (this will let you practice writing these methods!)
-
A
Fraction
will need atoString()
method so that you can easily print it out. Remember, atoString()
method does not actually print anything, it just returns a String that can be printed elsewhere! -
A
Fraction
will also need anadd()
method. This method should take in anotherFraction
as a parameter, and return anew
Fraction
as the result. For example, if I make aFraction
object that represents 3/4 and another object that represents 1/2, I should be able to add them together to produce a third object that represents 5/4. This way I can get the result, but still have my 3/4 and 1/2 objects to do more math with!Thus your method signature might look like:
public Fraction add(Fraction otherFraction) //note: not a constructor!
-
Remember how parameters are just variables, and variables can be Object types? The same thing is happening here: the "variable" of our parameter will be a Fraction-shaped nametag, and we will put inside it a Fraction object. Similarly, we can make a new Fraction object (using the constructor and appropriate setters) and then
return
that object, the exact same way we would return an int or a String. - Think about how you add fractions without a computer: finding a common denominator (how?), multiplying the numerators by the appropriate value, and then adding those numbers. You do NOT need to find the lowest common denominator--it is fine and expected to have non-reduced fractions!
-
Remember how parameters are just variables, and variables can be Object types? The same thing is happening here: the "variable" of our parameter will be a Fraction-shaped nametag, and we will put inside it a Fraction object. Similarly, we can make a new Fraction object (using the constructor and appropriate setters) and then
-
Similarly, your
Fraction
will need to have amultiply()
method. Likeadd()
, this method should take in another Fraction as an argument, and return anew
Fraction as the result.- Again, think about how you calculate the product of two fractions (hint: cross-multiply), and write that into code!
-
Finally, a
Fraction
will need atoMixed()
method that returns anew
Mixed
object that represents the same value. This will let you easily switch between Fractions and Mixeds. Important hint: Implement most of theMixed
class before you do this!!- You'll need to calculate the whole number, new numerator, and new denominator for your new
Mixed
object. In order to figure out the whole number part, you can use integer division (or the Math.floor() function)--this will literally give you the whole number part of the resulting quotient. - In order to figure out the remainder of the whole number division (that will become the new numerator), you can subtract from the numerator in a manner similar to how you calculated change. Alternatively, you can use the modulo operator
%
to DIRECTLY get the remainder of the division! The modulo operator is described in the text on page 140. If you have questions on this, please ask! Using mod (%
) is slicker ;)
- You'll need to calculate the whole number, new numerator, and new denominator for your new
- You can use the provided tester to check that most of your methods work as expected, or you can write your tests!
Mixed
Mixed
represents a mixed number: the combination of a whole number and a proper fraction--a rational number where the numerator is smaller than the denominator. For example, the fraction number 3/2 can be expressed as the mixed number 1 1/2, while the fraction number 1/2 can be expressed as the mixed number 0 1/2.
- Think about what attributes a
Mixed
has. What instance variables will you need to declare? -
You will need to create one constructor for the Mixed class that takes in 3
int
s as parameters and assigns them to the attributes. Your constructor should not have a Fraction as a parameter! -
Like with the
Fraction
class, you will also need to create a second constuctor for theMixed
class. This constructor should take a singleString
as a parameter, representing the String version of aMixed
(for example"3 1/4"
).- This constructor will work similar to the one in the Fraction class--you'll need to split the String parameter apart, convert the Strings into numbers, and then store them in instance variables. Look at your code for the Fraction class as a place to start.
-
Hint:
You can find the location of a space (a
" "
character) just as easily as a"/"
character!
-
A Mixed will need a
toString()
method so that you can easily print it out. Remember, atoString()
method does not actually print anything, it just returns a String that can be printed elsewhere! -
A Mixed will need a
toFraction()
method that returns anew
Fraction object that represents the same value. This will let you easily switch between Mixeds and Fractions. Important hint: Implement most of the Fraction class before you do this!!- This method will be like
Fraction
's.toMixed()
method, except you need to calculate the new numerator and denominator.
- This method will be like
-
A Mixed will need an
add()
method. This method should take in anotherMixed
as an argument, and return anew
Mixed as the result (the same way that the Fraction's add() method works).- If you think about it, you'll quickly discover that adding Mixed numbers together is not as straight forward as working with fractions (example: how do you easily add 1 2/3 + 2 3/4, so that the result continues to be a proper Mixed with a proper fraction at the end?) How do we normally add these numbers? Well we convert them into fractions (e.g., 5/3 and 11/4) and then add those. This is exactly how we will solve the problem here!
-
This method should call upon the
toFraction()
method (described above) to get a Fraction number with the same value as itself, as well as a Fraction number version of the parameter. You can then add those Fraction numbers (using their add() method), get the sum, and change that sum BACK into a Mixed number to return!- This technique demonstrates the usefulness of being able to switch between data types. It's why we created the Fraction class!
-
A Mixed will also need a
multiply()
method. This method should take in another Mixed as an argument, and return anew
Mixed
as the result. Again, you can use the same technique as youradd()
method to easily do this math. - Make sure to test your methods thoroughly--check that your math produces the results you expect! For example, make sure to test all of the example sums and products listed in this assignment.
FractionCalculator
This class provides a user interface that easily allows students to do math with Fractions and Mixed by typing in values to add and multiply. This will give you a chance to practice working with text input and output--creating interfaces that don't rely on BlueJ as much.
-
This class will have two
static
methods:/** * Has the user enter three (3) fractions, then prints their sum */ public static void addFractions() /** * Has the user enter two mixed numbers, then prints their product */ public static void multiplyMixed()
Both methods will use similar approaches, they'll just call on different constructors and methods.
- The methods are static since we don't need to have a separate calculator to do the work--let's just call them on the calculating class!
-
You will need to prompt the user for what to type in (and to make the terminal show up in BlueJ). You can use
System.out.print()
to print a message to the user. -
The methods will need to use a
Scanner
to get typed input from the user. You will need to import this class to make it accessible. At the very top of your
FractionCalculator
, add the code:import java.util.Scanner;
-
Now you can create a new Scanner that can read text typed into the terminal using
Scanner sc = new Scanner(System.in); //creates a new Scanner on the terminal's typed input
You can then fetch the next line of text typed in by using
String input = sc.nextLine(); //stores the typed text in the 'input' variable
- Note that calling
sc.nextLine()
will cause your algorithm to "pause" and wait for the user to type something in. - You only need one Scanner object per method. Just tell the Scanner to read the next line whenever you want to get more input.
- Note that calling
- Once you have the String the user typed in, you can easily use that value as the parameter to the constructors that create new Fraction and Mixed objects as appropriate. This is why you defined constructors that took Strings as parameters!
-
You can then use the methods you previously wrote to perform the required math. Remember you can store intermediate results as variables, or simply chain together
add()
calls and use the intermediate result as an anonymous variable. -
Finally, be sure and print out the result--easy using the
toString()
methods!- Remember to print out the sum as both a Fraction and as a Mixed, per the example at the top of the page.
- Test these methods to make sure it works. Overall, they should be fairly short and straightforward. The biggest complexity is using the Scanner, and let me know if there are any problems with that.
Helpful Advice: On Testers
I have provided a (basic) tester in the form of FractionTester. This can help you make sure your Fraction class is working correctly, without needing to click around in BlueJ a lot. You are welcome to use this class or not as you see fit--you are not required to use it!
However, I hope this illustrates how handy testers are, and if you have time I encourage you to extend the tester and/or create one for Mixed numbers. As programmers, we often need to produce "extra" code that doesn't get used in order to make sure that things works. This is like how you need to build extra scaffolding when you're constructing a building, even if that buttressing ends up being removed from the final product.
If you make any testers, include them in your final program submission! I'd love to see what you did :)
Extensions
If you finish early (hah!), these extensions will help you to achieve enlightment (and better prepare you for the exam!) You can earn up to 5% extra credit for extensions on this assignment. Be sure to finish the rest of your program first!
- Add functionality so that the user can type in the entire equation on one line (e.g., "3/4 + 1/2"). You can use the Scanner and/or String methods to pull the numbers out of this String. Note that you will need to be careful about whether to use spaces before or after the + sign (the operation). Be sure to prompt the user with the proper format!
- Add other mathematical operations to the Fraction and Mixed classes (subtraction, division). Subtraction is very similar to addition, while division is like multiplication but you invert the numerator and denominator (can you re-use your multiplication method?). You will want to create additional methods in your
FractionCalculator
class to allow the user to easily call these operations.
Submitting Your Assignment
There are a couple of details to keep in mind before you submit your assignment.
-
Double-check that your methods all work and give the correct output. Use the FractionTester to help you check!
- If your program doesn't compile, I can't give you credit for it!
- Make sure you include method comments that explain how each method works, and be sure that your name is in the class comment at the top of all of your classes!
-
You will also need to fill out the README.txt file. You can open this file in BlueJ by double-clicking on the white paper icon in the upper left corner of the class window. You should place the answer to each question below the question box, replacing the "<Replace this with your response!>". Remember to save your changes (select "Class > Save" from the menu).
-
You should compress the entire Hwk3 folder into a single zip file (like you did for Lab A), and then submit it to the Hwk3 Submission page on Moodle.
- Be sure an upload the ENTIRE project folder--that is what includes all your work!
- This assignment is due at midnight on Mon, Feb 16.
Grading
This assignment will be graded out of 35 points. Note that even though there are more listed points, all homeworks are given the same weight (there is just more precision in later assignments).
- Fraction (13pt)
- [1pt] Your Fraction class has appropriate instance variables
- [1pt] Your Fraction class has a working constructor that takes two ints as parameters
- [2pt] Your Fraction class has a working constructor that takes a String as a parameter
- [1pt] Your Fraction class has getters and setters for all its instance variables
- [1pt] Your Fraction class has an appropriate toString() method
- [1pt] Your Fraction class has an add() and multiply() methods that fits the required method signatures
- [1pt] Your add() method correctly calculates the sum of the Fractions
- [1pt] Your multiply() method correctly calculates the product of the Fractions
- [2pt] Your add() and multiply() methods return new Fraction objects without changing the operands
- [1pt] Your Fraction class has a toMixed() method that returns a new Mixed object
- [1pt] Your toMixed() method correctly calculate the attributes of the returned Mixed object
- Mixed (10pt)
- [1pt] Your Mixed class has appropriate instance variables
- [1pt] Your Mixed class has a working constructor that takes three ints as parameters
- [2pt] Your Mixed class has a working constructor that takes a String as a parameter
- [1pt] Your Mixed class has an appropriate toString() method
- [1pt] Your Mixed class has a toFraction() method that returns a new Fraction object
- [1pt] Your Mixed class has an add() and multiply() methods that fits the required method signatures
- [1pt] Your add() method correctly calculates the sum of the Mixed
- [1pt] Your multiply() method correctly calculates the product of the Mixed
- [1pt] Your add() and multiply() methods return new Mixed objects without changing the operands
- FractionCalculator (6pt)
- [1pt] Your FractionCalculator contains the required static methods
- [1pt] Your methods print out an appropriate prompt for user input
- [2pt] You use a Scanner to read input from the user
- [2pt] Your methods calculate and print out the appropriate sums ∓ products
- Style & Documentation (6pt)
-
[1pt] Instance variables in all of your classes are
private
- [1pt] You only use instance variables for attributes; all other variables are local
- [1pt] Your code is properly formatted (indentation, etc) and methods/variables are properly named
- [1pt] Your code includes some inline comments, as well as a completed class comment
- [1pt] Each of your methods includes a method comment
- [1pt] You have completed the included README.txt file