Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,25 @@
# javascript-calculator-precourse
# javascript-calculator-precourse

## 구현할 기능 목록

### > 초기 질문 출력 및 문자열 입력 받은 후, 예시 결과 출력

- `@woowacourse/mission-utils` 패키지의 `Console` 객체를 사용하여 `초기 질문 출력`, `문자열 입력` 기능을 수행하도록 한다.
- 마찬가지로 예시 결과 출력도 `Console` 객체를 사용하여 요구사항대로 구현하고자 한다.
- 예시 결과까지 출력하는 이유는 프로그램의 전체적인 뼈대를 잡고, 핵심 기능에 집중하기 위함이다.

### > 핵심 기능 구현 - divider를 기준으로 값 계산 및 예시 결과를 실제 결과로 바꿈

- 프로그램의 전체적인 flow는 잡았으니, 핵심 기능(계산)에 집중한다.
- 입력받은 string을 해석하는 기능을 구현한다.
- divider를 기준으로 number 값을 구분하여 가져올 때마다 변수에 직접 합산하는 로직을 구현한다.

### > 핵심 기능 구현 - new divider를 수용하도록 로직 추가

- 요구사항에 따라 divider가 변수화 돼야 한다. 따라서 하드코딩된 divider를 변수화 하여, //<new_divider>\n 와 같은 형태로, "//"와 "\n" 사이에 존재하는 string을 divider로 사용한다.

### > 사용자 친화적인 마무리 작업

- 입력 받은 데이터가 parse 후 number가 아닌 경우 계산하지 않고, 경고 메시지를 출력한다.
- 만일 "1:2,,3:4"과 같은 입력이 들어왔을 경우 빈 number 데이터가 생기게 되는데, 빈 number 데이터를 0으로 처리함 으로써 편의성을 높일 수 있다고 생각하여 그렇게 처리하도록 한다.
- new divider를 받을 때, 공백이 있을 경우 공백을 삭제하고 divider를 지정할까? 라고 생각 했지만, 1-space divider, 2-space divider ... n-space divider도 수행되어야 함으로, 이 기능을 구현하지 않는다.
107 changes: 106 additions & 1 deletion src/App.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,5 +1,110 @@
import { Console } from "@woowacourse/mission-utils";

const DEFAULT_DIVIDER = [",", ":"];
const NEW_DIVIDER_SYNTAX_CHAR = ["/", "\\", "n"];

class App {
async run() {}
_isNaN(value, onNotANumber) {
const isNotANumber = isNaN(value);
isNotANumber && onNotANumber && onNotANumber();
return isNotANumber;
}

async run() {
// 사용자의 입력을 받는다.
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(
"[ERROR] 입력한 값이 숫자가 아닙니다. 프로그램을 종료합니다."
);
process.exit();
};

// 계산을 수행한다.
let calcResult = 0;
let numberMemory = ""; // string으로 누적하도록 수정

// 2가 되면 `isNewDivider` flag 변수를 활성화 시킨다.
let newDividerActivateCount = 0;
let newDividerDeActivateFlag = 0; // 이전 char가 '\'여야 함을 분기하기 위해 사용하는 변수다.
charsOfUserInput.forEach((char, i) => {
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);
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(`결과 : ${calcResult}`);
}
}

export default App;