Search code examples
javatype-conversioncurrencyjava.util.concurrenttypeconverter

This is my first program. I wanted to create a converts currencies and gives advices to user on how best to spend money. I need some advances


package firstproject;
import java.util.Scanner;
public class Currency{
    public static void main(String[] args) {

        int rubles = 100;
        double rateUSD = 1.35;
        double rateEUR = 1.20;
        double rateGBP = 1.02;
        double rateJPY = 153.29;

        // Interface
        System.out.println("Welcome to the Currency Converter Program \n");
        System.out.println("Используйте одну из перечисленных валют для конвертации: \n 1 - Rubles \n 2 - US dollars \n 3 - Euros \n 4 - British Pounds \n 5 - Japanese Yen \n");
        System.out.println("Please choose the input currency");
        Scanner in = new Scanner(System.in);
        int choice = in.nextInt();
        String inType;
        switch(choice) {
            case 1 -> inType = "Rubles >> " + rubles;
            case 2 -> inType = "US Dollars >> " + rateUSD;
            case 3 -> inType = "Euros >> " + rateEUR;
            case 4 -> inType = "British Pounds >> " + rateGBP;
            case 5 -> inType = "Japanese Yen >> " + rateJPY;
            default -> {
                System.out.println("Какая печаль, я пока не знаю такой валюты.\nПожалуйста, перезапустите программу и выберите валюту из списка :)");
                return;
            }
        }  System.out.println("Please choose the output currency");
        Scanner scanner = new Scanner(System.in);

        System.out.println("Сколько денег у вас осталось до зарплаты?");
        double moneyBeforeSalary = scanner.nextDouble();

        System.out.println("Сколько дней до зарплаты?");
        int daysBeforeSalary = scanner.nextInt();

        System.out.println("Введите команду. Доступные команды: convert и advice.");
        String command = scanner.next();

        if (command.equals("convert")) {

                System.out.println("В какую валюту хотите конвертировать рубли? Доступные варианты: USD, EUR, JPY, GBP.");

                String currency = scanner.next(); // считываю значения с помощью scanner

                if (currency.equals("RUB")) {
                    System.out.println("Ваши сбережения в рублях: " + moneyBeforeSalary / rubles);

                }
                switch (currency) {
                    case "RUS" -> System.out.println("Ваши сбережения в рублях:" + rubles );
                    case "USD" -> System.out.println("Ваши сбережения в долларах: " + moneyBeforeSalary / rateUSD);
                    case "EUR" -> System.out.println("Ваши сбережения в евро: " + moneyBeforeSalary / rateEUR);
                    case "GBP" -> System.out.println("Ваши сбережения в долларах: " + moneyBeforeSalary / rateGBP);
                    case "JPY" -> System.out.println("Ваши сбережения в иенах: " + moneyBeforeSalary / rateJPY);
                    default -> System.out.println("Валюта не поддерживается.");
                }

            } else if (command.equals("advice")) {
            if (moneyBeforeSalary < 3000) {
                System.out.println("Сегодня лучше поесть дома. Экономьте, и вы дотянете до зарплаты!");
            } else if (moneyBeforeSalary < 10000) {
                if (daysBeforeSalary < 10) {
                    System.out.println("Окей, пора в Макдак!");
                } else {
                    System.out.println("Сегодня лучше поесть дома. Экономьте, и вы дотянете до зарплаты!");
                }
            } else if (moneyBeforeSalary < 30000) {
                if (daysBeforeSalary < 10) {
                    System.out.println("Неплохо! Прикупите долларов и зайдите поужинать в классное место. :)");
                } else {
                    System.out.println("Окей, пора в Макдак!");
                }
            } else {
                if (daysBeforeSalary < 10) {
                    System.out.println("Отлично! Заказывайте крабов!");
                } else {
                    System.out.println("Неплохо! Прикупите долларов и зайдите поужинать в классное место. :)");
                }
            }
        } else {
            System.out.println("Извините, такой команды пока нет.");
        }
    }
}

I'm not sure about switch(choice), I think this is redundant here. I am missing the code to convert currencies correctly. I found examples of currency converters, but for some reason they called their variables of the char type. I'm a beginner, and I didn't understand why assign a currency value to such a variable. I found something similar: char us_dollar_sym = 36; But I did not understand what the logic of these variables is.

After all, a char can store a symbol, not numbers... or not?


