Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
6c7a96d
initial commit
boramson Nov 25, 2024
30a006a
docs(README): 구현할 기능 목록 작성
boramson Nov 25, 2024
e3ec6a2
feat(constants): inputMessages 상수화
boramson Nov 25, 2024
6464421
feat(InputView): 입력받을 값 내용 정의
boramson Nov 25, 2024
4237548
feat(controller): [입력] 로또 구입 금액을 입력받는다.
boramson Nov 25, 2024
b6b7dd5
feat(module) : [입력] 로또 구입 금액을 입력받는다. with validation
boramson Nov 25, 2024
b59e2da
feat(constants): errorMessages 상수화
boramson Nov 25, 2024
6b2b920
feat(validation): 여러가지 상황에서 사용될 validtaion 클래스 생성
boramson Nov 25, 2024
b51406f
feat(constants): outputMessages 상수화
boramson Nov 25, 2024
b5e1cff
feat(OutputView): 출력될 내용 정의
boramson Nov 25, 2024
4a3c8db
fix(module): awiat 코드 추가
boramson Nov 25, 2024
328ea43
fix(module): InputPurchaseModule이 구매수량을 return할 수 있도록 만들었습니다.
boramson Nov 25, 2024
c1f4bf8
feat(contorller): [출력] 발행한 로또 수량 및 번호를 출력한다.
boramson Nov 25, 2024
6ae0035
feat(OutputView): 수정 및 일부 코드 추가
boramson Nov 25, 2024
d9cd286
feat(controller): [출력] 발행한 로또 수량 및 번호를 출력한다. 로또 번호는 오름차순으로 정렬하여 보여준다.
boramson Nov 25, 2024
03cb4f5
feat(module): 검증된 Lotto번호 최종 return 할 수 있도록 만듬
boramson Nov 25, 2024
25899e5
feat(module): 보너스넘버를 입력받고 validation 하는 클래스
boramson Nov 25, 2024
1bb4cd7
feat(controller): [입력] 보너스 번호를 입력 받는다.
boramson Nov 25, 2024
f4943c4
feat(constants): outputMessages 상수 추가
boramson Nov 25, 2024
a286cfc
feat(OutputView): 출력에 필요한 내용 추가
boramson Nov 25, 2024
bd8d4b9
============ 5시간 내 구현을 하지 못함 ================
boramson Nov 26, 2024
27a258f
chroe: LottoController 한줄로 만들었습니다.
boramson Nov 29, 2024
b771a16
feat(constants): errorMessage 중복제거, ERROR_MESSAGES 키값 상수명칭에서 카멜케이스로 변…
boramson Nov 29, 2024
26ef7b2
chore: errorMessages.js export 변경으로 인하여 import {} 추가
boramson Nov 29, 2024
6b3b3f9
chore(constants): outputMessages 키명칭 카멜케이스로 변경
boramson Nov 29, 2024
2e0ea5c
chore(constants): outputMessages 키명칭 카멜케이스로 변경에 따른 print 명칭 변경
boramson Nov 29, 2024
ad80c86
chore(constants): inputMessages 키명칭 카멜케이스로 변경
boramson Nov 29, 2024
14650ef
chore(OInputView): inputMessages 키명칭 카멜케이스로 변경에 따른 print 명칭 변경
boramson Nov 29, 2024
732e159
chore(constants): errorMessages 키명칭 카멜케이스로 변경
boramson Nov 30, 2024
0f79b81
feat(util): throw Error 중복 제거를 위한 util 함수 생성
boramson Nov 30, 2024
e247daa
feat(validation) : throw new Error를 createThrowError() 함수로 변경
boramson Nov 30, 2024
07b2974
chore: 알파벳 오타 수정
boramson Nov 30, 2024
9b66531
feat(validation): add method winningNumberSixDigit
boramson Nov 30, 2024
cd1d4ca
feat(module): add validation winningNumberSixDigit
boramson Nov 30, 2024
3d59a8c
feat(validation): add Mesaage winningNumberSixDigit
boramson Nov 30, 2024
bc20677
chore: ERROR_MESSAGE import 변경 및 키명칭 변경
boramson Nov 30, 2024
90c1edf
feat(module): ERROR_MESSAGE import 변경 및 키명칭 변경 / construct를 통해 winni…
boramson Nov 30, 2024
db0d3bb
feat(validation): add new method 'isDuplicatedInWinningNumber'
boramson Nov 30, 2024
a61eb34
feat(constants): add ERROR_MESSAGES 'isDuplicatedInWinningNumber'
boramson Nov 30, 2024
6c30c61
chore(module): console.log 제거
boramson Nov 30, 2024
c42cb60
chore: return 제거
boramson Nov 30, 2024
b0e07b8
feat(module): 구매수량을 리턴하는 클래스에서 구매금액을 리턴하는 클래스로 변경
boramson Nov 30, 2024
1ddce8f
chore: 단순 띄어쓰기 수정
boramson Nov 30, 2024
f05b992
chore: 단순 outputMessage 키값 수정
boramson Nov 30, 2024
2303ec1
chore: matchedFiveBonus: '5개 일치, 보너스 볼 일치 (30,000,000원) - ', 에서 보너스 볼…
boramson Nov 30, 2024
cae0e80
feat(module): 당첨내역과 총 수익률을 출력하는 기능목록 구현
boramson Nov 30, 2024
6642614
feat(controller): [출력] 당첨 내역을 출력한다. / [출력] 총 수익률을 출력한다.
boramson Nov 30, 2024
8276e3c
feat(module): printRandomNumber Module로 만들고, import로 가져와서 사용하기
boramson Nov 30, 2024
8950e6d
chore: 주석 제거
boramson Nov 30, 2024
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
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,67 @@
# javascript-lotto-precourse

 

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

