룰루코딩

우테코 프리코스 1주차 회고록 본문

우테코

우테코 프리코스 1주차 회고록

rulru01 2024. 10. 22. 00:34

문자열 덧셈 계산기

기능 요구 사항

입력한 문자열에서 숫자를 추출하여 더하는 계산기를 구현한다.

  • 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다.
    • 예: "" => 0, "1,2" => 3, "1,2,3" => 6, "1,2:3" => 6
  • 앞의 기본 구분자(쉼표, 콜론) 외에 커스텀 구분자를 지정할 수 있다. 커스텀 구분자는 문자열 앞부분의 "//"와 "\n" 사이에 위치하는 문자를 커스텀 구분자로 사용한다.
    • 예를 들어 "//;\n1;2;3"과 같이 값을 입력할 경우 커스텀 구분자는 세미콜론(;)이며, 결과 값은 6이 반환되어야 한다.
  • 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시킨 후 애플리케이션은 종료되어야 한다.

입출력 요구 사항

입력

  • 구분자와 양수로 구성된 문자열

출력

  • 덧셈 결과
    결과 : 6

실행 결과 예시

덧셈할 문자열을 입력해 주세요.
1,2:3
결과 : 6

프로그래밍 요구 사항

  • JDK 21 버전에서 실행 가능해야 한다.
  • 프로그램 실행의 시작점은 Application의 main()이다.
  • build.gradle 파일은 변경할 수 없으며, 제공된 라이브러리 이외의 외부 라이브러리는 사용하지 않는다.
  • 프로그램 종료 시 System.exit()를 호출하지 않는다.
  • 프로그래밍 요구 사항에서 달리 명시하지 않는 한 파일, 패키지 등의 이름을 바꾸거나 이동하지 않는다.
  • 자바 코드 컨벤션을 지키면서 프로그래밍한다.

라이브러리

  • camp.nextstep.edu.missionutils에서 제공하는 Console API를 사용하여 구현해야 한다.
    • 사용자가 입력하는 값은 camp.nextstep.edu.missionutils.Console의 readLine()을 활용한다.

💡 구현할 기능 목록 💡

  • 문자열 입력받기
  • "//"와 "\n" 사이에 위치하는 문자를 커스텀 구분자로 사용하는 경우, 커스텀 구분자를 기준으로 분리
  • 쉼표(,)나 콜론(:)을 구분자로 가지는 문자열의 경우, 해당 구분자를 기준으로 분리
  • 입력받은 숫자의 합 출력
  • 문자열 입력 없을 시 0 반환
  • 잘못된 값 입력 시 오류 예외 처리

⚠️ 예외처리 목록 ⚠️

  • 입력된 문자열에 숫자가 아닌 문자가 포함된 경우
  • 입력받은 수가 양수가 아닐 경우
  • 커스텀 구분자의 형식이 잘못된 경우
  • 연속된 구분자가 입력된 경우

➕ 추가해야 할 기능 목록 ➕

  • 커스텀 구분자가 한문자가 아닐경우
  • 클래스로 분리
  • 테스트케이스 추가

내코드

class App {
  async run() {
    const input = await new Input().getInput();

    if (!input) return Console.print("결과 : 0");

    let numbers = new Separator().process(input);

    new Validator().validate(numbers);

    const sum = new Calculator().sum(numbers);

    Console.print(`결과 : ${sum}`);
  }
}

 

run() 메서드: 애플리케이션의 주요 로직을 실행

  • 사용자로부터 문자열 입력 받음.
  • 입력이 비어 있으면 0을 출력
  • 입력된 문자열을 구분하여 숫자 배열로 변환
  • 숫자 배열에 대한 유효성을 검사
  • 합계를 계산하고 결과를 출력
class Input {
  async getInput() {
    return await Console.readLineAsync("덧셈할 문자열을 입력해 주세요.\n");
  }
}

getInput() 메서드: 사용자에게 덧셈할 문자열을 입력받음

