본문 바로가기

후기/강의 후기

[3주 차 회고] 우테코 프리코스 5기 (feat. 우아한테크코스)

728x90

-  총 4주 과정 (22.10.26 ~ 22.11.22)

-  100% 온라인 진행

-  수강료 무료

3주 차 학습일지 (22.11.10 ~ 11.16)


-  문제 1 (로또 만들기)

 

 

GitHub - meena2003/java-lotto: 로또 미션을 진행하는 저장소

로또 미션을 진행하는 저장소. Contribute to meena2003/java-lotto development by creating an account on GitHub.

github.com

 

로또 만들기란 미션명을 보고 첫인상은 "우와! 재미있겠다"였다. 기본적으로 '로또'라고 하면 무작위 숫자를 추출해 비교하는 기능을 바로 떠올린다. 생각보다 요구사항이 복잡하지 않을 것 같아서 부담이 줄어들었다. 실제 입력값으로 금액을 받으면 1,000원 단위로 무작위 로또를 생성해서 출력하는 기능까지 어렵지 않게 구현했다. 

 

 

여기까지 무난히 오니 금방 해결할 것 같았다. 하지만 다음부터가 문제였다. 당첨 번호와 보너스 번호를 입력받은 다음 기존의 로또 번호들과 비교를 해야 했는데, 생각보다 쉽지 않았다. 일단 당첨 번호를 어디에 저장할지부터 고민이 됐다. 그리고 가능한 간결하고 짧게 코드를 작성하려고 하니 막막함 때문에 더 이상 진도를 나갈 수 없었다. 일단 가독성을 신경 쓰지 않으면서 기능 구현만을 최우선으로 작성하면 어떻게든 해결할 것 같았지만 그러기엔 '시간'이 부족했다.

 

여기에 가장 큰 후회가 남는다. 내가 '로또 만들기' 미션 구현을 시작한 건 과제 제출 하루 전인 월요일이었다. 즉 단 이틀이란 짧은 시간에 모든 것을 해결해야 했다. 우테코가 내뿜는 중압감이 "완벽하지 않으면 의미 없어"라는 부담감으로 느껴졌고, 조금이라도 내 기대에 못 미치면 실망에 전의를 상실하곤 했다. 사실 우테코와 함께 코드스쿼드의 프리캠프도 동시에 진행하고 있었다. 그래서 우테코 프리캠프에 온전히 시간을 투자하지 못했다. 물론 이것도 변명이다. 진짜 이유는 높은 벽 앞에 서기가 무서워 계속 미뤄 온 내 잘못이다.

 

이번 세 번째 미션을 시작하는 때에는 굉장히 고무적이었다. 두 번째 '숫자 야구게임' 미션 때에는 README.md 파일 작성하기, 기능별 커밋하기, TDD 등과 같은 너무나도 낯선 요구사항들로 힘들었는데, 이번 미션엔 2시간 40분짜리 동영상 수업이 첨부되어 있었다. 미션을 시작 전, 기능별로 README 파일을 작성하는 것부터 TDD를 작성하는 방법까지 영상에 담겨 있어 매우 큰 도움을 받았다. 한정된 정보지만 적어도 이제는 막막하진 않았다. 덕분에 처음으로 README 파일을 제대로 작성할 수 있었다. 

 

# 로또 만들기

## 구현해야 하는 기능
1. 주요 기능
* [x] 중복되지 않는 6개의 숫자로 이뤄진 로또를 n장을 발행한다. - Player/buyLotterys(int n)
* [x] 1부터 45까지 서로 다른 임의의 수 6개를 뽑는다. - Numbers/createRandomNumbers()
  * [x] 구매한 로또 숫자와 당첨 번호를 오름차순으로 정렬한다. - Numbers/sortNumbers()
* [] 사용자가 구매한 로또의 번호와 당첨 번호 사이에 몇 개가 일치하는지 비교한다. - Application/compareNumbers(int n)
* [] 소수점 둘째 자리에서 반올림 하여 수익률을 계산한다(수익 / 투자금액 * 100). - Application/calculateRateOfReturn()

2. 입력 기능
* [x] 사용자에게 1부터 45까지 서로 다른 임의의 수 6개를 당첨 번호를 입력 받는다. - Input/askWinningNumber()
  * [x] 입력 받은 6개의 숫자가 중복되지 않는지 확인한다. - Input/validate()
* [x] 사용자에게 1부터 45까지 1개의 보너스 번호를 입력 받는다. - Input/askBonusNumber()
* [x] 사용자에게 로또 구입 금액을 입력 받는다. - Input/askHowMuchToBuy()

3. 출력 기능
* [x] 발행한 로또 수량 및 번호를 출력한다. - Application/printLotteryCountAndNumbers()
* [] 일치하는 숫자의 개수만큼 당첨 내역을 출력한다. - Application/printLotteryWinningResult()
* [] 수익률을 출력한다. - Application/printRateOfReturn()

## 예외사항
1. 구입 금액 관련 예외사항
- [x] 사용자가 로또 구입 금액을 1,000원 단위로 입력하지 않았을 경우 - "[ERROR] 구매 금액을 1,000원 단위로 입력해야 합니다."
- [x] 사용자가 로또 구입 금액에 숫자가 아닌 값을 입력했을 경우 - "[ERROR] 구매 금액은 숫자만 입력해야 합니다."
- [x] 사용자가 로또 구입 금액에 0을 입력했을 경우 - "[ERROR] 구매 금액은 숫자만 입력해야 합니다."