줄바꿈인가요? 그냥 띄어쓰기해도 줄바꿈이 되는 경우도 있고 저 같은 경우는 \n으로 사용하는데,
  사용하시는 이유가 궁금합니다!

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위 아래 간격을 더 띄어놓고 문서형태로 볼 때 가독성을 더 높이기 위해서 사용했던 HTML 코드입니다.
잘 사용되지 않는 것이며 개인적인 만족감에 사용하였던 것입니다 ㅎㅎ

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@boramson 그렇군요 :) 감사합니다!


 

# ✅ 구현할 기능 목록

간단한 로또 발매기를 구현한다.

 

### 🟢 [입력] 로또 구입 금액을 입력받는다.

#### ㄴ validation

- 예외 상황 시 에러 문구를 출력해야 한다. 단, 에러 문구는 "[ERROR]"로 시작해야 한다.
- 구입 금액은 1,000원 단위로 입력 받으며 1,000원으로 나우어 떨어지지 않는 경우 예외 처리한다.

 

 

### 🟢 [출력] 발행한 로또 수량 및 번호를 출력한다. 로또 번호는 오름차순으로 정렬하여 보여준다.

 

 

### 🟢 [입력] 당첨번호를 입력 받는다. 번호는 쉼표(,)를 기준으로 구분한다.

#### ㄴ validation

- 예외 상황 시 에러 문구를 출력해야 한다. 단, 에러 문구는 "[ERROR]"로 시작해야 한다.

 

 

### 🟢 [입력] 보너스 번호를 입력 받는다.

#### ㄴ validation

- 예외 상황 시 에러 문구를 출력해야 한다. 단, 에러 문구는 "[ERROR]"로 시작해야 한다.

 

 

### 🟢 [출력] 당첨 내역을 출력한다.

<출력 예시>
당첨 통계

\---

3개 일치 (5,000원) - 1개

&nbsp;

&nbsp;

### 🟢 [출력] 총 수익률을 출력한다.

수익률은 소수점 둘쨰 자리에서 반올림 한다. (ex. 100.0%, 51.5%, 1,000,000.0%)

-
6 changes: 5 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import LottoController from './controller/LottoController.js';

class App {
async run() {}
async run() {
await new LottoController().runLotto();
}
}

export default App;
2 changes: 1 addition & 1 deletion src/Lotto.js

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

