따꿍의 프로젝트
[Precourse] 로또 본문
학습 목표
- 관련 함수를 묶어 클래스를 만들고, 객체들이 협력하여 하나의 큰 기능을 수행하도록 한다.
- 클래스와 함수에 대한 단위 테스트를 통해 의도한 대로 정확하게 작동하는 영역을 확보한다.
- 2주 차 공통 피드백(디스코드 참고)을 최대한 반영한다.
프로그래밍 요구 사항
- indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다.
- 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다.
- 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다.
- 3항 연산자를 쓰지 않는다.
- 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라.
- Jest를 이용하여 정리한 기능 목록이 정상적으로 작동하는지 테스트 코드로 확인한다.
- 함수(또는 메서드)의 길이가 15라인을 넘어가지 않도록 구현한다.
- 함수(또는 메서드)가 한 가지 일만 잘 하도록 구현한다.
- else를 지양한다.
- 때로는 if/else, when문을 사용하는 것이 더 깔끔해 보일 수 있다. 어느 경우에 쓰는 것이 적절할지 스스로 고민해 본다.
- 힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다.
- 구현한 기능에 대한 단위 테스트를 작성한다. 단, UI(System.out, System.in, Scanner) 로직은 제외한다.
- 단위 테스트 작성이 익숙하지 않다면 LottoTest를 참고하여 학습한 후 테스트를 작성한다.
참고할 라이브러리
import { Console, MissionUtils } from "@woowacourse/mission-utils";
await Console.readLineAsync("덧셈할 문자열을 입력해 주세요.");
Console.print(input);
MissionUtils.Random.pickNumberInRange(0, 9);
MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6);
기능 요구 사항
간단한 로또 발매기를 구현한다.
- 로또 번호의 숫자 범위는 1~45까지이다.
- 1개의 로또를 발행할 때 중복되지 않는 6개의 숫자를 뽑는다.
- 당첨 번호 추첨 시 중복되지 않는 숫자 6개와 보너스 번호 1개를 뽑는다.
- 당첨은 1등부터 5등까지 있다. 당첨 기준과 금액은 아래와 같다.
- 1등: 6개 번호 일치 / 2,000,000,000원
- 2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원
- 3등: 5개 번호 일치 / 1,500,000원
- 4등: 4개 번호 일치 / 50,000원
- 5등: 3개 번호 일치 / 5,000원
- 로또 구입 금액을 입력하면 구입 금액에 해당하는 만큼 로또를 발행해야 한다.
- 로또 1장의 가격은 1,000원이다.
- 당첨 번호와 보너스 번호를 입력받는다.
- 사용자가 구매한 로또 번호와 당첨 번호를 비교하여 당첨 내역 및 수익률을 출력하고 로또 게임을 종료한다.
- 사용자가 잘못된 값을 입력할 경우 "[ERROR]"로 시작하는 메시지와 함께 Error를 발생시키고 해당 메시지를 출력한 다음 해당 지점부터 다시 입력을 받는다.



