-
Notifications
You must be signed in to change notification settings - Fork 0
Eunsaem03 #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Eunsaem03 #2
Changes from all commits
c2f1fa8
805957d
d27ad44
fc5ba35
76182f9
be33cec
a392e55
9ead665
d1e32c3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,107 @@ | ||
| # java-calculator-precourse | ||
| # java-calculator-precourse | ||
|
|
||
| ## 과제 진행 요구 사항 | ||
| - 문자열 덧셈 계산기 저장소를 포크하고 클론 하는 것으로 시작 | ||
| - 기능을 구현하기 전 README.md에 구현할 기능 목록을 정리해 추가 | ||
| - Git의 커밋 단위는 앞 단계에서 README.md에 정리한 기능 목록 단위로 추가 | ||
|
|
||
| ## 기능 요구 사항 | ||
| > 입력한 문자열에서 숫자를 추출하여 더하는 계산기 구현 | ||
| - 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다. | ||
|
|
||
| `ex) "" => 0, "1,2" => 3, "1,2,3" => 6, "1,2:3" => 6` | ||
| - 앞의 기본 구분자(쉼표, 콜론) 외에 커스텀 구분자를 지정할 수 있다. | ||
| - 커스텀 구분자는 문자열 앞부분의 "//"와 "\n" 사이에 위치하는 문자를 커스텀 구분자로 사용한다. | ||
|
|
||
| `ex) "//;\n1;2;3"과 같이 값을 입력할 경우 커스텀 구분자는 세미콜론이며, 결과 값은 6이 반환되어야 한다.` | ||
|
|
||
| - 사용자가 잘못된 값을 입력할 경우 `IllegalArguemntException`을 발생시킨 후 애플리케이션은 종료되어야 한다. | ||
|
|
||
| ## 입출력 요구 사항 | ||
| ### 입력 | ||
| - 구분자와 양수로 구성된 문자열 | ||
| ### 출력 | ||
| - 덧셈 결과 | ||
|
|
||
| `결과 : 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()`을 활용한다. | ||
|
|
||
| ## 기능 목록 | ||
| - 사용자가 문자열을 입력한다. | ||
| - 잘못된 값인지 확인한다. | ||
| - 잘못된 값(음수, 숫자가 아닌 문자)이라면 IllegalArgumentException 발생 후 종료 | ||
| - 커스텀 구분자가 있는지 확인한다. | ||
| - 있을 경우 커스텀 구분자를 기준으로 숫자 분리 | ||
| - 없을 경우 기본 구분자로 분리 | ||
| - 분리된 문자열을 숫자로 변환한다. | ||
| - 변환된 숫자를 합한다. | ||
| - 합을 반환한다. | ||
|
|
||
| ## 베운 것 | ||
| ### regex 패키지 클래스 | ||
| - Pattern 클래스 | ||
| - 문자열을 정규표현식 패턴 객체로 변환해주는 역할 | ||
| - 문자열을 정규식 문법에 알맞게 구성해주지 않으면 예외 발생 | ||
| - 일반 클래스처럼 공개된 생성자를 제공하지 않아서 정규식 패턴 객체를 생성하려면 compile() 정적 메서드를 호출해야 함 | ||
| - Matcher 클래스 | ||
| - 대상 문자열의 패턴을 해석하고 주어진 패턴과 일치하는지 판별하고 반환된 필터링된 결과값들을 지니고 있음 | ||
| - Patter 클래스와 마찬가지로 공개된 생성자가 없으며, Pattern 객체의 matcher() 메서드를 호출해서 얻음 | ||
| ### StringTokenizer vs split | ||
| - StringTokenizer | ||
| - java.util에 포함되어 있는 클래스 | ||
| - 문자 또는 문자열로 문자열 구분 | ||
| - 빈 문자열을 토큰으로 인식하지 않음 | ||
| - 결과 값이 문자열 | ||
| - 전체 토큰을 보고싶다면 반복문으로 하나씩 뽑아야 함 | ||
| - split | ||
| - String 클래스에 속해있는 메서드 | ||
| - 정규표현식으로 구분 | ||
| - 빈 문자열을 토큰으로 인식 | ||
| - 결과값이 문자열 배열 | ||
| ### Character.isDigit() | ||
| - 주어진 문자가 숫자인지 판별 | ||
| - 문자가 숫자면 true | ||
| ### 문자열을 숫자로 변환 | ||
| - java.lang.Integer 클래스의 parseInt()와 valueOf() 메서드 사용 가능 | ||
|
|
||
| **Integer.parseInt()** | ||
| - 파라미터로 숫자로 변환할 문자열을 입력받고, 입력받은 문자열을 integer로 변환한 int 값을 리턴 | ||
| - private type인 int 리턴 | ||
|
|
||
| **integer.valueOf()** | ||
| - 문자열을 변환하여 integer Object를 리턴 | ||
|
|
||
| ### replace vs replaceAll | ||
| - replace: 단순 문자열 `replace(".", "#");` | ||
| - replaceAll: 정규식 `replaceAll("\\.", "#");` | ||
| - 정규식이어서 이스케이프를 사용하지 않으면 전체로 인식해서 모든 문자가 #으로 대체 | ||
|
|
||
| ### IllgalArgumentException | ||
| - 메서드에 인수가 잘못된 경우 발생하는 예외 | ||
| - 메서드에 전달된 인수가 예상된 형식이나 범위를 벗어나는 경우에 발생 | ||
| - 주로 메서드의 파라미터 유효성을 검사하는데 사용 | ||
|
|
||
| **발생 이유** | ||
| - 메서드에 전달된 인수의 형식이나 타입이 예상과 다를때 | ||
| - 메서드에 전달된 인수가 null이지만 null을 허용하지 않는 경우 | ||
| - 메서드에 전달된 인수가 허용되는 범위를 벗어날때 | ||
| - 기타 인수의 유효성을 검사하는 조건에 위반될 때 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package calculator; | ||
|
|
||
| import camp.nextstep.edu.missionutils.Console; | ||
|
|
||
| public class InputView { | ||
|
|
||
| public static String readInput() { | ||
| System.out.println("덧셈할 문자열을 입력해 주세요."); | ||
| String line = Console.readLine(); | ||
| return line; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package calculator; | ||
|
|
||
| public class NumberParser { | ||
| public static int[] changeNumber(String[] splitInput) { | ||
| int[] numbers = new int[splitInput.length]; | ||
| for (int i = 0; i < splitInput.length; i++) { | ||
| if (!splitInput[i].matches("\\d+")) { | ||
| throw new IllegalArgumentException("형식을 벗어남"); | ||
| } | ||
|
Comment on lines
+7
to
+9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분에서 예외 메시지를 더 구체적으로 작성하는건 어떨까요?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저도 그렇게 생각해요! 다음에는 더 세분화해서 작성해보도록 하겠습니다 |
||
| numbers[i] = Integer.valueOf(splitInput[i]); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 엄청 중요한 부분은 아닌데요, |
||
| } | ||
| return numbers; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package calculator; | ||
|
|
||
| public class OutputView { | ||
| public static void printResult(int result) { | ||
| System.out.println("결과 : " + result); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package calculator; | ||
|
|
||
| public class StringSplitter { | ||
| public static String[] splitInput(String input) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 입력값이 null이거나 빈 문자열일 경우 에러가 날 것 같아요
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 에러가 날 것 같은 부분을 더 세세하게 설정해야겠다고 생각했습니다 반영할게요! |
||
| if (!Character.isDigit(input.charAt(0))) { | ||
| String delimiter; | ||
| delimiter = String.valueOf(input.charAt(2)); | ||
| input = input.replaceAll("^.*\\\\n", ""); | ||
| String customRegex = "[" + delimiter + ",:]"; | ||
| return input.split(customRegex); | ||
| } | ||
| return input.split("[,:]"); | ||
|
Comment on lines
+5
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분에서 의도하신 게 입력값의 첫 글자가 숫자가 아닌 경우 커스텀 구분자가 존재한다고 판단하고, 그런데 이 경우 2가지 문제점이 우려되는데요 따라서 Pattern, Matcher를 사용해서
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (1) 우테코에서 제공한 테스트 케이스가 (2) 사실 구분자가 2글자 이상인 경우를 어떻게 해야 커버가 가능할까 고민했는데요 |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package calculator; | ||
|
|
||
| public class SumCalculator { | ||
| public static int sum (int[] numbers) { | ||
| int total = 0; | ||
|
|
||
| for (int number : numbers) { | ||
| total += number; | ||
| } | ||
|
|
||
| return total; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
은샘님이 해주신 제 코드 리뷰와도 관련이 있어서 살펴봤는데요,
마지막 제어 담당 클래스인
Application에서throw e로 예외를 다시 잡아서 던져주신 것 같아요.이렇게 하면 프로그램이 비정상 종료되고, 콘솔에 에러 메시지와 스택 트레이스가 두 번 출력될 가능성이 있을 것 같습니다.
따라서 제 생각에는 예외를 다시 잡아 던지는
rethrow대신return으로main()이 정상 종료 시키면 스택트레이스가 안 남아서 출력이 깔끔해질거 같아요There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아하 이해했습니다 감사합니다!