개별과제 : Lv1. 클래스없는 사칙연산 계산기 (+ 트러블 슈팅)

커비·2024년 11월 14일
0

과제 해결

목록 보기
4/5

❗ 개별과제

핵심목표 : 자바 문법의 실습과 객체 지향 개념의 적용
이 버전에서는 자바의 객체 지향 원칙을 적용하여 클래스를 정의하고, 연산을 수행하는 메소드를 작성해야 합니다. 이 과정에서 클래스와 객체의 개념을 이해하고 활용하는 방법을 익힐 수 있습니다.


📍 요구사항 정의

  • 계산기 기능 : 사칙연산 (덧셈, 뺄셈, 곱셈, 나눗셈)
  • 사용자 인터페이스 방식 : 콘솔기반
  • 예외 처리 : 0으로 나누거나 기호를 잘못 입력하면 다시 첫 입력창 출력

마음같아선 GUI기반으로 만들고 싶었지만, 첫 시작은 콘솔기반이 좋겠다고 판단했다.


✅ 작업 기록

작업하면서 남기려고 했지만 정신이 없어서 다 만들고 난 후인 지금 Localhistory를 보며 남겨보려고 한다!

1️⃣ 양의 정수(0 포함)입력받기

❗ 필수 기능 가이드

  • Scanner를 사용하여 양의 정수 2개(0 포함)를 전달 받을 수 있습니다.
  • 양의 정수는 각각 하나씩 전달 받습니다.
  • 양의 정수는 적합한 타입으로 선언한 변수에 저장합니다.

사실 처음에는 무슨 말인지 이해가 안됐다.
예시코드를 열어서 확인해보고 어떤 것을 원하는지 감으로 느꼈다.

Scanner를 보자마자 어떻게 해야할지 찾아온 감으로 주석부터 쭉 입력해보았다.

  • 사용자 입력 객체 생성
  • 첫번째 피연산자 입력
  • 연산자 입력
  • 두번째 피연산자 입력
  • 결과값 저장하는 변수 선언

변수는 저장된 값을 잘 나타낼 수 있는 의미있는 이름으로 지으면서도 공통단어가 앞쪽으로 오도록 입력했다. (최대한 직관적이게 operand / First = 피연산자 / 첫번째)

			// 사용자 입력 객체 생성
            Scanner scanner = new Scanner(System.in);

            // 첫번째 피연산자 입력
            System.out.print("첫 번째 숫자를 입력하세요 : ");
            double operandFirst = scanner.nextDouble();

            // 연산자 입력
            System.out.print("기호를 입력하세요 (+, -, *, /) : ");
            char operator = scanner.next().charAt(0);

            // 두번째 피연산자 입력
            System.out.print("두 번째 숫자를 입력하세요 : ");
            double operandSecond = scanner.nextDouble();

            // 결과값 저장 변수 선언
            double result = 0;

그 후, 입력할 때 사용자를 위한 System.out.print 를 추가했다.
나눗셈이 들어가기 때문에 Int보다 double가 적당할 것이라고 생각이 들어 피연산자는 모두 double 타입으로 설정했다.

❗ 필수 기능 가이드

  • Scanner를 사용하여 사칙연산 기호를 전달 받을 수 있습니다.
  • 사칙연산 기호를 적합한 타입으로 선언한 변수에 저장합니다. (charAt(0))
// 연산자 입력
System.out.print("기호를 입력하세요 (+, -, *, /) : ");
char operator = scanner.next().charAt(0);

연산자 입력창에는 어떤 연산자부터 어떤 연산자까지 가능한지 모를 것을 감안하여 (+, -, *, /) 를 함께 입력했다. 지금은 char로 변경했지만 이전에는 String으로 입력했었다.
변경하게 된 이유는 charAt(0)을 사용해야한다는 2번째 항목이 있었기 때문이다.


2️⃣ 사칙연산 기호(➕,➖,✖️,➗)를 입력받기

❗ 필수 기능 가이드

