How can I remove redundancy's from this java problem if there exist any?

Viewed 329

I'm in CS140 and trying to solve problems in Practice-It. I'm not sure what else to do for this problem to make it correct. The instructions are, "The following program redundantly repeats the same expressions many times. Modify the program to remove all redundant expressions using variables of appropriate types." I'm just learning how to use integers and am struggling with it so I'm sure I'm missing something simple. I posted the code in its original form below how I tried to solve it. Thanks in advance for any help! :)

// This program computes the total amount owed for a meal,
// assuming 8% tax and a 15% tip.
public class Receipt {
    public static void main(String[] args) {
        int x=38+40+30;
        double y=.08;
        double z=.15;
        System.out.println("Subtotal:");
        System.out.println(x);
        System.out.println("Tax:");
        System.out.println((x) * y);
        System.out.println("Tip:");
        System.out.println((x) * z);
        System.out.println("Total:");
        System.out.println((x) + (x) * y + (x) * z);
                           
                            

    }
}

The original problem is below.

// This program computes the total amount owed for a meal,
// assuming 8% tax and a 15% tip.
public class Receipt {
    public static void main(String[] args) {
        System.out.println("Subtotal:");
        System.out.println(38 + 40 + 30);
        System.out.println("Tax:");
        System.out.println((38 + 40 + 30) * .08);
        System.out.println("Tip:");
        System.out.println((38 + 40 + 30) * .15);
        System.out.println("Total:");
        System.out.println(38 + 40 + 30 +
                            (38 + 40 + 30) * .08 +
                            (38 + 40 + 30) * .15);

    }
}
3 Answers

You're on the right track. Clearly you're intended to assign common values to variables, which you've done as x and y and z. Note, however, that these variable names aren't very descriptive -- a better solution would start by calling these things what they actually are ... subtotal, taxMultiplier and tipMultiplier.

But note that you still have some redundancies. You repeat your calculating for tax twice -- once when printing the tax and then again when printing the total. So you should assign that value to a new double (tax). A similar refactor can be done with tip and total.

This turns your code into something like this:

// This program computes the total amount owed for a meal,
// assuming 8% tax and a 15% tip.
public class Receipt {
    public static void main(String[] args) {
        int subtotal = 38 + 40 + 30; // formerly x
        double taxMultiplier = 0.08; // formerly y
        double tipMultiplier = 0.15; // formerly z
        double tax = subtotal * taxMultiplier;
        double tip = subtotal * tipMultiplier;
        double total = subtotal + tax + tip;

        System.out.println("Subtotal:");
        System.out.println(subtotal);
        System.out.println("Tax:");
        System.out.println(tax);
        System.out.println("Tip:");
        System.out.println(tip);
        System.out.println("Total:");
        System.out.println(total);
    }
}

Of course, you could then look at this code and say "Hey, I only use taxMultiplier and tipMultiplier once, why bother declaring them?" and you'd be right -- you could then refactor again to inline the values of taxMultiplier and tipMultiplier into the tax and tip calculations.

Assigning intermediate values to variables with sensible names is a technique which we use to minimize errors (eg you mght typo a value when repeating it) and also to make it clear what is going on. In this code, you can clearly see that total is the sum of the subtotal, tax, and tip. The number soup in the original code made it really hard to see that. Further, if a value changes (eg the subtotal), you'll only have to change it in one place and the appropriate changes will cascade throughout the rest of the code.

I suspect that the lesson is teaching you to separate your calculations from your display.

Here's what I think the lesson wanted you to code.

public class Receipt {

    public static void main(String[] args) {
        int subTotal = 38 + 40 + 30;
        double tax = .08 * subTotal;
        double tip = .15 * subTotal;
        double total = subTotal + tax + tip;

        System.out.println("Subtotal:");
        System.out.println(subTotal);
        System.out.println("Tax:");
        System.out.println(tax);
        System.out.println("Tip:");
        System.out.println(tip);
        System.out.println("Total:");
        System.out.println(total);
    }

}

You can further reduce the size of the code by creating a print method to print the values.

public class Receipt {

    public static void main(String[] args) {
        int subTotal = 38 + 40 + 30;
        double tax = .08 * subTotal;
        double tip = .15 * subTotal;
        double total = subTotal + tax + tip;

        printAmount("Subtotal:", subTotal);
        printAmount("Tax:", tax);
        printAmount("Tip:", tip);
        printAmount("Total:", total);
    }

    private static void printAmount(String label, double value) {
        System.out.println(label);
        System.out.println(value);
    }

}

Finally, it's possible to print the text and value on the same line with the value formatted with a dollar sign, but that's going way beyond your lesson for now.

My version:

public class Receipt {

  public static void main(String[] args) {
    int firstMealPrice = 38;
    int secondMealPrice = 40;
    int thirdMealPrice = 30;

    double taxMultiplier = 0.08;
    double tipMultiplier = 0.15;

    int mealSubtotalPrice = firstMealPrice + secondMealPrice + thirdMealPrice;
    double mealTax = mealSubtotalPrice * taxMultiplier;
    double mealTip = mealSubtotalPrice * tipMultiplier;

    double mealTotalPrice = mealSubtotalPrice +
        mealTax +
        mealTip;

    print("Subtotal:");
    print(mealSubtotalPrice);
    print("Tax:");
    print(mealTax);
    print("Tip:");
    print(mealTip);
    print("Total:");
    print(mealTotalPrice);

  }

  private static void print(Object obj) {
    System.out.println(obj);
  }
}
Related