From 842e917ccab428575e234b5e3957b49ed8ba4fe5 Mon Sep 17 00:00:00 2001 From: sungeunp Date: Mon, 20 Oct 2025 22:54:49 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat(input/output):=20=EC=B4=88=EA=B8=B0=20?= =?UTF-8?q?=EC=9E=85=EC=B6=9C=EB=A0=A5=20=EC=8A=A4=EC=BC=88=EB=A0=88?= =?UTF-8?q?=ED=86=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `@woowacourse/mission-utils` 패키지의 `Console` 객체를 사용하여 `초기 질문 출력`, `문자열 입력` 기능을 수행하도록 한다. - 마찬가지로 예시 결과 출력도 `Console` 객체를 사용하여 요구사항대로 구현하고자 한다. - 예시 결과까지 출력하는 이유는 프로그램의 전체적인 뼈대를 잡고, 핵심 기능에 집중하기 위함이다. --- README.md | 25 ++++++++++++++++++++++++- src/App.js | 15 ++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) mode change 100644 => 100755 src/App.js diff --git a/README.md b/README.md index 13420b29..e3e64972 100644 --- a/README.md +++ b/README.md @@ -1 +1,24 @@ -# javascript-calculator-precourse \ No newline at end of file +# javascript-calculator-precourse + +## 구현할 기능 목록 + +### > 초기 질문 출력 및 문자열 입력 받은 후, 예시 결과 출력 + +- `@woowacourse/mission-utils` 패키지의 `Console` 객체를 사용하여 `초기 질문 출력`, `문자열 입력` 기능을 수행하도록 한다. +- 마찬가지로 예시 결과 출력도 `Console` 객체를 사용하여 요구사항대로 구현하고자 한다. +- 예시 결과까지 출력하는 이유는 프로그램의 전체적인 뼈대를 잡고, 핵심 기능에 집중하기 위함이다. + +### > 핵심 기능 구현 - divider를 기준으로 값 계산 및 예시 결과를 실제 결과로 바꿈 + +- 프로그램의 전체적인 flow는 잡았으니, 핵심 기능(계산)에 집중한다. +- 입력받은 string을 해석하는 기능을 구현한다. +- divider를 기준으로 number 값을 구분하여 가져올 때마다 변수에 직접 합산하는 로직을 구현한다. + +### > 핵심 기능 구현 - new divider를 수용하도록 로직 추가 + +- 요구사항에 따라 divider가 변수화 돼야 한다. 따라서 하드코딩된 divider를 변수화 하여, //\n 와 같은 형태로, "//"와 "\n" 사이에 존재하는 string을 divider로 사용한다. + +### > 사용자 친화적인 마무리 작업 + +- 입력 받은 데이터가 parse 후 number가 아닌 경우 계산하지 않고, 경고 메시지를 출력한다. +- new divider를 받을 때, 공백이 있을 경우 공백을 삭제하고 divider를 지정할까? 라고 생각 했지만, 1-space divider, 2-space divider ... n-space divider도 수행되어야 함으로, 이 기능을 구현하지 않는다. diff --git a/src/App.js b/src/App.js old mode 100644 new mode 100755 index 091aa0a5..d16450d1 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,18 @@ +import { Console } from "@woowacourse/mission-utils"; + class App { - async run() {} + async run() { + // 사용자의 입력을 받는다. + const userInput = await Console.readLineAsync( + "덧셈할 문자열을 입력해 주세요. \n" + ); + + // 계산을 수행한다. + const result = 0; + + // 계산된 결과를 출력한다. (현재는 예시 결과 출력) + Console.print(`결과 : ${result}`); + } } export default App; From 978d974bb708b93e91c7e8b3e5d0510fad34b19b Mon Sep 17 00:00:00 2001 From: sungeunp Date: Mon, 20 Oct 2025 23:36:14 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat(calc):=20=ED=95=B5=EC=8B=AC=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20-=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 프로그램의 전체적인 flow는 잡았으니, 핵심 기능(계산)에 집중한다. - 입력받은 string을 해석하는 기능을 구현한다. - divider를 기준으로 number 값을 구분하여 가져올 때마다 변수에 직접 합산하는 로직을 구현한다. - number 형을 다루는 로직인 만큼 예외처리를 적용하고 모듈화 했다. --- src/App.js | 62 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/src/App.js b/src/App.js index d16450d1..19afbf6f 100755 --- a/src/App.js +++ b/src/App.js @@ -1,17 +1,69 @@ import { Console } from "@woowacourse/mission-utils"; +const DEFAULT_DIVIDER = [",", ":"]; class App { + _isNaN(value, onNotANumber) { + const isNotANumber = isNaN(value); + isNotANumber && onNotANumber && onNotANumber(); + return isNotANumber; + } + async run() { // 사용자의 입력을 받는다. - const userInput = await Console.readLineAsync( - "덧셈할 문자열을 입력해 주세요. \n" - ); + let validInputFlag = false; + let userInput = ""; + while (!validInputFlag) { + userInput = await Console.readLineAsync( + "덧셈할 문자열을 입력해 주세요. \n" + ); + if (userInput.trim() !== "") validInputFlag = true; + } + const charsOfUserInput = Array.from(userInput); + + // 공통 예외처리 함수 + const exceptionFunc = () => { + console.error("입력한 값이 숫자가 아닙니다. 프로그램을 종료합니다."); + process.exit(); + }; // 계산을 수행한다. - const result = 0; + let calcResult = 0; + let numberMemory = ""; // string으로 누적하도록 수정 + + charsOfUserInput.forEach((char, i) => { + const isDivider = DEFAULT_DIVIDER.includes(char); + const isDigit = /[0-9]/.test(char); + + // divider일 경우 메모리 숫자 파싱 후 결과에 합산 + if (isDivider) { + const _num = parseInt(numberMemory || "0", 10); + this._isNaN(_num, exceptionFunc); // 예외처리 + calcResult += _num; + numberMemory = ""; + return; + } + + // 예외 처리 + if (!isDigit) { + // isNaN 검사를 통해 예외처리 함수 실행하도록 함 + this._isNaN(Number(char), exceptionFunc); + return; + } + + // 숫자일 경우 메모리에 누적 + numberMemory += char; + + // 마지막 문자이면 메모리 파싱하여 합산 + if (i === charsOfUserInput.length - 1) { + const _num = parseInt(numberMemory, 10); + this._isNaN(_num, exceptionFunc); // 예외처리 + calcResult += _num; + numberMemory = ""; + } + }); // 계산된 결과를 출력한다. (현재는 예시 결과 출력) - Console.print(`결과 : ${result}`); + Console.print(`결과 : ${calcResult}`); } } From 1a65d7cdd44d858081eaecb01a430e353b142bba Mon Sep 17 00:00:00 2001 From: sungeunp Date: Tue, 21 Oct 2025 00:07:04 +0900 Subject: [PATCH 3/3] =?UTF-8?q?feat(calc):=20WIP=20=ED=95=B5=EC=8B=AC=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20-=20new=20divider?= =?UTF-8?q?=EB=A5=BC=20=EC=88=98=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 요구사항에 따라 divider가 변수화 돼야 한다. 따라서 하드코딩된 divider를 변수화 하여, //\n 와 같은 형태로, "//"와 "\n" 사이에 존재하는 string을 divider로 사용한다. - 시간 내에 완성하지 못했습니다. --- README.md | 1 + src/App.js | 44 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e3e64972..4f6e2cc0 100644 --- a/README.md +++ b/README.md @@ -21,4 +21,5 @@ ### > 사용자 친화적인 마무리 작업 - 입력 받은 데이터가 parse 후 number가 아닌 경우 계산하지 않고, 경고 메시지를 출력한다. +- 만일 "1:2,,3:4"과 같은 입력이 들어왔을 경우 빈 number 데이터가 생기게 되는데, 빈 number 데이터를 0으로 처리함 으로써 편의성을 높일 수 있다고 생각하여 그렇게 처리하도록 한다. - new divider를 받을 때, 공백이 있을 경우 공백을 삭제하고 divider를 지정할까? 라고 생각 했지만, 1-space divider, 2-space divider ... n-space divider도 수행되어야 함으로, 이 기능을 구현하지 않는다. diff --git a/src/App.js b/src/App.js index 19afbf6f..10cc6743 100755 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,8 @@ import { Console } from "@woowacourse/mission-utils"; const DEFAULT_DIVIDER = [",", ":"]; +const NEW_DIVIDER_SYNTAX_CHAR = ["/", "\\", "n"]; + class App { _isNaN(value, onNotANumber) { const isNotANumber = isNaN(value); @@ -22,7 +24,9 @@ class App { // 공통 예외처리 함수 const exceptionFunc = () => { - console.error("입력한 값이 숫자가 아닙니다. 프로그램을 종료합니다."); + console.error( + "[ERROR] 입력한 값이 숫자가 아닙니다. 프로그램을 종료합니다." + ); process.exit(); }; @@ -30,10 +34,46 @@ class App { let calcResult = 0; let numberMemory = ""; // string으로 누적하도록 수정 + // 2가 되면 `isNewDivider` flag 변수를 활성화 시킨다. + let newDividerActivateCount = 0; + let newDividerDeActivateFlag = 0; // 이전 char가 '\'여야 함을 분기하기 위해 사용하는 변수다. charsOfUserInput.forEach((char, i) => { - const isDivider = DEFAULT_DIVIDER.includes(char); + let newDivider = ""; + let isNewDivider = false; + const isDivider = isNewDivider + ? isNewDivider === char + : DEFAULT_DIVIDER.includes(char); const isDigit = /[0-9]/.test(char); + console.log("isNewDivider :>> ", isNewDivider); + // 새로운 divider를 저장 + if (isNewDivider) { + newDivider += char; + console.log(`store new divider ${newDivider}`); + return; + } + + // new divider를 위한 char별 분기 로직 + if (NEW_DIVIDER_SYNTAX_CHAR[1] === char) { + newDividerDeActivateFlag = true; + return; + } + if (newDividerDeActivateFlag && NEW_DIVIDER_SYNTAX_CHAR[2] === char) { + isNewDivider = false; + return; + } + if (NEW_DIVIDER_SYNTAX_CHAR[0] === char) { + if (++newDividerActivateCount == 2) { + isNewDivider = true; + } + return; + } + if (isNewDivider) { + newDivider += char; + return; + } + + console.log(`isDivider on ${char} :>> `, isDivider); // divider일 경우 메모리 숫자 파싱 후 결과에 합산 if (isDivider) { const _num = parseInt(numberMemory || "0", 10);