HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Dollar value of coins and calculating interest compounded annually

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
coinscompoundeddollarannuallyvaluecalculatinginterestand

Problem

I've made this program to do a few integer calculations. Do the methods for converting the numbers look good? Do you have any other basic tips?

/* Dollar Value of Coins, Investment Compounded Annually
 * B, Morris
 */

import java.util.*;
import java.lang.*;
import java.text.*;
public class HW3_DollarValuOfCoinsInvestmentCompoundedAnnually {
public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
NumberFormat priceFormat = NumberFormat.getCurrencyInstance();

//Dollar value of coins

System.out.println("How many quarters do you have?");
double quarters = keyboard.nextDouble();

System.out.println("How many dimes do you have?");
double dimes = keyboard.nextDouble();

System.out.println("How many nickles do you have?");
double nickles = keyboard.nextDouble();

quarters = quarters * (0.25);
dimes = dimes * (0.10);
nickles = nickles * (0.05);
double total =(quarters + dimes + nickles);
System.out.println("You have: " + priceFormat.format(total));

//Investment Compounded Annually

System.out.println("What is the initial investment?");
double investment = keyboard.nextDouble();

System.out.println("At what intrest rate is the intrest compounded annually?");
double intrestRate = keyboard.nextDouble();

double futureValueFive = investment * (Math.pow((1 + intrestRate), (double) 5));
System.out.println("In five years the investment will be worth : " + priceFormat.format(futureValueFive));

double futureValueTen = investment * (Math.pow((1 + intrestRate), (double) 10));
System.out.println("In ten years the investment will be worth : " + priceFormat.format(futureValueTen));

double futureValueTwenty = investment * (Math.pow((1 + intrestRate), (double) 20));
System.out.println("In twenty years the investment will be worth : " + priceFormat.format(futureValueTwenty));

}
}

Solution

Choose the right types

You used double for the coin types, for example:

System.out.println("How many quarters do you have?");
double quarters = keyboard.nextDouble();
quarters = quarters * (0.25);


To the question "how many quarters ...",
it's logical to get an integer (whole number) as the answer, not a double.

I can guess that you choose the double type because you want to use the quarters variable for two different purposes:

  • Count the quarters



  • Count the dollar value of the quarters



These are conflicting meanings, and the right thing to do is to not mix them,
for example:

int quarters = keyboard.nextInt();
double dollarValueOfQuarters = quarters * .25;


The Single Responsibility Principle

The main is doing too much: it has too many responsibilities:

  • Calculate the dollar value of coins



  • Calculate the compound interest



It would be better to split the method into, and give them a name according to their main responsibility, for example:

private static void calculateDollarValueOfCoins(Scanner scanner, NumberFormat moneyFormat) { ... }

private static void calculateCompoundInterest(Scanner scanner, NumberFormat moneyFormat) { ... }

public static void main(String args[]) {
    Scanner scanner = new Scanner(System.in);
    NumberFormat moneyFormat = NumberFormat.getCurrencyInstance();

    calculateDollarValueOfCoins(scanner, moneyFormat);
    calculateCompoundInterest(scanner, moneyFormat);
}


Now the responsibilities are clearly separated.
I also renamed some variables to better match their purposes:

  • scanner instead of keyboard, because you don't really "scan" things from a keyboard. A scanner is a more abstract concept than a keyboard: for all you care, the input values could come as radio signals from the moon, as long as it implements the Scanner's API, your method can work.



  • moneyFormat instead of priceFormat, which works for both responsibilities nicely: the dollar value of your coins is certainly not a "price", and the worth of your investment is not exactly a "price". They are both about money, and formatting money, so this more general name seems appropriate.



Modeling coins

It might be a good idea to model coins using an enum:

enum Coin {
    NICKLE(.05),
    DIME(.1),
    QUARTER(.25);

    private final double value;

    Coin(double value) {
        this.value = value;
    }
}


And to add a helper class for adding coins:

private static class CoinAdder {
    private double value = 0;

    CoinAdder addCoins(Coin coin, int number) {
        value += coin.value * number;
        return this;
    }

    public double getValue() {
        return value;
    }
}


This way, the calculateDollarValueOfCoins method I suggested above can be implemented in a somewhat more natural way,
and without embedding the dollar value of coins in it:

private static void calculateDollarValueOfCoins(Scanner scanner, NumberFormat moneyFormat) {
    System.out.println("How many quarters do you have?");
    int quarters = scanner.nextInt();

    System.out.println("How many dimes do you have?");
    int dimes = scanner.nextInt();

    System.out.println("How many nickles do you have?");
    int nickles = scanner.nextInt();

    double total = new CoinAdder()
            .addCoins(Coin.QUARTER, quarters)
            .addCoins(Coin.DIME, dimes)
            .addCoins(Coin.NICKLE, nickles)
            .getValue();
    System.out.println("You have: " + moneyFormat.format(total));
}


Now we have separated the responsibilities even further:
calculateDollarValueOfCoins doesn't know anymore the value of the different types of coins, and it doesn't know how to add them.
Those responsibilities are delegated to the Coin enum and the CoinAdder class,
which is a good thing.

Quick tips

Instead of this:

quarters = quarters * (0.25);


Better:

quarters *= 0.25;


You can write 0.25 as .25.

You can write 5. instead of (double) 5.

Suggested implementation

Putting the above suggestions together, something like this would be better:

```
class InterestCalculator {

enum Coin {
NICKLE(.05),
DIME(.1),
QUARTER(.25);

private final double value;

Coin(double value) {
this.value = value;
}
}

private static class CoinAdder {
private double value = 0;

CoinAdder addCoins(Coin coin, int number) {
value += coin.value * number;
return this;
}

public double getValue() {
return value;
}
}

private static void calculateDollarValueOfCoins(Scanner scanner, NumberFormat moneyFormat) {
System.out.println("How many quarters do you have?");
int quarters = scanner.nextInt();

System.out.println("How many dimes do you have?");
int dimes = scanner.nextInt();

System.out.println("How many nickles do you have?");
int nickles = scanner.nextI

Code Snippets

System.out.println("How many quarters do you have?");
double quarters = keyboard.nextDouble();
quarters = quarters * (0.25);
int quarters = keyboard.nextInt();
double dollarValueOfQuarters = quarters * .25;
private static void calculateDollarValueOfCoins(Scanner scanner, NumberFormat moneyFormat) { ... }

private static void calculateCompoundInterest(Scanner scanner, NumberFormat moneyFormat) { ... }

public static void main(String args[]) {
    Scanner scanner = new Scanner(System.in);
    NumberFormat moneyFormat = NumberFormat.getCurrencyInstance();

    calculateDollarValueOfCoins(scanner, moneyFormat);
    calculateCompoundInterest(scanner, moneyFormat);
}
enum Coin {
    NICKLE(.05),
    DIME(.1),
    QUARTER(.25);

    private final double value;

    Coin(double value) {
        this.value = value;
    }
}
private static class CoinAdder {
    private double value = 0;

    CoinAdder addCoins(Coin coin, int number) {
        value += coin.value * number;
        return this;
    }

    public double getValue() {
        return value;
    }
}

Context

StackExchange Code Review Q#64695, answer score: 8

Revisions (0)

No revisions yet.