From 0ad080063975b052d532fc09b0a17c187dd8546e Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Tue, 4 Feb 2025 17:28:12 +0900 Subject: [PATCH 01/28] [#1] Add ability to generate 3 different random numbers from 1 to 9 --- .github/workflows/codecov.yml | 23 +++++++++++++++++++++ docs/README.md | 2 ++ src/baseball/main.py | 11 ++++++++++ tests/{test_application.py => test_main.py} | 0 4 files changed, 36 insertions(+) create mode 100644 .github/workflows/codecov.yml rename tests/{test_application.py => test_main.py} (100%) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml new file mode 100644 index 0000000..26548fe --- /dev/null +++ b/.github/workflows/codecov.yml @@ -0,0 +1,23 @@ +name: Run tests and upload coverage +on: + push +jobs: + test: + name: Run tests and collect coverage + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v4 + - name: Install dependencies + run: pip install pytest pytest-cov + - name: Run tests + run: pytest --cov=. --cov-report=xml --cov-branch + - name: Upload results to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + slug: swthewhite/python-baseball diff --git a/docs/README.md b/docs/README.md index e69de29..ba4e8a7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,2 @@ +## 기능 추가 +1. 1에서 9까지 서로 다른 임의의 수 3개 생성 기능 추가 (2025/02/04) \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index cd8d2f3..c6d2d08 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -1,10 +1,21 @@ +import random + +def make_computer_num(): + computer = random.sample(range(1, 9), 3) + return computer + def main(): """ 프로그램의 진입점 함수. 여기에서 전체 프로그램 로직을 시작합니다. """ # 프로그램의 메인 로직을 여기에 구현 + print("숫자 야구 게임을 시작합니다.") + computer = make_computer_num() + print(computer) if __name__ == "__main__": # 프로그램이 직접 실행될 때만 main() 함수를 호출 main() + + \ No newline at end of file diff --git a/tests/test_application.py b/tests/test_main.py similarity index 100% rename from tests/test_application.py rename to tests/test_main.py From e9b990320fb0c2abe219ac6ec2f89c5f1f77882a Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 02:43:54 +0900 Subject: [PATCH 02/28] [#2] Add: ability to ask player to enter 3 numbers --- docs/README.md | 5 ++++- src/baseball/main.py | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index ba4e8a7..ab1a093 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,2 +1,5 @@ ## 기능 추가 -1. 1에서 9까지 서로 다른 임의의 수 3개 생성 기능 추가 (2025/02/04) \ No newline at end of file +1. make_computer_num() +> 1에서 9까지 서로 다른 임의의 수 3개 생성 기능 함수 추가 (2025/02/04) +2. player_input() +> 플레이어에게 3개의 숫자 입력 받는 기능 함수 추가 (2025/02/05) \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index c6d2d08..23ca401 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -4,6 +4,10 @@ def make_computer_num(): computer = random.sample(range(1, 9), 3) return computer +def player_input(): + get_num = list(map(int, input("숫자를 입력해주세요 : "))) + return get_num + def main(): """ 프로그램의 진입점 함수. @@ -13,9 +17,9 @@ def main(): print("숫자 야구 게임을 시작합니다.") computer = make_computer_num() print(computer) + get = player_input() + print(get) if __name__ == "__main__": # 프로그램이 직접 실행될 때만 main() 함수를 호출 main() - - \ No newline at end of file From fa83c50ae2267a36e75f2cc021977bab2afe7ef8 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 02:50:35 +0900 Subject: [PATCH 03/28] [#3] Add: a function to print the results for the numvers entered by the player --- docs/README.md | 4 +++- src/baseball/main.py | 23 +++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index ab1a093..05e737e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,4 +2,6 @@ 1. make_computer_num() > 1에서 9까지 서로 다른 임의의 수 3개 생성 기능 함수 추가 (2025/02/04) 2. player_input() -> 플레이어에게 3개의 숫자 입력 받는 기능 함수 추가 (2025/02/05) \ No newline at end of file +> 플레이어에게 3개의 숫자 입력 받는 기능 함수 추가 (2025/02/05) +3. check_input() +> 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 추가 (2025/02/05) \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index 23ca401..5ed6571 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -8,6 +8,26 @@ def player_input(): get_num = list(map(int, input("숫자를 입력해주세요 : "))) return get_num +def check_input(get, com): + ball, strike = 0, 0 + for i in range(0,3): + if get[i] == com[i]: + strike += 1 + elif get[i] in com: + ball += 1 + else: + continue + if strike == 3: + return "3스트라이크" + elif ball + strike == 0: + return "낫싱" + elif ball == 0: + return "{0}스트라이크".format(strike) + elif strike == 0: + return "{0}볼".format(ball) + else: + return "{0}볼 {1}스트라이크".format(ball, strike) + def main(): """ 프로그램의 진입점 함수. @@ -16,9 +36,8 @@ def main(): # 프로그램의 메인 로직을 여기에 구현 print("숫자 야구 게임을 시작합니다.") computer = make_computer_num() - print(computer) get = player_input() - print(get) + print(check_input(get, computer)) if __name__ == "__main__": # 프로그램이 직접 실행될 때만 main() 함수를 호출 From 29aee5cc392028baa4b37916b8496b27aecfa688 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 03:00:00 +0900 Subject: [PATCH 04/28] [#4] Add: a function that repeats the process from 1 to 3 and the game ends when all 3 numbers are guessed correctly --- docs/README.md | 4 +++- src/baseball/main.py | 12 ++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 05e737e..fa126c1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,4 +4,6 @@ 2. player_input() > 플레이어에게 3개의 숫자 입력 받는 기능 함수 추가 (2025/02/05) 3. check_input() -> 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 추가 (2025/02/05) \ No newline at end of file +> 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 추가 (2025/02/05) +4. loop_check() +> 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 추가 (2025/02/05) \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index 5ed6571..ee1d2dc 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -27,6 +27,13 @@ def check_input(get, com): return "{0}볼".format(ball) else: return "{0}볼 {1}스트라이크".format(ball, strike) + +def loop_check(com): + get = player_input() + result_check_input = check_input(get, com) + print(result_check_input) + if result_check_input != "3스트라이크": + loop_check(com) def main(): """ @@ -36,8 +43,9 @@ def main(): # 프로그램의 메인 로직을 여기에 구현 print("숫자 야구 게임을 시작합니다.") computer = make_computer_num() - get = player_input() - print(check_input(get, computer)) + print(computer) + loop_check(computer) + print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") if __name__ == "__main__": # 프로그램이 직접 실행될 때만 main() 함수를 호출 From 7d16fdcb53b1d9fb1b7fd657d618681c77d31270 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 03:05:44 +0900 Subject: [PATCH 05/28] [#5] Add: a function to restart when you input '1' after ending the game, and completely quit when you input '2' --- docs/README.md | 4 +++- src/baseball/main.py | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/README.md b/docs/README.md index fa126c1..1d34ef0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,4 +6,6 @@ 3. check_input() > 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 추가 (2025/02/05) 4. loop_check() -> 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 추가 (2025/02/05) \ No newline at end of file +> 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 추가 (2025/02/05) +5. restart_baseball() +> 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 추가 (2025/02/05) \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index ee1d2dc..332f884 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -35,17 +35,25 @@ def loop_check(com): if result_check_input != "3스트라이크": loop_check(com) +def restart_baseball(): + print("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.") + user_key = int(input()) + return user_key + def main(): """ 프로그램의 진입점 함수. 여기에서 전체 프로그램 로직을 시작합니다. """ # 프로그램의 메인 로직을 여기에 구현 + restart = 1 print("숫자 야구 게임을 시작합니다.") - computer = make_computer_num() - print(computer) - loop_check(computer) - print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + while restart == 1: + computer = make_computer_num() + print(computer) + loop_check(computer) + print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + restart = restart_baseball() if __name__ == "__main__": # 프로그램이 직접 실행될 때만 main() 함수를 호출 From 63af4f59aa6709465845ab37dd9f99f6810af9ce Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 17:18:02 +0900 Subject: [PATCH 06/28] [#6] Add & Fix: IF and incorrect value is entered, a Value Error occurs and the program terminates --- docs/README.md | 6 +++++- src/baseball/main.py | 51 ++++++++++++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/docs/README.md b/docs/README.md index 1d34ef0..acc5607 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,4 +8,8 @@ 4. loop_check() > 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 추가 (2025/02/05) 5. restart_baseball() -> 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 추가 (2025/02/05) \ No newline at end of file +> 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 추가 (2025/02/05) +6. validate_input() +> 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 추가 (2025/02/05) +7. same_num_check() +> 입력 값에서 중복되는 수를 인식하는 기능 함수 추가 (2025/02/05) \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index 332f884..05f4ce9 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -1,14 +1,26 @@ import random -def make_computer_num(): - computer = random.sample(range(1, 9), 3) +def same_num_check(check_array): # list에서 중복되는 수를 인식하는 기능 함수 + for i in check_array: + if check_array.count(i) != 1: + return 0 + else: + return 1 + +def validate_input(compare_array, want_len): # 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 + if (len(compare_array) != want_len) or (0 in compare_array) or (same_num_check(compare_array) == 0): # 플레이어가 입력한 값이 예상되는 값의 길이가 아니거나, 0이 포함되거나, 중복되는 수가 입력되어도 예외 처리 + raise ValueError + +def make_computer_num(): # random 모듈을 사용하여 임의의 수 생성하는 함수 (요구사항) + computer = random.sample(range(1, 9), 3) # basecode return computer -def player_input(): - get_num = list(map(int, input("숫자를 입력해주세요 : "))) - return get_num +def player_input(): # 플레이어에게 3개의 숫자 입력 받는 기능 함수 + get_array = list(map(int, input("숫자를 입력해주세요 : "))) + validate_input(get_array, 3) + return get_array -def check_input(get, com): +def check_input(get, com): # 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 ball, strike = 0, 0 for i in range(0,3): if get[i] == com[i]: @@ -28,17 +40,23 @@ def check_input(get, com): else: return "{0}볼 {1}스트라이크".format(ball, strike) -def loop_check(com): +def loop_check(com): # 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 get = player_input() result_check_input = check_input(get, com) print(result_check_input) - if result_check_input != "3스트라이크": + if result_check_input == "3스트라이크": # check_input()의 결과가 "3스트라이크"일 경우 게임을 종료하고, 아닐 경우 다시 loop_check() 수해 + print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + return 0 + else: loop_check(com) -def restart_baseball(): +def restart_baseball(): # 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 print("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.") user_key = int(input()) - return user_key + if user_key in [1, 2]: + return user_key + else: # 잘못된 값을 입력할 경우 'ValueError'를 발생 + raise ValueError def main(): """ @@ -46,14 +64,15 @@ def main(): 여기에서 전체 프로그램 로직을 시작합니다. """ # 프로그램의 메인 로직을 여기에 구현 - restart = 1 print("숫자 야구 게임을 시작합니다.") - while restart == 1: - computer = make_computer_num() - print(computer) - loop_check(computer) - print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + while True: + com_num = make_computer_num() + loop_check(com_num) restart = restart_baseball() + if restart == 1: + continue + else: + break if __name__ == "__main__": # 프로그램이 직접 실행될 때만 main() 함수를 호출 From d67269a6ab9f734a263d38398ee0de1d290e9615 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 17:41:07 +0900 Subject: [PATCH 07/28] [#7] Fix: During the random number generation process, errors with number ranges from 1 to 8 have been corrected so that 1 to 9 operates normally --- docs/README.md | 6 +++++- src/baseball/main.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index acc5607..1ef5b93 100644 --- a/docs/README.md +++ b/docs/README.md @@ -12,4 +12,8 @@ 6. validate_input() > 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 추가 (2025/02/05) 7. same_num_check() -> 입력 값에서 중복되는 수를 인식하는 기능 함수 추가 (2025/02/05) \ No newline at end of file +> 입력 값에서 중복되는 수를 인식하는 기능 함수 추가 (2025/02/05) + +## 오류 수정 +1. make_computer_num() 수정 +> 랜덤 숫자 생성 과정에서 숫자 범위가 1~8인 오류 1~9 정상 작동하도록 수정 \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index 05f4ce9..7e13697 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -12,7 +12,7 @@ def validate_input(compare_array, want_len): # 잘못된 값을 입력한 경 raise ValueError def make_computer_num(): # random 모듈을 사용하여 임의의 수 생성하는 함수 (요구사항) - computer = random.sample(range(1, 9), 3) # basecode + computer = random.sample(range(1, 10), 3) # basecode return computer def player_input(): # 플레이어에게 3개의 숫자 입력 받는 기능 함수 From a8002927311eab944c70d44e85c47f6736a30249 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 17:50:46 +0900 Subject: [PATCH 08/28] [#7] Fix: During the random number generation process, errors with number ranges from 1 to 8 have been corrected so that 1 to 9 operates normally --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 1ef5b93..2f3881d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,4 +16,4 @@ ## 오류 수정 1. make_computer_num() 수정 -> 랜덤 숫자 생성 과정에서 숫자 범위가 1~8인 오류 1~9 정상 작동하도록 수정 \ No newline at end of file +> 랜덤 숫자 생성 과정에서 숫자 범위가 1에서 8인 오류 1에서 9 정상 작동하도록 수정 \ No newline at end of file From aec6b51b88654a1d5861c4236ddbe326e7708029 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 19:14:06 +0900 Subject: [PATCH 09/28] [#7] Fix: same_num_check() / An error that only check the first number and returns immediately has been modified to check for duplicates in the entire array. --- docs/README.md | 6 +++++- src/baseball/main.py | 3 +-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 2f3881d..deefedc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,4 +16,8 @@ ## 오류 수정 1. make_computer_num() 수정 -> 랜덤 숫자 생성 과정에서 숫자 범위가 1에서 8인 오류 1에서 9 정상 작동하도록 수정 \ No newline at end of file +> 랜덤 숫자 생성 과정에서 숫자 범위가 1에서 8인 오류 1에서 9 정상 작동하도록 수정 (2025/02/05 +0) +>> random.sample(range(1, ~~9~~10), 3) +2. same_num_check() 수정 +> 첫 번째 숫자만 확인하고 바로 반환하는 오류를 전체 배열의 중복을 확인하도록 수정 (2025/02/05) \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index 7e13697..4e889b2 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -4,8 +4,7 @@ def same_num_check(check_array): # list에서 중복되는 수를 인식하 for i in check_array: if check_array.count(i) != 1: return 0 - else: - return 1 + return 1 def validate_input(compare_array, want_len): # 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 if (len(compare_array) != want_len) or (0 in compare_array) or (same_num_check(compare_array) == 0): # 플레이어가 입력한 값이 예상되는 값의 길이가 아니거나, 0이 포함되거나, 중복되는 수가 입력되어도 예외 처리 From 31f7e1529d96d55441dc0e649bf2ee089efc67b3 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Thu, 6 Feb 2025 00:38:22 +0900 Subject: [PATCH 10/28] =?UTF-8?q?[#8]=20Refactor:=20=EC=9E=AC=EA=B7=80=20?= =?UTF-8?q?=ED=98=B8=EC=B6=9C=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EB=B0=8F=20=EC=97=90=EB=9F=AC=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존 loop_check()에서 재귀 호출을 이용해 게임을 진행해왔던 방식을 while 루프로 변경 (스택 오버플로우 방지) 기존 validate_input()에서 ValueError 발생 시 에러 메시지 추가 (입력 타입, 입력 길이, 중복 유무 3가지로 나눠 에러 메시지 출력) --- docs/README.md | 57 ++++++++++++++++++++++++++++++++++++-------- src/baseball/main.py | 36 ++++++++++++++++------------ 2 files changed, 68 insertions(+), 25 deletions(-) diff --git a/docs/README.md b/docs/README.md index deefedc..aeed71f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,23 +1,60 @@ +## 기능 요구 사항 +- [X] 입력 기능 + - [X] 반복 입력, 1~9 서로다른 3자리의 수 (ex:123) + - [X] 게임이 끝난 경우 재시작/종료를 선택하는 1과 2 중 하나의 수 + +- [X] 출력 기능 + - [X] 게임 시작 문구 "숫자 야구 게임을 시작합니다." + - [X] 숫자 입력 요구 문구 "숫자를 입력해주세요 : " + - [X] 입력한 수에 대한 결과를 볼, 스트라이크 개수로 표시 + - [X] 볼 먼저 출력 (ex: 2볼 1스트라이크) + - [X] 모두 0개이면 "낫싱" + - [X] 일치 시, 게임 종료 안내 문구 "3개의 숫자를 모두 맞히셨습니다! 게임 종료" + - [X] 게임 새로 시작 여부 확인 질문 "게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요." + +- [X] 컴퓨터 기능 + - [X] 1~9의 서로 다른 임의의 수 3개를 선택 + - [X] 입력한 숫자와 비교하여 ball, strike 카운트 + +- [X] 게임 새로 시작 또는 종료 기능 + - [X] 1 입력 시 재시작 + - [X] 2 입력 시 종료 + +- [X] 예외 처리 및 종료 기능 + - [X] 사용자가 잘못된 값을 입력할 경우 ValueError를 발생 후 게임 종료 + - [X] 3자리 수 입력 시 예외 사항 + - [X] 정자가 아닌 것을 포함한 경우 + - [X] 3자리 수가 아닌 경우 + - [X] 0이 포함된 경우 + - [X] 중복 값이 있는 경우 + - [X] 게임 새로 시작 여부 확인 질문 시 + - [X] 1, 2 이외의 값을 입력한 경우 + ## 기능 추가 1. make_computer_num() -> 1에서 9까지 서로 다른 임의의 수 3개 생성 기능 함수 추가 (2025/02/04) +> 1에서 9까지 서로 다른 임의의 수 3개 생성 기능 함수 추가 [\#1] 2. player_input() -> 플레이어에게 3개의 숫자 입력 받는 기능 함수 추가 (2025/02/05) +> 플레이어에게 3개의 숫자 입력 받는 기능 함수 추가 [\#2] 3. check_input() -> 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 추가 (2025/02/05) +> 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 추가 [\#3] 4. loop_check() -> 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 추가 (2025/02/05) +> 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 추가 [\#4] 5. restart_baseball() -> 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 추가 (2025/02/05) +> 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 추가 [\#5] 6. validate_input() -> 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 추가 (2025/02/05) +> 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 추가 [\#6] 7. same_num_check() -> 입력 값에서 중복되는 수를 인식하는 기능 함수 추가 (2025/02/05) +> 입력 값에서 중복되는 수를 인식하는 기능 함수 추가 [\#6] ## 오류 수정 1. make_computer_num() 수정 -> 랜덤 숫자 생성 과정에서 숫자 범위가 1에서 8인 오류 1에서 9 정상 작동하도록 수정 (2025/02/05 -0) +> 랜덤 숫자 생성 과정에서 숫자 범위가 1에서 8인 오류 1에서 9 정상 작동하도록 수정 [\#7] >> random.sample(range(1, ~~9~~10), 3) 2. same_num_check() 수정 -> 첫 번째 숫자만 확인하고 바로 반환하는 오류를 전체 배열의 중복을 확인하도록 수정 (2025/02/05) \ No newline at end of file +> 첫 번째 숫자만 확인하고 바로 반환하는 오류를 전체 배열의 중복을 확인하도록 수정 [\#7] + +## 기능 수정 +1. loop_check() 재귀 호출에서 while 루프로 변경 +> 재귀 호출은 스택 오버플로우를 일으킬 수 있으므로, while 루프로 변경 [\#8] +2. validate_input() ValueError 발생 시 에러 메시지 추가 +> 입력 길이, 입력 숫자, 중복 유무 3가지로로 나눠 에러 메시지 출력 [\#8] \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index 4e889b2..6be849a 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -7,8 +7,12 @@ def same_num_check(check_array): # list에서 중복되는 수를 인식하 return 1 def validate_input(compare_array, want_len): # 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 - if (len(compare_array) != want_len) or (0 in compare_array) or (same_num_check(compare_array) == 0): # 플레이어가 입력한 값이 예상되는 값의 길이가 아니거나, 0이 포함되거나, 중복되는 수가 입력되어도 예외 처리 - raise ValueError + if (len(compare_array) != want_len): # 플레이어가 입력한 값이 예상되는 값의 길이가 아니거나, 0이 포함되거나, 중복되는 수가 입력되어도 예외 처리 + raise ValueError("3개의 숫자를 입력해주세요.") + elif (0 in compare_array): + raise ValueError("1 ~ 9의 숫자만 입력해주세요.") + elif (same_num_check(compare_array) == 0): + raise ValueError("중복되는 수가 있습니다.") def make_computer_num(): # random 모듈을 사용하여 임의의 수 생성하는 함수 (요구사항) computer = random.sample(range(1, 10), 3) # basecode @@ -40,22 +44,24 @@ def check_input(get, com): # 플레이어가 입력한 숫자에 대한 결과 return "{0}볼 {1}스트라이크".format(ball, strike) def loop_check(com): # 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 - get = player_input() - result_check_input = check_input(get, com) - print(result_check_input) - if result_check_input == "3스트라이크": # check_input()의 결과가 "3스트라이크"일 경우 게임을 종료하고, 아닐 경우 다시 loop_check() 수해 - print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") - return 0 - else: - loop_check(com) + while True: + get = player_input() + result_check_input = check_input(get, com) + print(result_check_input) + if result_check_input == "3스트라이크": # check_input()의 결과가 "3스트라이크"일 경우 게임을 종료하고, 아닐 경우 다시 loop_check() 수해 + print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + return 0 def restart_baseball(): # 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 print("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.") - user_key = int(input()) - if user_key in [1, 2]: - return user_key - else: # 잘못된 값을 입력할 경우 'ValueError'를 발생 - raise ValueError + try: + user_key = int(input()) + if user_key in [1, 2]: + return user_key + else: # 잘못된 값을 입력할 경우 'ValueError'를 발생 + raise ValueError("1 또는 2만 입력 가능합니다") + except ValueError: + raise ValueError("올바른 숫자를 입력해주세요 (1 또는 2)") def main(): """ From 578fa97188171bfd3903dacb1880601c3f52dd9b Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Tue, 4 Feb 2025 17:28:12 +0900 Subject: [PATCH 11/28] Add: ability to generate 3 different random numbers from 1 to 9 --- .github/workflows/codecov.yml | 23 +++++++++++++++++++++ docs/README.md | 2 ++ src/baseball/main.py | 11 ++++++++++ tests/{test_application.py => test_main.py} | 0 4 files changed, 36 insertions(+) create mode 100644 .github/workflows/codecov.yml rename tests/{test_application.py => test_main.py} (100%) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml new file mode 100644 index 0000000..26548fe --- /dev/null +++ b/.github/workflows/codecov.yml @@ -0,0 +1,23 @@ +name: Run tests and upload coverage +on: + push +jobs: + test: + name: Run tests and collect coverage + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v4 + - name: Install dependencies + run: pip install pytest pytest-cov + - name: Run tests + run: pytest --cov=. --cov-report=xml --cov-branch + - name: Upload results to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + slug: swthewhite/python-baseball diff --git a/docs/README.md b/docs/README.md index e69de29..ba4e8a7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,2 @@ +## 기능 추가 +1. 1에서 9까지 서로 다른 임의의 수 3개 생성 기능 추가 (2025/02/04) \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index cd8d2f3..c6d2d08 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -1,10 +1,21 @@ +import random + +def make_computer_num(): + computer = random.sample(range(1, 9), 3) + return computer + def main(): """ 프로그램의 진입점 함수. 여기에서 전체 프로그램 로직을 시작합니다. """ # 프로그램의 메인 로직을 여기에 구현 + print("숫자 야구 게임을 시작합니다.") + computer = make_computer_num() + print(computer) if __name__ == "__main__": # 프로그램이 직접 실행될 때만 main() 함수를 호출 main() + + \ No newline at end of file diff --git a/tests/test_application.py b/tests/test_main.py similarity index 100% rename from tests/test_application.py rename to tests/test_main.py From 806c52b10ec53e40408f76246b3ed5125b0c5ad7 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 02:43:54 +0900 Subject: [PATCH 12/28] Add: ability to ask player to enter 3 numbers --- docs/README.md | 5 ++++- src/baseball/main.py | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index ba4e8a7..ab1a093 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,2 +1,5 @@ ## 기능 추가 -1. 1에서 9까지 서로 다른 임의의 수 3개 생성 기능 추가 (2025/02/04) \ No newline at end of file +1. make_computer_num() +> 1에서 9까지 서로 다른 임의의 수 3개 생성 기능 함수 추가 (2025/02/04) +2. player_input() +> 플레이어에게 3개의 숫자 입력 받는 기능 함수 추가 (2025/02/05) \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index c6d2d08..23ca401 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -4,6 +4,10 @@ def make_computer_num(): computer = random.sample(range(1, 9), 3) return computer +def player_input(): + get_num = list(map(int, input("숫자를 입력해주세요 : "))) + return get_num + def main(): """ 프로그램의 진입점 함수. @@ -13,9 +17,9 @@ def main(): print("숫자 야구 게임을 시작합니다.") computer = make_computer_num() print(computer) + get = player_input() + print(get) if __name__ == "__main__": # 프로그램이 직접 실행될 때만 main() 함수를 호출 main() - - \ No newline at end of file From 34cf9649920d493c39898fb915397180107b646d Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 02:50:35 +0900 Subject: [PATCH 13/28] Add: a function to print the results for the numvers entered by the player --- docs/README.md | 4 +++- src/baseball/main.py | 23 +++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index ab1a093..05e737e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,4 +2,6 @@ 1. make_computer_num() > 1에서 9까지 서로 다른 임의의 수 3개 생성 기능 함수 추가 (2025/02/04) 2. player_input() -> 플레이어에게 3개의 숫자 입력 받는 기능 함수 추가 (2025/02/05) \ No newline at end of file +> 플레이어에게 3개의 숫자 입력 받는 기능 함수 추가 (2025/02/05) +3. check_input() +> 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 추가 (2025/02/05) \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index 23ca401..5ed6571 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -8,6 +8,26 @@ def player_input(): get_num = list(map(int, input("숫자를 입력해주세요 : "))) return get_num +def check_input(get, com): + ball, strike = 0, 0 + for i in range(0,3): + if get[i] == com[i]: + strike += 1 + elif get[i] in com: + ball += 1 + else: + continue + if strike == 3: + return "3스트라이크" + elif ball + strike == 0: + return "낫싱" + elif ball == 0: + return "{0}스트라이크".format(strike) + elif strike == 0: + return "{0}볼".format(ball) + else: + return "{0}볼 {1}스트라이크".format(ball, strike) + def main(): """ 프로그램의 진입점 함수. @@ -16,9 +36,8 @@ def main(): # 프로그램의 메인 로직을 여기에 구현 print("숫자 야구 게임을 시작합니다.") computer = make_computer_num() - print(computer) get = player_input() - print(get) + print(check_input(get, computer)) if __name__ == "__main__": # 프로그램이 직접 실행될 때만 main() 함수를 호출 From 7e93e04f92a981d4e6bb5d84803d02d10b9f94ea Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 03:00:00 +0900 Subject: [PATCH 14/28] Add: a function that repeats the process from 1 to 3 and the game ends when all 3 numbers are guessed correctly --- docs/README.md | 4 +++- src/baseball/main.py | 12 ++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 05e737e..fa126c1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,4 +4,6 @@ 2. player_input() > 플레이어에게 3개의 숫자 입력 받는 기능 함수 추가 (2025/02/05) 3. check_input() -> 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 추가 (2025/02/05) \ No newline at end of file +> 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 추가 (2025/02/05) +4. loop_check() +> 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 추가 (2025/02/05) \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index 5ed6571..ee1d2dc 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -27,6 +27,13 @@ def check_input(get, com): return "{0}볼".format(ball) else: return "{0}볼 {1}스트라이크".format(ball, strike) + +def loop_check(com): + get = player_input() + result_check_input = check_input(get, com) + print(result_check_input) + if result_check_input != "3스트라이크": + loop_check(com) def main(): """ @@ -36,8 +43,9 @@ def main(): # 프로그램의 메인 로직을 여기에 구현 print("숫자 야구 게임을 시작합니다.") computer = make_computer_num() - get = player_input() - print(check_input(get, computer)) + print(computer) + loop_check(computer) + print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") if __name__ == "__main__": # 프로그램이 직접 실행될 때만 main() 함수를 호출 From 5d3fa3af7749c8acd87aed370e3f881b230d3fa7 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 03:05:44 +0900 Subject: [PATCH 15/28] Add: a function to restart when you input '1' after ending the game, and completely quit when you input '2' --- docs/README.md | 4 +++- src/baseball/main.py | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/README.md b/docs/README.md index fa126c1..1d34ef0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,4 +6,6 @@ 3. check_input() > 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 추가 (2025/02/05) 4. loop_check() -> 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 추가 (2025/02/05) \ No newline at end of file +> 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 추가 (2025/02/05) +5. restart_baseball() +> 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 추가 (2025/02/05) \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index ee1d2dc..332f884 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -35,17 +35,25 @@ def loop_check(com): if result_check_input != "3스트라이크": loop_check(com) +def restart_baseball(): + print("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.") + user_key = int(input()) + return user_key + def main(): """ 프로그램의 진입점 함수. 여기에서 전체 프로그램 로직을 시작합니다. """ # 프로그램의 메인 로직을 여기에 구현 + restart = 1 print("숫자 야구 게임을 시작합니다.") - computer = make_computer_num() - print(computer) - loop_check(computer) - print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + while restart == 1: + computer = make_computer_num() + print(computer) + loop_check(computer) + print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + restart = restart_baseball() if __name__ == "__main__": # 프로그램이 직접 실행될 때만 main() 함수를 호출 From 5acd13a5d2bebe137fbe372147fa9a0042678501 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 17:18:02 +0900 Subject: [PATCH 16/28] Add & Fix: IF and incorrect value is entered, a Value Error occurs and the program terminates --- docs/README.md | 6 +++++- src/baseball/main.py | 51 ++++++++++++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/docs/README.md b/docs/README.md index 1d34ef0..acc5607 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,4 +8,8 @@ 4. loop_check() > 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 추가 (2025/02/05) 5. restart_baseball() -> 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 추가 (2025/02/05) \ No newline at end of file +> 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 추가 (2025/02/05) +6. validate_input() +> 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 추가 (2025/02/05) +7. same_num_check() +> 입력 값에서 중복되는 수를 인식하는 기능 함수 추가 (2025/02/05) \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index 332f884..05f4ce9 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -1,14 +1,26 @@ import random -def make_computer_num(): - computer = random.sample(range(1, 9), 3) +def same_num_check(check_array): # list에서 중복되는 수를 인식하는 기능 함수 + for i in check_array: + if check_array.count(i) != 1: + return 0 + else: + return 1 + +def validate_input(compare_array, want_len): # 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 + if (len(compare_array) != want_len) or (0 in compare_array) or (same_num_check(compare_array) == 0): # 플레이어가 입력한 값이 예상되는 값의 길이가 아니거나, 0이 포함되거나, 중복되는 수가 입력되어도 예외 처리 + raise ValueError + +def make_computer_num(): # random 모듈을 사용하여 임의의 수 생성하는 함수 (요구사항) + computer = random.sample(range(1, 9), 3) # basecode return computer -def player_input(): - get_num = list(map(int, input("숫자를 입력해주세요 : "))) - return get_num +def player_input(): # 플레이어에게 3개의 숫자 입력 받는 기능 함수 + get_array = list(map(int, input("숫자를 입력해주세요 : "))) + validate_input(get_array, 3) + return get_array -def check_input(get, com): +def check_input(get, com): # 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 ball, strike = 0, 0 for i in range(0,3): if get[i] == com[i]: @@ -28,17 +40,23 @@ def check_input(get, com): else: return "{0}볼 {1}스트라이크".format(ball, strike) -def loop_check(com): +def loop_check(com): # 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 get = player_input() result_check_input = check_input(get, com) print(result_check_input) - if result_check_input != "3스트라이크": + if result_check_input == "3스트라이크": # check_input()의 결과가 "3스트라이크"일 경우 게임을 종료하고, 아닐 경우 다시 loop_check() 수해 + print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + return 0 + else: loop_check(com) -def restart_baseball(): +def restart_baseball(): # 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 print("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.") user_key = int(input()) - return user_key + if user_key in [1, 2]: + return user_key + else: # 잘못된 값을 입력할 경우 'ValueError'를 발생 + raise ValueError def main(): """ @@ -46,14 +64,15 @@ def main(): 여기에서 전체 프로그램 로직을 시작합니다. """ # 프로그램의 메인 로직을 여기에 구현 - restart = 1 print("숫자 야구 게임을 시작합니다.") - while restart == 1: - computer = make_computer_num() - print(computer) - loop_check(computer) - print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + while True: + com_num = make_computer_num() + loop_check(com_num) restart = restart_baseball() + if restart == 1: + continue + else: + break if __name__ == "__main__": # 프로그램이 직접 실행될 때만 main() 함수를 호출 From 78c1da0df1b2d10542c3791476eb283bde9eebc3 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 17:41:07 +0900 Subject: [PATCH 17/28] Fix: During the random number generation process, errors with number ranges from 1 to 8 have been corrected so that 1 to 9 operates normally --- docs/README.md | 6 +++++- src/baseball/main.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index acc5607..1ef5b93 100644 --- a/docs/README.md +++ b/docs/README.md @@ -12,4 +12,8 @@ 6. validate_input() > 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 추가 (2025/02/05) 7. same_num_check() -> 입력 값에서 중복되는 수를 인식하는 기능 함수 추가 (2025/02/05) \ No newline at end of file +> 입력 값에서 중복되는 수를 인식하는 기능 함수 추가 (2025/02/05) + +## 오류 수정 +1. make_computer_num() 수정 +> 랜덤 숫자 생성 과정에서 숫자 범위가 1~8인 오류 1~9 정상 작동하도록 수정 \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index 05f4ce9..7e13697 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -12,7 +12,7 @@ def validate_input(compare_array, want_len): # 잘못된 값을 입력한 경 raise ValueError def make_computer_num(): # random 모듈을 사용하여 임의의 수 생성하는 함수 (요구사항) - computer = random.sample(range(1, 9), 3) # basecode + computer = random.sample(range(1, 10), 3) # basecode return computer def player_input(): # 플레이어에게 3개의 숫자 입력 받는 기능 함수 From da99498bae71e0c81ccf1c73a629e8d3f05f4721 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 17:50:46 +0900 Subject: [PATCH 18/28] Fix: During the random number generation process, errors with number ranges from 1 to 8 have been corrected so that 1 to 9 operates normally --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 1ef5b93..2f3881d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,4 +16,4 @@ ## 오류 수정 1. make_computer_num() 수정 -> 랜덤 숫자 생성 과정에서 숫자 범위가 1~8인 오류 1~9 정상 작동하도록 수정 \ No newline at end of file +> 랜덤 숫자 생성 과정에서 숫자 범위가 1에서 8인 오류 1에서 9 정상 작동하도록 수정 \ No newline at end of file From 0745578f7db593cc79a51605ce1e77773a2f5ef3 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Wed, 5 Feb 2025 19:14:06 +0900 Subject: [PATCH 19/28] Fix: same_num_check() / An error that only check the first number and returns immediately has been modified to check for duplicates in the entire array. --- docs/README.md | 6 +++++- src/baseball/main.py | 3 +-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 2f3881d..deefedc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,4 +16,8 @@ ## 오류 수정 1. make_computer_num() 수정 -> 랜덤 숫자 생성 과정에서 숫자 범위가 1에서 8인 오류 1에서 9 정상 작동하도록 수정 \ No newline at end of file +> 랜덤 숫자 생성 과정에서 숫자 범위가 1에서 8인 오류 1에서 9 정상 작동하도록 수정 (2025/02/05 +0) +>> random.sample(range(1, ~~9~~10), 3) +2. same_num_check() 수정 +> 첫 번째 숫자만 확인하고 바로 반환하는 오류를 전체 배열의 중복을 확인하도록 수정 (2025/02/05) \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index 7e13697..4e889b2 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -4,8 +4,7 @@ def same_num_check(check_array): # list에서 중복되는 수를 인식하 for i in check_array: if check_array.count(i) != 1: return 0 - else: - return 1 + return 1 def validate_input(compare_array, want_len): # 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 if (len(compare_array) != want_len) or (0 in compare_array) or (same_num_check(compare_array) == 0): # 플레이어가 입력한 값이 예상되는 값의 길이가 아니거나, 0이 포함되거나, 중복되는 수가 입력되어도 예외 처리 From d2ba4deda0f0e8ae8da139d597ad074482d954e8 Mon Sep 17 00:00:00 2001 From: SW Baek Date: Tue, 4 Feb 2025 19:14:05 +0900 Subject: [PATCH 20/28] [#0] change actions yml `push` -> `pull_request` --- .github/workflows/codecov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 26548fe..af07329 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -1,6 +1,6 @@ name: Run tests and upload coverage on: - push + pull_request jobs: test: name: Run tests and collect coverage From e7a0b7f43f26b1b1e080915bc00d0e0a56092e2e Mon Sep 17 00:00:00 2001 From: SW Baek Date: Wed, 5 Feb 2025 00:01:33 +0900 Subject: [PATCH 21/28] [#0] fix actions yml's target slug --- .github/workflows/codecov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index af07329..3482b06 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -20,4 +20,4 @@ jobs: uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} - slug: swthewhite/python-baseball + slug: swthewhite-lab/python-baseball From 2cbddfb8b87eace2cfd0a403960a0eb7735f602a Mon Sep 17 00:00:00 2001 From: SW Baek Date: Wed, 5 Feb 2025 00:17:54 +0900 Subject: [PATCH 22/28] [#0] use context in actions yml's slug --- .github/workflows/codecov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 3482b06..7db31c9 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -20,4 +20,4 @@ jobs: uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} - slug: swthewhite-lab/python-baseball + slug: ${{ github.repository }} From 2a66eb83789fb71a2d444aa6ed5fdb813ed59db1 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Thu, 6 Feb 2025 00:38:22 +0900 Subject: [PATCH 23/28] =?UTF-8?q?Refactor:=20=EC=9E=AC=EA=B7=80=20?= =?UTF-8?q?=ED=98=B8=EC=B6=9C=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EB=B0=8F=20=EC=97=90=EB=9F=AC=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존 loop_check()에서 재귀 호출을 이용해 게임을 진행해왔던 방식을 while 루프로 변경 (스택 오버플로우 방지) 기존 validate_input()에서 ValueError 발생 시 에러 메시지 추가 (입력 타입, 입력 길이, 중복 유무 3가지로 나눠 에러 메시지 출력) --- docs/README.md | 57 ++++++++++++++++++++++++++++++++++++-------- src/baseball/main.py | 36 ++++++++++++++++------------ 2 files changed, 68 insertions(+), 25 deletions(-) diff --git a/docs/README.md b/docs/README.md index deefedc..aeed71f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,23 +1,60 @@ +## 기능 요구 사항 +- [X] 입력 기능 + - [X] 반복 입력, 1~9 서로다른 3자리의 수 (ex:123) + - [X] 게임이 끝난 경우 재시작/종료를 선택하는 1과 2 중 하나의 수 + +- [X] 출력 기능 + - [X] 게임 시작 문구 "숫자 야구 게임을 시작합니다." + - [X] 숫자 입력 요구 문구 "숫자를 입력해주세요 : " + - [X] 입력한 수에 대한 결과를 볼, 스트라이크 개수로 표시 + - [X] 볼 먼저 출력 (ex: 2볼 1스트라이크) + - [X] 모두 0개이면 "낫싱" + - [X] 일치 시, 게임 종료 안내 문구 "3개의 숫자를 모두 맞히셨습니다! 게임 종료" + - [X] 게임 새로 시작 여부 확인 질문 "게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요." + +- [X] 컴퓨터 기능 + - [X] 1~9의 서로 다른 임의의 수 3개를 선택 + - [X] 입력한 숫자와 비교하여 ball, strike 카운트 + +- [X] 게임 새로 시작 또는 종료 기능 + - [X] 1 입력 시 재시작 + - [X] 2 입력 시 종료 + +- [X] 예외 처리 및 종료 기능 + - [X] 사용자가 잘못된 값을 입력할 경우 ValueError를 발생 후 게임 종료 + - [X] 3자리 수 입력 시 예외 사항 + - [X] 정자가 아닌 것을 포함한 경우 + - [X] 3자리 수가 아닌 경우 + - [X] 0이 포함된 경우 + - [X] 중복 값이 있는 경우 + - [X] 게임 새로 시작 여부 확인 질문 시 + - [X] 1, 2 이외의 값을 입력한 경우 + ## 기능 추가 1. make_computer_num() -> 1에서 9까지 서로 다른 임의의 수 3개 생성 기능 함수 추가 (2025/02/04) +> 1에서 9까지 서로 다른 임의의 수 3개 생성 기능 함수 추가 [\#1] 2. player_input() -> 플레이어에게 3개의 숫자 입력 받는 기능 함수 추가 (2025/02/05) +> 플레이어에게 3개의 숫자 입력 받는 기능 함수 추가 [\#2] 3. check_input() -> 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 추가 (2025/02/05) +> 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 추가 [\#3] 4. loop_check() -> 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 추가 (2025/02/05) +> 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 추가 [\#4] 5. restart_baseball() -> 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 추가 (2025/02/05) +> 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 추가 [\#5] 6. validate_input() -> 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 추가 (2025/02/05) +> 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 추가 [\#6] 7. same_num_check() -> 입력 값에서 중복되는 수를 인식하는 기능 함수 추가 (2025/02/05) +> 입력 값에서 중복되는 수를 인식하는 기능 함수 추가 [\#6] ## 오류 수정 1. make_computer_num() 수정 -> 랜덤 숫자 생성 과정에서 숫자 범위가 1에서 8인 오류 1에서 9 정상 작동하도록 수정 (2025/02/05 -0) +> 랜덤 숫자 생성 과정에서 숫자 범위가 1에서 8인 오류 1에서 9 정상 작동하도록 수정 [\#7] >> random.sample(range(1, ~~9~~10), 3) 2. same_num_check() 수정 -> 첫 번째 숫자만 확인하고 바로 반환하는 오류를 전체 배열의 중복을 확인하도록 수정 (2025/02/05) \ No newline at end of file +> 첫 번째 숫자만 확인하고 바로 반환하는 오류를 전체 배열의 중복을 확인하도록 수정 [\#7] + +## 기능 수정 +1. loop_check() 재귀 호출에서 while 루프로 변경 +> 재귀 호출은 스택 오버플로우를 일으킬 수 있으므로, while 루프로 변경 [\#8] +2. validate_input() ValueError 발생 시 에러 메시지 추가 +> 입력 길이, 입력 숫자, 중복 유무 3가지로로 나눠 에러 메시지 출력 [\#8] \ No newline at end of file diff --git a/src/baseball/main.py b/src/baseball/main.py index 4e889b2..6be849a 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -7,8 +7,12 @@ def same_num_check(check_array): # list에서 중복되는 수를 인식하 return 1 def validate_input(compare_array, want_len): # 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 - if (len(compare_array) != want_len) or (0 in compare_array) or (same_num_check(compare_array) == 0): # 플레이어가 입력한 값이 예상되는 값의 길이가 아니거나, 0이 포함되거나, 중복되는 수가 입력되어도 예외 처리 - raise ValueError + if (len(compare_array) != want_len): # 플레이어가 입력한 값이 예상되는 값의 길이가 아니거나, 0이 포함되거나, 중복되는 수가 입력되어도 예외 처리 + raise ValueError("3개의 숫자를 입력해주세요.") + elif (0 in compare_array): + raise ValueError("1 ~ 9의 숫자만 입력해주세요.") + elif (same_num_check(compare_array) == 0): + raise ValueError("중복되는 수가 있습니다.") def make_computer_num(): # random 모듈을 사용하여 임의의 수 생성하는 함수 (요구사항) computer = random.sample(range(1, 10), 3) # basecode @@ -40,22 +44,24 @@ def check_input(get, com): # 플레이어가 입력한 숫자에 대한 결과 return "{0}볼 {1}스트라이크".format(ball, strike) def loop_check(com): # 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 - get = player_input() - result_check_input = check_input(get, com) - print(result_check_input) - if result_check_input == "3스트라이크": # check_input()의 결과가 "3스트라이크"일 경우 게임을 종료하고, 아닐 경우 다시 loop_check() 수해 - print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") - return 0 - else: - loop_check(com) + while True: + get = player_input() + result_check_input = check_input(get, com) + print(result_check_input) + if result_check_input == "3스트라이크": # check_input()의 결과가 "3스트라이크"일 경우 게임을 종료하고, 아닐 경우 다시 loop_check() 수해 + print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + return 0 def restart_baseball(): # 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 print("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.") - user_key = int(input()) - if user_key in [1, 2]: - return user_key - else: # 잘못된 값을 입력할 경우 'ValueError'를 발생 - raise ValueError + try: + user_key = int(input()) + if user_key in [1, 2]: + return user_key + else: # 잘못된 값을 입력할 경우 'ValueError'를 발생 + raise ValueError("1 또는 2만 입력 가능합니다") + except ValueError: + raise ValueError("올바른 숫자를 입력해주세요 (1 또는 2)") def main(): """ From 6b89471efc311e2065bbb84332e38c4dd19ef811 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Fri, 7 Feb 2025 16:45:52 +0900 Subject: [PATCH 24/28] =?UTF-8?q?Test:=20ValueError=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=99=80=20=EC=9E=85=EB=A0=A5=20=EA=B2=BD=EC=9A=B0?= =?UTF-8?q?=EC=9D=98=20=EC=88=98=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 예외에서 테스트되지 않은 테스트 케이스 추가 입력값 경우의 수에서 부족한 테스트 케이스 추가 --- tests/test_main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_main.py b/tests/test_main.py index 81a176e..225e276 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -8,19 +8,19 @@ def test_게임종료_후_재시작(capsys): # 랜덤값 임의 정의 with patch('random.sample', side_effect=[[1, 3, 5], [5, 8, 9]]): # 입력값 모의 처리 - with patch('builtins.input', side_effect=["246", "135", "1", "597", "589", "2"]): + with patch('builtins.input', side_effect=["246", "135", "1", "512", "894", "597", "589", "2"]): main() # 출력값 캡처 캡처된_출력 = capsys.readouterr().out # 결과 검증 - assert all(예상_출력 in 캡처된_출력 for 예상_출력 in ["낫싱", "3스트라이크", "1볼 1스트라이크", "3스트라이크", "게임 종료"]) + assert all(예상_출력 in 캡처된_출력 for 예상_출력 in ["낫싱", "3스트라이크", "1볼 1스트라이크", "1스트라이크", "2볼", "3스트라이크", "게임 종료"]) # 예외 테스트 def test_예외_테스트(): with pytest.raises(ValueError): # 잘못된 입력 처리 - with patch('builtins.input', side_effect=["1234"]): + with patch('builtins.input', side_effect=["1234", "012", "233", "3", "ㄱ"]): main() From d19d0b976388fbf4ddcc4c358267ff795ba6534c Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Fri, 7 Feb 2025 19:47:49 +0900 Subject: [PATCH 25/28] =?UTF-8?q?Update:=20Improve=20input=20validation=20?= =?UTF-8?q?and=20error=20handling=ED=95=A8=20Comment:=20Add=20comments=20a?= =?UTF-8?q?nd=20refactor=20code=20for=20better=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit validate_input()에서 restart_baseball() 오류 처리도 함께 할 수 있도록 변경 "Criteria"에서 "Data" 비교 기준을 달리하여 범용성을 높임 각 함수의 역할에 대한 간단한 설명을 추가하였고, 코드의 구체적인 기능에 대해 주석을 닮 함수의 입력 값과 변환 값에 대한 설명을 추가하여, 코드의 의도를 쉽게 파악할 수 있도록 --- src/baseball/main.py | 134 +++++++++++++++++++++++++++++-------------- 1 file changed, 91 insertions(+), 43 deletions(-) diff --git a/src/baseball/main.py b/src/baseball/main.py index 6be849a..78d555d 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -1,67 +1,115 @@ import random -def same_num_check(check_array): # list에서 중복되는 수를 인식하는 기능 함수 +def same_num_check(check_array): + """ + 리스트에서 중복된 숫자가 있는지 확인하는 함수. + 중복된 숫자가 있으면 1을 반환하고, 없으면 0을 반환. + """ for i in check_array: if check_array.count(i) != 1: - return 0 - return 1 + return 1 + return 0 + +def validate_input(Data, Criteria): + """ + 사용자가 입력한 값을 검증하는 함수. + - Data: 사용자가 입력한 값 + - Criteria: 예상하는 값의 조건 (정수 또는 리스트 형식() + 잘못된 값이 입력되면 ValueError를 발생시킴. + """ + try: + int(Data) # Data가 int 형식인지 확인 + except ValueError as e: + if "invalid literal for int()" in str(e): # int로 변환할 수 없는 값일 경우 + raise ValueError("숫자만 입력해주세요.") # 숫자가 아닌 값 입력시 예외 처리 + + if type(Criteria) == int: # Criteria가 int일 경우, player_input()에서 사용 + compare_array = list(map(int, Data)) # Data를 정수형 리스트로 변환 + + # 플레이어가 입력한 값이 예상되는 값의 길이가 아닐 경우 예외 처리 + if (len(compare_array) != Criteria): + raise ValueError("3개의 숫자를 입력해주세요.") + + # 중복된 숫자가 있을 경우 예외 처리 + if (same_num_check(compare_array) == 1): + raise ValueError("숫자 중복 없이 입력해주세요.") + + # 1~9의 숫자가 아닌 0이 포함된 경우 예외 처리 + if (0 in compare_array): + raise ValueError("1 ~ 9의 숫자만 입력해주세요.") + + return compare_array # 입력이 정상이면 정수 리스트 변환 + + elif type(Criteria) == list: # Criteria가 list일 경우, restart_baseball()에서 사용 + # Data가 Criteria에 포함되지 않은 값일 경우 예외 처리 + if int(Data) not in Criteria: + raise ValueError("숫자 1 또는 2만 입력해주세요.") -def validate_input(compare_array, want_len): # 잘못된 값을 입력한 경우 ValueError가 발생하여 프로그램을 종료하는 기능 함수 - if (len(compare_array) != want_len): # 플레이어가 입력한 값이 예상되는 값의 길이가 아니거나, 0이 포함되거나, 중복되는 수가 입력되어도 예외 처리 - raise ValueError("3개의 숫자를 입력해주세요.") - elif (0 in compare_array): - raise ValueError("1 ~ 9의 숫자만 입력해주세요.") - elif (same_num_check(compare_array) == 0): - raise ValueError("중복되는 수가 있습니다.") -def make_computer_num(): # random 모듈을 사용하여 임의의 수 생성하는 함수 (요구사항) - computer = random.sample(range(1, 10), 3) # basecode +def make_computer_num(): + """ + 컴퓨터가 랜덤으로 3개의 숫자를 생성하는 함수. + 1에서 9까지의 숫자 중에서 중복 없이 3개를 뽑음. + """ + computer = random.sample(range(1, 10), 3) # 1~9 사이에서 중복 없이 3개 숫자 선택 return computer -def player_input(): # 플레이어에게 3개의 숫자 입력 받는 기능 함수 - get_array = list(map(int, input("숫자를 입력해주세요 : "))) - validate_input(get_array, 3) +def player_input(): + """ + 플레이어에게 숫자 3개를 입력받는 함수. + 입력 값 검증 후 정상적인 값을 반환. + """ + get_array = validate_input(input("숫자를 입력해주세요 : "), 3) # 입력 값 검증 return get_array -def check_input(get, com): # 플레이어가 입력한 숫자에 대한 결과를 출력하는 함수 +def check_input(get, com): + """ + 플레이어가 입력한 값과 컴퓨터가 생성한 값을 비교하여 결과를 출력하는 함수. + - get: 플레이어가 입력한 숫자 리스트 + - com: 컴퓨터가 생성한 숫자 리스트 + 결과에 따라 '스트라이크', '볼', '낫싱'을 반환. + """ ball, strike = 0, 0 for i in range(0,3): - if get[i] == com[i]: + if get[i] == com[i]: # 숫자와 위치가 맞으면 스트라이크 strike += 1 - elif get[i] in com: + elif get[i] in com: # 숫자는 맞지만 위치가 다르면 볼 ball += 1 else: continue if strike == 3: - return "3스트라이크" + return "3스트라이크" # 3개의 숫자가 모두 맞으면 3스트라이크 elif ball + strike == 0: - return "낫싱" + return "낫싱" # 맞는 숫자가 없으면 낫싱 elif ball == 0: - return "{0}스트라이크".format(strike) + return "{0}스트라이크".format(strike) # 볼은 없고 스트라이크만 있는 경우 elif strike == 0: - return "{0}볼".format(ball) + return "{0}볼".format(ball) # 스트라이크는 없고 볼만 있는 경우 else: - return "{0}볼 {1}스트라이크".format(ball, strike) + return "{0}볼 {1}스트라이크".format(ball, strike) # 볼과 스트라이크가 모두 있는 경우 -def loop_check(com): # 1에서 3까지의 과정을 반복해 3개의 숫자를 모두 맞히면 게임이 종료되는 기능 함수 +def loop_check(com): + """ + 게임을 반복하여 진행하는 함수. + 플레이어가 3개의 숫자를 모두 맞힐 때까지 반복. + """ while True: - get = player_input() - result_check_input = check_input(get, com) - print(result_check_input) - if result_check_input == "3스트라이크": # check_input()의 결과가 "3스트라이크"일 경우 게임을 종료하고, 아닐 경우 다시 loop_check() 수해 + get = player_input() # 플레이어 입력 받기 + result_check_input = check_input(get, com) # 입력한 값과 컴퓨터 값 비교 + print(result_check_input) # 결과 출력 + if result_check_input == "3스트라이크": # 3스트라이크면 게임 종료 print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") - return 0 + return 0 # 게임 종료 -def restart_baseball(): # 게임 종료 후 '1' 입력시 다시 시작, '2' 입력시 완전히 종료하는 기능 함수 +def restart_baseball(): + """ + 게임 종료 후 '1'을 입력하면 게임을 새로 시작하고, '2'를 입력하면 종료하는 함수. + """ print("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.") - try: - user_key = int(input()) - if user_key in [1, 2]: - return user_key - else: # 잘못된 값을 입력할 경우 'ValueError'를 발생 - raise ValueError("1 또는 2만 입력 가능합니다") - except ValueError: - raise ValueError("올바른 숫자를 입력해주세요 (1 또는 2)") + restart_input = input() # 플레이어 입력 받기 + validate_input(restart_input, [1, 2]) # 입력 값 검증 + return int(restart_input) + def main(): """ @@ -71,12 +119,12 @@ def main(): # 프로그램의 메인 로직을 여기에 구현 print("숫자 야구 게임을 시작합니다.") while True: - com_num = make_computer_num() - loop_check(com_num) - restart = restart_baseball() - if restart == 1: + com_num = make_computer_num() # 컴퓨터가 생성한 숫자 + loop_check(com_num) # 게임 진행 + restart = restart_baseball() # 게임 재시작 여부 확인 + if restart == 1: # 1을 입력하면 게임 재시작 continue - else: + else: # 2를 입력하면 게임 종료 break if __name__ == "__main__": From d83709b8f35c2a0b34bb7eee1dd646ff1db8e8f2 Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Fri, 7 Feb 2025 20:11:18 +0900 Subject: [PATCH 26/28] =?UTF-8?q?Refactor:=20=EA=B0=80=EB=8F=85=EC=84=B1?= =?UTF-8?q?=20=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EA=B0=84=EC=86=8C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit same_num_check() set을 사용하여 성능 개선 및 Boolean 값을 반환 is_number() 분리하여 가독성 개선 check_input() 결과 문자열 생성 로직으로 코드 간소화 --- src/baseball/main.py | 62 ++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/src/baseball/main.py b/src/baseball/main.py index 78d555d..ada1fbc 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -5,10 +5,17 @@ def same_num_check(check_array): 리스트에서 중복된 숫자가 있는지 확인하는 함수. 중복된 숫자가 있으면 1을 반환하고, 없으면 0을 반환. """ - for i in check_array: - if check_array.count(i) != 1: - return 1 - return 0 + return len(set(check_array)) != len(check_array) + +def is_number (Data): + """ + Data가 숫자인지 확인하는 함수. + 숫자가 아니면 ValueError를 발생시킴. + """ + try: + int(Data) # Data가 int 형식인지 확인 + except ValueError: + raise ValueError("숫자만 입력해주세요.") # 숫자가 아닌 값 입력시 예외 처리 def validate_input(Data, Criteria): """ @@ -17,13 +24,10 @@ def validate_input(Data, Criteria): - Criteria: 예상하는 값의 조건 (정수 또는 리스트 형식() 잘못된 값이 입력되면 ValueError를 발생시킴. """ - try: - int(Data) # Data가 int 형식인지 확인 - except ValueError as e: - if "invalid literal for int()" in str(e): # int로 변환할 수 없는 값일 경우 - raise ValueError("숫자만 입력해주세요.") # 숫자가 아닌 값 입력시 예외 처리 - - if type(Criteria) == int: # Criteria가 int일 경우, player_input()에서 사용 + # 숫자 확인 + is_number(Data) + + if isinstance(Criteria, int): # Criteria가 int일 경우, player_input()에서 사용 compare_array = list(map(int, Data)) # Data를 정수형 리스트로 변환 # 플레이어가 입력한 값이 예상되는 값의 길이가 아닐 경우 예외 처리 @@ -40,7 +44,7 @@ def validate_input(Data, Criteria): return compare_array # 입력이 정상이면 정수 리스트 변환 - elif type(Criteria) == list: # Criteria가 list일 경우, restart_baseball()에서 사용 + elif isinstance(Criteria, list): # Criteria가 list일 경우, restart_baseball()에서 사용 # Data가 Criteria에 포함되지 않은 값일 경우 예외 처리 if int(Data) not in Criteria: raise ValueError("숫자 1 또는 2만 입력해주세요.") @@ -69,24 +73,36 @@ def check_input(get, com): - com: 컴퓨터가 생성한 숫자 리스트 결과에 따라 '스트라이크', '볼', '낫싱'을 반환. """ - ball, strike = 0, 0 - for i in range(0,3): + ball, strike = 0, 0 # 볼과 스트라이크를 카운트할 변수 초기화 + + for i in range(0,3): # 입력된 숫자와 컴퓨터가 생성한 숫자를 비교 if get[i] == com[i]: # 숫자와 위치가 맞으면 스트라이크 strike += 1 elif get[i] in com: # 숫자는 맞지만 위치가 다르면 볼 ball += 1 else: - continue + continue # 숫자도 위치도 맞지 않으면 아무것도 하지 않음 + + # 스트라이크가 3이면 3스트라이크 반환 if strike == 3: - return "3스트라이크" # 3개의 숫자가 모두 맞으면 3스트라이크 + return "3스트라이크" + + # 스트라이크와 볼이 모두 없으면 낫싱 반환 elif ball + strike == 0: - return "낫싱" # 맞는 숫자가 없으면 낫싱 - elif ball == 0: - return "{0}스트라이크".format(strike) # 볼은 없고 스트라이크만 있는 경우 - elif strike == 0: - return "{0}볼".format(ball) # 스트라이크는 없고 볼만 있는 경우 - else: - return "{0}볼 {1}스트라이크".format(ball, strike) # 볼과 스트라이크가 모두 있는 경우 + return "낫싱" + + result = [] # 결과를 저장할 리스트 + + # 볼이 하나 이상 있으면 볼 정보 추가 + if ball > 0: + result.append(f"{ball}볼") + + # 스트라이크가 하나 이상 있으면 스트라이크 정보 추가 + if strike > 0: + result.append(f"{strike}스트라이크") + + # 볼과 스트라이크가 있을 경우 공백으로 구분해서 반환 + return " ".join(result) def loop_check(com): """ From 68769651dd8161e6c9da247e31c6ec6d0595dc9e Mon Sep 17 00:00:00 2001 From: AI-WonYJ Date: Fri, 7 Feb 2025 20:49:25 +0900 Subject: [PATCH 27/28] =?UTF-8?q?Refactor:=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20docstring=20?= =?UTF-8?q?=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 예외처리 시 원본 예외 컨텍스트를 보존하기 위해 raise ... from e 패턴 사용 validate_input() docstring에서 예외 경우 포함 make_computer_num() 코드 개선 --- src/baseball/main.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/baseball/main.py b/src/baseball/main.py index ada1fbc..8ea727d 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -14,15 +14,20 @@ def is_number (Data): """ try: int(Data) # Data가 int 형식인지 확인 - except ValueError: - raise ValueError("숫자만 입력해주세요.") # 숫자가 아닌 값 입력시 예외 처리 + except ValueError as e: + raise ValueError("숫자만 입력해주세요.") from e # 숫자가 아닌 값 입력시 예외 처리 def validate_input(Data, Criteria): """ 사용자가 입력한 값을 검증하는 함수. - Data: 사용자가 입력한 값 - - Criteria: 예상하는 값의 조건 (정수 또는 리스트 형식() - 잘못된 값이 입력되면 ValueError를 발생시킴. + - Criteria: 예상하는 값의 조건 (정수 또는 리스트 형식) + 다음과 같은 경우 ValueError를 발생시킴: + - 입력 값이 숫자가 아닌 경우 + - 3개의 숫자가 아닌 경우 + - 중복된 숫자가 포함된 경우 + - 0이 포함된 경우 + - 입력 값이 1 또는 2가 아닌 경우 (재시작 시) """ # 숫자 확인 is_number(Data) @@ -93,13 +98,8 @@ def check_input(get, com): result = [] # 결과를 저장할 리스트 - # 볼이 하나 이상 있으면 볼 정보 추가 - if ball > 0: - result.append(f"{ball}볼") - - # 스트라이크가 하나 이상 있으면 스트라이크 정보 추가 - if strike > 0: - result.append(f"{strike}스트라이크") + result.extend([f"{ball}볼" for _ in [1] if ball > 0]) # 볼이 하나 이상 있으면 볼 정보 추가 + result.extend([f"{strike}스트라이크" for _ in [1] if strike > 0]) # 스트라이크가 하나 이상 있으면 스트라이크 정보 추가 # 볼과 스트라이크가 있을 경우 공백으로 구분해서 반환 return " ".join(result) From 8ca20d2a8f6ff8ec00f32473339d66f62e4f80cc Mon Sep 17 00:00:00 2001 From: YoungJin <101448204+AI-WonYJ@users.noreply.github.com> Date: Mon, 24 Mar 2025 19:56:50 +0900 Subject: [PATCH 28/28] Update main.py --- src/baseball/main.py | 144 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/src/baseball/main.py b/src/baseball/main.py index cd8d2f3..8fb72d1 100644 --- a/src/baseball/main.py +++ b/src/baseball/main.py @@ -1,9 +1,153 @@ +import random + +def same_num_check(check_array): + """ + 리스트에서 중복된 숫자가 있는지 확인하는 함수. + 중복된 숫자가 있으면 1을 반환하고, 없으면 0을 반환. + """ + return len(set(check_array)) != len(check_array) + + +def is_number (Data): + """ + Data가 숫자인지 확인하는 함수. + 숫자가 아니면 ValueError를 발생시킴. + """ + try: + int(Data) # Data가 int 형식인지 확인 + except ValueError as e: + raise ValueError("숫자만 입력해주세요.") from e # 숫자가 아닌 값 입력시 예외 처리 + + +def validate_input(Data, Criteria): + """ + 사용자가 입력한 값을 검증하는 함수. + - Data: 사용자가 입력한 값 + - Criteria: 예상하는 값의 조건 (정수 또는 리스트 형식) + 다음과 같은 경우 ValueError를 발생시킴: + - 입력 값이 숫자가 아닌 경우 + - 3개의 숫자가 아닌 경우 + - 중복된 숫자가 포함된 경우 + - 0이 포함된 경우 + - 입력 값이 1 또는 2가 아닌 경우 (재시작 시) + """ + # 숫자 확인 + is_number(Data) + + if isinstance(Criteria, int): # Criteria가 int일 경우, player_input()에서 사용 + compare_array = list(map(int, Data)) # Data를 정수형 리스트로 변환 + + # 플레이어가 입력한 값이 예상되는 값의 길이가 아닐 경우 예외 처리 + if (len(compare_array) != Criteria): + raise ValueError("3개의 숫자를 입력해주세요.") + + # 중복된 숫자가 있을 경우 예외 처리 + if (same_num_check(compare_array) == 1): + raise ValueError("숫자 중복 없이 입력해주세요.") + + # 1~9의 숫자가 아닌 0이 포함된 경우 예외 처리 + if (0 in compare_array): + raise ValueError("1 ~ 9의 숫자만 입력해주세요.") + + return compare_array # 입력이 정상이면 정수 리스트 변환 + + elif isinstance(Criteria, list): # Criteria가 list일 경우, restart_baseball()에서 사용 + # Data가 Criteria에 포함되지 않은 값일 경우 예외 처리 + if int(Data) not in Criteria: + raise ValueError("숫자 1 또는 2만 입력해주세요.") + + +def make_computer_num(): + """ + 컴퓨터가 랜덤으로 3개의 숫자를 생성하는 함수. + 1에서 9까지의 숫자 중에서 중복 없이 3개를 뽑음. + """ + computer = random.sample(range(1, 10), 3) # 1~9 사이에서 중복 없이 3개 숫자 선택 + return computer + + +def player_input(): + """ + 플레이어에게 숫자 3개를 입력받는 함수. + 입력 값 검증 후 정상적인 값을 반환. + """ + get_array = validate_input(input("숫자를 입력해주세요 : "), 3) # 입력 값 검증 + return get_array + + +def check_input(get, com): + """ + 플레이어가 입력한 값과 컴퓨터가 생성한 값을 비교하여 결과를 출력하는 함수. + - get: 플레이어가 입력한 숫자 리스트 + - com: 컴퓨터가 생성한 숫자 리스트 + 결과에 따라 '스트라이크', '볼', '낫싱'을 반환. + """ + ball, strike = 0, 0 # 볼과 스트라이크를 카운트할 변수 초기화 + + for i in range(0,3): # 입력된 숫자와 컴퓨터가 생성한 숫자를 비교 + if get[i] == com[i]: # 숫자와 위치가 맞으면 스트라이크 + strike += 1 + elif get[i] in com: # 숫자는 맞지만 위치가 다르면 볼 + ball += 1 + else: + continue # 숫자도 위치도 맞지 않으면 아무것도 하지 않음 + + # 스트라이크가 3이면 3스트라이크 반환 + if strike == 3: + return "3스트라이크" + + # 스트라이크와 볼이 모두 없으면 낫싱 반환 + elif ball + strike == 0: + return "낫싱" + + result = [] # 결과를 저장할 리스트 + + result.extend([f"{ball}볼" for _ in [1] if ball > 0]) # 볼이 하나 이상 있으면 볼 정보 추가 + result.extend([f"{strike}스트라이크" for _ in [1] if strike > 0]) # 스트라이크가 하나 이상 있으면 스트라이크 정보 추가 + + # 볼과 스트라이크가 있을 경우 공백으로 구분해서 반환 + return " ".join(result) + + +def loop_check(com): + """ + 게임을 반복하여 진행하는 함수. + 플레이어가 3개의 숫자를 모두 맞힐 때까지 반복. + """ + while True: + get = player_input() # 플레이어 입력 받기 + result_check_input = check_input(get, com) # 입력한 값과 컴퓨터 값 비교 + print(result_check_input) # 결과 출력 + if result_check_input == "3스트라이크": # 3스트라이크면 게임 종료 + print("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + return 0 # 게임 종료 + + +def restart_baseball(): + """ + 게임 종료 후 '1'을 입력하면 게임을 새로 시작하고, '2'를 입력하면 종료하는 함수. + """ + print("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.") + restart_input = input() # 플레이어 입력 받기 + validate_input(restart_input, [1, 2]) # 입력 값 검증 + return int(restart_input) + + def main(): """ 프로그램의 진입점 함수. 여기에서 전체 프로그램 로직을 시작합니다. """ # 프로그램의 메인 로직을 여기에 구현 + print("숫자 야구 게임을 시작합니다.") + while True: + com_num = make_computer_num() # 컴퓨터가 생성한 숫자 + loop_check(com_num) # 게임 진행 + restart = restart_baseball() # 게임 재시작 여부 확인 + if restart == 1: # 1을 입력하면 게임 재시작 + continue + else: # 2를 입력하면 게임 종료 + break if __name__ == "__main__": # 프로그램이 직접 실행될 때만 main() 함수를 호출