From 5a36a23664fbd7f90b5c19c7a1fcc9e12040a43a Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 01:27:51 +0900 Subject: [PATCH 01/19] update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 13420b29..eab86b19 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# javascript-calculator-precourse \ No newline at end of file +# javascript-calculator-precourse From 742e3c69b355996761551faf9a6a858f4e9a669c Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 01:33:01 +0900 Subject: [PATCH 02/19] docs: update README.md --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index eab86b19..c50eb9b9 100644 --- a/README.md +++ b/README.md @@ -1 +1,12 @@ # javascript-calculator-precourse + +## 기능 구현 목록 + +- [ ] 문자열 입력 받기 +- [ ] 구분자를 기준으로 구분하기 + - [ ] ,, : 기준으로 구분하기 + - [ ] 커스텀 구분자 기준으로 구분하기 +- [ ] 구분한 숫자가 양수인지 확인 + - [ ] 잘못된 값일 시 에러 처리 후 종료 +- [ ] 구분한 숫자 더하기 +- [ ] 결과 출력하기 From ef9af01185e50851fff4f06f06d2f0ac7274485f Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 02:32:31 +0900 Subject: [PATCH 03/19] =?UTF-8?q?feat(ConsoleView):=20=EB=AC=B8=EC=9E=90?= =?UTF-8?q?=EC=97=B4=EC=9D=84=20=EC=9E=85=EB=A0=A5=EB=B0=9B=EB=8A=94=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/ConsoleView.js | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/view/ConsoleView.js diff --git a/src/view/ConsoleView.js b/src/view/ConsoleView.js new file mode 100644 index 00000000..d0aec291 --- /dev/null +++ b/src/view/ConsoleView.js @@ -0,0 +1,10 @@ +import { Console } from "@woowacourse/mission-utils"; + +class ConsoleView { + async getInput() { + const input = await Console.readLineAsync("덧셈할 문자열을 입력해 주세요\n"); + return input; + } +} + +export default ConsoleView; \ No newline at end of file From 751c88e518688254b14cf20b4c4eb1626c3a324d Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 02:45:48 +0900 Subject: [PATCH 04/19] =?UTF-8?q?feat(CalculatorController):=20CalculatorC?= =?UTF-8?q?ontroller=20=EA=B8=B0=EB=B3=B8=20=EA=B5=AC=EC=A1=B0=20=EB=B0=8F?= =?UTF-8?q?=20ConsoleView=20=EC=97=B0=EA=B2=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ConsoleView 인스턴스 생성 및 run 메서드 추가 - 사용자 입력을 비동기적으로 처리하는 구조 설정 --- src/controller/CalculatorController.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/controller/CalculatorController.js diff --git a/src/controller/CalculatorController.js b/src/controller/CalculatorController.js new file mode 100644 index 00000000..50fd621c --- /dev/null +++ b/src/controller/CalculatorController.js @@ -0,0 +1,13 @@ +import ConsoleView from "../view/ConsoleView.js"; + +class CalculatorController { + constructor() { + this.view = new ConsoleView(); + } + + async run() { + const input = await this.view.getInput(); + } +} + +export default CalculatorController; \ No newline at end of file From f1ac463625c6a383eb5adcc0c535a5503b941743 Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 02:48:46 +0900 Subject: [PATCH 05/19] =?UTF-8?q?feat(App):=20CalculatorController=20?= =?UTF-8?q?=EC=8B=A4=ED=96=89=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index 091aa0a5..204c73a1 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,10 @@ +import CalculatorController from "./controller/CalculatorController.js"; + class App { - async run() {} + async run() { + const controller = new CalculatorController(); + await controller.run(); + } } export default App; From e14b6b6fd54e095e825daac5adf59b92c56e02d2 Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 03:31:16 +0900 Subject: [PATCH 06/19] =?UTF-8?q?feat(Calculator):=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EA=B0=92=EC=9D=84=20=EA=B3=84=EC=82=B0=ED=95=98=EB=8A=94=20Cal?= =?UTF-8?q?culator.js=20=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ,과 :를 구분자로 사용해 문자열을 구분해 배열로 저장 --- src/model/Calculator.js | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/model/Calculator.js diff --git a/src/model/Calculator.js b/src/model/Calculator.js new file mode 100644 index 00000000..dd6b94de --- /dev/null +++ b/src/model/Calculator.js @@ -0,0 +1,7 @@ +class Calculator { + splitByDefaultSeperator(input) { + return input.split(/[,:]/); + } +} + +export default Calculator; \ No newline at end of file From d6d1b079540e031ebad0b91f14ad31c1663a4d1d Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 04:10:55 +0900 Subject: [PATCH 07/19] =?UTF-8?q?refactor(Calculator):=20parseInt=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=ED=86=B5=ED=95=A9=ED=95=B4=20=EC=BB=A4=EC=8A=A4?= =?UTF-8?q?=ED=85=80=20=EA=B5=AC=EB=B6=84=EC=9E=90=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EB=B0=8F=20splitNumbers=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존 splitByDefaultSeperator를 parseInt으로 통합 - getCustomSeperator 메서드에서 커스텀 구분자를 추출 - 기본 구분자(, :)와 커스텀 구분자를 모두 처리하도록 splitNumbers 메서드 구현 --- src/model/Calculator.js | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/model/Calculator.js b/src/model/Calculator.js index dd6b94de..c1685f8d 100644 --- a/src/model/Calculator.js +++ b/src/model/Calculator.js @@ -1,7 +1,31 @@ class Calculator { - splitByDefaultSeperator(input) { - return input.split(/[,:]/); + parseInput(input){ + let numbersPart = input; + const customSeperator = this.getCustomSeperator(input); + + if(customSeperator) { + numbersPart = input.split(`\\n`)[1]; + } + + return this.splitNumbers(numbersPart, customSeperator); + } + getCustomSeperator(input){ + if(!input.startsWith("//")) return null; + const match = input.match(/^\/\/(.*?)\\n/); + return match ? match[1] : null; + } + + splitNumbers(numbersPart, customSeperator = null) { + let delimiters = ",:"; + + if(customSeperator) { + delimiters += customSeperator; + } + + const regex = new RegExp(`[${delimiters}]`); + return numbersPart.split(regex); } + } export default Calculator; \ No newline at end of file From aba99e919239cec42f05e3cea4c56180546e748b Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 18:24:30 +0900 Subject: [PATCH 08/19] =?UTF-8?q?feat(CalculatorController):=20Calculator?= =?UTF-8?q?=20=EB=AA=A8=EB=8D=B8=EC=97=90=20=EC=9E=85=EB=A0=A5=EA=B0=92?= =?UTF-8?q?=EC=9D=84=20=EC=A0=84=EB=8B=AC=ED=95=98=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 입력받은 문자열을 parseInt 메서드로 전달해 구분자를 기준으로 문자를 구분 --- src/controller/CalculatorController.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/controller/CalculatorController.js b/src/controller/CalculatorController.js index 50fd621c..e2634e7b 100644 --- a/src/controller/CalculatorController.js +++ b/src/controller/CalculatorController.js @@ -1,12 +1,15 @@ import ConsoleView from "../view/ConsoleView.js"; +import Calculator from "../model/Calculator.js"; class CalculatorController { constructor() { this.view = new ConsoleView(); + this.calculator = new Calculator(); } async run() { const input = await this.view.getInput(); + const numbers = this.calculator.parseInput(input); } } From 5dc4ce5bc20fbc90121988e311c3534ec130ef3d Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 19:27:54 +0900 Subject: [PATCH 09/19] =?UTF-8?q?feat(Calculator):=20=EA=B5=AC=EB=B6=84?= =?UTF-8?q?=ED=95=9C=20=EA=B0=92=EC=9D=B4=20=EC=96=91=EC=88=98=EC=9D=B8?= =?UTF-8?q?=EC=A7=80=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20validateNumb?= =?UTF-8?q?ers=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 구분한 값이 숫자가 아니거나 0 이하인 경우 에러 발생 후 애플리케이션 종료 --- src/model/Calculator.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/model/Calculator.js b/src/model/Calculator.js index c1685f8d..97f0f5af 100644 --- a/src/model/Calculator.js +++ b/src/model/Calculator.js @@ -9,6 +9,7 @@ class Calculator { return this.splitNumbers(numbersPart, customSeperator); } + getCustomSeperator(input){ if(!input.startsWith("//")) return null; const match = input.match(/^\/\/(.*?)\\n/); @@ -26,6 +27,15 @@ class Calculator { return numbersPart.split(regex); } + validateNumbers(numbers) { + numbers.forEach((value) => { + const num = Number(value); + if(isNaN(num) || num < 0) { + throw new Error("[Error]"); + } + }); + } + } export default Calculator; \ No newline at end of file From bebbd222076581c7752c0611ccb15b7a0993a8fb Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 20:43:39 +0900 Subject: [PATCH 10/19] =?UTF-8?q?feat(Calculator):=20=EA=B5=AC=EB=B6=84?= =?UTF-8?q?=ED=95=9C=20=EC=88=AB=EC=9E=90=EB=A5=BC=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=ED=95=9C=20=EB=B0=B0=EC=97=B4=EC=97=90=20=EC=9E=88=EB=8A=94=20?= =?UTF-8?q?=EA=B0=92=EB=93=A4=EC=9D=84=20=EB=8D=94=ED=95=98=EB=8A=94=20sum?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/Calculator.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/model/Calculator.js b/src/model/Calculator.js index 97f0f5af..7a53fc9d 100644 --- a/src/model/Calculator.js +++ b/src/model/Calculator.js @@ -36,6 +36,9 @@ class Calculator { }); } + sum(numbers) { + return numbers.reduce((acc, cur) => acc + Number(cur), 0); + } } export default Calculator; \ No newline at end of file From d4e605e7a0e01afbf2c769b3d16d360905758f3f Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 20:46:09 +0900 Subject: [PATCH 11/19] =?UTF-8?q?refector(Calculator):=20sum=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=EC=9D=98=20reduce=20=EB=82=B4=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=EB=AA=85=EC=9D=84=20sum=EA=B3=BC=20value=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/Calculator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model/Calculator.js b/src/model/Calculator.js index 7a53fc9d..e2248944 100644 --- a/src/model/Calculator.js +++ b/src/model/Calculator.js @@ -37,7 +37,7 @@ class Calculator { } sum(numbers) { - return numbers.reduce((acc, cur) => acc + Number(cur), 0); + return numbers.reduce((sum, value) => sum + Number(value), 0); } } From 0ccf51a79ae6e350a76f0cd59cf3d5c554df0a94 Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 20:53:15 +0900 Subject: [PATCH 12/19] =?UTF-8?q?feat(ConsoleView):=20=EA=B2=B0=EA=B3=BC?= =?UTF-8?q?=EC=99=80=20=EC=97=90=EB=9F=AC=20=EB=A9=94=EC=8B=9C=EC=A7=80?= =?UTF-8?q?=EB=A5=BC=20=EC=B6=9C=EB=A0=A5=ED=95=98=EB=8A=94=20printResult,?= =?UTF-8?q?=20printError=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/ConsoleView.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/view/ConsoleView.js b/src/view/ConsoleView.js index d0aec291..3b6fb094 100644 --- a/src/view/ConsoleView.js +++ b/src/view/ConsoleView.js @@ -5,6 +5,14 @@ class ConsoleView { const input = await Console.readLineAsync("덧셈할 문자열을 입력해 주세요\n"); return input; } + + printResult(result) { + Console.print(`결과 : ${result}`); + } + + printError(error){ + Console.print(error.message); + } } export default ConsoleView; \ No newline at end of file From a3da97a5c8b0305dd2d86c09a3cc5161d19764f5 Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 21:25:18 +0900 Subject: [PATCH 13/19] =?UTF-8?q?refactor(ConsoleView):=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=EB=B0=8F?= =?UTF-8?q?=20=EC=97=90=EB=9F=AC=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=ED=98=95?= =?UTF-8?q?=EC=8B=9D=20=EC=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - readLineAsync 호출 시 try-catch로 에러 처리 추가 --- src/view/ConsoleView.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/view/ConsoleView.js b/src/view/ConsoleView.js index 3b6fb094..4df7f9e9 100644 --- a/src/view/ConsoleView.js +++ b/src/view/ConsoleView.js @@ -2,8 +2,13 @@ import { Console } from "@woowacourse/mission-utils"; class ConsoleView { async getInput() { - const input = await Console.readLineAsync("덧셈할 문자열을 입력해 주세요\n"); - return input; + try { + const input = await Console.readLineAsync("덧셈할 문자열을 입력해 주세요\n"); + return input; + } catch { + throw new Error("[Error]"); + } + } printResult(result) { @@ -11,7 +16,7 @@ class ConsoleView { } printError(error){ - Console.print(error.message); + Console.print("[Error]" + error.message); } } From d5e7fd0638bf6c8383a1b1a02e89b21251156516 Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 21:29:26 +0900 Subject: [PATCH 14/19] =?UTF-8?q?feat(CalculatorController):=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=20=ED=9D=90=EB=A6=84=20=EA=B4=80=EB=A6=AC=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 입력 문자열 파싱 후 숫자 배열 생성 - 숫자 유효성 검사 기능 추가 - 숫자 합산 후 결과 출력 - try-catch로 예외 처리하여 오류 발생 시 에러 메시지 출력 --- src/controller/CalculatorController.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/controller/CalculatorController.js b/src/controller/CalculatorController.js index e2634e7b..564950ce 100644 --- a/src/controller/CalculatorController.js +++ b/src/controller/CalculatorController.js @@ -1,5 +1,6 @@ import ConsoleView from "../view/ConsoleView.js"; import Calculator from "../model/Calculator.js"; +import { Console } from "@woowacourse/mission-utils"; class CalculatorController { constructor() { @@ -8,8 +9,15 @@ class CalculatorController { } async run() { - const input = await this.view.getInput(); - const numbers = this.calculator.parseInput(input); + try{ + const input = await this.view.getInput(); + const numbers = this.calculator.parseInput(input); + this.calculator.validateNumbers(numbers); + const result = this.calculator.sum(numbers); + this.view.printResult(result); + } catch(error) { + this.view.printError(error); + } } } From efb11affc10fe835edc1cf3cb55a5d4970586896 Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 21:55:22 +0900 Subject: [PATCH 15/19] =?UTF-8?q?refator:=20=EC=97=90=EB=9F=AC=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/CalculatorController.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/controller/CalculatorController.js b/src/controller/CalculatorController.js index 564950ce..d985ad67 100644 --- a/src/controller/CalculatorController.js +++ b/src/controller/CalculatorController.js @@ -17,6 +17,7 @@ class CalculatorController { this.view.printResult(result); } catch(error) { this.view.printError(error); + throw error; } } } From 99a2cb59e43ae6c4ea7da8855cb61277d3ad2a9d Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 21:55:52 +0900 Subject: [PATCH 16/19] =?UTF-8?q?refactor:=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/Calculator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model/Calculator.js b/src/model/Calculator.js index e2248944..c9d2060f 100644 --- a/src/model/Calculator.js +++ b/src/model/Calculator.js @@ -31,7 +31,7 @@ class Calculator { numbers.forEach((value) => { const num = Number(value); if(isNaN(num) || num < 0) { - throw new Error("[Error]"); + throw new Error("[ERROR]"); } }); } From 39ea419bc3e129753d5abbc8580c6e76d2282aea Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 21:56:23 +0900 Subject: [PATCH 17/19] =?UTF-8?q?refactor:=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/ConsoleView.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/view/ConsoleView.js b/src/view/ConsoleView.js index 4df7f9e9..f88028c7 100644 --- a/src/view/ConsoleView.js +++ b/src/view/ConsoleView.js @@ -6,7 +6,7 @@ class ConsoleView { const input = await Console.readLineAsync("덧셈할 문자열을 입력해 주세요\n"); return input; } catch { - throw new Error("[Error]"); + throw new Error("[ERROR]"); } } @@ -16,7 +16,7 @@ class ConsoleView { } printError(error){ - Console.print("[Error]" + error.message); + Console.print("[ERROR]" + error.message); } } From fb4791d1444ba223f1a54a9418e52f249d54b57a Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 22:09:06 +0900 Subject: [PATCH 18/19] =?UTF-8?q?refactor:=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EB=AA=A8=EB=93=88=20import=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/CalculatorController.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/controller/CalculatorController.js b/src/controller/CalculatorController.js index d985ad67..096738c2 100644 --- a/src/controller/CalculatorController.js +++ b/src/controller/CalculatorController.js @@ -1,6 +1,5 @@ import ConsoleView from "../view/ConsoleView.js"; import Calculator from "../model/Calculator.js"; -import { Console } from "@woowacourse/mission-utils"; class CalculatorController { constructor() { From e29ec19d55e3e6c77b279412fe9660cea3f081bb Mon Sep 17 00:00:00 2001 From: Kimyerim Date: Mon, 20 Oct 2025 22:43:07 +0900 Subject: [PATCH 19/19] docs: update README.md --- README.md | 111 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 101 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c50eb9b9..8fbb9e01 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,103 @@ # javascript-calculator-precourse -## 기능 구현 목록 - -- [ ] 문자열 입력 받기 -- [ ] 구분자를 기준으로 구분하기 - - [ ] ,, : 기준으로 구분하기 - - [ ] 커스텀 구분자 기준으로 구분하기 -- [ ] 구분한 숫자가 양수인지 확인 - - [ ] 잘못된 값일 시 에러 처리 후 종료 -- [ ] 구분한 숫자 더하기 -- [ ] 결과 출력하기 +## ✅ 기능 구현 목록 + +- [x] 문자열 입력 받기 +- [x] 구분자를 기준으로 구분하기 + - [x] `,`, `:` 기준으로 구분하기 + - [x] 커스텀 구분자 기준으로 구분하기 +- [x] 구분한 숫자가 양수인지 확인 + - [x] 잘못된 값일 시 에러 처리 후 종료 +- [x] 구분한 숫자 더하기 +- [x] 결과 출력하기 + +## 💻 구현 내용 + +### 커스텀 구분자 처리 + +``` +getCustomSeperator(input){ + if(!input.startsWith("//")) return null; + const match = input.match(/^\/\/(.*?)\\n/); + return match ? match[1] : null; +} +``` + +- 정규표현식을 사용해 `//`와 `\n` 사이에 있는 문자를 추출. +- match 메서드로 추출한 값이 있는 경우, 두 번째 값이 커스텀 구분자이므로 index 1번 값을 반환. +- match 메서드에 매치되는 결과가 없는 경우에는 null 반환. +- `\n`이 줄바꿈을 의미하는 이스케이프 문자로 인식되어 제대로 인식되지 않는 문제가 있었는데 앞에 `\`을 붙여 `\\n`으로 사용하니 `\n`을 그냥 문자로 사용할 수 있었음. +- `/`도 마찬가지로 인식되지 않는 문제가 있었는데 앞에 `\`을 붙여 사용하니 인식됨. + +### 문자열 구분자로 구분 + +``` +splitNumbers(numbersPart, customSeperator = null) { + let delimiters = ",:"; + + if(customSeperator) { + delimiters += customSeperator; + } + + const regex = new RegExp(`[${delimiters}]`); + return numbersPart.split(regex); +} +``` + +- `,`,`:`, 커스텀 구분자를 사용해 문자열을 분리. +- 배열로 저장된 분리한 문자열을 반환. + +### 입력값 잘못된 경우 에러 처리 후 종료 + +``` +validateNumbers(numbers) { + numbers.forEach((value) => { + const num = Number(value); + if(isNaN(num) || num < 0) { + throw new Error("[ERROR]"); + } + }); +} +``` + +- 입력값이 구분자와 양수 외에 다른 문자로 이루어져 있는지 확인하는 메서드. +- 구분자로 구분한 값이 저장되어 있는 배열 numbers를 forEach로 순환하면서 확인. +- Number 메서드를 사용했을 때 숫자로 변경되지 않는 문자면 NaN이 저장되므로 isNaN 메서드를 사용해서 숫자인지 아닌지 확인. +- 변경된 숫자는 음수인지 아닌지 확인 +- 두 조건 중 하나라도 만족하지 않으면 `throw new Error()`를 사용해 메시지와 함께 에러를 발생시킨 후 애플리케이션을 종료. + +### 추출한 숫자 더하기 + +``` +sum(numbers) { + return numbers.reduce((sum, value) => sum + Number(value), 0); +} +``` + +- reduce 메서드를 사용해 배열을 돌면서 배열의 값들을 모두 더해 반환. +- 배열에 있는 값들이 문자열이기 때문에 Number를 사용해 숫자로 변환. + +## ⭐️ 실행 결과 + +### 옳은 입력 + +- `,`를 구분자로 사용한 경우 + Image + +- `:`를 구분자로 사용한 경우 + Image + +- 커스텀 구분자를 입력한 경우 + Image + +### 잘못된 입력 시 + +- 양수가 아닌 문자를 입력한 경우 + Image + +- 양수가 아닌 음수를 입력한 경우 + Image + +### 테스트 결과 + +Image