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;
Choose the right names
The name HW3_DollarValuOfCoinsInvestmentCompoundedAnnually
is not great.
For one thing, class names in Java should use CamelCase
,
which is violated by the _
there.
The current name includes the 2 purposes used in the class:
- Calculate the dollar value of coins
- Calculate the compound interest
Since these are completely different things, either split the class into 2 separate classes, or give it a more generic name.
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 ofkeyboard
, 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 ofpriceFormat
, 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.
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
Note: I'm still typing the explanation of the code below and will update my answer as I go, adding sections above, hang on.
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.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));
}
private static void calculateCompoundInterest(Scanner scanner, NumberFormat moneyFormat) {
System.out.println("What is the initial investment?");
double investment = scanner.nextDouble();
System.out.println("At what intrest rate is the intrest compounded annually?");
double intrestRate = scanner.nextDouble();
double futureValueFive = investment * Math.pow(1 + intrestRate, 5.);
System.out.println("In five years the investment will be worth : " + moneyFormat.format(futureValueFive));
double futureValueTen = investment * Math.pow(1 + intrestRate, 10.);
System.out.println("In ten years the investment will be worth : " + moneyFormat.format(futureValueTen));
double futureValueTwenty = investment * Math.pow(1 + intrestRate, 20.);
System.out.println("In twenty years the investment will be worth : " + moneyFormat.format(futureValueTwenty));
}
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
NumberFormat moneyFormat = NumberFormat.getCurrencyInstance();
calculateDollarValueOfCoins(scanner, moneyFormat);
calculateCompoundInterest(scanner, moneyFormat);
}
}