Solution

  • Some suggestions to improve the code

    • Break the program up into smaller pieces
    • Use a method for the conversion
    • Use methods for some of the if/else branches
    • Use constants for common information

    This will make it easier to read and maintain

    • Use BigDecimal instead of double
    • Pick a rounding mode for your divisions (in the code I used "half even")

    This will avoid unintended loss of precision.

    As Turing85 mentioned in the comments, floating points (i.e. double) are not good for representing money. This is because floating points may not exactly represent the value (you could lose precision). See more here.

    For example

    import java.io.PrintStream;
    import java.math.BigDecimal;
    import java.math.RoundingMode;
    import java.util.Scanner;
    
    
    public class Test {
    
        private final static Scanner IN = new Scanner(System.in);
        private final static PrintStream OUT = System.out;
        
        private static final BigDecimal RUBLES = BigDecimal.valueOf(100);
        private static final BigDecimal RATE_USD = BigDecimal.valueOf(1.35);
        private static final BigDecimal RATE_EUR = BigDecimal.valueOf(1.20);
        private static final BigDecimal RATE_GBP = BigDecimal.valueOf(1.02);
        private static final BigDecimal RATE_JPY = BigDecimal.valueOf(153.29);
        private static final RoundingMode ROUNDING_MODE = RoundingMode.HALF_EVEN;
        
        public static void main(String[] args) {
            // Interface
            OUT.println("Welcome to the Currency Converter Program \n");
            OUT.println("Используйте одну из перечисленных валют для конвертации: \n 1 - Rubles \n 2 - US dollars \n 3 - Euros \n 4 - British Pounds \n 5 - Japanese Yen \n");
            OUT.println("Please choose the input currency");
            choose();
            OUT.println("Сколько денег у вас осталось до зарплаты?");
            BigDecimal moneyBeforeSalary = BigDecimal.valueOf(IN.nextDouble());
            OUT.println("Введите команду. Доступные команды: convert и advice.");
            String command = IN.next();
            if (command.equals("convert")) {
                convert(moneyBeforeSalary);
            } else if (command.equals("advice")) {
                OUT.println("Сколько дней до зарплаты?");
                BigDecimal daysBeforeSalary = BigDecimal.valueOf(IN.nextInt());
                advice(moneyBeforeSalary, daysBeforeSalary);
            } else {
                OUT.println("Извините, такой команды пока нет.");
            }
        }
    
        private static void advice(BigDecimal moneyBeforeSalary, BigDecimal daysBeforeSalary) {
            if (moneyBeforeSalary.compareTo(BigDecimal.valueOf(3000)) < 0) {
                OUT.println("Сегодня лучше поесть дома. Экономьте, и вы дотянете до зарплаты!");
            } else if (moneyBeforeSalary.compareTo(BigDecimal.valueOf(10000)) < 0) {
                if (daysBeforeSalary.compareTo(BigDecimal.valueOf(10)) < 0) {
                    OUT.println("Окей, пора в Макдак!");
                } else {
                    OUT.println("Сегодня лучше поесть дома. Экономьте, и вы дотянете до зарплаты!");
                }
            } else if (moneyBeforeSalary.compareTo(BigDecimal.valueOf(30000)) < 0) {
                if (daysBeforeSalary.compareTo(BigDecimal.valueOf(10)) < 0) {
                    OUT.println("Неплохо! Прикупите долларов и зайдите поужинать в классное место. :)");
                } else {
                    OUT.println("Окей, пора в Макдак!");
                }
            } else {
                if (daysBeforeSalary.compareTo(BigDecimal.valueOf(10)) < 0) {
                    OUT.println("Отлично! Заказывайте крабов!");
                } else {
                    OUT.println("Неплохо! Прикупите долларов и зайдите поужинать в классное место. :)");
                }
            }
        }
    
        private static void choose() {
            int choice = IN.nextInt();
            String inType;
            switch (choice) {
                case 1 -> inType = "Rubles >> " + RUBLES;
                case 2 -> inType = "US Dollars >> " + RATE_USD;
                case 3 -> inType = "Euros >> " + RATE_EUR;
                case 4 -> inType = "British Pounds >> " + RATE_GBP;
                case 5 -> inType = "Japanese Yen >> " + RATE_JPY;
                default -> {
                    OUT.println("Какая печаль, я пока не знаю такой валюты.\nПожалуйста, перезапустите программу и выберите валюту из списка :)");
                    return;
                }
            }
            OUT.println("In type: " + inType);
        }
    
        private static void convert(BigDecimal moneyBeforeSalary) {
            OUT.println("Please choose the output currency");
            OUT.println("В какую валюту хотите конвертировать рубли? Доступные варианты: USD, EUR, JPY, GBP.");
            String currency = IN.next(); // считываю значения с помощью scanner
            if (currency.equals("RUB")) {
                OUT.println("Ваши сбережения в рублях: " + moneyBeforeSalary.divide(RUBLES, ROUNDING_MODE));
            }
            switch (currency) {
                case "RUS" -> OUT.println("Ваши сбережения в рублях:" + RUBLES);
                case "USD" -> OUT.println("Ваши сбережения в долларах: " + moneyBeforeSalary.divide(RATE_USD, ROUNDING_MODE));
                case "EUR" -> OUT.println("Ваши сбережения в евро: " + moneyBeforeSalary.divide(RATE_EUR, ROUNDING_MODE));
                case "GBP" -> OUT.println("Ваши сбережения в долларах: " + moneyBeforeSalary.divide(RATE_GBP, ROUNDING_MODE));
                case "JPY" -> OUT.println("Ваши сбережения в иенах: " + moneyBeforeSalary.divide(RATE_JPY, ROUNDING_MODE));
                default -> OUT.println("Валюта не поддерживается.");
            }
        }
    }