웹 프론트엔드 3주차 공통 피드백의 객체는 객체답게 사용한다에 로또 파일을 사용하는 방법이 좀 나와있는 것 같아요!! 도움이 되면 좋겠네요 😊

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Lotto {

#validate(numbers) {
if (numbers.length !== 6) {
throw new Error("[ERROR] 로또 번호는 6개여야 합니다.");
throw new Error('[ERROR] 로또 번호는 6개여야 합니다.');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아래 createMsg 메서드를 재사용하는 것이 좋아보입니다!

}
}

Expand Down
20 changes: 20 additions & 0 deletions src/constants/errorMessages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const ERROR_PREFIX = '[ERROR]';

const createMsg = (msg) => `${ERROR_PREFIX} ${msg} ${'다시 입력해주세요.'}\n`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다시 입력해주세요. 부분은 일반 문자열이라 ${}밖에 있어도 괜찮을 것 같아요! 🤔


const ERROR_MESSAGES = {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수화를 엄청 꼼꼼하게 하셨네요! 👍

emptyValue: createMsg('값이 존재하지 않습니다.'),
regexpTest: createMsg('형식이 잘 못되었습니다.'),
startComma: createMsg('입력이 콤마(,)부터 시작할 수 없습니다.'),
endComma: createMsg('입력 끝에 콤마(,)로 끝날 수 없습니다.'),
enteredMoreFiveTimes: '5회 이상 잘못 입력하여 종료되없습니다. 다시 실행해주세요.',
limitDigits: createMsg('최소 4자리 숫자부터 6자리 숫자까지 입력 가능합니다.'),
negativeNumber: createMsg('음수가 입력될 수 없습니다.'),
thousandUnit: createMsg(
'로또 금액인 1000원 단위로만 입력 가능하며, 최대 10만원까지 입력 가능합니다.'
),
winningNumberSixDigit: createMsg('당첨번호는 6자리를 입력해야합니다.'),
isDuplicatedInWinningNumber: createMsg('당첨번호와 중복되는 번호를 입력하셨습니다.'),
};

Comment on lines +6 to +19

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

우와! 예외 처리 진짜 상세하게 하셨네요!

export { ERROR_PREFIX, ERROR_MESSAGES };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ERROR_PREFIX는 외부에서 사용하지 않는다면 굳이 export할 필요가 없을 것 같아요 !

7 changes: 7 additions & 0 deletions src/constants/inputMessages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const INPUT_MESSAGES = {
whatPurchaseAmount: '구매금액을 입력해주세요. \n => ',
winningNumber: '당첨번호를 입력해주세요. \n => ',
bonusNumber: '보너스번호를 입력해주세요. \n => ',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=> 는 미션의 출력 형식에는 포함되어있지 않아서, 미션의 요구사항에 맞추려면 출력값을 동일하게 설정하는 것이 어떨까 생각합니다 :)

};

export default INPUT_MESSAGES;
14 changes: 14 additions & 0 deletions src/constants/outputMessages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const OUTPUT_MESSAGES = {
purchaseNumber: '개를 구매했습니다.',
winningStatistics: '당첨 통계\n--- ',
matchedThree: '3개 일치 (5,000원) - ',
matchedFour: '4개 일치 (50,000원) - ',
matchedFive: '5개 일치 (1,500,000원) - ',
matchedFiveBonus: '5개 일치, 보너스 볼 일치 (30,000,000원) - ',
matchedSix: '6개 일치 (2,000,000,000원) - ',
printQuantity: '개',
totalReturn: '총 수익률은 ',
totalReturnPercentage: '% 입니다.',
};
Comment on lines +2 to +12

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수처리를 하는 이유가 유지보수와 가독성 때문이라고 알고 있는데,
문장 자체를 상수처리 하면 오히려 가독성이 떨어지지는 않을까? 개인적으로 생각이 듭니다.
차라리 '당첨 통계', '총 수익률'과 같은 단어들을 상수화 하면 어떨지? 생각이 드는데, 여기에 대한 보람님 생각도 궁금합니다!