class Separator {
  process(input) {
    const PATTERN = /^\/\/(.*)\\n(.*)$/;
    const MATCH = input.match(PATTERN);

    if (MATCH) {
      const CUSTOM = MATCH[1];
      const NUMS = MATCH[2];

      return NUMS.split(CUSTOM);
    }
    return input.split(/,|:/);
  }
}

Separator 클래스 - 입력 문자열을 지정된 구분자에 따라 분리하는 역할

process(input) 메서드:

  • 입력 문자열이 커스텀 구분자를 사용하는 경우 처리
  • 기본 구분자(쉼표 ,와 콜론 :)로도 분리
class Validator {
  validate(numbers) {
    if (numbers.some((num) => num === "")) {
      throw new Error("[ERROR] 연속된 구분자는 사용할 수 없습니다.");
    }

    numbers.forEach((num) => {
      if (isNaN(Number(num))) {
        throw new Error("[ERROR] 문자는 입력할 수 없습니다.");
      }
    });

    if (numbers.some((num) => Number(num) <= 0)) {
      throw new Error("[ERROR] 양수만 입력할 수 있습니다.");
    }
  }
}

validate(numbers) 메서드:

  • 연속된 구분자를 사용할 수 없음을 검사
  • 입력된 값이 숫자인지 확인
  • 음수를 입력할 수 없음을 검사
class Calculator {
  sum(numbers) {
    let sum = 0;
    for (const num of numbers) {
      sum += Number(num);
    }
    return sum;
  }
}

Calculator 클래스 - 숫자 배열의 합을 계산하는 기능

sum(numbers) 메서드: 입력된 숫자 배열의 합을 계산하여 반환


📝 1주차 회고

이번 미션은 첫 주차라 크게 어려움은 없었지만, 문제를 깊이 파고들수록 계속 새로운 아이디어가 떠올랐다. 처음에는 단순한 문자열 덧셈이라고 생각했지만, 점점 더 많은 예외 상황을 처리해야 한다는 것을 알게 되었고, 그 과정에서 흥미와 보람을 느꼈다. 이번 과제를 통해 배운 것과 느낀 점을 주제별로 나눠서 정리해 보았다.

📜 과정

처음 문제를 접했을 때는 기본 문자열 덧셈을 간단하게 처리하는 것으로 생각했다. 그래서 먼저 우아한테크코스의 라이브러리를 설치하고, 문자를 입력받은 후 커스텀 구분자와 일반 구분자를 if-else 문으로 나누어 처리하는 방식으로 코드를 작성했다.

일반 구분자의 경우 , 또는 ;로 split하여 숫자를 배열에 넣고, 커스텀 구분자는 패턴을 처리하기 위해 정규 표현식을 사용했다. 커스텀 구분자의 모양은 //(구분자)\n 형식이어야 했기 때문에, 이를 상수로 정의한 후 match() 함수를 이용해 정확하게 구분자를 처리했다.

특히, 구분자의 길이에 제한이 없다는 점을 고려하여 한 글자 이상인 경우도 처리할 수 있도록 코드를 확장했다. 예를 들어 //abc\n3abc5abc9처럼 여러 글자로 이루어진 커스텀 구분자를 지원하는 방식으로 코드를 수정했다. 그리고 이 배열을 순회하면서 숫자의 합계를 계산하는 로직을 추가했다.

또한, 문제 예시에서 빈 문자열이 입력되면 0을 반환해야 한다는 부분을 발견하고, 빈 문자열 처리도 추가했다. 이를 통해 입력이 없을 경우에도 프로그램이 안정적으로 동작하도록 구현했다.

처음에는 모든 기능을 하나의 함수에 몰아넣으려 했지만, 객체지향적 코드 설계의 필요성을 느끼고 클래스로 기능을 분리했다. 이렇게 코드를 구조화하니 가독성과 유지보수성이 크게 향상되었고, 앞으로도 이런 객체지향적 접근을 더 자주 활용할 예정이다.

⚡ 예외 처리 과정

코드를 작성하면서 예외 상황들이 계속해서 떠올랐다. 기본적으로 숫자가 아닌 문자가 입력될 경우, 음수가 입력될 경우를 쉽게 예외 처리할 수 있었다. 음수 처리의 경우에도 에러 메시지를 출력해 직관적인 피드백을 제공했다.