위에서 입력받은 양의 정수 2개와 사칙연산 기호를 사용하여 연산을 진행한 후 결과값을 출력하기
키워드 : if, switch

  • 사칙연산 기호에 맞는 연산자를 사용하여 연산을 진행합니다.
  • 입력받은 연산 기호를 구분하기 위해 제어문을 사용합니다. (예를 들면 if, switch)
  • 연산 오류가 발생할 경우 해당 오류에 대한 내용을 정제하여 출력합니다.
  • ex) “나눗셈 연산에서 분모(두번째 정수)에 0이 입력될 수 없습니다.“
			// 사용자가 입력한 기호에 따른 case(operator) 실행
            switch (operator) {
                // 덧셈
                case '+':
                    result = operandFirst + operandSecond;
                    break;
                // 뺄셈
                case '-':
                    result = operandFirst - operandSecond;
                    break;
                // 곱셈
                case '*':
                    result = operandFirst * operandSecond;
                    break;
                // 나눗셈
                case '/':
                    if (operandSecond != 0) { // 0으로 나눌 수 없음
                        result = operandFirst / operandSecond;
                    } else {
                        System.out.println("0으로 나눌 수 없습니다. 다시 입력하세요.");
                        operatorNo = false;
                    }
                    break;

                // 안내한 기호 외의 것을 입력한 경우 오류 메세지 출력
                default:
                    System.out.println("기호입력이 잘못되었습니다.");
                    operatorNo = false; // 유효하지 않은 연산자
                    break;
            }

operator 는 연산자에게 준 변수명이다.

이 부분도 String일 때에는 case"": 이었던 부분을 case'': 이렇게 변경했다.
주석에 불필요한 글을 남기고 싶지 않아서 최대한 직관적이고 깔끔하게 적어보았다.

// 유효하지 않은 연산자 변수 선언
boolean operatorNo = true;

처음에는 나눗셈도 덧셈, 뺄셈, 곱셈과 동일하게 입력했다가 가이드에 0으로 나눌 수 없다는 부분을 추가해야 해서 if~else 문을 추가하게 되었다. 이름 짓는데 살짝 고민이되었던 operatorNo 가 이 때 추가되었다.

잘못된 기호0으로 나누려고 할 때마다 오류 메세지와 함께 즉시 처음으로 넘어갈 수 있도록 operatorNo = false; 사이에 넣어주었다. (처음으로 넘어가는 코드는 아래에 나옴)


3️⃣ 반복문을 사용하되, 반복의 종료를 알려주는 “exit” 문자열을 입력하기 전까지 무한으로 계산을 진행할 수 있도록 소스 코드를 수정하기

❗ 필수 기능 가이드

  • 키워드 : 무한으로 반복, 수정하기
    (처음부터 무한 반복하는 것이 아니라, 위 스텝별로 진행하며 수정)
  • 반복문을 사용합니다. (예를 들어, for, while…)

여기서 사실 시간이 조금 걸렸다. 대략 15분 정도 소모한 부분인데 다시 시작하게 하는 방법을 몰랐기 때문이다. 이전에 구구단에서도 이 부분으로 시간을 끌다가 포기한 적이 있는데 이번에는 해냈다!

해내게 된 이유는 구구단을 만들 때에는 while문의 어디에 continue; 를 주어야 반복문이 작동하는지 많이 헷갈렸다. 그래서 이 전에 한 공부의 흔적을 찾아 적용해보았다.

우선 지금까지 입력한 코드를 모두 잘라내고 while(true){} 안에 집어넣었다.

// 잘못된 입력으로 인한 루프 발생 > 시작으로 돌아감
if (!operatorNo) {
	continue;
}

