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
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,36 @@
# javascript-calculator-precourse
# javascript-calculator-precourse

# 문자열 덧셈 계산기 기능 구현 목록

- 문자열 입력 받기.
- `덧셈할 문자열을 입력해 주세요.` 시작 문구 출력.
- `Console.print()` 사용.
- `Console.readLineAsync()` 사용.

<br>

- 결과 계산하기.

- 구분자로 분리한 숫자 배열 생성.
- 정규표현식 사용하여 `,`와 `:`으로 분리.
- 커스텀 구분자로 분리.
- 생성된 숫자 배열을 `reduce` 내장 메소드 사용하여, 합 계산.br>

- 결과 출력하기.
- `Console.print()` 사용.

<br>

- 예외 처리하기.

- "[ERROR]"로 시작하는 메시지와 함께 Error를 발생.
- 커스텀 구분자 예외 처리.
- 커스텀 구분자가 문자가 아닌 경우 Error 처리.
- 커스텀 구분자 구분 표시(`\n`)가 없는 경우 Error 처리.
- 피연산자 예외 처리.
- Operands가 숫자가 아닌 경우 Error 처리.
- 구분자가 아닌 다른 문자 포함된(구분자를 잘못 입력한) 경우 Error 처리.
- 양수가 아닌 경우 Error 처리.
- 빈 문자열 입력 시, `0` 출력.

- 애플리케이션 종료.
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

80 changes: 79 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,83 @@
import { Console } from "@woowacourse/mission-utils";
import {
CALCULATOR_MESSAGE,
EMPTY_STRING,
ERROR_MESSAGE,
} from "./Constants.js";
import {
isValidCharSeparator,
isValidCustomEndIndex,
isValidIsOperands,
isValidVaildSeparator,
isValidOperandRange,
} from "./validation.js";

class App {
async run() {}
async run() {
await this.enterInput();

try {
this.calculateResult();
this.printResult();
} catch (error) {
throw error;
}
}
async enterInput() {
this.input = await Console.readLineAsync(
CALCULATOR_MESSAGE.CALCULATOR_START
);
}

printResult() {
Console.print(CALCULATOR_MESSAGE.CALCULATOR_RESULT + this.sum);
}

calculateResult() {
const operands = this.splitInput();

if (operands.length === 1 && operands[0] === EMPTY_STRING) {
this.sum = 0;
return;
}

this.validateOperands(operands);
this.sum = operands.reduce((acc, cur) => acc + Number(cur), 0);
}

splitInput() {
if (this.input.startsWith("//")) {
const customEndIndex = this.input.indexOf("\\n");
const separator = this.input.slice(2, customEndIndex);
const separatedInput = this.input.slice(customEndIndex + 2);

this.validateSeperator(customEndIndex, separator);
return separatedInput.split(separator);
}

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

validateSeperator(customEndIndex, seperator) {
if (!isValidCustomEndIndex(customEndIndex)) {
throw new Error(ERROR_MESSAGE.INVALID_CUSTOM_END);
}
if (!isValidCharSeparator(seperator)) {
throw new Error(ERROR_MESSAGE.INVALID_CHARACTER);
}
}

validateOperands(Input) {
if (!isValidIsOperands(Input)) {
throw new Error(ERROR_MESSAGE.INVALID_NUMBER);
}
if (!isValidVaildSeparator(Input)) {
throw new Error(ERROR_MESSAGE.INVALID_SEPARATOR);
}
if (!isValidOperandRange(Input)) {
throw new Error(ERROR_MESSAGE.INVALID_RANGE);
}
}
}

export default App;
12 changes: 12 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const CALCULATOR_MESSAGE = {
CALCULATOR_START: "덧셈할 문자열을 입력해 주세요.\n",
CALCULATOR_RESULT: "결과 : ",
};

export const ERROR_MESSAGE = {
INVALID_CUSTOM_END: "[ERROR] 커스텀 구분자가 정확히 지정되지 않았습니다.",
INVALID_NUMBER: "[ERROR] 숫자를 입력해주세요.",
INVALID_RANGE: "[ERROR] 양수를 입력해주세요.",
};

export const EMPTY_STRING = "";
19 changes: 19 additions & 0 deletions src/validation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export function isValidCharSeparator(seperator) {
return seperator.length === 1 && isNaN(seperator);
}

export function isValidCustomEndIndex(endIndex) {
return endIndex !== -1;
}

export function isValidIsOperands(input) {
return input.every((operand) => !isNaN(parseInt(operand)));
}

export function isValidVaildSeparator(input) {
return input.every((operand) => !Number.isNaN(Number(operand)));
}

export function isValidOperandRange(input) {
return input.every((operand) => 0 < Number(operand));
}