본문 바로가기
카테고리 없음

Trouble Shooting 계산기 과제

by 차리하루일기 2024. 9. 11.

계산기 만들기 요구 조건 

Lev1. 클래스 없이 기본적인 연산을 수행할 수 있는 계산기 만들기

  • 양의 정수(0 포함)를 입력받기
  • 사칙연산 기호(,,✖️,)를 입력받기
  • 위에서 입력받은 양의 정수 2개와 사칙연산 기호를 사용하여 연산을 진행한 후 결과값을 출력하기
  • 반복문을 사용하되, 반복의 종료를 알려주는 “exit” 문자열을 입력하기 전까지 무한으로 계산을 진행할 수 있도록 소스 코드를 수정하기
  • 예외 처리 : 0으로 나누기와 같은 오류를 어떻게 처리할지 결정합니다.

 

Lev2. 클래스를 적용해 기본적인 연산을 수행할 수 있는 계산기 만들기

  • 사칙연산을 수행 후, 결과값 반환 메서드 구현 & 연산 결과를 저장하는 컬렉션 타입 필드를 가진 Calculator 클래스를 생성
  • Lv 1에서 구현한 App 클래스의 main 메서드에 Calculator 클래스가 활용될 수 있도록 수정
  • App 클래스의 main 메서드에서 Calculator 클래스의 연산 결과를 저장하고 있는 컬렉션 필드에 직접 접근하지 못하도록 수정 (캡슐화)

 

[발단] 요구 조건에 따른 설계 단계에서의 문제점 발생

Lev 1. 이슈1.계산기의 기능을 가지고 있는데 양의 정수를 입력받는다는 말이 이해가 가지 않았음.계산기는 정수값 뿐만 아니라 실수 값 또한 출력 받아야 하는데 int로 굳이 접근할 필요가 있는가? 라는 근원적인 이슈였음

 

이슈2.

사칙연산 기호를 입력받기 !

입력을 받는다는 말을 이해하지 못했다. 여기서 고민을 많이 했던거 같다. calculator 라는 객체와 scanner 클래스를 어떤식으로 연계를 해야 할까? 

 

이슈3. 반복문

반복문을 while for 중에 어떤걸 써야 할 지 고민을 했으며, operator 를 어떻게 적용을 해야할 지 고민했다. 

 

이슈4.

예외처리 

if 문 안에 사칙연산 중 나누기 0은 안된다는 걸 인지하고 있었고, 어떤 방식으로 작성할 지 고민이 있었다.

 

lev2.

이슈5.

캡슐화 이슈 게터와 세터를 이해하지 못했기에 (왜 여기서 굳이? 계산기에서? 라는 의미가 더 컸음) 

 

이슈 6

클래스 분류의 문제 

 

 

[전개]  실행 

lv1. 은 클래스 없이 나의 코드들을 쭉 써보는 장이 였음. 그렇기 때문에 여러가지 코드를 작성해 보았음. 일단 Sanner가 필요해 보였다. 

Scanner sc = new Scanner;

스캐너를 생성하여 이 스캐너를 통해 계산기에 필요한 숫자 두개와 사칙연산자를 sout을 통해 입력하고자 했다.

sout (" 첫 번째 숫자를 입력 :");
int num1 = Sc.nextlnt();

sout(" 사칙연산 입력 : " );
String operator : Sc.next();

그 다음 생각 난 것이 while문을 통해 반복문을 작성해 보자였다. 

for문 vs while문 
while문을 선택한 이유  : 계산기는 반복 횟수가 정해져 있지 않고, 특정 조건이 만족될 때까지 반복해야 하는 경우에 적합했기 때문이다. while(조건){ 

// 반복할 코드}

while (true) {
.... //각종 연산자 
System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)");
            sc.nextLine();
            String input = sc.nextLine();
            if (input("exit")) {
                System.out.println("프로그램을 종료합니다.");
                break;

 

[위기] 문제의 인식

operator를  String으로 접근할 생각을 하지못해 구글링을 통해 많이 찾아보았다. 

 

다음은 사칙연산 처리를 할 차례라고 생각했다. 

switch (operator) {
                case "+":
                    result = num1 + num2;
                    break;
                    ....
    			case "/":
                    if (num2 != 0) {
                        result = (double)num1 / num2;
                    } else {
                        System.out.println("오류: 0으로 나눌 수 없습니다.");
                    }
                    break;

문제가 발생했다

값이 나오지 않았다. 

 

반복문에 문제가 있는건지 프로그램이 종료가 되지 않았다.

 

[절정] 문제의 해결 

결과값에 관한 선언이 필요하다고 했다. 

조원분들에게 물어보았다. 

int 타입의 정수형 선언한 것을 결과값에 double 타입으로 형변환 선언을 하고 

논리형 변수인 boolean을 선언해서 잘못된 결과값을 출력 방지하고자 작성하였다. 

double result = 0;
boolean isValid = true;
case "/":
        if (num2 != 0) {
            result = (double)num1 / num2;
        } else {
            System.out.println("오류: 0으로 나눌 수 없습니다.");
            isValid = false;
        } 
        break;
	default:
        System.out.println("오류: 잘못된 연산자입니다.");
        isValid = false; // 유효하지 않은 연산자일 경우
}
// 연산이 유효한 경우에만 결과 출력
if (isValid) {
    System.out.println("결과: " + result);
}

 

반복문에서의 문제 해결 : equals가 빠져있었다. 
왜 == 기호를 쓰지 않고 equals를 쓸까 하고 찾아봤다. 

 

  • == 연산자: 두 객체가 같은 메모리 위치를 가리키는지(같은 객체인지) 비교합니다.
  • equals() 메서드: 두 문자열의 내용이 같은지를 비교합니다.

 

if (input.equals("exit")) {
                System.out.println("프로그램을 종료합니다.");
                break;

 

[결말] 

어째어째 lev1에 관한 문제를 해결했고 출력결과 문제는 없이 잘 돌아가는것 같기도 하다. 

 

lev2가 문제였다. 

lev2에서의 캡슐화 문제는 바로 전 til에 관련해서 공부한 자료가 있다. 
클래스에 관한 이슈는 기본기가 부족했던거 같다. 강의를 마져 듣고 복습할 필요가 있다.