From b857f56ba30ac8fa2cd78bd1531f89b10237447f Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Fri, 14 Feb 2025 00:17:06 +0900 Subject: [PATCH 01/19] docs: Write functional requirements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 개발 전, 기능 요구 사항 작성 --- docs/README.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/docs/README.md b/docs/README.md index e69de29..3cfec05 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,48 @@ +## 기능 요구 사항 +- [ ] 입력 기능 + - [ ] 로또 구입 금액 입력 + - [ ] 당첨 번호 입력. 번호는 쉽표(',')를 기준으로 구분 + - [ ] 보너스 번호 입력 + +- [ ] 출력 기능 + - [ ] 구입 금액 입력 요구 문구 "구입금액을 입력해 주세요." + - [ ] 발행한 로또 수량 출력 + - [ ] 발행한 로또 수량만큼 번호 출력. 번호는 오름차순으로 정렬하여 출력 + - [ ] 당첨 내역 출력 + - [ ] 수익률 출력, 수익률은 소수점 둘째 자리에서 반올림 + - [ ] 예외 상황 시 에러 문구 출력. 에러 문구는 "[ERROR]"로 시작 + +- [ ] 컴퓨터 기능 + - [ ] 구입 금액에 해당하는 만큼 로또 발행 + - [ ] 로또는 6자리이며, 범위는 1 ~ 45 사이 정수 + - [ ] 사용자가 구매한 로또 번호와 당첨 번호 비교 + - [ ] 당첨 내역 및 수익률 계산 + +- [ ] 당첨 기준 및 금액 + - [ ] 1등: 6개 번호 일치 / 2,000,000,000원 + - [ ] 2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원 + - [ ] 3등: 5개 번호 일치 / 1,500,000원 + - [ ] 4등: 4개 번호 일치 / 50,000원 + - [ ] 5등: 3개 번호 일치 / 5,000원 + +- [ ] 예외 처리 기능 + - [ ] 사용자가 잘못된 값을 입력할 경우 ValueError를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받음 + - [ ] 로또 구입 금액 입력 예외 사항 + - [ ] int형이 아닌 경우 + - [ ] 양의 정수가 아닌 경우 + - [ ] 1,000원 단위가 아닌 경우 + - [ ] 당첨 번호 입력 예외 사항 + - [ ] 정수가 아닌 것이 포함된 경우 + - [ ] 당첨 번호 길이가 6자리가 아닌 경우 + - [ ] 번호 범위가 1 ~ 45를 벗어날 경우 + - [ ] 당첨 번호가 중복될 경우 + - [ ] 보너스 번호 입력 예외사항 + - [ ] 정수가 아닌 경우 + - [ ] 번호 범위가 1 ~ 45를 벗어날 경우 + - [ ] 당첨 번호와 중복될 경우우 + +## 기능 추가 + +## 오류 수정 + +## 기능 수정 \ No newline at end of file From 2865daa902f5894be7ae65f800e890f5f326729f Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Fri, 14 Feb 2025 01:58:46 +0900 Subject: [PATCH 02/19] feat: Add purchase amount input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 구매 금액 입력 기능 함수 추가 --- docs/README.md | 18 ++++++++++++------ src/lotto/main.py | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/docs/README.md b/docs/README.md index 3cfec05..e5f777d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,11 +1,11 @@ ## 기능 요구 사항 - [ ] 입력 기능 - - [ ] 로또 구입 금액 입력 + - [X] 로또 구입 금액 입력 - [ ] 당첨 번호 입력. 번호는 쉽표(',')를 기준으로 구분 - [ ] 보너스 번호 입력 - [ ] 출력 기능 - - [ ] 구입 금액 입력 요구 문구 "구입금액을 입력해 주세요." + - [X] 구입 금액 입력 요구 문구 "구입금액을 입력해 주세요." - [ ] 발행한 로또 수량 출력 - [ ] 발행한 로또 수량만큼 번호 출력. 번호는 오름차순으로 정렬하여 출력 - [ ] 당첨 내역 출력 @@ -27,10 +27,10 @@ - [ ] 예외 처리 기능 - [ ] 사용자가 잘못된 값을 입력할 경우 ValueError를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받음 - - [ ] 로또 구입 금액 입력 예외 사항 - - [ ] int형이 아닌 경우 - - [ ] 양의 정수가 아닌 경우 - - [ ] 1,000원 단위가 아닌 경우 + - [X] 로또 구입 금액 입력 예외 사항 + - [X] int형이 아닌 경우 + - [X] 양의 정수가 아닌 경우 + - [X] 1,000원 단위가 아닌 경우 - [ ] 당첨 번호 입력 예외 사항 - [ ] 정수가 아닌 것이 포함된 경우 - [ ] 당첨 번호 길이가 6자리가 아닌 경우 @@ -42,6 +42,12 @@ - [ ] 당첨 번호와 중복될 경우우 ## 기능 추가 +1. is_number() +> 입력 값이 정수인지 검증하는 함수 +2. validate_input_prchase_amount() +> 구매 금액 입력에 대한 검증 함수 +3. input_purchase_amount() +> 구매 금액을 입력받는 함수수 ## 오류 수정 diff --git a/src/lotto/main.py b/src/lotto/main.py index 5f270aa..a935547 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -1,6 +1,35 @@ +LOTTO_EACH_PRICE = 1000 # 로또 구입 금액 단위 매직넘버상수 + +# data가 정수인지 검증 함수 +def is_number(data): + try: + return int(data) + except ValueError as e: + raise ValueError("[ERROR] 정수만 입력해주세요.") from e + + +# 구입 금액 입력 검증 함수 +def validate_input_purchase_amount(data): + purchase_amount = is_number(data) # 입력 값이 정수인지 검증 + if purchase_amount <= 0: # 입력 값이 양의 정수인지 검증 + raise ValueError("[ERROR] 구입 금액은 양의 정수 입니다.") + elif purchase_amount % LOTTO_EACH_PRICE != 0: # 입력 값이 1,000원 단위인지 검증 + raise ValueError("[ERROR] 구입 금액을 1,000원 단위로 입력해 주세요.") + return purchase_amount # 검증 통과 + + +def input_purchase_amount(): # 구입 금액 입력 함수 + print("구입금액을 입력해 주세요.") + while True: + purchase_amount = input() + purchase_amount = validate_input_purchase_amount(purchase_amount) # 구입 금액 검증 + return purchase_amount + + def main(): - # TODO: 프로그램 구현 - pass + purchase_amount = input_purchase_amount() # 구입 금액 입력 + + if __name__ == "__main__": main() From e9ae1631a8b1d7fcbaefcc7537a7cbbaf2289d24 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Fri, 14 Feb 2025 02:14:43 +0900 Subject: [PATCH 03/19] feat: Add function to calculate the number of lottery tickets issued MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 구입 금액에 해당하는 만큼 로또 수량 계산 함수 추가 --- docs/README.md | 2 +- src/lotto/main.py | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index e5f777d..ae19807 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,7 +6,7 @@ - [ ] 출력 기능 - [X] 구입 금액 입력 요구 문구 "구입금액을 입력해 주세요." - - [ ] 발행한 로또 수량 출력 + - [X] 발행한 로또 수량 출력 - [ ] 발행한 로또 수량만큼 번호 출력. 번호는 오름차순으로 정렬하여 출력 - [ ] 당첨 내역 출력 - [ ] 수익률 출력, 수익률은 소수점 둘째 자리에서 반올림 diff --git a/src/lotto/main.py b/src/lotto/main.py index a935547..9381b9a 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -1,5 +1,6 @@ LOTTO_EACH_PRICE = 1000 # 로또 구입 금액 단위 매직넘버상수 + # data가 정수인지 검증 함수 def is_number(data): try: @@ -26,8 +27,15 @@ def input_purchase_amount(): # 구입 금액 입력 함수 return purchase_amount +def generate_lotto_quantity(purcahse_amount): + lotto_quantity = purcahse_amount // LOTTO_EACH_PRICE + print("\n{0}개를 구매했습니다.".format(lotto_quantity)) + return lotto_quantity + + def main(): purchase_amount = input_purchase_amount() # 구입 금액 입력 + lotto_quantity = generate_lotto_quantity(purchase_amount) From df8e25951885299ff09543a767d3dd5fcd11544f Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Fri, 14 Feb 2025 02:35:50 +0900 Subject: [PATCH 04/19] feat: Add a function to generate numbers if lottery tickets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 구입한 로또 개수만큼 로또를 발행하는 함수 추가 PEP8 Style로 변경 기존 코드 개선 및 주석 추가가 --- docs/README.md | 6 +++--- src/lotto/lotto.py | 24 +++++++++++++++++++++--- src/lotto/main.py | 18 +++++++++++++----- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/docs/README.md b/docs/README.md index ae19807..e52d2de 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,14 +7,14 @@ - [ ] 출력 기능 - [X] 구입 금액 입력 요구 문구 "구입금액을 입력해 주세요." - [X] 발행한 로또 수량 출력 - - [ ] 발행한 로또 수량만큼 번호 출력. 번호는 오름차순으로 정렬하여 출력 + - [X] 발행한 로또 수량만큼 번호 출력. 번호는 오름차순으로 정렬하여 출력 - [ ] 당첨 내역 출력 - [ ] 수익률 출력, 수익률은 소수점 둘째 자리에서 반올림 - [ ] 예외 상황 시 에러 문구 출력. 에러 문구는 "[ERROR]"로 시작 - [ ] 컴퓨터 기능 - - [ ] 구입 금액에 해당하는 만큼 로또 발행 - - [ ] 로또는 6자리이며, 범위는 1 ~ 45 사이 정수 + - [X] 구입 금액에 해당하는 만큼 로또 발행 + - [X] 로또는 6자리이며, 범위는 1 ~ 45 사이 정수 - [ ] 사용자가 구매한 로또 번호와 당첨 번호 비교 - [ ] 당첨 내역 및 수익률 계산 diff --git a/src/lotto/lotto.py b/src/lotto/lotto.py index 9c8c935..12b2cf6 100644 --- a/src/lotto/lotto.py +++ b/src/lotto/lotto.py @@ -1,12 +1,30 @@ from typing import List +import random class Lotto: - def __init__(self, numbers: List[int]): + def __init__(self, numbers: List[int] = None): + if numbers is None: # numbers가 주어지지 않으면 자동으로 생성성 + numbers = self.issuance_lotto() self._validate(numbers) self._numbers = numbers + def _validate(self, numbers: List[int]): if len(numbers) != 6: - raise ValueError + raise ValueError() + + @staticmethod + def issuance_lotto(): + """랜덤한 6자리 로또 번호 생성 후 정렬하여 반환""" + value = sorted(random.sample(range(1, 46), 6)) + return value + + + def __str__(self): + """str 형식으로 변환하여 반환""" + return str(self._numbers) + - # TODO: 추가 기능 구현 + def get_numbers(self): + """로또 번호 리스트 반환환""" + return self._numbers \ No newline at end of file diff --git a/src/lotto/main.py b/src/lotto/main.py index 9381b9a..49b9c1d 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -1,3 +1,6 @@ +from lotto import Lotto + + LOTTO_EACH_PRICE = 1000 # 로또 구입 금액 단위 매직넘버상수 @@ -21,22 +24,27 @@ def validate_input_purchase_amount(data): def input_purchase_amount(): # 구입 금액 입력 함수 print("구입금액을 입력해 주세요.") - while True: - purchase_amount = input() - purchase_amount = validate_input_purchase_amount(purchase_amount) # 구입 금액 검증 - return purchase_amount + purchase_amount = input() + purchase_amount = validate_input_purchase_amount(purchase_amount) # 구입 금액 검증 + return purchase_amount +# 구매 가능한 로또 개수 계산산 def generate_lotto_quantity(purcahse_amount): lotto_quantity = purcahse_amount // LOTTO_EACH_PRICE print("\n{0}개를 구매했습니다.".format(lotto_quantity)) return lotto_quantity + + def main(): purchase_amount = input_purchase_amount() # 구입 금액 입력 - lotto_quantity = generate_lotto_quantity(purchase_amount) + lotto_quantity = generate_lotto_quantity(purchase_amount) # 로또 수량 계산산 + issued_lotto_list = [Lotto.issuance_lotto() for _ in range(lotto_quantity)] # 로또 발행 + for lotto in issued_lotto_list: # 발행된 로또 출력 + print(lotto) if __name__ == "__main__": From d2f5861664412c01e0b7fe693f215859d5259e2f Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Fri, 14 Feb 2025 02:39:43 +0900 Subject: [PATCH 05/19] docs: Add feature Edit document --- docs/README.md | 6 +++++- src/lotto/main.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index e52d2de..7335645 100644 --- a/docs/README.md +++ b/docs/README.md @@ -47,7 +47,11 @@ 2. validate_input_prchase_amount() > 구매 금액 입력에 대한 검증 함수 3. input_purchase_amount() -> 구매 금액을 입력받는 함수수 +> 구매 금액을 입력받는 함수 +4. generate_lotto_quantity() +> 구매 가능한 로또 개수 계산 함수 +5. issuance_lotto() +> 로또 발행 함수 ## 오류 수정 diff --git a/src/lotto/main.py b/src/lotto/main.py index 49b9c1d..f126da0 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -29,7 +29,7 @@ def input_purchase_amount(): # 구입 금액 입력 함수 return purchase_amount -# 구매 가능한 로또 개수 계산산 +# 구매 가능한 로또 개수 계산 def generate_lotto_quantity(purcahse_amount): lotto_quantity = purcahse_amount // LOTTO_EACH_PRICE print("\n{0}개를 구매했습니다.".format(lotto_quantity)) From 5139c3689c8daaa1200c91dec25f87f257419daa Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Fri, 14 Feb 2025 02:49:56 +0900 Subject: [PATCH 06/19] refactor: Change the Lotto lenghth to a magic number constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 로또 숫자 범위와 로또 크기를 매직넘버상수로 변경 --- src/lotto/lotto.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lotto/lotto.py b/src/lotto/lotto.py index 12b2cf6..3f360b9 100644 --- a/src/lotto/lotto.py +++ b/src/lotto/lotto.py @@ -1,6 +1,11 @@ from typing import List import random + +LOTTO_SIZE = 6 # 로또 길이 매직넘버상수 +LOTTO_NUMBER_RANGE = range(1, 46) # 로또 숫자 범위 매직넘버상수 + + class Lotto: def __init__(self, numbers: List[int] = None): if numbers is None: # numbers가 주어지지 않으면 자동으로 생성성 @@ -16,7 +21,7 @@ def _validate(self, numbers: List[int]): @staticmethod def issuance_lotto(): """랜덤한 6자리 로또 번호 생성 후 정렬하여 반환""" - value = sorted(random.sample(range(1, 46), 6)) + value = sorted(random.sample(LOTTO_NUMBER_RANGE, LOTTO_SIZE)) return value From 1371e6ff8cad75a9741fdd340d19ec34a7d24744 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Fri, 14 Feb 2025 18:58:32 +0900 Subject: [PATCH 07/19] feat: Add a function to input winning numbers --- docs/README.md | 12 ++++++------ src/lotto/lotto.py | 9 +++++++-- src/lotto/main.py | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/docs/README.md b/docs/README.md index 7335645..51d0851 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,7 @@ ## 기능 요구 사항 - [ ] 입력 기능 - [X] 로또 구입 금액 입력 - - [ ] 당첨 번호 입력. 번호는 쉽표(',')를 기준으로 구분 + - [X] 당첨 번호 입력. 번호는 쉽표(',')를 기준으로 구분 - [ ] 보너스 번호 입력 - [ ] 출력 기능 @@ -31,11 +31,11 @@ - [X] int형이 아닌 경우 - [X] 양의 정수가 아닌 경우 - [X] 1,000원 단위가 아닌 경우 - - [ ] 당첨 번호 입력 예외 사항 - - [ ] 정수가 아닌 것이 포함된 경우 - - [ ] 당첨 번호 길이가 6자리가 아닌 경우 - - [ ] 번호 범위가 1 ~ 45를 벗어날 경우 - - [ ] 당첨 번호가 중복될 경우 + - [X] 당첨 번호 입력 예외 사항 + - [X] 정수가 아닌 것이 포함된 경우 + - [X] 당첨 번호 길이가 6자리가 아닌 경우 + - [X] 번호 범위가 1 ~ 45를 벗어날 경우 + - [X] 당첨 번호가 중복될 경우 - [ ] 보너스 번호 입력 예외사항 - [ ] 정수가 아닌 경우 - [ ] 번호 범위가 1 ~ 45를 벗어날 경우 diff --git a/src/lotto/lotto.py b/src/lotto/lotto.py index 3f360b9..aef8521 100644 --- a/src/lotto/lotto.py +++ b/src/lotto/lotto.py @@ -15,8 +15,13 @@ def __init__(self, numbers: List[int] = None): def _validate(self, numbers: List[int]): - if len(numbers) != 6: - raise ValueError() + if len(numbers) != LOTTO_SIZE: + raise ValueError("[ERROR] 당첨 번호는 6자리입니다.") + elif not all(num in LOTTO_NUMBER_RANGE for num in numbers): + raise ValueError("[ERROR] 당첨 번호는 1 ~ 45 사이여야 합니다.") + elif not all(numbers.count(num) == 1 for num in numbers): + raise ValueError("[ERROR] 당첨 번호는 중복될 수 없습니다.") + @staticmethod def issuance_lotto(): diff --git a/src/lotto/main.py b/src/lotto/main.py index f126da0..22e99f7 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -36,6 +36,21 @@ def generate_lotto_quantity(purcahse_amount): return lotto_quantity +def convert_to_list(data): + try: + data = list(map(int, data.replace(" ","").split(","))) + return data + except ValueError as e: + raise ValueError("[ERROR] 당첨 번호는 정수로 이루어져 있어야 합니다.") + + +def input_winning_numbers(): + print("\n당첨 번호를 입력해 주세요.") + winning_numbers = input() + winning_numbers = convert_to_list(winning_numbers) + winning_numbers = Lotto(winning_numbers) + return winning_numbers + def main(): @@ -45,6 +60,8 @@ def main(): issued_lotto_list = [Lotto.issuance_lotto() for _ in range(lotto_quantity)] # 로또 발행 for lotto in issued_lotto_list: # 발행된 로또 출력 print(lotto) + winning_numbers = input_winning_numbers() + print(winning_numbers) if __name__ == "__main__": From 53ac279984e9547d4e0a3b5a66901ddd0364c263 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Fri, 14 Feb 2025 19:01:22 +0900 Subject: [PATCH 08/19] feat: Add a function to input winning numbers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 당첨 번호를 입력받고, 검증하는 함수 추가 --- src/lotto/main.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/lotto/main.py b/src/lotto/main.py index 22e99f7..ccb8ac6 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -36,19 +36,21 @@ def generate_lotto_quantity(purcahse_amount): return lotto_quantity +# 입력 값을 list 형식으로 변환해주는 함수 def convert_to_list(data): try: data = list(map(int, data.replace(" ","").split(","))) return data except ValueError as e: - raise ValueError("[ERROR] 당첨 번호는 정수로 이루어져 있어야 합니다.") + raise ValueError("[ERROR] 번호는 정수로 이루어져 있어야 합니다.") from e +# 당첨 번호를 입력받고 검증하는 함수 def input_winning_numbers(): print("\n당첨 번호를 입력해 주세요.") - winning_numbers = input() - winning_numbers = convert_to_list(winning_numbers) - winning_numbers = Lotto(winning_numbers) + winning_numbers = input() # 당첨 번호 입력 + winning_numbers = convert_to_list(winning_numbers) # 당첨 번호 list형으로 변경 + winning_numbers = Lotto(winning_numbers) # 당첨 번호 검증 return winning_numbers @@ -60,7 +62,7 @@ def main(): issued_lotto_list = [Lotto.issuance_lotto() for _ in range(lotto_quantity)] # 로또 발행 for lotto in issued_lotto_list: # 발행된 로또 출력 print(lotto) - winning_numbers = input_winning_numbers() + winning_numbers = input_winning_numbers() # 당첨 번호 입력 print(winning_numbers) From 4a9fd97fb833f2421a3cd5c3f04e93a9929a07ed Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Fri, 14 Feb 2025 19:23:51 +0900 Subject: [PATCH 09/19] feat: Add a function to input bonus number MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 보너스 번호 입력 함수 추가 보너스 번호 검증 --- docs/README.md | 12 ++++++------ src/lotto/lotto.py | 11 ++++++++++- src/lotto/main.py | 20 ++++++++++++++++---- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/docs/README.md b/docs/README.md index 51d0851..591b262 100644 --- a/docs/README.md +++ b/docs/README.md @@ -25,8 +25,8 @@ - [ ] 4등: 4개 번호 일치 / 50,000원 - [ ] 5등: 3개 번호 일치 / 5,000원 -- [ ] 예외 처리 기능 - - [ ] 사용자가 잘못된 값을 입력할 경우 ValueError를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받음 +- [X] 예외 처리 기능 + - [X] 사용자가 잘못된 값을 입력할 경우 ValueError를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받음 - [X] 로또 구입 금액 입력 예외 사항 - [X] int형이 아닌 경우 - [X] 양의 정수가 아닌 경우 @@ -36,10 +36,10 @@ - [X] 당첨 번호 길이가 6자리가 아닌 경우 - [X] 번호 범위가 1 ~ 45를 벗어날 경우 - [X] 당첨 번호가 중복될 경우 - - [ ] 보너스 번호 입력 예외사항 - - [ ] 정수가 아닌 경우 - - [ ] 번호 범위가 1 ~ 45를 벗어날 경우 - - [ ] 당첨 번호와 중복될 경우우 + - [X] 보너스 번호 입력 예외사항 + - [X] 정수가 아닌 경우 + - [X] 번호 범위가 1 ~ 45를 벗어날 경우 + - [X] 당첨 번호와 중복될 경우 ## 기능 추가 1. is_number() diff --git a/src/lotto/lotto.py b/src/lotto/lotto.py index aef8521..aee0105 100644 --- a/src/lotto/lotto.py +++ b/src/lotto/lotto.py @@ -8,10 +8,11 @@ class Lotto: def __init__(self, numbers: List[int] = None): - if numbers is None: # numbers가 주어지지 않으면 자동으로 생성성 + if numbers is None: # numbers가 주어지지 않으면 자동으로 생성 numbers = self.issuance_lotto() self._validate(numbers) self._numbers = numbers + self.number = int def _validate(self, numbers: List[int]): @@ -23,6 +24,14 @@ def _validate(self, numbers: List[int]): raise ValueError("[ERROR] 당첨 번호는 중복될 수 없습니다.") + def validate_bonus_number(self, number: int): + self.number = number + if self.number in self._numbers: + raise ValueError("[ERROR] 보너스 번호는 당첨 번호와 중복될 수 없습니다.") + elif self.number not in LOTTO_NUMBER_RANGE: + raise ValueError("[ERROR] 보너스 번호는 1 ~ 45 사이여야 합니다.") + + @staticmethod def issuance_lotto(): """랜덤한 6자리 로또 번호 생성 후 정렬하여 반환""" diff --git a/src/lotto/main.py b/src/lotto/main.py index ccb8ac6..02bbe2a 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -50,10 +50,19 @@ def input_winning_numbers(): print("\n당첨 번호를 입력해 주세요.") winning_numbers = input() # 당첨 번호 입력 winning_numbers = convert_to_list(winning_numbers) # 당첨 번호 list형으로 변경 - winning_numbers = Lotto(winning_numbers) # 당첨 번호 검증 - return winning_numbers + lotto = Lotto(winning_numbers) # 당첨 번호 검증 + return lotto +# 보너스 번호를 입력받고 검증하는 함수수 +def input_bonus_number(lotto): + print("\n보너스 번호를 입력해 주세요.") + bouns_number = input() # 보너스 번호 입력 + bouns_number = is_number(bouns_number) # 보너스 번호를 int형으로 변환 + lotto.validate_bonus_number(bouns_number) # 보너스 번호 검증증 + return bouns_number + + def main(): purchase_amount = input_purchase_amount() # 구입 금액 입력 @@ -62,8 +71,11 @@ def main(): issued_lotto_list = [Lotto.issuance_lotto() for _ in range(lotto_quantity)] # 로또 발행 for lotto in issued_lotto_list: # 발행된 로또 출력 print(lotto) - winning_numbers = input_winning_numbers() # 당첨 번호 입력 - print(winning_numbers) + + lotto = input_winning_numbers() # 당첨 번호 입력 + + bonus_number = input_bonus_number(lotto) # 보너스 번호 입력력 + print(bonus_number) if __name__ == "__main__": From 04230f5740880a7578246c921dc792e12a860cef Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Fri, 14 Feb 2025 20:38:20 +0900 Subject: [PATCH 10/19] feat: Add a function to compare the issued lotto docs: Add feature Edit document MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 발행된 로또를 당첨 번호, 보너스 번호와 비교하는 함수 추가 기능 추가 문서 작성 --- docs/README.md | 25 +++++++++++++++++++++---- src/lotto/lotto.py | 42 ++++++++++++++++++++++++++++++++++++------ src/lotto/main.py | 10 +++++++--- 3 files changed, 64 insertions(+), 13 deletions(-) diff --git a/docs/README.md b/docs/README.md index 591b262..be1d4a3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,8 +1,8 @@ ## 기능 요구 사항 -- [ ] 입력 기능 +- [X] 입력 기능 - [X] 로또 구입 금액 입력 - [X] 당첨 번호 입력. 번호는 쉽표(',')를 기준으로 구분 - - [ ] 보너스 번호 입력 + - [X] 보너스 번호 입력 - [ ] 출력 기능 - [X] 구입 금액 입력 요구 문구 "구입금액을 입력해 주세요." @@ -15,7 +15,7 @@ - [ ] 컴퓨터 기능 - [X] 구입 금액에 해당하는 만큼 로또 발행 - [X] 로또는 6자리이며, 범위는 1 ~ 45 사이 정수 - - [ ] 사용자가 구매한 로또 번호와 당첨 번호 비교 + - [X] 사용자가 구매한 로또 번호와 당첨 번호 비교 - [ ] 당첨 내역 및 수익률 계산 - [ ] 당첨 기준 및 금액 @@ -50,8 +50,25 @@ > 구매 금액을 입력받는 함수 4. generate_lotto_quantity() > 구매 가능한 로또 개수 계산 함수 -5. issuance_lotto() +5. Lotto.issuance_lotto() > 로또 발행 함수 +6. convert_to_list() +> 입력 값을 list 형식으로 변환하는 함수 +7. input_winning_numbers() +> 당첨 번호를 입력받는 함수 +8. Lotto._validate() +> 당첨 번호를 검증하는 함수 +9. input_bonus_number() +> 보너스 번호를 입력받는 함수 +10. Lotto.validate_bonus_number() +> 보너스 번호를 검증하는 함수 +11. Lotto.compare_winning_number() +> 당첨 번호와 발행 번호를 비교하는 함수 +12. Lotto.compare_bonus_number() +> 보너스 번호와 발행 번호를 비교하는 함수 +13. Lotto.calculate_result() +> 발행한 로또를 순서대로 당첨 번호, 보너스 번호 비교 함수를 실행하는 함수 + ## 오류 수정 diff --git a/src/lotto/lotto.py b/src/lotto/lotto.py index aee0105..c757280 100644 --- a/src/lotto/lotto.py +++ b/src/lotto/lotto.py @@ -12,7 +12,10 @@ def __init__(self, numbers: List[int] = None): numbers = self.issuance_lotto() self._validate(numbers) self._numbers = numbers - self.number = int + self.bonus_number = int + self.numbers_list = List[list] + self.result_list = List[int] + self.statistics_list = List[list] def _validate(self, numbers: List[int]): @@ -25,10 +28,10 @@ def _validate(self, numbers: List[int]): def validate_bonus_number(self, number: int): - self.number = number - if self.number in self._numbers: + self.bonus_number = number + if self.bonus_number in self._numbers: raise ValueError("[ERROR] 보너스 번호는 당첨 번호와 중복될 수 없습니다.") - elif self.number not in LOTTO_NUMBER_RANGE: + elif self.bonus_number not in LOTTO_NUMBER_RANGE: raise ValueError("[ERROR] 보너스 번호는 1 ~ 45 사이여야 합니다.") @@ -45,5 +48,32 @@ def __str__(self): def get_numbers(self): - """로또 번호 리스트 반환환""" - return self._numbers \ No newline at end of file + """로또 번호 리스트 반환""" + return self._numbers + + + def compare_winning_number(self, numbers: List[int]): + """당첨 번호와 발행 번호를 비교""" + count = 0 + for i in numbers: + if i in self._numbers: + count += 1 + return count + + + def compare_bonus_number(self, numbers: List[int]): + """보너스 번호와 발행 번호를 비교""" + if self.bonus_number in numbers: + return 1 + return 0 + + + def calculate_result(self, numbers_list: List[list]): + """발행한 로또를 순서대로 당첨 번호, 보너스 번호와 비교""" + self.numbers_list = numbers_list + self.result_list = [0 for _ in range(len(numbers_list))] + for i in range(len(self.result_list)): + count_winning = self.compare_winning_number(self.numbers_list[i]) + count_bonus = self.compare_bonus_number(self.numbers_list[i]) + self.result_list[i] = [count_winning, count_bonus] + return self.result_list \ No newline at end of file diff --git a/src/lotto/main.py b/src/lotto/main.py index 02bbe2a..d1899e7 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -54,7 +54,7 @@ def input_winning_numbers(): return lotto -# 보너스 번호를 입력받고 검증하는 함수수 +# 보너스 번호를 입력받고 검증하는 함수 def input_bonus_number(lotto): print("\n보너스 번호를 입력해 주세요.") bouns_number = input() # 보너스 번호 입력 @@ -74,8 +74,12 @@ def main(): lotto = input_winning_numbers() # 당첨 번호 입력 - bonus_number = input_bonus_number(lotto) # 보너스 번호 입력력 - print(bonus_number) + bonus_number = input_bonus_number(lotto) # 보너스 번호 입력 + + result_list = lotto.calculate_result(issued_lotto_list) + + print(result_list) + if __name__ == "__main__": From 655b81971758345c2b2a607ac1d44f67e1f24b79 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Sat, 15 Feb 2025 16:30:37 +0900 Subject: [PATCH 11/19] feat: Add print result statistics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 당첨 통계 출력 함수 추가 --- src/lotto/lotto.py | 27 ++++++++++++++++++++++++++- src/lotto/main.py | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/lotto/lotto.py b/src/lotto/lotto.py index c757280..bf43616 100644 --- a/src/lotto/lotto.py +++ b/src/lotto/lotto.py @@ -1,4 +1,5 @@ from typing import List +from enum import Enum import random @@ -76,4 +77,28 @@ def calculate_result(self, numbers_list: List[list]): count_winning = self.compare_winning_number(self.numbers_list[i]) count_bonus = self.compare_bonus_number(self.numbers_list[i]) self.result_list[i] = [count_winning, count_bonus] - return self.result_list \ No newline at end of file + return self.result_list + + +class Score(Enum): + FIRST = (6, 0, 2000000000) # 6개 일치, 보너스 X, 1등 + SECOND = (5, 1, 30000000) # 5개 일치, 보너스 O, 2등 + THIRD = (5, 0, 1500000) # 5개 일치, 보너스 X, 3등 + FOURTH = (4, 0, 50000) # 4개 일치, 보너스 X, 4등 + FIFTH = (3, 0, 5000) # 3개 일치, 보너스 X, 5등 + NONE = (0, 0, 0) # 당첨되지 않음 + + def __init__(self, match_count, bonus_match, prize): + self.match_count = match_count # 맞춘 숫자 개수 + self.bonus_match = bonus_match # 보너스 번호 일치 여부 + self.prize = prize # 상금 + + @classmethod + def get_score(cls, match_count, bonus_match): + """ + 당첨 번호 개수와 보너스 번호 여부를 받아 해당하는 Score 반환 + """ + for score in cls: + if score.match_count == match_count and score.bonus_match == bonus_match: + return score + return cls.NONE # 당첨되지 않은 경우 \ No newline at end of file diff --git a/src/lotto/main.py b/src/lotto/main.py index d1899e7..a77d20a 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -1,4 +1,4 @@ -from lotto import Lotto +from lotto import Lotto, Score LOTTO_EACH_PRICE = 1000 # 로또 구입 금액 단위 매직넘버상수 @@ -63,6 +63,34 @@ def input_bonus_number(lotto): return bouns_number +def print_result(result_list, purchase_amount): + print("\n당첨 통계\n---") + + # 등수별 당첨 개수 저장 딕셔너리 초기화 + score_count = {score: 0 for score in Score if score != Score.NONE} + + # 당첨 개수 세기 + for match_count, bonus_match in result_list: + score = Score.get_score(match_count, bonus_match) + if score != Score.NONE: + score_count[score] += 1 + + # 총 당첨 금액 계산 + total_prize = sum(score.prize * count for score, count in score_count.items()) + + # 결과 출력 + for score in Score: + if score == Score.NONE: + continue # NONE 등급(낙첨)은 출력하지 않음 + description = f"{score.match_count}개 일치" + if score.bonus_match == 1: + description += ", 보너스 볼 일치" + print(f"{description} ({format(score.prize, ',d')}원) - {score_count[score]}개") + + # 수익률 계산 및 출력 + revenue_rate = (total_prize / purchase_amount) * 100 + print(f"총 수익률은 {revenue_rate:.1f}%입니다.") + def main(): purchase_amount = input_purchase_amount() # 구입 금액 입력 @@ -77,9 +105,8 @@ def main(): bonus_number = input_bonus_number(lotto) # 보너스 번호 입력 result_list = lotto.calculate_result(issued_lotto_list) - - print(result_list) + print_result(result_list, purchase_amount) if __name__ == "__main__": From c0b132b3841c1fcff0162b9f9eb491b4ff68b7d4 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Sat, 15 Feb 2025 16:47:27 +0900 Subject: [PATCH 12/19] test: Add unit tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 단위 테스트 기능 추가 --- src/lotto/main.py | 2 +- tests/lotto/test_lotto.py | 61 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/lotto/main.py b/src/lotto/main.py index a77d20a..5792f38 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -1,4 +1,4 @@ -from lotto import Lotto, Score +from lotto.lotto import Lotto, Score LOTTO_EACH_PRICE = 1000 # 로또 구입 금액 단위 매직넘버상수 diff --git a/tests/lotto/test_lotto.py b/tests/lotto/test_lotto.py index e515562..98397e7 100644 --- a/tests/lotto/test_lotto.py +++ b/tests/lotto/test_lotto.py @@ -21,4 +21,63 @@ def test_create_lotto_by_duplicated_number(): Lotto([1, 2, 3, 4, 5, 5]) -# 추가 테스트 작성 가능 +# 로또 번호 범위 초과 예외 테스트 (예: 46이 포함된 경우) +@pytest.mark.custom_name("로또 번호가 1~45 범위를 벗어나면 예외가 발생한다.") +def test_create_lotto_by_out_of_range(): + with pytest.raises(ValueError): + Lotto([0, 1, 2, 3, 4, 5]) # 0 포함 + with pytest.raises(ValueError): + Lotto([1, 2, 3, 4, 5, 46]) # 46 포함 + + +# 보너스 번호 중복 예외 테스트 (보너스 번호가 당첨 번호와 중복) +@pytest.mark.custom_name("보너스 번호가 당첨 번호와 중복되면 예외가 발생한다.") +def test_validate_bonus_number_by_duplicate(): + lotto = Lotto([1, 2, 3, 4, 5, 6]) + with pytest.raises(ValueError): + lotto.validate_bonus_number(5) # 기존 당첨 번호와 중복된 보너스 번호 + + +# 보너스 번호 범위 초과 예외 테스트 +@pytest.mark.custom_name("보너스 번호가 1~45 범위를 벗어나면 예외가 발생한다.") +def test_validate_bonus_number_by_out_of_range(): + lotto = Lotto([1, 2, 3, 4, 5, 6]) + with pytest.raises(ValueError): + lotto.validate_bonus_number(0) # 0 포함 + with pytest.raises(ValueError): + lotto.validate_bonus_number(46) # 46 포함 + + +# 로또 자동 발행 시, 6개의 숫자가 포함되어 있는지 확인 +@pytest.mark.custom_name("로또 자동 발행 시, 6개의 숫자가 포함되어야 한다.") +def test_issuance_lotto_size(): + numbers = Lotto.issuance_lotto() + assert len(numbers) == 6 + + +# 로또 자동 발행 시, 숫자가 정렬되어 있는지 확인 +@pytest.mark.custom_name("로또 자동 발행 시, 번호가 오름차순 정렬되어야 한다.") +def test_issuance_lotto_sorted(): + numbers = Lotto.issuance_lotto() + assert numbers == sorted(numbers) + + +# 로또 번호 비교 테스트 (당첨 개수 확인) +@pytest.mark.custom_name("발행된 로또 번호와 당첨 번호를 비교하여 일치 개수를 확인한다.") +def test_compare_winning_number(): + winning_lotto = Lotto([1, 2, 3, 4, 5, 6]) + issued_numbers = [1, 2, 3, 10, 20, 30] # 3개 일치 + assert winning_lotto.compare_winning_number(issued_numbers) == 3 + + +# 보너스 번호 비교 테스트 +@pytest.mark.custom_name("발행된 로또 번호와 보너스 번호를 비교하여 일치 여부를 확인한다.") +def test_compare_bonus_number(): + winning_lotto = Lotto([1, 2, 3, 4, 5, 6]) + winning_lotto.validate_bonus_number(7) + + issued_numbers = [7, 8, 9, 10, 11, 12] # 보너스 번호(7) 포함 + assert winning_lotto.compare_bonus_number(issued_numbers) == 1 + + issued_numbers = [1, 2, 3, 4, 5, 6] # 보너스 번호 미포함 + assert winning_lotto.compare_bonus_number(issued_numbers) == 0 \ No newline at end of file From 9cb1af2c5a4338d791637866d52e38ccc4ce8340 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Sat, 15 Feb 2025 16:53:18 +0900 Subject: [PATCH 13/19] style: remove Trailing whitespace --- src/lotto/__init__.py | 2 +- src/lotto/lotto.py | 10 +++++----- src/lotto/main.py | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lotto/__init__.py b/src/lotto/__init__.py index 769b83e..126e455 100644 --- a/src/lotto/__init__.py +++ b/src/lotto/__init__.py @@ -1,7 +1,7 @@ # src/lotto/__init__.py # 📌 이 패키지는 로또 관련 기능을 제공하는 모듈입니다. -# 외부에서 `from lotto import Lotto`와 같은 방식으로 사용할 수 있도록 +# 외부에서 `from lotto import Lotto`와 같은 방식으로 사용할 수 있도록 # 필요한 모듈을 여기에 등록하세요. # # ✅ 새로운 모듈을 추가할 경우: diff --git a/src/lotto/lotto.py b/src/lotto/lotto.py index bf43616..fde8846 100644 --- a/src/lotto/lotto.py +++ b/src/lotto/lotto.py @@ -41,17 +41,17 @@ def issuance_lotto(): """랜덤한 6자리 로또 번호 생성 후 정렬하여 반환""" value = sorted(random.sample(LOTTO_NUMBER_RANGE, LOTTO_SIZE)) return value - + def __str__(self): """str 형식으로 변환하여 반환""" return str(self._numbers) - + def get_numbers(self): """로또 번호 리스트 반환""" return self._numbers - + def compare_winning_number(self, numbers: List[int]): """당첨 번호와 발행 번호를 비교""" @@ -60,7 +60,7 @@ def compare_winning_number(self, numbers: List[int]): if i in self._numbers: count += 1 return count - + def compare_bonus_number(self, numbers: List[int]): """보너스 번호와 발행 번호를 비교""" @@ -101,4 +101,4 @@ def get_score(cls, match_count, bonus_match): for score in cls: if score.match_count == match_count and score.bonus_match == bonus_match: return score - return cls.NONE # 당첨되지 않은 경우 \ No newline at end of file + return cls.NONE # 당첨되지 않은 경우 diff --git a/src/lotto/main.py b/src/lotto/main.py index 5792f38..001dc38 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -61,11 +61,11 @@ def input_bonus_number(lotto): bouns_number = is_number(bouns_number) # 보너스 번호를 int형으로 변환 lotto.validate_bonus_number(bouns_number) # 보너스 번호 검증증 return bouns_number - + def print_result(result_list, purchase_amount): print("\n당첨 통계\n---") - + # 등수별 당첨 개수 저장 딕셔너리 초기화 score_count = {score: 0 for score in Score if score != Score.NONE} @@ -103,7 +103,7 @@ def main(): lotto = input_winning_numbers() # 당첨 번호 입력 bonus_number = input_bonus_number(lotto) # 보너스 번호 입력 - + result_list = lotto.calculate_result(issued_lotto_list) print_result(result_list, purchase_amount) From 57a45ba20658df9cb9565599cc38819f6d31b89d Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Sat, 15 Feb 2025 20:34:48 +0900 Subject: [PATCH 14/19] style: Change to PEP8 style --- src/lotto/__init__.py | 3 ++- src/lotto/lotto.py | 10 +--------- src/lotto/main.py | 3 ++- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/lotto/__init__.py b/src/lotto/__init__.py index 126e455..f2cc83a 100644 --- a/src/lotto/__init__.py +++ b/src/lotto/__init__.py @@ -10,9 +10,10 @@ # - `flake8`의 F401 경고(`imported but unused`)가 발생하는 경우, `__all__`을 활용해 해결하세요. from .lotto import Lotto # 🎲 로또 번호 생성 및 검증을 위한 클래스 +from .lotto import Score # 패키지 외부에서 `from lotto import *` 사용 시 제공할 모듈을 명시적으로 정의합니다. -__all__ = ["Lotto"] +__all__ = ["Lotto", "Score"] # 💡 예시: 새로운 모듈을 추가할 때 # from .other_module import OtherClass # 🆕 예: 새로운 클래스 추가 시 diff --git a/src/lotto/lotto.py b/src/lotto/lotto.py index fde8846..9d70439 100644 --- a/src/lotto/lotto.py +++ b/src/lotto/lotto.py @@ -18,7 +18,6 @@ def __init__(self, numbers: List[int] = None): self.result_list = List[int] self.statistics_list = List[list] - def _validate(self, numbers: List[int]): if len(numbers) != LOTTO_SIZE: raise ValueError("[ERROR] 당첨 번호는 6자리입니다.") @@ -26,8 +25,7 @@ def _validate(self, numbers: List[int]): raise ValueError("[ERROR] 당첨 번호는 1 ~ 45 사이여야 합니다.") elif not all(numbers.count(num) == 1 for num in numbers): raise ValueError("[ERROR] 당첨 번호는 중복될 수 없습니다.") - - + def validate_bonus_number(self, number: int): self.bonus_number = number if self.bonus_number in self._numbers: @@ -35,24 +33,20 @@ def validate_bonus_number(self, number: int): elif self.bonus_number not in LOTTO_NUMBER_RANGE: raise ValueError("[ERROR] 보너스 번호는 1 ~ 45 사이여야 합니다.") - @staticmethod def issuance_lotto(): """랜덤한 6자리 로또 번호 생성 후 정렬하여 반환""" value = sorted(random.sample(LOTTO_NUMBER_RANGE, LOTTO_SIZE)) return value - def __str__(self): """str 형식으로 변환하여 반환""" return str(self._numbers) - def get_numbers(self): """로또 번호 리스트 반환""" return self._numbers - def compare_winning_number(self, numbers: List[int]): """당첨 번호와 발행 번호를 비교""" count = 0 @@ -61,14 +55,12 @@ def compare_winning_number(self, numbers: List[int]): count += 1 return count - def compare_bonus_number(self, numbers: List[int]): """보너스 번호와 발행 번호를 비교""" if self.bonus_number in numbers: return 1 return 0 - def calculate_result(self, numbers_list: List[list]): """발행한 로또를 순서대로 당첨 번호, 보너스 번호와 비교""" self.numbers_list = numbers_list diff --git a/src/lotto/main.py b/src/lotto/main.py index 001dc38..939fc0d 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -1,4 +1,5 @@ -from lotto.lotto import Lotto, Score +from lotto.lotto import Lotto +from lotto.lotto import Score LOTTO_EACH_PRICE = 1000 # 로또 구입 금액 단위 매직넘버상수 From a406f68dd22f6abcfc6835cc1379f67202da219e Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Sat, 15 Feb 2025 20:43:28 +0900 Subject: [PATCH 15/19] style: Change Style --- src/lotto/lotto.py | 12 ++++++------ src/lotto/main.py | 26 +++++++++++++------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/lotto/lotto.py b/src/lotto/lotto.py index 9d70439..7e2032c 100644 --- a/src/lotto/lotto.py +++ b/src/lotto/lotto.py @@ -25,7 +25,7 @@ def _validate(self, numbers: List[int]): raise ValueError("[ERROR] 당첨 번호는 1 ~ 45 사이여야 합니다.") elif not all(numbers.count(num) == 1 for num in numbers): raise ValueError("[ERROR] 당첨 번호는 중복될 수 없습니다.") - + def validate_bonus_number(self, number: int): self.bonus_number = number if self.bonus_number in self._numbers: @@ -80,17 +80,17 @@ class Score(Enum): FIFTH = (3, 0, 5000) # 3개 일치, 보너스 X, 5등 NONE = (0, 0, 0) # 당첨되지 않음 - def __init__(self, match_count, bonus_match, prize): - self.match_count = match_count # 맞춘 숫자 개수 - self.bonus_match = bonus_match # 보너스 번호 일치 여부 + def __init__(self, m_count, b_match, prize): + self.m_count = m_count # 맞춘 숫자 개수 + self.b_match = b_match # 보너스 번호 일치 여부 self.prize = prize # 상금 @classmethod - def get_score(cls, match_count, bonus_match): + def get_score(cls, m_count, b_match): """ 당첨 번호 개수와 보너스 번호 여부를 받아 해당하는 Score 반환 """ for score in cls: - if score.match_count == match_count and score.bonus_match == bonus_match: + if score.m_count == m_count and score.b_match == b_match: return score return cls.NONE # 당첨되지 않은 경우 diff --git a/src/lotto/main.py b/src/lotto/main.py index 939fc0d..0db2543 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -14,7 +14,7 @@ def is_number(data): # 구입 금액 입력 검증 함수 -def validate_input_purchase_amount(data): +def validate_purchase_amount(data): purchase_amount = is_number(data) # 입력 값이 정수인지 검증 if purchase_amount <= 0: # 입력 값이 양의 정수인지 검증 raise ValueError("[ERROR] 구입 금액은 양의 정수 입니다.") @@ -26,7 +26,7 @@ def validate_input_purchase_amount(data): def input_purchase_amount(): # 구입 금액 입력 함수 print("구입금액을 입력해 주세요.") purchase_amount = input() - purchase_amount = validate_input_purchase_amount(purchase_amount) # 구입 금액 검증 + purchase_amount = validate_purchase_amount(purchase_amount) # 구입 금액 검증 return purchase_amount @@ -40,7 +40,7 @@ def generate_lotto_quantity(purcahse_amount): # 입력 값을 list 형식으로 변환해주는 함수 def convert_to_list(data): try: - data = list(map(int, data.replace(" ","").split(","))) + data = list(map(int, data.replace(" ", "").split(","))) return data except ValueError as e: raise ValueError("[ERROR] 번호는 정수로 이루어져 있어야 합니다.") from e @@ -61,7 +61,6 @@ def input_bonus_number(lotto): bouns_number = input() # 보너스 번호 입력 bouns_number = is_number(bouns_number) # 보너스 번호를 int형으로 변환 lotto.validate_bonus_number(bouns_number) # 보너스 번호 검증증 - return bouns_number def print_result(result_list, purchase_amount): @@ -77,16 +76,17 @@ def print_result(result_list, purchase_amount): score_count[score] += 1 # 총 당첨 금액 계산 - total_prize = sum(score.prize * count for score, count in score_count.items()) + total_prize = sum(score.prize * cnt for score, cnt in score_count.items()) # 결과 출력 for score in Score: if score == Score.NONE: continue # NONE 등급(낙첨)은 출력하지 않음 - description = f"{score.match_count}개 일치" - if score.bonus_match == 1: + description = f"{score.m_count}개 일치" + if score.b_match == 1: description += ", 보너스 볼 일치" - print(f"{description} ({format(score.prize, ',d')}원) - {score_count[score]}개") + print(f"{description} ({format(score.prize, ',d')}원)", end="") + print(f" - {score_count[score]}개") # 수익률 계산 및 출력 revenue_rate = (total_prize / purchase_amount) * 100 @@ -95,17 +95,17 @@ def print_result(result_list, purchase_amount): def main(): purchase_amount = input_purchase_amount() # 구입 금액 입력 - lotto_quantity = generate_lotto_quantity(purchase_amount) # 로또 수량 계산산 + l_quantity = generate_lotto_quantity(purchase_amount) # 로또 수량 계산산 - issued_lotto_list = [Lotto.issuance_lotto() for _ in range(lotto_quantity)] # 로또 발행 - for lotto in issued_lotto_list: # 발행된 로또 출력 + issued_l_list = [Lotto.issuance_lotto() for _ in range(l_quantity)] # 로또 발행 + for lotto in issued_l_list: # 발행된 로또 출력 print(lotto) lotto = input_winning_numbers() # 당첨 번호 입력 - bonus_number = input_bonus_number(lotto) # 보너스 번호 입력 + input_bonus_number(lotto) # 보너스 번호 입력 - result_list = lotto.calculate_result(issued_lotto_list) + result_list = lotto.calculate_result(issued_l_list) print_result(result_list, purchase_amount) From b063e9940d0aaebef7e7d2fae4d3b93e3c30bdf7 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Sat, 15 Feb 2025 22:47:44 +0900 Subject: [PATCH 16/19] style: Change style --- src/lotto/main.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/lotto/main.py b/src/lotto/main.py index 0db2543..f638488 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -63,6 +63,18 @@ def input_bonus_number(lotto): lotto.validate_bonus_number(bouns_number) # 보너스 번호 검증증 +def just_print(Score, score_count): + # 결과 출력 + for score in Score: + if score == Score.NONE: + continue # NONE 등급(낙첨)은 출력하지 않음 + description = f"{score.m_count}개 일치" + if score.b_match == 1: + description += ", 보너스 볼 일치" + print(f"{description} ({format(score.prize, ',d')}원)", end="") + print(f" - {score_count[score]}개") + + def print_result(result_list, purchase_amount): print("\n당첨 통계\n---") @@ -74,19 +86,12 @@ def print_result(result_list, purchase_amount): score = Score.get_score(match_count, bonus_match) if score != Score.NONE: score_count[score] += 1 + + just_print(Score, score_count) # 총 당첨 금액 계산 total_prize = sum(score.prize * cnt for score, cnt in score_count.items()) - # 결과 출력 - for score in Score: - if score == Score.NONE: - continue # NONE 등급(낙첨)은 출력하지 않음 - description = f"{score.m_count}개 일치" - if score.b_match == 1: - description += ", 보너스 볼 일치" - print(f"{description} ({format(score.prize, ',d')}원)", end="") - print(f" - {score_count[score]}개") # 수익률 계산 및 출력 revenue_rate = (total_prize / purchase_amount) * 100 @@ -97,15 +102,15 @@ def main(): purchase_amount = input_purchase_amount() # 구입 금액 입력 l_quantity = generate_lotto_quantity(purchase_amount) # 로또 수량 계산산 - issued_l_list = [Lotto.issuance_lotto() for _ in range(l_quantity)] # 로또 발행 - for lotto in issued_l_list: # 발행된 로또 출력 + issu_l_list = [Lotto.issuance_lotto() for _ in range(l_quantity)] # 로또 발행 + for lotto in issu_l_list: # 발행된 로또 출력 print(lotto) lotto = input_winning_numbers() # 당첨 번호 입력 input_bonus_number(lotto) # 보너스 번호 입력 - result_list = lotto.calculate_result(issued_l_list) + result_list = lotto.calculate_result(issu_l_list) print_result(result_list, purchase_amount) From 9e947cc5779fdef29067db9e726999e909e015df Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Sat, 15 Feb 2025 22:48:44 +0900 Subject: [PATCH 17/19] style: Change style --- src/lotto/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lotto/main.py b/src/lotto/main.py index f638488..5a3697a 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -86,7 +86,7 @@ def print_result(result_list, purchase_amount): score = Score.get_score(match_count, bonus_match) if score != Score.NONE: score_count[score] += 1 - + just_print(Score, score_count) # 총 당첨 금액 계산 From 8178407c0e00a5953569619eded108b8cb914938 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Sat, 15 Feb 2025 22:49:14 +0900 Subject: [PATCH 18/19] style: Change style --- src/lotto/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lotto/main.py b/src/lotto/main.py index 5a3697a..01258fd 100644 --- a/src/lotto/main.py +++ b/src/lotto/main.py @@ -92,7 +92,6 @@ def print_result(result_list, purchase_amount): # 총 당첨 금액 계산 total_prize = sum(score.prize * cnt for score, cnt in score_count.items()) - # 수익률 계산 및 출력 revenue_rate = (total_prize / purchase_amount) * 100 print(f"총 수익률은 {revenue_rate:.1f}%입니다.") From ab9302bd0e1ecc3feb4abf0b7704f82b23354fd4 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Sat, 15 Feb 2025 22:53:20 +0900 Subject: [PATCH 19/19] style: Change style --- src/lotto/lotto.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/lotto/lotto.py b/src/lotto/lotto.py index 7e2032c..965933e 100644 --- a/src/lotto/lotto.py +++ b/src/lotto/lotto.py @@ -1,4 +1,3 @@ -from typing import List from enum import Enum import random @@ -8,17 +7,17 @@ class Lotto: - def __init__(self, numbers: List[int] = None): + def __init__(self, numbers: list[int] = None): if numbers is None: # numbers가 주어지지 않으면 자동으로 생성 numbers = self.issuance_lotto() self._validate(numbers) self._numbers = numbers self.bonus_number = int - self.numbers_list = List[list] - self.result_list = List[int] - self.statistics_list = List[list] + self.numbers_list = list[list] + self.result_list = list[int] + self.statistics_list = list[list] - def _validate(self, numbers: List[int]): + def _validate(self, numbers: list[int]): if len(numbers) != LOTTO_SIZE: raise ValueError("[ERROR] 당첨 번호는 6자리입니다.") elif not all(num in LOTTO_NUMBER_RANGE for num in numbers): @@ -47,7 +46,7 @@ def get_numbers(self): """로또 번호 리스트 반환""" return self._numbers - def compare_winning_number(self, numbers: List[int]): + def compare_winning_number(self, numbers: list[int]): """당첨 번호와 발행 번호를 비교""" count = 0 for i in numbers: @@ -55,13 +54,13 @@ def compare_winning_number(self, numbers: List[int]): count += 1 return count - def compare_bonus_number(self, numbers: List[int]): + def compare_bonus_number(self, numbers: list[int]): """보너스 번호와 발행 번호를 비교""" if self.bonus_number in numbers: return 1 return 0 - def calculate_result(self, numbers_list: List[list]): + def calculate_result(self, numbers_list: list[list]): """발행한 로또를 순서대로 당첨 번호, 보너스 번호와 비교""" self.numbers_list = numbers_list self.result_list = [0 for _ in range(len(numbers_list))]