TIL

[250226 TIL] 계산기 트러블 슈팅

도원좀비 2025. 2. 26. 16:21

배경 : 어떤 현상을 발견해서

lv.1 에서 lv.2로 변환중에 입력이랑 연산을 각각의 메서드로 변환하고 나니 오류가 발생

발단 : 

설계당시에 무한이 연산을 이어 갈 수 있는 계산기를 만들고자 해서 첫 입력을 반복문 밖으로 보냄과 동시에

결과 값을 첫 입력값으로 변수 설정을 해서 오류가 발생

기존 코드

(Calcurator_lv1.java)

import java.util.Scanner;

public class Calculator_lv1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.println("양의 정수를 입력해주세요 또는 'exit'입력시 종료 :");
        String input = sc.nextLine();
        if (input.equalsIgnoreCase("exit")) {
            System.out.println("계산기를 종료합니다.");
            return;
        }
        int a = Integer.parseInt(input);
        while (true) {




            System.out.println("연산자를 입력하세요 (+,-,*,/) 또는 'exit'입력시 종료 :");
            String input2 = sc.nextLine();
            if (input2.equalsIgnoreCase("exit")) {
                System.out.println("계산기를 종료합니다.");
                break;
            }

            char operator = input2.charAt(0);

            System.out.println("다음 양의 정수를 입력해주세요 또는 'exit'입력시 종료 :");
            String input3 = sc.nextLine();
            if (input3.equalsIgnoreCase("exit")) {
                System.out.println("계산기를 종료합니다.");
                break;
            }

            int b = Integer.parseInt(input3);

            switch (operator) {
                case '+':
                    a += b;
                    break;
                case '-':
                    a -= b;
                    break;
                case '*':
                    a *= b;
                    break;
                case '/':
                    if (b != 0) {
                        a /= b;
                    } else {
                        System.out.println("0으로 나눌 수 없습니다.");
                        continue;
                    }
                    break;
                default:
                    System.out.println("잘못된 연산자입니다.");
                    continue;
            }
            System.out.println("결과 값 : " + a);
        }
        sc.close();
    }
}

전개 : 

그래서 무한히 연산가능한 계산기 보다 문제에 맞는 한번 계산하고 결과값이 저장되도록 하기 위해 while 반복문에 입력 위치를 변경

위기 : 

모든 결과 값을 가져오는 리스트는 구현했지만 위에 설명한것과 같이 초기 입력값이 배열 0번으로 출력 됨 그래서 구조를 전체적으로 수정

절정 : 

다음과 같이 코드를 변경

코드 변경후

(Calculator_lv2.java)

import java.util.Scanner;

public class Calculator_lv2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Calculator calculator = new Calculator(); // 계산기 객체 생성

        while (true) {
            System.out.println("첫 번째 숫자를 입력하세요. 'exit' 입력 시 종료, 'remove' 입력시 첫번 째 결과 값 삭제 : ");
            String input1 = sc.nextLine();
            if (input1.equalsIgnoreCase("exit")) {
                System.out.println("계산기를 종료합니다.");
                break;
            } // remove 메서드 호출
            if (input1.equalsIgnoreCase("remove")) {
                calculator.removeList();
                System.out.println("삭제 후 현재 값들 : "+ calculator.getResults());
                continue;
            }

            System.out.println("연산자를 입력하세요 (+,-,*,/) 또는 'exit' 입력 시 종료:");
            String operatorInput = sc.nextLine();
            if (operatorInput.equalsIgnoreCase("exit")) {
                System.out.println("계산기를 종료합니다.");
                break;
            }
            char operator = operatorInput.charAt(0);

            System.out.println("두 번째 숫자를 입력하세요 또는 'exit' 입력 시 종료:");
            String input2 = sc.nextLine();
            if (input2.equalsIgnoreCase("exit")) {
                System.out.println("계산기를 종료합니다.");
                break;
            }

            try {
                double num1 = Double.parseDouble(input1);
                double num2 = Double.parseDouble(input2);

                // 연산 수행
                calculator.calculate(num1, operator, num2);

                // 결과 출력
                System.out.println("현재 결과 값: " + calculator.getLastResult());
                System.out.println("전체 결과 내역: " + calculator.getResults());
            } catch (NumberFormatException e) {
                System.out.println("올바른 숫자를 입력하세요.");
            }
        }

        sc.close();
    }
}

 

(Calculator.java)

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Calculator {
    private final List<Double> results; // 연산 결과를 저장하는 리스트

    // 생성자
    public Calculator() {
        results = new ArrayList<>();
    }

    // 연산 수행
    public void calculate(double num1, char operator, double num2) {
        double newResult;

        // 각 연산자를 해당 메서드 호출로 분리
        switch (operator) {
            case '+':
                newResult = add(num1, num2);
                break;
            case '-':
                newResult = subtract(num1, num2);
                break;
            case '*':
                newResult = multiply(num1, num2);
                break;
            case '/':
                try {
                    newResult = divide(num1, num2);
                } catch (IllegalArgumentException e) {
                    System.out.println(e.getMessage());
                    return; // 연산 수행하지 않고 리턴
                }
                break;
            default:
                System.out.println("잘못된 연산자입니다.");
                return; // 연산 수행하지 않고 리턴
        }

        results.add(newResult); // 결과 저장
    }

    private double add(double num1, double num2) {
        return  num1 + num2;
    }
    private  double subtract(double num1, double num2) {
        return  num1 - num2;
    }
    private  double multiply(double num1, double num2) {
        return  num1 * num2;
    }
    private double divide(double num1, double num2) {
        if (num2 == 0) {
            throw new IllegalArgumentException("0으로 나눌 수 없습니다.");
        }
        return num1 / num2;
    }


    // 최신 연산 결과 반환
    public double getLastResult() {
        if (results.isEmpty()) {
            return 0; // 결과가 없으면 0 반환
        }
        return results.get(results.size() - 1);
    }

    // 모든 결과 리스트 반환
    public List<Double> getResults() {
        return new ArrayList<>(results); // 원본 보호를 위해 새 리스트 반환
    }

    // 가장 먼저 생성된 데이터 삭제
    public void removeList() {
        if(!results.isEmpty()) {
            results.remove(0);
            System.out.println("첫번 째 데이터가 삭제되었습니다.");
        } else {
            System.out.println("삭제 할 데이터가 없습니다.");
        }

    }
}

결말 :  

다음 부터는 변수 설정과 설계를 조금 더 확실하고 정밀하게 해서 추가 기능들을 넣거나 수정 하더라도 원하는 결과를 얻을 수 있도록 하겠다.