2. 당첨 번호 관련 예외사항
- [x] 사용자가 당첨 번호를 6개로 설정하지 않은 경우 - "[ERROR] 당첨 번호는 6개의 숫자여야 합니다."
- [x] 사용자가 당첨 번호를 중복 숫자로 입력한 경우 - "[ERROR] 당첨 번호는 서로 다른 숫자여야 합니다."
- [] 사용자가 당첨 번호를 입력할 때 구분자로 ','를 사용하지 않을 경우 - "[ERROR] 각각의 당첨 번호는 쉼표(,)를 이용해서 구분해야 합니다."
- [] 사용자가 당첨 번호를 입력할 때 마지막 번호 뒤 ','를 사용했을 경우 - "[ERROR] 마지막 번호 뒤에는 구분자를 기입하지 않아야 합니다."
- [x] 사용자가 당첨 번호를 입력할 때 1보다 작거나 45보다 큰 수를 입력한 경우 - "[ERROR] 입력 번호는 1 ~ 45 범위 내 숫자여야 합니다."

3. 보너스 번호 관련 예외사항
- [x] 사용자가 보너스 번호를 입력할 때 1보다 작거나 45보다 큰 수를 입력한 경우 - "[ERROR] 입력 번호는 1 ~ 45 범위 내 숫자여야 합니다."
- [] 사용자가 보너스 번호를 0개, 또는 2개 이상 입력할 경우 - "[ERROR] 보너스 금액은 1개만 입력이 가능합니다."
- [x] 보너스 숫자와 당첨 번호가 중복되는 경우 - "[ERROR] 보너스 번호와 당첨 번호는 중복될 수 없습니다."

## 기능 요구사항
- 로또 번호의 숫자 범위는 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원이다.
- 당첨 번호와 보너스 번호를 입력받는다.
- 사용자가 구매한 로또 번호와 당첨 번호를 비교하여 당첨 내역 및 수익률을 출력하고 로또 게임을 종료한다.
- 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 종료한다.

 

 

그러나 내 실력은 여기까지였다. 입력값에 대한 '예외 처리'가 이번 요구사항에 있었는데 머릿속에서 그림이 그려져도 실제 코드론 어떻게 할지 몰라 갈팡질팡했다. 분명히 자바 문법을 공부할 때 '예외 처리'를 배웠음에도 실제론 적용이 안되어 매우 답답했다. 특히 테스트 코드를 작성해서 원하는 예외 처리 메시지가 출력되도록 구현하는 것도 못했다. 난이도 자체가 높은 건 아니었다. 단지 해당 개념에 대해 잘 몰랐던 것이다. 시간이 충분했다면 차근차근 개념부터 알아보고 연습하면서 풀었겠지만, 하루 이틀 사이에 모든 문제를 풀어야 하니 마음의 여유가 사라졌다. 또 다양한 클래스로 구분해서 구현해야 한다는 요구 조건에서 전체적인 구조에 대한 설계에 대한 큰 고민에 빠졌다.

 

마감 시간 3시간 30분 전, 나는 결국 완주하겠다는 초기 약속을 지키지 못한 채 프로그램을 종료시킴으로써 포기를 선언했다. 명백한 패배였다. 이미 TDD, 예외처리 등 기본적인 요구 사항을 충족시키지 못했으니 가망이 없다는 생각에 기운이 쭉 빠졌다. 그래도 제출은 해야 하지 않을까 끝까지 망설였다. 그러나 이미 의욕은 사라졌고, 얼마 남지 않은 시간에 로또 번호를 비교하는 메서드 구현에서 가로막히면서 여정은 끝이 났다.

3주 차를 마치면서...


완주까지 한 주를 남기고 멈추면서 좌절감도 컸다. 특히 과거 POCU 아카데미의 객체지향 수업을 들을 때 느꼈던 무력감과 비슷했다. 함께 경쟁했던 많은 사람들은 문제없이 잘해나가는 모습을 보곤 다시 한번 나의 재능에 의구심을 가졌다.

 

하지만 그게 다였다. 방황은 오래가지 않았다. 절망에 빠진 시간은 딱 5시간. 과거에 비하면 매우 짧은 상심의 기간이었다. 스스로도 놀랐다. 이유를 생각해보니 현실을 왜곡하지 않고 그대로 받아들였기 때문인 것 같다. 우테코 프리코스에서 마주쳤던 여러 도전 과제들을 해결하지 못한 이유는 오로지 내 노력의 부족에 있다. 아직 우테코에서 기대하는 수준에 도달하지 않았을 뿐 시간을 들이면 나도 할 수 있다는 생각이 절망에서 나를 끄집어냈다.

 

돌이켜보면 여기까지 온 것도 내 성장을 의미한다. POCU 아카데미 미션 때는 자료구조가 무엇인지도 몰랐는데 이젠 능숙하진 않을지언정 컬렉션 프레임워크를 사용해서 문제를 풀 수 있다. 또 미션 1, 2까지 통과했던 사실도 내가 앞으로 나아가고 있다는 방증이다.

 

우테코 프리코스에서 '방향성'을 발견한 것이 가장 큰 수확이다. 특히 먼 나라 이웃 이야기였던 TDD의 개념과 중요성을 깨닫고, 앞으로 클린 코드를 지향하자는 목표를 얻었다. 우테코에서 이러한 연습을 많이 강조하는 이유가 있겠지... 생각을 곱씹어보며 내가 바라보아야 할 길에 대해 조금이지만 엿볼 수 있었던 계기가 됐다.

 

"중요한 건, 하루하루 내 삶에 집중하고 성실히 살아가는 것이다."

 

과거의 미련은 뒤에 놔두고, 이젠 내 앞에 온 기회들을 소중히 안고 가겠다.