추가로 구분자가 연속으로 등장하는 경우도 처리했다. 예를 들어 2,,4;5와 같이 구분자가 반복되는 상황에서는 예외 처리를 통해 이 부분을 안정적으로 해결했다. 그리고 빈 문자열 처리는 0을 반환하도록 설정해 문제의 요구사항을 충족했다.

커스텀 구분자의 형식이 맞지 않는 경우도 자연스럽게 처리되도록 코드를 수정했다. 구분자가 규칙에 맞지 않으면 에러가 발생하도록 설계했으며, 이를 통해 정규 표현식의 활용성을 다시금 깨달았다. 정규 표현식을 사용하여 커스텀 구분자와 숫자 문자열을 분리하는 방식이 매우 인상적이었고, 이를 통해 커스텀 구분자의 유연한 처리 방식을 구현할 수 있었다.

또한, 음수가 입력되었을 때에는 [ERROR] 메시지를 출력하여 프로그램의 신뢰성을 높였다. 이를 통해 잘못된 입력에 대해 사용자가 명확하게 이해할 수 있도록 오류 메시지를 제공했다.

💡 배운 점과 느낀 점

이번 미션을 통해 다양한 것들을 배울 수 있었다. 처음에는 간단하게 문자열 덧셈을 처리할 수 있다고 생각했지만, 문제를 깊이 파고들면서 다양한 예외 상황과 구현 방법을 고민하게 되었다. 그 과정에서 공부가 되었고, 더 나은 해결책을 찾는 즐거움을 느낄 수 있었다.

특히 정규 표현식을 활용하여 커스텀 구분자와 숫자를 유연하게 처리하는 방법을 배우면서 정규 표현식의 강력함을 실감했다. 단순히 고정된 구분자만 처리하던 기존 방식에서 벗어나, 확장된 기능을 구현하는 데 큰 도움이 되었다.

또한, 입력값 검증과 예외 처리의 중요성도 깨달았다. 빈 문자열, 연속된 구분자, 음수, 그리고 숫자가 아닌 문자가 입력될 경우 등 다양한 예외 상황을 고려해야 했다. 이러한 예외 처리를 통해 프로그램이 보다 안전하고, 사용자 경험이 향상된다는 점을 알게 되었다.

마지막으로 객체지향적으로 코드를 구조화하면서 코드의 가독성과 유지보수성이 크게 향상되었음을 느꼈다. 모든 기능을 하나의 함수에 몰아넣기보다는, 클래스를 사용해 각 기능을 분리함으로써 코드가 한층 더 깔끔해졌다. 유지보수와 확장성 측면에서도 객체지향적 접근이 얼마나 유용한지 깨달았으며, 앞으로도 이런 방식을 더 자주 활용할 계획이다.

➡️ 다음 주차에서

이번 주차에서는 비교적 간단한 문제를 해결했지만, 다음 주차에는 더 계획적으로 문제에 접근하고자 한다. 문제를 처음 읽고 나서 전체적인 구조를 먼저 설계하고, 그다음 세부 사항을 차근차근 해결해 나가는 방식으로 접근할 것이다. 이렇게 미리 발생할 수 있는 다양한 상황을 고려해 문제를 해결하는 데 있어 더 효율적으로 접근하고자 한다. 또한, 이번 미션에서는 코드를 작성하면서 예상치 못한 부분에서 배울 수 있었는데, 앞으로의 미션에서도 리뷰를 통해 제가 미처 생각하지 못했던 부분에 대해 새로운 배움을 얻을 수 있을 것이라 기대하고 있다. 계속해서 새로운 문제를 접하고, 그 과정에서 더 많은 것을 배우며 성장할 수 있을 것이라고 생각한다.

'우테코' 카테고리의 다른 글

우테코 프리코스 4주차 회고록  (7) 2024.11.12
우테코 프리코스 3주차 회고록  (0) 2024.11.04
우테코 프리코스 2주차 회고록  (3) 2024.10.28