Reputation: 71
This is my basic currency converter for my intro to java class. I'm supposed to be able to convert between yen, dollars, pounds and euros using static rates. It works, but I was curious to know if I did it in the most efficient way possible. It seems quite long and looks like a huge mess. Just wanting some feedback.
import java.util.Scanner;
public class currency
{
public currency()
{
char us_dollar_sym = 36;
char pound_sym = 163;
char yen_sym = 165;
char euro_sym = 8364;
String us_dollar = "Dollars";
String pound = "Pounds";
String yen = "Yen";
String euro = "Euros";
double rate = 0;
// Interface
System.out.println("Welcome to the Currency Converter Program \n");
System.out.println("Use the following codes to input your currency choices: \n 1 - US dollars \n 2 - Euros \n 3 - British Pounds \n 4 - Japanese Yen \n");
//
System.out.println("Please choose the input currency:");
Scanner in = new Scanner(System.in);
int choice = in.nextInt();
String inType = null;
switch(choice) {
case 1: inType = "US Dollars >> " + us_dollar_sym; break;
case 2: inType = "Euros >> " + euro_sym; break;
case 3: inType = "British Pounds >> " + pound_sym; break;
case 4: inType = "Japanese Yen >> " + yen_sym; break;
default:
System.out.println("Please restart the program & enter a number from the list.");
return;
}
System.out.println("Please choose the output currency");
int output = in.nextInt();
System.out.printf("Now enter the input in " + inType);
double input = in.nextDouble();
if (choice == output)
System.out.println("Same currency no need to convert");
if (choice == 1 && output == 2)
{
double dollar_euro_rate = 0.78391;
rate = input * dollar_euro_rate;
System.out.printf( "%s" + input + " at a conversion rate of " + dollar_euro_rate + " Dollars to %s = %.2f\n", (char)us_dollar_sym, euro, rate);
}
else if (choice == 1 && output == 3){
double dollar_pound_rate = 0.621484;
rate = input * dollar_pound_rate;
System.out.printf( "%s" + input + " at a conversion rate of " + dollar_pound_rate + " Dollars to %s = %.2f\n", (char)us_dollar_sym, pound, rate);
}
else if (choice == 1 && output == 4){
double dollar_yen_rate = 107.174;
rate = input * dollar_yen_rate;
System.out.printf( "%s" + input + " at a conversion rate of " + dollar_yen_rate + " Dollars to %s = %.2f\n", (char)us_dollar_sym, yen, rate);
}
if (choice == 2 && output == 1)
{
double euro_dollar_rate = 1.27579;
rate = input * euro_dollar_rate;
System.out.printf( "%s" + input + " at a conversion rate of " + euro_dollar_rate + " Euros to %s = %.2f\n", (char)euro_sym, us_dollar, rate);
}
else if (choice == 2 && output == 3)
{
double euro_pound_rate = 0.792648;
rate = input * euro_pound_rate;
System.out.printf( "%s" + input + " at a conversion rate of " + euro_pound_rate + " Euros to %s = %.2f\n", (char)euro_sym, pound, rate);
}
else if (choice == 2 && output == 4)
{
double euro_yen_rate = 136.708;
rate = input * euro_yen_rate;
System.out.printf( "%s" + input + " at a conversion rate of " + euro_yen_rate + " Euros to %s = %.2f\n", (char)euro_sym, yen, rate);
}
if (choice == 3 && output == 1)
{
double pound_dollar_rate = 1.60972;
System.out.printf( "%s" + input + " at a conversion rate of " + pound_dollar_rate + " Pounds to %s = %.2f\n", (char)pound_sym, us_dollar, rate);
}
else if (choice == 3 && output == 2)
{
double pound_euro_rate = 1.26161;
System.out.printf( "%s" + input + " at a conversion rate of " + pound_euro_rate + " Pounds to %s = %.2f\n", (char)pound_sym, euro, rate);
}
else if (choice == 3 && output == 4)
{
double pound_yen_rate = 172.511;
System.out.printf( "%s" + input + " at a conversion rate of " + pound_yen_rate + " Pounds to %s = %.2f\n", (char)pound_sym, yen, rate);
}
if (choice == 4 && output == 1)
{
double yen_dollar_rate = 0.00932574;
System.out.printf( "%s" + input + " at a conversion rate of " + yen_dollar_rate + " Yen to %s = %.2f\n", (char)yen_sym, us_dollar, rate);
}
else if (choice == 4 && output == 2)
{
double yen_euro_rate = 0.00730615;
System.out.printf( "%s" + input + " at a conversion rate of " + yen_euro_rate + " Yen to %s = %.2f\n", (char)yen_sym, euro, rate);
}
else if (choice == 4 && output == 3)
{
double yen_pound_rate = 0.00579135;
System.out.printf( "%s" + input + " at a conversion rate of " + yen_pound_rate + " Yen to %s = %.2f\n", (char)yen_sym, pound, rate);
}
System.out.println("Thank you for using the currency converter");
}
}
Upvotes: -1
Views: 23143
Reputation: 424943
Here's a modularized version of your code that supports any number of currencies by just adding to enum Currency
and handles bad input gracefully:
public class CurrencyConverter {
public static void main(String[] args) {
printWelcomeMessage();
Currency fromCurrency = read("Please enter the input currency code:", Currency::fromString);
Currency toCurrency = read("Please enter the output currency code:", Currency::fromString);
Double fromAmount = read("Please enter the amount:", CurrencyConverter::parseDouble);
double toAmount = fromCurrency.convertTo(fromAmount, toCurrency);
System.out.printf("The conversion rate from %s to %s is %.2f. %s%.2f is %s%.2f\n",
fromCurrency, toCurrency, fromCurrency.rateTo(toCurrency),
fromCurrency.getSymbol(), fromAmount, toCurrency.getSymbol(), toAmount);
System.out.println("Thank you for using the currency converter!");
}
private enum Currency {
USD('$', 1),
EUR('€', 0.78391),
YEN('¥', 107.174),
GBP('£', 0.621484);
private final char symbol;
private final double toUsd;
private static class Holder {
private final static Map<String, Currency> LOOKUP = new HashMap<>();
}
Currency(char symbol, double toUsd) {
this.symbol = symbol;
this.toUsd = toUsd;
Holder.LOOKUP.put(name(), this);
}
public double rateTo(Currency currency) {
return currency.toUsd / toUsd;
}
public double convertTo(double fromAmount, Currency currency) {
return fromAmount * rateTo(currency);
}
public char getSymbol() {
return symbol;
}
public static Optional<Currency> fromString(String str) {
return Optional.ofNullable(str).map(String::toUpperCase).map(Holder.LOOKUP::get);
}
}
private static Optional<Double> parseDouble(String str) {
try {
return Optional.of(Double.parseDouble(str));
} catch (NumberFormatException ignore) {
return Optional.empty();
}
}
private static <T> T read(String message, Function<String, Optional<T>> parser) {
System.out.println(message);
Scanner in = new Scanner(System.in);
Optional<T> parsedInput = Optional.empty();
while (parsedInput.isEmpty()) {
String input = in.nextLine();
parsedInput = parser.apply(input);
if (parsedInput.isEmpty()) {
System.out.printf("Invalid input '%s'. Please try again:\n", input);
}
}
return parsedInput.get();
}
private static void printWelcomeMessage() {
System.out.println("Welcome to the Currency Converter Program");
System.out.println("The following currencies are supported:");
Arrays.stream(Currency.values()).forEach(System.out::println);
}
}
Upvotes: 0
Reputation: 1377
Why you are using this way to convert currency. You have the JSR 354 Money and Currency API here are some examples you can use, its really easy to use and fast:
MonetaryAmount monetaryAmount = Money.of(100.20, usd);
CurrencyUnit currency = monetaryAmount.getCurrency();
NumberValue numberValue = monetaryAmount.getNumber();
int value= numberValue.intValue();
Upvotes: 0
Reputation: 2143
Express all of your rates as a multiplier of one standard value, for instance use the USD as the standard value. Then the conversion values for GBP would be 1.60, the USD would be 1.0 and the Euro would be 1.29. Then the conversion calculation would be:
From Value * From Conversion * 1/To Conversion
For instance from 1 GBP to Euro would be:
1 * 1.60 * (1/1.29) = 1.24
If you store all of your rates in a HashMap then you can avoid the switch statements completely.
Upvotes: 0
Reputation: 316
Since you refer to your currency as int, I would use an n by m matrix for storing the exchange rate. n would be the first currency and m the second. With both int you can retrace the correct exchange rate.
The diagonal in the matrix would be 1 (since USD >> USD =1 ).
Finally, write a function to compute the exchange rate and return the corresponding text (you can use an hashmap for that, with the int as a key and the name ( string) as the value)
exchange_rate = currency[1][2];
HashMap hm = new HashMap();
hm.put(1, new string("USD");
etc...
Upvotes: 0
Reputation: 78
I am always cautious of using integer input. If someone types a char, your program would likely crash as an exception would occur. Accepting a char of the number might be a safer alternative.
When you check the "choice" and "output" in the same if statement it requires more resources. Nesting the if statements might improve efficiency. This would be having the if statement for choice with the if statements for output within them.
Upvotes: 0