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:

  1. 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.

  2. 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

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.

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.

  1. 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!
  2. You will need to create one constructor for the Fraction class that takes in two ints (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)
  3. You will also need to create a second constuctor for the Fraction class. This constructor should take a single String 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 the Integer.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) and nextInt() to get a number from a String! This is generally more complicated though.
  4. Your class should have a getter and setter for each attribute (this will let you practice writing these methods!)
  5. A Fraction will need a toString() method so that you can easily print it out. Remember, a toString() method does not actually print anything, it just returns a String that can be printed elsewhere!
  6. A Fraction will also need an add() method. This method should take in another Fraction as a parameter, and return a new Fraction as the result. For example, if I make a Fraction 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!
  7. Similarly, your Fraction will need to have a multiply() method. Like add(), this method should take in another Fraction as an argument, and return a new Fraction as the result.
    • Again, think about how you calculate the product of two fractions (hint: cross-multiply), and write that into code!
  8. Finally, a Fraction will need a toMixed() method that returns a new Mixed object that represents the same value. This will let you easily switch between Fractions and Mixeds. Important hint: Implement most of the Mixed 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 ;)
  9. 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.

  1. Think about what attributes a Mixed has. What instance variables will you need to declare?
  2. You will need to create one constructor for the Mixed class that takes in 3 ints as parameters and assigns them to the attributes. Your constructor should not have a Fraction as a parameter!
  3. Like with the Fraction class, you will also need to create a second constuctor for the Mixed class. This constructor should take a single String as a parameter, representing the String version of a Mixed (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!
  4. A Mixed will need a toString() method so that you can easily print it out. Remember, a toString() method does not actually print anything, it just returns a String that can be printed elsewhere!
  5. A Mixed will need a toFraction() method that returns a new 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.
  6. A Mixed will need an add() method. This method should take in another Mixed as an argument, and return a new 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!
  7. A Mixed will also need a multiply() method. This method should take in another Mixed as an argument, and return a new Mixed as the result. Again, you can use the same technique as your add() method to easily do this math.
  8. 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.

  1. 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!
  2. 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.
  3. 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;
  4. 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
    This method returns a String that is whatever text the user typed in!
    • 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.
  5. 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!
  6. 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.
  7. 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.
  8. 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!

  1. 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!
  2. 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.

  1. 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!
  2. 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!
  3. 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).

  4. 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!
  5. 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).