export default OUTPUT_MESSAGES;
26 changes: 26 additions & 0 deletions src/controller/LottoController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import InputPurchaseModule from '../modules/InputPurchaseModule.js';
import InputWinningModule from '../modules/InputWinningModule.js';
import InputBonusModule from '../modules/InputBonusModule.js';
import PrintWinningDetails from '../modules/printWinningDetails.js';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

보람님의 로또 프로젝트를 실행을 해봤는데, 에러가 납니다.

node:internal/modules/esm/resolve:265
throw new ERR_MODULE_NOT_FOUND(
^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/workspaces/javascript-lotto-7/src/modules/printWinningDetails.js' imported from /workspaces/javascript-lotto-7/src/controller/LottoController.js

LottoController.js파일 import부분
import PrintWinningDetails from '../modules/printWinningDetails.js';

이 부분에 파일명은 대문자로 시작을 해서 연결이 안되었네요!

vscode환경에서는 대소문자는 허용되는 경우가 있어서, 최종 코테 과제 제출하실 때 꼼꼼히 확인해보시면 좋을 것 같아요~

import PrintRandomNumber from '../modules/PrintRandomNumber.js';

class LottoController {
constructor() {
this.inputPurchaseModule = new InputPurchaseModule();
this.inputWinningModule = new InputWinningModule();
this.printRandomNumber = new PrintRandomNumber();
}

async runLotto() {
const purchasPrice = await this.inputPurchaseModule.inputPurchaseAmount();
const purchasQuantity = purchasPrice / 1000;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로또 1장 단위가 1000원이라 이 부분은 상수처리해도 좋겠다는 생각이 듭니다 :)

const lottoNumber = this.printRandomNumber.printRandomNumber(purchasQuantity);
const winningNumber = await this.inputWinningModule.inputWinningNumber();
const inputBonusModule = new InputBonusModule(winningNumber);
const bonusNumber = await inputBonusModule.inputBonusNumber();
const printWinningDetails = new PrintWinningDetails(purchasPrice);
printWinningDetails.winningDetails(lottoNumber, winningNumber, bonusNumber);
}
}

export default LottoController;
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import App from "./App.js";
import App from './App.js';

const app = new App();
await app.run();
52 changes: 52 additions & 0 deletions src/modules/InputBonusModule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { ERROR_MESSAGES } from '../constants/errorMessages.js';
import validation from '../validation/validation.js';
import InputView from '../view/InputView.js';
import OutputView from '../view/OutputView.js';

class InputBonusModule {
constructor(winningNumber) {
this.validation = new validation();
this.winningNumber = winningNumber;
}

async inputBonusNumber() {
const validatedBonusNumber = await this.repeatInput();
const changeTypeNumber = Number(validatedBonusNumber);
OutputView.printSpace();
return changeTypeNumber;
}

async inputAndValidation() {
const input = await InputView.readBonusNumber();
const winningNumber = this.winningNumber;
this.validateBonusNumber(input, winningNumber);
return input;
}

validateBonusNumber(value, winningNumber) {
this.validation.empty(value);
const regExpPattern = /\d{1,2}/;
this.validation.regularExpression(value, regExpPattern);
this.validation.isDuplicatedInWinningNumber(value, winningNumber);
}

async errorCatch() {
try {
const validatedInput = await this.inputAndValidation();
return validatedInput;
} catch (error) {
OutputView.printError(error);
return false;
}
}

async repeatInput() {
for (let i = 0; i < 10; i++) {
const vlaidatedInput = await this.errorCatch();
if (vlaidatedInput) return vlaidatedInput;
if (i === 5) throw new Error(ERROR_MESSAGES.enteredMoreFiveTimes);
}
}
}

export default InputBonusModule;
52 changes: 52 additions & 0 deletions src/modules/InputPurchaseModule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { ERROR_MESSAGES } from '../constants/errorMessages.js';
import validation from '../validation/validation.js';
import InputView from '../view/InputView.js';
import OutputView from '../view/OutputView.js';