과제 진행 소감
1. __tests__안에 있는 예제 무조건 먼저 보기
여기 안에 있는 예제들은 약간 기능 명세서 같은 역할을 하는 것이다.
이거 안 읽고 Lotto.js를 내 마음대로 구성을 했다.
그 당시에는 로또 종이 개수 count를 constructor에 넣고,
그러면 자동으로 종이를 생성해주는 그런 클래스를 생성했다.
근데 나중에 npm test를 돌려보니까 뭐 어떻게 해도 테스트가 실패하는 것 아니겠는가
그래서 LottoTest.js를 직접 들어가서 보니
describe("로또 클래스 테스트", () => {
test("로또 번호의 개수가 6개가 넘어가면 예외가 발생한다.", () => {
expect(() => {
new Lotto([1, 2, 3, 4, 5, 6, 7]);
}).toThrow("[ERROR]");
});
// TODO: 테스트가 통과하도록 프로덕션 코드 구현
test("로또 번호에 중복된 숫자가 있으면 예외가 발생한다.", () => {
expect(() => {
new Lotto([1, 2, 3, 4, 5, 5]);
}).toThrow("[ERROR]");
});
// TODO: 추가 기능 구현에 따른 테스트 코드 작성
});
Lotto 클래스는 로또 종이 한장 그 자체를 뜻하고 있었는 것이다.
로또 종이 안에 찍을 숫자를 넣으면
종이 한장을 생성해주는 그런 느낌이었다....
애초에 생각하고 있던 Lotto.js의 정의가 달랐으니 뭐 어떻게 해도 테스트가 안 돌아갔던 것이다.
다음에는 뭐 작성하기 전에 미리 테스트부터 보도록 하겠다.
2. 함수 쪼개기
error.js랑 io.js에서 반복되는 구절이 계속 있어서
"공통 에러 확인", 그리고 "공통 io"를 꺼내줬다.
그러니까 코드 줄 수가 확 줄어들었다.
귀찮긴 해도, 코드를 다시 보고 리팩토링하고, 반복되는 코드는 따로 빼서 만들어주는 것이 얼마나 중요한지 느꼈다.
3. 새로 배운 문법 / 복습해야하는 문법
- array에 element가 있는지 확인하기
arrayName.includes(element)
- 숫자인지 확인하기
isNan(num)
- integer인지 확인하기
Number.isInteger(num)
- class 구조
import { Console } from "@woowacourse/mission-utils";
class Lotto {
#numbers;
constructor(numbers) {
this.#validate(numbers);
this.#numbers = numbers;
}
#validate(numbers) {
if (numbers.length !== 6)
throw new Error("[ERROR] 로또 번호는 6개여야 합니다.");
if (new Set(numbers).size !== numbers.length)
throw new Error("[ERROR] 로또 번호는 중복될 수 없습니다.");
}
getNumbers() {
return this.#numbers;
}
print() {
Console.print(`[${this.#numbers.join(", ")}]`);
}
}
export default Lotto;
#는 private을 뜻한다고 한다.
# 없는 모든 애들은 public이다.
- count개 Array의 Array를 만들기
Array.from(arrayLike, mapFn)
- arrayLike: something with a length property (like { length: 3 } or arguments or a NodeList).
- mapFn: a function to run for each element being created.
Array.from({length: count}, () => MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6))
- Array ascending order로 나열하기
ArrayName.sort((a,b) => a-b)
- total 구할때 reduce 사용하기
let moneyEarned = 0;
LottoRank.forEach((rank) => {
moneyEarned += rank.prize * rank.count;
});
//는 이걸로 줄일 수 있다.
const moneyEarned = LottoRank.reduce(
(sum, rank) => sum + rank.prize * rank.count,
0
);
- 한 array가 다른 array랑 얼마나 겹치는지 확인하기
const matchCount = ArrayA.filter((num)=> ArrayB.includes(num)).length
arrayA의 각 element에 대해서 ArrayB에 존재하는지 확인하고,
존재하는 녀석들만 새 array에 넣어준다.
결국에는 ArrayB에 존재하는 arrayA element들만 존재하게 되고,
그걸 length로 세면 얼마나 겹치는지 알 수 있다.
4. 좀 더 자세한 README 작성
리드미에 모든게 정의되어 있으니까
뭐 해야할지 모르겠으면 거기 가면 되니 편했다.
'우테코' 카테고리의 다른 글
| [Precourse] 최종 코딩 테스트 - 행성 로또 후기 (1) | 2026.01.10 |
|---|---|
| [Precourse] 프리코스 챌린지 - Snake 게임 만들기 (0) | 2025.11.22 |
| [Precourse] 자동차 경주 (0) | 2025.10.25 |
| [Precourse] 문자열 덧셈 계산기 (0) | 2025.10.16 |
