우테코 1차에 운이 좋게, 또 감사하게도 합격해서 최종 코딩 테스트를 볼 수 있게 되었다.
사실 햇병아리였던 나로선 (지금도지만) 최종 코테를 본다는 것 자체가 큰 기회이고, 경험이어서 경험했다는 거에 의의를 두자 하고 싶지만?
사람은 원래 욕심이 끝이 없다. 아니 그리고 나는 원래 우테코에 작년부터 정말 정말 가고싶었다.
작년 1차에 떨어진 것은 너무나도 당연했고 100퍼 짐작했다. 왜냐면 그냥 배우고 싶어서 경험하는 목적으로 했고, 1년 뒤에 두고보자 -- ^ 하는 마음으로 지원했었던 것이기 때문이다.
사실 그랬지만? 이번 7기에는 열심히 해보자. 적극적으로 하자. 배우고자 하는 마음을 넓히자 하고 4주간 몰입했었던 것 같긴 하다. 하지만 진짜 꼭 붙고싶었지만, 그만큼의 욕심을 냈지만, 그냥 사실 내가 너무 재밌어서 열심히 했던 것이 컸다.
열심히 하는 사람들은 많다. 잘하는 사람들도 많다. 다들 나보다 뛰어나고 대단하다. 당장 우테코 커뮤니티만 보면 개발에 몰입하시는 분들이 대단하다. 나도 그냥 말없이 열심히 달려왔는데, 나의 열정과 노력을 대가 없이 알아주신 것만 같아 너무 너무 행복하고 기쁘다.
하지만 1차 뽕은 절대 취해선 안 되고, 기만해서도 안 된다. 절대!
나는 준비를 많이 하지 않은 시험이면 그대로 결과가 나오는 스타일이다. 운이 한 번도 따른 적이 없다...ㅎ 그래서 고등학교 때부터 그냥 잘하고 싶은 건 열심히 몰입해서 했었다.
그런데 이번 1차는 정말 붙을 줄 몰랐다. 사실 우테코 프리코스가 끝나고선 후회없이 열심히 했으니, 혹시 모를 1차 발표 기다리면서 우테코 스터디원들과 PS 스터디로 변형해서 진행하기로 해서 계속 PS만 하고 있었다.
따라서 전-혀 노베이스였던 것이다. 부랴부랴 저번 기수 문제를 시간 재서 풀어봤다......사실 혼자서만 풀다가, 내가 왜 이렇게 풀이했는지 설계했는지를 나만의 템플릿 같은것을 적는 것이 좋을 것 같아서 회고록과 함께 써봤다.
우테코 6기: 크리스마스 4주차
# 크리스마스 할인 프로모션
## 크리스마스 할인 프로모션을 구현한다.
⚠️ 은 예외를 의미한다.
### 1. 환영 인사를 출력한다.
```text
안녕하세요! 우테코 식당 12월 이벤트 플래너입니다.
```
### 2. 사용자에게 식당 예상 방문 날짜를 입력받는다.
```text
12월 중 식당 예상 방문 날짜는 언제인가요? (숫자만 입력해 주세요!)
```
- ⚠️방문할 날짜는 1이상 31이하의 **숫자**로만 입력.
- ⚠️아닐시 ``[ERROR] 유효하지 않은 날짜입니다. 다시 입력해 주세요."``출력
#### 2-2. 사용자의 방문 날짜가 숫자인지 체크한다.
### 3. 주문할 갯수와 메뉴를 입력받는다.
```text
주문하실 메뉴를 메뉴와 개수를 알려 주세요. (e.g. 해산물파스타-2,레드와인-1,초코케이크-1)
티본스테이크-1,바비큐립-1,초코케이크-2,제로콜라-1
```
- 모든 에러는 ```[ERROR] 유효하지 않은 주문입니다. 다시 입력해 주세요.``` 출력
- ⚠️ **메뉴판에 없는 메뉴**를 주문시 에러 출력.
- ⚠️ 음료만 주문 시, 주문 불가
```text
<애피타이저>
양송이수프(6,000), 타파스(5,500), 시저샐러드(8,000)
<메인>
티본스테이크(55,000), 바비큐립(54,000), 해산물파스타(35,000), 크리스마스파스타(25,000)
<디저트>
초코케이크(15,000), 아이스크림(5,000)
<음료>
제로콜라(3,000), 레드와인(60,000), 샴페인(25,000)
```
- ⚠️ 메뉴 와 갯수 사이에 하이픈이 없을 경우 에러 출력
- ⚠️ 메뉴의 갯수는 **1이상 숫자만 입력 가능.**
- ⚠️ 모든 메뉴를 합쳐서 **20**개가 넘으면 에러 출력
- ⚠️ **중복 메뉴를 입력**했을 경우 에러 출력
### 4. 메뉴 할인을 적용한다.
#### 4-1. 고객이 주문한 요일이 일-목(평일)일 때: 평일 할인 적용
```text
<디저트>
초코케이크(15,000), 아이스크림(5,000)
```
- 고객이 주문한 메뉴 중 디저트 메뉴가 있으면 2023원 할인한다.
- 고객이 주문한 메뉴 중 디저트 메뉴가 없으면 넘어간다.
#### 4-2 고객이 주문한 요일이 금-토(주말)일 때: 주말 할인 적용
```text
<메인>
티본스테이크(55,000), 바비큐립(54,000), 해산물파스타(35,000), 크리스마스파스타(25,000)
```
- 고객이 주문한 메뉴 중 메인 메뉴가 있으면 2023원 할인한다.
- 고객이 주문한 메뉴 중 메인 메뉴가 없으면 넘어간다.
### 5. 총주문 할인을 확인한다.
#### 5-1. 특별 할인을 적용한다.
- 특별 할인 날짜: 3,10,17,24,31
- 총주문 할인 금액에 **1000원** 추가
#### 5-2. 1 - 25일 사이면 디데이 할인을 적용한다.
[12/1 ~ 12/25일] 사이가 아니면 5-1번은 건너뛴다.
- 총 주문 금액에서 날짜에 해당하는 **할인 금액**만큼 추가
- 1일(천원)부터 100원씩 추가
#### 5-3. 1 - 25일 사이면 디데이 할인을 적용한다.
[12/1 ~ 12/25일] 사이가 아니면 5-1번은 건너뛴다.
- 총 주문 금액에서 날짜에 해당하는 할인 금액만큼 할인한다.
- 1일(천원)부터 100원씩 추가
#### 5-4. 증정 이벤트를 적용한다.
12만원 이상인지 확인한다.
- 12만원 이상이면 샴페인(25,000) 1개 증정
- 혜택 금액에 25000원 추가
#### 5-5. 혜택 금액(할인금액 + 증정메뉴 가격)에 따라 뱃지를 증정한다.
혜택 금액에 따른 이벤트 뱃지 부여
- 별: 5천원 이상
- 트리: 만원 이상
- 산타: 이만원 이상
### 6. 출력한다.
[출력 순서]
0. 12월 26일에 우테코 식당에서 받을 이벤트 혜택 미리 보기!
1. 주문메뉴: 고객이 주문한 메뉴 (순서 상관없음)
2. 할인 전 총주문 금액: 총 메뉴 주문 금액
3. 증정메뉴 = 없으면 없음 출력
4. 혜택 내역: 할인 목록들 출력. 없으면 없음 출력
4. 총혜택 금액 = - (할인금액 + 증정 메뉴의 가격) (없으면 0원)
5. 할인 후 예상 결제 금액 = 할인 전 총 주문 금액 - 할인 금액
```text
안녕하세요! 우테코 식당 12월 이벤트 플래너입니다.
12월 중 식당 예상 방문 날짜는 언제인가요? (숫자만 입력해 주세요!)
3
주문하실 메뉴를 메뉴와 개수를 알려 주세요. (e.g. 해산물파스타-2,레드와인-1,초코케이크-1)
티본스테이크-1,바비큐립-1,초코케이크-2,제로콜라-1
12월 3일에 우테코 식당에서 받을 이벤트 혜택 미리 보기!
<주문 메뉴>
티본스테이크 1개
바비큐립 1개
초코케이크 2개
제로콜라 1개
<할인 전 총주문 금액>
142,000원
<증정 메뉴>
샴페인 1개
<혜택 내역>
크리스마스 디데이 할인: -1,200원
평일 할인: -4,046원
특별 할인: -1,000원
증정 이벤트: -25,000원
<총혜택 금액>
-31,246원
<할인 후 예상 결제 금액>
135,754원
<12월 이벤트 배지>
산타
```
## 예외 처리 요구사항
### ⚠️ 예외 상황 발생 시 에러 문구를 출력한다.
에러 문구는 [ERROR]로 시작해야 한다.
## 과제 진행 요구 사항
- [x] 기능 구현 전 READ.md에 구현할 기능 목록을 정리해 추가한다.
## 프로그래밍 요구 사항
- [x] 함수의 길이가 15라인을 넘어가지 않도록 구현한다.
- [x] else 예약어를 쓰지 않는다.
- [x] Java Enum 을 적용해서 프로그램을 구현한다.
- [x] 구현한 기능에 대한 단위 테스트를 작성한다. (입출력 제외)
- [x] 인덴트, 들여쓰기 depth 를 3이 넘지 않도록 구현한다.
- [x] 3항 연산자를 쓰지 않는다.
걸린 시간
설계는 1시간, 구현 + 테스트 통과까지 약 4시간정도 걸렸다.
설계
설계에서 가장 중요한 것은 도메인이다.
우리가 데이터베이스 및 ERD 설계하는 과정과 비슷하다고 생각한다.
크리스마스 프로모션에서는 메뉴와 할인이 가장 중요했다.
(사실 나도 그렇게 잘 설계를 못한 것 같지만,,,)
일단 제일 먼저 Enum이 떠올랐다. 왜냐면 우리는 데이터베이스가 없어서 값들을 알 수가 없다. 아는 방법은 객체를 일일히 생성해서 get을 쓰는 수밖에 없는데, 메뉴가 여러갠데 객체를 생성하기 힘들 것 같다고 판단했다.
결국 메뉴를 이렇게 나눴다. 사실 작년 4주차때도 이렇게 풀었던 것 같다 ㅠㅠㅠ 이거보다 더 나은 방법은 없을까,,,
메뉴 타입도 enum으로 한 이유는 평일이나 휴일일 때 메뉴타입에 따라 할인을 분류하기 위해서다.
구매자의 할인들을 확인하고, HashMap<SaleType,Integer>에 해당하는 SaleType을 넣어주는 방법으로 구현했다.. Integer는 할인 갯수이다. 여기서 내 설계가 멍텅구리인점!! 전체 총 세일은 숫자가 필요없는데? 그래서 그냥 1을 넣어줬다....
그리고 할인을 계산하는 방법도 복잡했다...........
1. 만약 손님의 SaleType에 평일 할인이 있는데, 손님이 가지고 있는 메뉴중에 MenuType.Dessert가 있다면 손님이 주문한 수량에 맞춰 할인 시작.
2. 원래 총 주문한 금액 - (원래 가격 * 수량) 하고 다시 + (할인 가격 * 수량 )
......
더 좋은 방법은 뭐였을까...사실 많을 것이다.
이걸 포비님이 본다면 뒤집어지실것같다. 이게 뭐죠??...
하지만 난 돌아가는 쓰레기를 만드는데 집중했다. . . . . . .
사실 여기서 난관이 있었는데 원래 List 형태의 saleTypes를 만들었다가 아 맞다 세일 수량도 필요하지 하고 허겁지겁 넣었다. 근데 생각해보니까 또 필요 없을 것 같기도 하고..... 구현하면서 설계가 오천번 바뀌는 나 어떡하죠 . .ㅎㅎ
가장 고민했던 것 중 하나는 손님의 객체였다.
어차피 쓰레드가 아니기도 하고,,, 한 명의 정보를 받는 거라 고민했지만 객체 지향을 해야하지 않겠나 싶어서 만들었는데,
세일 정보와 주문 정보가 따로 있어서 너무너무너무 힘들었다.....
내가 세일 정보와 주문 정보를 보고 할인을 계산할 수 있었던 이유는 그냥 Service에서 미리 계산을 했어서 그렇다.
if(세일정보 == 크리스마스 타입이면): 총 할인 금액에 += 크리스마스할인금액 해라.
if(세일정보 == 평일 타입이면 && 손님의 메뉴 중 디저트가 있는가) 이런식으로 했다.........
좀 더 좋은 설계는 없었을까..........있었겠지 그런데 4시간 제한두고 한 설계가 이렇게 쓰레기처럼 나왔다 ㅎㅎ
내생각엔 세일 정보 enum에 세일 가능한 정보를 추가해뒀으면 어땠을까 싶다.
요런식으로..?
그러면 굳이 분기를 저렇게 나누지 않아도, SaleType의 할인 가능한 종류가 있는지 알 수 있었을 것 같다.
총주문 이나 이런건 그냥 MenuType.ALL 로 치부하면 되니까..!
온콜 6기: 6기 최종 파이널
온콜은 솔직히 처음에 너무 막막했다. 문제가 이게 뭐죠,,
근데 내가 페어매칭을 먼저 풀고 이걸 풀어서 그런지 어? 예외 입력 받아도 어디 분기로 돌아가는 말이 없네... 하고 일단 도전했다.
문제가 처음에 좀 이해하기 힘들었다.....하지만 이해해냈다...
# 온콜
## 개발자 비상근무
⚠️ 은 예외를 의미한다.
### 1. 사용자에게 월(숫자)와 시작요일을 입력받는다.
```text
비상 근무를 배정할 월과 시작 요일을 입력하세요> 5,월
```
- ⚠️ 월이 1부터 12까지의 숫자가 아니면 예외처리한다.
- ⚠️ 일이 월부터 일까지의 한글이 아니면 예외처리한다.
### 2. 사용자에게 평일 비상 근무 순번대로 사원을 입력받는다.
```text
평일 비상 근무 순번대로 사원 닉네임을 입력하세요> 준팍,도밥,고니,수아,루루,글로,솔로스타,우코,슬링키,참새,도리
```
- ⚠️평일 근무 중 중복된 이름의 사람이 있으면 예외처리한다.
- ⚠️한글, 영어 외가 입력되면 예외처리한다.
### 3. 사용자에게 휴일 비상 근무 순번대로 사원을 입력받는다.
```text
휴일 비상 근무 순번대로 사원 닉네임을 입력하세요> 수아,루루,글로,솔로스타,우코,슬링키,참새,도리,준팍,도밥,고니
```
- ⚠️휴일 근무 중 중복된 이름의 사람이 있으면 예외처리한다.
- ⚠️한글, 영어 외가 입력되면 예외처리한다.
- ⚠️만약 평일 근무와 동일한 이름이 없을 시 예외처리한다.
- ➡️ 위의 예외들로 다시 입력받을 경우 2로 간다.
### 4. 입력받은 월과 일에 맞춰 날짜를 구성한다.
- 날짜를 구성하다가 휴일이 나오면 휴일이라고 기재한다.
- **휴일일 경우는 평일이면서 법정 공휴일일 경우이다.**
```text
법정 공휴일 목록:
1월 1일 신정
3월 1일 삼일절
5월 5일 어린이날
8월 15일 광복절
10월 3일 개천절
10월 9일 한글날
12월 25일 성탄절
```
만약 저 날들이 평일(월-금)이라면, 휴일이라고 기재한다.
### 5. 근무를 배정한다.
#### 5-1. 먼저 평일 근무자를 순번대로 차례대로 구성하다가, 휴일이 나오면 휴일 근무자에서 구성한다.
- 만약 휴일 근무자가 전 평일 근무자라면, 다음 순번의 근무자와 순서를 바꾼다.
#### 5-2. 5번을 반복한다.
### 6. 비상 근무표를 출력하고 종료한다.
````text
5월 1일 월 준팍
5월 2일 화 도밥
5월 3일 수 고니
5월 4일 목 수아
5월 5일 금(휴일) 루루
5월 6일 토 수아
5월 7일 일 글로
5월 8일 월 루루
5월 9일 화 글로
5월 10일 수 솔로스타
5월 11일 목 우코
5월 12일 금 슬링키
5월 13일 토 솔로스타
5월 14일 일 우코
5월 15일 월 참새
5월 16일 화 도리
5월 17일 수 준팍
5월 18일 목 도밥
5월 19일 금 고니
5월 20일 토 슬링키
5월 21일 일 참새
5월 22일 월 수아
5월 23일 화 루루
5월 24일 수 글로
5월 25일 목 솔로스타
5월 26일 금 우코
5월 27일 토 도리
5월 28일 일 준팍
5월 29일 월 슬링키
5월 30일 화 참새
5월 31일 수 도리
````
## 예외 처리 요구사항
### ⚠️ 예외 상황 발생 시 에러 문구를 출력한다.
에러 문구는 [ERROR]로 시작해야 한다.
```text
[ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다.
```
## 과제 진행 요구 사항
- [x] 기능 구현 전 READ.md에 구현할 기능 목록을 정리해 추가한다.
- [x] ReadMe에 적은 기능별 테스트 코드를 작성한다.
## 프로그래밍 요구 사항
- [x] 함수의 길이가 15라인을 넘어가지 않도록 구현한다.
- [x] else 예약어를 쓰지 않는다.
- [x] Java Enum 을 적용해서 프로그램을 구현한다.
- [x] 구현한 기능에 대한 단위 테스트를 작성한다. (입출력 제외)
- [x] 인덴트, 들여쓰기 depth 를 3이 넘지 않도록 구현한다.
- [x] 3항 연산자를 쓰지 않는다.
온콜은 사실 이해하고 나니깐 자료구조 Deque밖에 생각이 안 났다.. 왜냐면 순서를 변형하려면
String name = dq.poll();
String change = dq.poll()
dq.offerFirst();
이거밖에 생각이 나지 않아서.....ㅎ PS 공부를 한 게 좀 덕이 됐을까.
사실 요일도 고민이었다,..
입력받은 요일을 시작으로 반복해야 하는데,
이렇게 만들고 나니 엥? 요일을 어떻게 순서 바꾸라는거지??? 생각나서 한 10분동안 머리를 굴렸다...
결국, 또 Deque....
Deque<Day> days 에서
Day day = dq.poll();
dq.pollLast(); -> 마지막에 집어넣어주는것
사용자가 입력한 요일과 같은 요일이 오면 멈추고 그대로 List<Day> 목록에 addAll했다.
아 참고로 enum.values()하면 그 enum 들의 배열을 반환해준다!
enum을 좀 찾아봤는데 선언된 순서대로 values에 들어가는 것 같았다. 나는 월요일부터 선언해서 아마 월 - 일 이렇게 들어갔을듯?
참고로, 요렇게 해당하는 값에 대해서 반환도 가능함! (완전 애용중)
저 fillAmonth는 어차피 요일이 총 7개고, day에는 마지막 날이 있으니 나눠준 몫대로 계속 날짜들을 채우고, 나머지가 0이 아닌 경우엔 나머지만큼 더해주는 방법을 사용...
원래 저게 아니라 while(true) 해서 세다가 마지막 날이 되면 break; 했으나, depth 가 3이 돼 고민하다가 고쳤다.
원래 이런 이상한 코드였따 ㅎㅎ 최종이었으면 시간 없어서 부랴부랴 넘어가고 고대로 탈락엔딩이었을지도...
하하 여기까진 순조로워! 근데 ??? ? ? ?
또 어리바리한 내가 문제를 제 대 로 안 읽 엇 다 ! ! ! !
근무자의 이름 규칙과 최대 명수 규칙이 있었는데 그걸 예외처리 하지 않았다. 하 ! ! !
가장 중요한 부분이었는데 정신 똑바로 체리고 살았음 한다.
이 일을 계기로 입출력 부분은 눈을 부릅뜨고 보고 있다....
계속 설계랑 구현만 시간 안에 하려고 하고 있는데 실제로는 커밋도 중요하니깐 내일부턴 커밋하면서 해보면 얼마나 나올지 봐야겠다...........
'ETC > 2024 우테코 프리코스' 카테고리의 다른 글
2주차 프리코스 솔직 회고 (3) | 2024.11.02 |
---|---|
우테코 프리코스 1주차 솔직 회고 (1) | 2024.10.23 |