switch문이 끝나는 자리에 잘못된 입력으로 인해 시작으로 돌아가는 코드를 추가했다.
if문은 사용하는데 익숙해서 쓸 때마다 괜히 뿌듯한 마음이 차오른다.
(그냥 여담인데 유일하게 자주 쓰던 문법이라 그런 것 같다)

			// 결과 값 출력
            System.out.println("결과 : " + result);

            // 종료 및 재실행 여부 확인
            System.out.println("exit를 입력하면 계산을 종료합니다. 다시 계산을 원한다면 아무거나 입력해주세요.");

            // 사용자 입력 객체 생성
            String str = sc.nextLine();

            // 종료 여부 확인
            if (str.equalsIgnoreCase("exit")) {
                System.out.println("계산 종료");
                break; // 루프 종료
            } else {
                System.out.println("계산을 다시 시작합니다.");
            }

마지막으로 결과 값을 출력하는 System.out.println("결과 : " + result);와 연결되는 부분을 입력했다. (결과 값 출력은 1번을 입력했을 때 테스트 겸 계속 함께 했던 코드임)

종료할건지 다시 실행할 건지 물어보는 메세지를 출력한 후,
그럼.. exit를 입력하게 해줘야하는데? 라는 생각에 뒤늦게 Scanner sc = new Scanner(System.in); 도 추가로 입력했다.

			// 종료 여부 확인
            if (str.equalsIgnoreCase("exit")) {
                System.out.println("계산 종료");
                break; // 루프 종료
            } else {
                System.out.println("계산을 다시 시작합니다.");
            }

종료 여부를 확인하는 절차도 if~else문을 이용했다.


🛠️ 문제 해결

작업하면서 발생한 문제와 해결방법에 대해 적어보려고 한다.

1️⃣ 기호를 잘못 입력하거나, 0으로 나누거나 exit가 아닌 다른 문자를 입력하면 오류 발생

while(true){}를 추가하기 전에 발생했던 오류다.

잘못된 입력을 하게 되면 빨간 색의 영문이 6줄 정도 주욱 길게 나온다.
하지만, 기호도 정상적으로 입력하고 0으로 나누지 않고 exit까지 잘 입력하면 아무런 문제 없이 작동했다.

이때 문득 머릿속에 ❓가 찍혔다.

exit를 안누르는 사람도 있지 않겠는가?
(= 사실 너무 당연한 말임)

그럼 이건 여러모로 수정이 필요한 일 아닌가?
(= 아주 맞는 말이다)

그래서...
기호를 잘못 입력하거나 0으로 나누려고 하면 바로 처음부터 다시 입력하게 돌리게 된 것이다.
이 과정이 쉽지는 않았다. 구글링해서 들어간 사이트만 6곳이었다. 모두 만족스럽지 못했지만 한 사이트를 보고 참고해서 시도했던 코드가 정답이 되었다!

조금 아쉬운게 있다면, 기호를 잘못 입력할 경우 두번째 피연산자를 받고나서 처음으로 돌려준다는 것인데 이 부분을 바꾸면 대공사가 될 것 같아서 이대로 마무리하게 되었다.

추후, 과제가 끝나면 다시 작업해보려고 한다 :>


작업 후기

소요시간 : 50분 (Local History 기준)
난이도 : 하 - 중

시작할 때 GitHub에 프로젝트 첫 코드 올리고 시작해봤는데 50분에 감격하고, 확인차 GitHub들어왔더니 1시간으로 바뀌어있었다!
비밀 아닌 비밀이 있다면, 만든 코드를 다시 쭉 살펴보니 50분이나 걸릴 코드가 아니었던 것 같다는 생각에 많이 슬퍼하고 울었다. 만들자마자의 감정은 감격과 기쁨이었지만, 하루가 끝날 때 쯤에는 슬픔으로 가득차있었던 것을 잊을 수가 없다. 다음에는 조금 더 시간을 효율적으로 쓸 수 있도록 머리와 손에 많이 익혀야겠다고 생각했다.


>> Java : Lv1. 클래스를 활용한 계산기 GitHub Code 바로가기
다 만들어진 코드는 위의 깃허브에 올려놓았다.

profile
전공은 컴퓨터공학, 복수전공은 해킹보안학, 직장은 방학(파워 구직중)

0개의 댓글