class InputPurchaseModule {
constructor() {
this.validation = new validation();
}

async inputPurchaseAmount() {
const validatedPurchaseAmount = await this.repeatInput();
const changgeTypeNumber = Number(validatedPurchaseAmount);
OutputView.printSpace();
return changgeTypeNumber;
}

async inputAndValidation() {
const input = await InputView.readPurchaseAmount();
this.validatatePrice(input);
return input;
}

validatatePrice(value) {
this.validation.empty(value);
const regExpPattern = /\d/;
this.validation.regularExpression(value, regExpPattern);
this.validation.nagativeNumber(value);
this.validation.limitDigits(value);
this.validation.thousandUnit(value);
}

async errorCatch() {
try {
const validatedInput = await this.inputAndValidation();
return validatedInput;
} catch (error) {
OutputView.printError(error);
return false;
}
}

async repeatInput() {
for (let i = 0; i < 10; i++) {
const vlaidatedInput = await this.errorCatch();
if (vlaidatedInput) return vlaidatedInput;
if (i === 5) throw new Error(ERROR_MESSAGES.enteredMoreFiveTimes);
}
}
Comment on lines +43 to +49

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

repeatInput()이 반복되는 것 같은데 클래스의 상속이나 함수 등으로 모듈화 시켜도 좋을 것 같아요! 👍

}

export default InputPurchaseModule;
51 changes: 51 additions & 0 deletions src/modules/InputWinningModule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { ERROR_MESSAGES } from '../constants/errorMessages.js';
import validation from '../validation/validation.js';
import InputView from '../view/InputView.js';
import OutputView from '../view/OutputView.js';

class InputWinningModule {
constructor() {
this.validation = new validation();
}
async inputWinningNumber() {
const validatedLottoNumber = await this.repeatInput();
const changgeTypeArray = validatedLottoNumber.split(',').map((string) => Number(string));
OutputView.printSpace();
return changgeTypeArray;
}

async inputAndValidation() {
const input = await InputView.readWinningNumber();
this.validateWinningNumber(input);
return input;
}

validateWinningNumber(value) {
this.validation.empty(value);
this.validation.startedComma(value);
this.validation.endedComma(value);
const regExpPattern = /^\d(,\s?\d)*/;
this.validation.regularExpression(value, regExpPattern);
this.validation.winningNumberSixDigit(value);
}

async errorCatch() {
try {
const validatedInput = await this.inputAndValidation();
return validatedInput;
} catch (error) {
OutputView.printError(error);
return false;
}
}

async repeatInput() {
for (let i = 0; i < 10; i++) {
const vlaidatedInput = await this.errorCatch();
if (vlaidatedInput) return vlaidatedInput;
if (i === 5) throw new Error(ERROR_MESSAGES.enteredMoreFiveTimes);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

시도 횟수 제한을 걸 생각은 못했는데, 좋은 방식인 듯 합니다 !!

}
}

export default InputWinningModule;
19 changes: 19 additions & 0 deletions src/modules/PrintRandomNumber.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MissionUtils } from '@woowacourse/mission-utils';
import OutputView from '../view/OutputView.js';

class PrintRandomNumber {
printRandomNumber(purchasQuantity) {
OutputView.printPurchaseNumber(purchasQuantity);
let lottoNumberArrayss = [];
for (let i = 0; i < purchasQuantity; i++) {
const lottoNumber = MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6);
const ascendingOrder = lottoNumber.sort((a, b) => a - b);
OutputView.printLottoNumber(ascendingOrder);
lottoNumberArrayss = [...lottoNumberArrayss, ascendingOrder];
}
Comment on lines +12 to +13

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lottoNumberArrayss 마지막 s를 한번 더 적으셔서 오타가 있는 것 같습니다!

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 오타가 있네요 ㅜㅜ

OutputView.printSpace();
return lottoNumberArrayss;
}
}

export default PrintRandomNumber;
Comment on lines +1 to +19

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 파일과 OutputView에서 모두 Console 라이브러리를 import해서 출력하는 동일한 역할을 한다고 생각되는데요 ! 특별히 이 함수만 모듈로 분리한 이유가 있으신지 궁금합니다 :)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 같은 이유로 궁금합니다! 🤔

Loading