Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[자동차 경주]소현우 과제 제출합니다. #1

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,4 @@ jun : -----
- **기능을 구현하기 전 `docs/README.md`에 구현할 기능 목록을 정리**해 추가합니다.
- **Git의 커밋 단위는 앞 단계에서 `docs/README.md`에 정리한 기능 목록 단위**로 추가합니다.
- [커밋 메시지 컨벤션](https://gist.github.com/stephenparish/9941e89d80e2bc58a153) 가이드를 참고하여 커밋 메시지를 작성합니다.

22 changes: 22 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## 구현할 기능 목록
1. **자동차 이름 입력**
- 쉼표(`,`)로 구분된 자동차 이름을 입력
- 각 이름은 5자 이하로 제한 -> 넘으면 ValueError
- 중복된 이름은 제거

2. **시도 횟수 입력**
- 사용자로부터 경주 시도 횟수를 입력
- 입력값이 1 이상이어야 한다. -> 넘으면 ValueError
- 숫자가 아닌 값을 입력하면 -> ValueError

3. **자동차 경주 진행** (move_cars 함수로 구현)
- 각 자동차는 무작위 숫자를 받아 4 이상이면 한 칸 이동
- 이동 결과를 출력

4. **경주 상태 출력** (print_race 함수로 구현)
- 각 자동차의 현재 위치를 화면에 출력
- 자동차 이름 오른쪽에 이동한 거리를 `-`로 표시

5. **우승자 결정** (get_winners 함수로 구현)
- 가장 멀리 이동한 자동차를 우승자로 선정
- 여러 명이 동점일 경우, 공동 우승자로 처리
192 changes: 184 additions & 8 deletions src/racingcar/main.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,188 @@
<<<<<<< HEAD
"""자동차 경주 게임 메인 스크립트"""
=======
""" 자동차 경주 게임 메인 스크립트 """
>>>>>>> a8f68ff7178f271a24793fe592b609c29719c4aa

import random


<<<<<<< HEAD
# 상수 정의
MOVE_THRESHOLD = 4 # 자동차가 전진할 최소 랜덤 값
MIN_RAND = 1 # 랜덤 숫자의 최소값
MAX_RAND = 9 # 랜덤 숫자의 최대값
MAX_NAME_LENGTH = 5 # 자동차 이름 최대 길이


def move_cars(car_positions):
"""자동차 이동 로직 (랜덤 숫자가 MOVE_THRESHOLD 이상이면 이동)"""

for name in car_positions:
if random.randint(MIN_RAND, MAX_RAND) >= MOVE_THRESHOLD:
=======
def move_cars(car_positions):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

PEP8 스타일 가이드를 준수해야 합니다.

다음과 같은 스타일 문제를 수정해 주세요:

  • 함수 정의 사이에 빈 줄 2개가 필요합니다
  • 29번 줄이 최대 길이(79자)를 초과합니다
  • 45번 줄에 불필요한 공백이 있습니다
  • 변수 N은 snake_case 명명 규칙을 따라야 합니다
-def move_cars(car_positions):
+
+
+def move_cars(car_positions):

-def print_race(car_positions):
+
+
+def print_race(car_positions):

-def main():
+
+
+def main():

-    car_names = list(dict.fromkeys(name.strip() for name in car_names if name.strip()))
+    car_names = list(dict.fromkeys(
+        name.strip() for name in car_names if name.strip()
+    ))

-    N = int(input("시도할 횟수는 몇 회인가요? "))
+    num_attempts = int(input("시도할 횟수는 몇 회인가요? "))

-    for _ in range(N): 
+    for _ in range(num_attempts):

Also applies to: 11-11, 26-26, 29-29, 36-36, 45-45

🧰 Tools
🪛 GitHub Actions: Check PEP8 Style

[error] 5-5: E302 expected 2 blank lines, found 1

"""자동차 이동 로직 (랜덤 숫자가 4 이상이면 이동)"""

for name in car_positions:
if random.randint(1, 9) >= 4:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

숫자상수는, 매직넘버상수로 바꾸고 전방선언 해주는 것이 좋습니다.

>>>>>>> a8f68ff7178f271a24793fe592b609c29719c4aa
car_positions[name] += 1


def print_race(car_positions):
"""현재 경주 상태 출력"""

for name, pos in car_positions.items():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pos도 좋지만 position처럼 풀네임으로 작성하는 것도 고민해보세요.

if pos > 0:
print(f"{name} : {'-' * pos}")
else:
print(f"{name} : {' '.rstrip()}") # Trailing whitespace 제거
print()


def get_winners(car_positions):
"""최종 우승자 결정"""

max_pos = max(car_positions.values())
<<<<<<< HEAD
return [
name for name, pos in car_positions.items() if pos == max_pos
] # ✅ 긴 줄 개행 처리
=======
return [name for name, pos in car_positions.items() if pos == max_pos]
>>>>>>> a8f68ff7178f271a24793fe592b609c29719c4aa


def main():
"""
프로그램의 진입점 함수.
여기에서 전체 프로그램 로직을 시작합니다.
"""
# 프로그램의 메인 로직을 여기에 구현
print("프로그램이 시작되었습니다.")
"""메인 함수"""

<<<<<<< HEAD
car_names = input("경주할 자동차 이름을 입력하세요. (이름은 쉼표로 구분): ").split(
","
) # ✅ 긴 문자열 개행 처리

car_names = list(
dict.fromkeys(name.strip() for name in car_names if name.strip())
) # ✅ 중복 제거 및 공백 제거 (가독성 향상)

for name in car_names:
if len(name) > MAX_NAME_LENGTH:
raise ValueError(
f"⚠ 자동차 이름은 {MAX_NAME_LENGTH}자 이하만 가능합니다!"
) # ✅ 긴 문자열 개행 처리

try:
num_attempts = int(input("시도할 횟수는 몇 회인가요? ")) # 시도 횟수 입력
=======
car_names = input("경주할 자동차 이름을 입력하세요."
"(이름은 쉼표로 구분): ").split(",")
car_names = list(dict.fromkeys(
name.strip() for name in car_names if name.strip()
)) # ✅ 올바른 들여쓰기 수정

for name in car_names:
if len(name) > 5:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

숫자상수는, 매직넘버상수로 바꾸고 전방선언 해주는 것이 좋습니다.

raise ValueError("⚠ 자동차 이름은 5자 이하만 가능합니다!")
Comment on lines +78 to +86
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

입력 검증 로직을 별도 함수로 분리하세요.

현재 main 함수가 너무 많은 책임을 가지고 있습니다. 입력 검증 로직을 분리하면 코드의 가독성과 재사용성이 향상됩니다.

다음과 같이 분리하는 것을 제안합니다:

+def validate_car_names(names: list[str]) -> None:
+    """자동차 이름 유효성 검사"""
+    if not names:
+        raise ValueError("⚠ 유효한 자동차 이름이 없습니다!")
+    for name in names:
+        if len(name) > 5:
+            raise ValueError("⚠ 자동차 이름은 5자 이하만 가능합니다!")

 def main():
     car_names = input("경주할 자동차 이름을 입력하세요."
                      "(이름은 쉼표로 구분): ").split(",")
     car_names = list(dict.fromkeys(
         name.strip() for name in car_names if name.strip()
     ))
-    for name in car_names:
-        if len(name) > 5:
-            raise ValueError("⚠ 자동차 이름은 5자 이하만 가능합니다!")
+    validate_car_names(car_names)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
car_names = input("경주할 자동차 이름을 입력하세요."
"(이름은 쉼표로 구분): ").split(",")
car_names = list(dict.fromkeys(
name.strip() for name in car_names if name.strip()
)) # ✅ 올바른 들여쓰기 수정
for name in car_names:
if len(name) > 5:
raise ValueError("⚠ 자동차 이름은 5자 이하만 가능합니다!")
def validate_car_names(names: list[str]) -> None:
"""자동차 이름 유효성 검사"""
if not names:
raise ValueError("⚠ 유효한 자동차 이름이 없습니다!")
for name in names:
if len(name) > 5:
raise ValueError("⚠ 자동차 이름은 5자 이하만 가능합니다!")
def main():
car_names = input("경주할 자동차 이름을 입력하세요."
"(이름은 쉼표로 구분): ").split(",")
car_names = list(dict.fromkeys(
name.strip() for name in car_names if name.strip()
))
validate_car_names(car_names)


try:
num_attempts = int(input("시도할 횟수는 몇 회인가요? ")) # 변수명 수정
>>>>>>> a8f68ff7178f271a24793fe592b609c29719c4aa
if num_attempts <= 0:
raise ValueError("⚠ 시도 횟수는 1 이상이어야 합니다!")
except ValueError:
print("⚠ 잘못된 입력입니다. 숫자를 입력하세요.")
return

car_positions = {name: 0 for name in car_names} # 자동차 위치 초기화

<<<<<<< HEAD
for _ in range(num_attempts):
=======
for _ in range(num_attempts): # 변수명 수정
>>>>>>> a8f68ff7178f271a24793fe592b609c29719c4aa
move_cars(car_positions) # 자동차 이동
print_race(car_positions) # 현재 상태 출력

winners = get_winners(car_positions) # 우승자 결정
print(f"\n최종 우승자 : {', '.join(winners)}")


if __name__ == "__main__":
main() # ✅ 마지막 빈 줄 제거 (W391 해결) 현재 코드에서 """자동차 경주 게임 메인 스크립트"""

import random


# 상수 정의
MOVE_THRESHOLD = 4 # 자동차가 전진할 최소 랜덤 값
MIN_RAND = 1 # 랜덤 숫자의 최소값
MAX_RAND = 9 # 랜덤 숫자의 최대값
MAX_NAME_LENGTH = 5 # 자동차 이름 최대 길이


def move_cars(car_positions):
"""자동차 이동 로직 (랜덤 숫자가 MOVE_THRESHOLD 이상이면 이동)"""

for name in car_positions:
if random.randint(MIN_RAND, MAX_RAND) >= MOVE_THRESHOLD:
car_positions[name] += 1


def print_race(car_positions):
"""현재 경주 상태 출력"""

for name, pos in car_positions.items():
if pos > 0:
print(f"{name} : {'-' * pos}")
else:
print(f"{name} : {' '.rstrip()}") # Trailing whitespace 제거
print()


def get_winners(car_positions):
"""최종 우승자 결정"""

max_pos = max(car_positions.values())
return [
name for name, pos in car_positions.items() if pos == max_pos
] # ✅ 긴 줄 개행 처리


def main():
"""메인 함수"""

car_names = input("경주할 자동차 이름을 입력하세요. (이름은 쉼표로 구분): ").split(
","
) # ✅ 긴 문자열 개행 처리

car_names = list(
dict.fromkeys(name.strip() for name in car_names if name.strip())
) # ✅ 중복 제거 및 공백 제거 (가독성 향상)

for name in car_names:
if len(name) > MAX_NAME_LENGTH:
raise ValueError(
f"⚠ 자동차 이름은 {MAX_NAME_LENGTH}자 이하만 가능합니다!"
) # ✅ 긴 문자열 개행 처리

try:
num_attempts = int(input("시도할 횟수는 몇 회인가요? ")) # 시도 횟수 입력
if num_attempts <= 0:
raise ValueError("⚠ 시도 횟수는 1 이상이어야 합니다!")
except ValueError:
print("⚠ 잘못된 입력입니다. 숫자를 입력하세요.")
return

car_positions = {name: 0 for name in car_names} # 자동차 위치 초기화

for _ in range(num_attempts):
move_cars(car_positions) # 자동차 이동
print_race(car_positions) # 현재 상태 출력

winners = get_winners(car_positions) # 우승자 결정
print(f"\n최종 우승자 : {', '.join(winners)}")


if __name__ == "__main__":
# 프로그램이 직접 실행될 때만 main() 함수를 호출
main()
main() # ✅ 마지막 빈 줄 제거 (W391 해결)
Comment on lines +1 to +188
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🚨 병합 충돌을 해결해야 합니다.

파일에 해결되지 않은 병합 충돌이 있습니다:

  • <<<<<<< HEAD, =======, >>>>>>> a8f68ff7178f271a24793fe592b609c29719c4aa 마커가 여러 곳에 남아있습니다.
  • 이로 인해 파이프라인 검사가 실패하고 있습니다.

병합 충돌을 해결하고 다시 커밋해주세요. 병합 시에는 다음 사항을 고려해주세요:

  1. 상수 정의 부분은 HEAD 버전을 선택하는 것이 좋습니다 (매직 넘버 제거).
  2. 들여쓰기는 PEP8 스타일을 따르도록 해주세요.
  3. 중복된 코드 블록을 제거해주세요 (114-188줄이 1-113줄과 중복됨).
🧰 Tools
🪛 Ruff (0.8.2)

1-1: SyntaxError: Expected a statement


1-1: SyntaxError: Expected a statement


1-1: SyntaxError: Expected a statement


1-1: SyntaxError: Expected a statement


3-3: SyntaxError: Expected a statement


3-3: SyntaxError: Expected a statement


3-3: SyntaxError: Expected a statement


3-3: SyntaxError: Expected a statement


3-4: SyntaxError: Expected a statement


5-5: SyntaxError: Expected a statement


5-5: SyntaxError: Expected a statement


5-5: SyntaxError: Expected a statement


5-5: SyntaxError: Expected a statement


10-10: SyntaxError: Expected a statement


10-10: SyntaxError: Expected a statement


10-10: SyntaxError: Expected a statement


10-10: SyntaxError: Expected a statement


22-23: SyntaxError: Expected an indented block after if statement


23-23: SyntaxError: Expected a statement


23-23: SyntaxError: Expected a statement


23-23: SyntaxError: Expected a statement


23-23: SyntaxError: Expected a statement


23-24: SyntaxError: Expected a statement


28-29: SyntaxError: Expected an indented block after if statement


29-29: SyntaxError: Expected a statement


29-29: SyntaxError: Expected a statement


29-29: SyntaxError: Expected a statement


29-29: SyntaxError: Expected a statement


30-30: SyntaxError: Unexpected indentation


33-33: SyntaxError: Expected a statement


48-48: SyntaxError: Expected a statement


48-48: SyntaxError: Expected a statement


48-48: SyntaxError: Expected a statement


48-48: SyntaxError: Expected a statement


49-49: SyntaxError: Unexpected indentation


52-52: SyntaxError: Expected a statement


52-52: SyntaxError: Expected a statement


52-52: SyntaxError: Expected a statement


52-52: SyntaxError: Expected a statement


52-53: SyntaxError: Expected a statement


53-53: SyntaxError: Unexpected indentation


54-54: SyntaxError: Expected a statement


54-54: SyntaxError: Expected a statement


54-54: SyntaxError: Expected a statement


54-54: SyntaxError: Expected a statement


60-60: SyntaxError: Expected a statement


60-60: SyntaxError: Expected a statement


60-60: SyntaxError: Expected a statement


60-60: SyntaxError: Expected a statement


61-61: SyntaxError: Unexpected indentation


77-77: SyntaxError: Expected except or finally after try block


77-77: SyntaxError: Expected a statement


77-77: SyntaxError: Expected a statement


77-77: SyntaxError: Expected a statement


77-78: SyntaxError: Expected a statement


78-78: SyntaxError: Unexpected indentation


90-90: SyntaxError: Expected except or finally after try block


90-90: SyntaxError: Expected a statement


90-90: SyntaxError: Expected a statement


90-90: SyntaxError: Expected a statement


91-91: SyntaxError: Unexpected indentation


93-93: SyntaxError: unindent does not match any outer indentation level


93-94: SyntaxError: Expected an expression


94-94: SyntaxError: Unexpected indentation


97-97: SyntaxError: unindent does not match any outer indentation level


99-99: SyntaxError: Expected a statement


99-99: SyntaxError: Expected a statement


99-99: SyntaxError: Expected a statement


99-99: SyntaxError: Expected a statement


100-100: SyntaxError: Unexpected indentation


100-101: SyntaxError: Expected an indented block after for statement


101-101: SyntaxError: Expected a statement


101-101: SyntaxError: Expected a statement


101-101: SyntaxError: Expected a statement


101-101: SyntaxError: Expected a statement


101-102: SyntaxError: Expected a statement


102-102: SyntaxError: Unexpected indentation


102-103: SyntaxError: Expected an indented block after for statement


103-103: SyntaxError: Expected a statement


103-103: SyntaxError: Expected a statement


103-103: SyntaxError: Expected a statement


103-103: SyntaxError: Expected a statement


104-104: SyntaxError: Unexpected indentation


107-107: SyntaxError: unindent does not match any outer indentation level


108-108: SyntaxError: Unexpected indentation


111-111: SyntaxError: Expected a statement

🪛 GitHub Actions: Check Indentation Depth

[error] 1-1: Parsing failed: 'invalid syntax (racingcar.main, line 1)'

🪛 GitHub Actions: Check No External Libraries

[error] 1-1: SyntaxError: invalid syntax due to merge conflict markers (<<<<<<< HEAD).

🪛 GitHub Actions: Run tests and upload coverage

[error] 1-1: SyntaxError: invalid syntax due to unresolved merge conflict markers.

🪛 GitHub Actions: Check PEP8 Style

[error] 1-1: SyntaxError: invalid syntax

2 changes: 1 addition & 1 deletion tests/racingcar/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def test_전진_및_정지(capsys):
main() # 프로그램 실행

# 출력값을 캡처한 후 검증
캡처된_출력 = capsys.readouterr()
캡처된_출력 = capsys.readouterr().out
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ㅎㅎ 제가 실수한 부분인데 잘 체크하고 고치셨어요!

assert all(예상_출력 in 캡처된_출력 for 예상_출력 in ["pobi : -", "woni : ", "최종 우승자 : pobi"])


Expand Down
2 changes: 1 addition & 1 deletion tests/study/test_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@ def test_charAt_메서드_위치_잘못된_경우_예외():

# 문자열 범위를 벗어나는 위치에 접근할 때 예외가 발생하는지 확인
with pytest.raises(IndexError, match="string index out of range"):
_ = input_str[5]
_ = input_str[5]
Loading