Nonamed Develog
[TIL][240701] UP & DOWN Game, Code Conventions, try/except, 다중 반복문 본문
[TIL][240701] UP & DOWN Game, Code Conventions, try/except, 다중 반복문
노네임드개발자 2024. 7. 1. 23:031. 입력한 값이 범위가 벗어날 경우 설정
어떤 문제가 있었나?
import random
random_number = random.randint(1, 100)
위의 random 입력값의 범위는 1~100 정수가 되는 것이 조건이다. 따라서 try/except을 이용하여 1~100 정수 외 숫자와 문자를 제외시켜보려 했다.
try:
print("UP&DOWN! 1~100까지 숫자를 입력하세요!")
number = int(input("숫자 입력: "))
if number < random_number:
print("UP")
elif number > random_number:
print("DOWN")
else:
print(f"딩동댕! 정답은 {random_number}입니다!")
print(f"시도한 횟수: {count}")
break
except ValueError:
print("유효한 범위 내 숫자를 넣어주세요")
위와 같이 코드를 작성하고 실행시켜 봤는데, 문자열은 예외처리가 잘 되지만 1~100 외 숫자를 제외시키지 못했다.
무엇을 시도했나?
except 뒤에 에러 종류에 따른 로직 처리 중 정수와 관련된 것을 있나 찾아봤다. 강의에서 없었던 여러 가지 로직을 찾아볼 수 있었다.
AssertionError: assert 문이 제대로 작동하지 않을 때 발생
IndexError: 참조 하려는 인덱스가 범위를 벗어날 때 발생
KeyError: 참조 하려는 키가 기존 키 집합에서 찾을 수 없을 때 발생
KeyboardInterrupt: 사용자가 인터럽트 키(Control + C, 혹은 Delete)를 누를 때 발생하며, 모든 Exception을 잡는 코드에 의해 인터프리터가 종료하는 것을 막지 못하도록 Exception 상위에 있는 BaseException을 직접 계승
MemoryError: 메모리가 부족하지만, 가비지 컬렉터가 일부 객체의 삭제를 함으로써 복구될 수 있는 경우 발생
NameError: 참조하는 지역, 전역 변수 혹은 함수, 클래스 등을 찾을 수 없을 때 발생
OSError: 시스템 함수가 시스템 관련 에러를 돌려줄 때 발생 (파일을 찾을 수 없거나, 디스크가 찼거나..)
OverflowError: 산술 연산의 결과가 너무 커서 표현할 수 없을 때, 혹은 정수 범위를 벗어났을 때 발생
RecursionError: 최대 재귀 깊이가 초과하였을 때 발생
TypeError: 연산이나 함수가 부적절한 데이터 타입의 객체에 적용되었을 때 발생
ValueError: 연산이나 함수가 부적절한 값을 가진 객체에 적용 되었을 때 발생
ZeroDivisionError: 나누기, 나머지 연산의 두 번째 인자가 0일 때 발생
어떻게 해결했는가?
try/except의 로직에서 정수를 걸러내는 로직은 없었기 때문에 if절에 조건을 추가하기로 했다.
random_numeber가 1~100의 입력값만 조건으로 하고 싶어 처음엔 아무 생각 없이 in을 사용했다.(sql 때문인가?)
number = int(input("숫자 입력: "))
if not number in random_number:
print("유효한 범위 내 숫자를 넣어주세요")
결과는 TypeError: argument of type 'int' is not iterable
구글링해보니 iterable(리스트, 튜플)한 타입이 와야 하는데 int가 와서 생긴 에러라고 나왔다. 간편하게 비교 연산자를 사용하여 조건을 변경해 주었다.
try:
print("UP&DOWN! 1~100까지 숫자를 입력하세요!")
number = int(input("숫자 입력: "))
if not 1 <= number <= 100:
print("유효한 범위 내 숫자를 넣어주세요")
elif number < random_number:
print("UP")
elif number > random_number:
print("DOWN")
else:
print(f"딩동댕! 정답은 {random_number}입니다!")
print(f"시도한 횟수: {count}")
break
except ValueError:
print("유효한 범위 내 숫자를 넣어주세요")
다음과 같이 1~100의 입력값만 들어갈 수 있게 설정 완료했다.
2. 다중 반복문 들여 쓰기
어떤 문제가 있었나?
while True 무한 반복을 통해서 UP&DONW 게임 한판은 할 수 있게 코드를 완성했지만 두 번 이상을 반복하는 코드를 완성하는 것에 시간을 많이 썼다. 처음 작성한 코드는 다음과 같다.
while True:
count += 1
try:
# (생략) UP&DOWN 게임 조건문
re_game = input("다시 하시겠습니까? (y/n): ")
if re_game == "y":
print(f"이전 게임 플레이어 최고 시도 횟수: {count}")
continue
elif re_game == "n":
print("게임을 종료합니다")
break
except ValueError:
print("유효한 범위 내 숫자를 넣어주세요")
무엇을 시도했나?
들여 쓰기를 수정해 보고 continue를 이용하여 루프가 계속 반복되도록 코드를 작성해 봤지만 random_number가 변화가 없다는 것을 깨달았다. while True 반복문에 random_number를 추가해 봤다.
while True:
random_number = random.randint(1, 100)
count += 1
try:
# (생략) UP&DOWN 게임 조건문
re_game = input("다시 하시겠습니까? (y/n): ")
if re_game == "y":
print(f"이전 게임 플레이어 최고 시도 횟수: {count}")
continue
elif re_game == "n":
print("게임을 종료합니다")
break
except ValueError:
print("유효한 범위 내 숫자를 넣어주세요")
하지만 무한 루프에서 random_number는 계속 바뀌어서 문제를 풀 수 없었다.(도대체 10보다 크고 11보다 작은 정수가 어딨 는데!!!!! print(random_number)로 숫자가 계속 바뀐다는 것을 파악)
어떻게 해결했는가?
결국 re_game에서 ramdom_number까지 어떻게 다시 루프를 돌리느냐가 포인트였다. 게임을 진행하는 코드에서는 random_number가 변하면 안 되기에 코드 밖에 있어야 하므로 루프에 루프를 씌우는 다중 반복문을 사용했다.
import random
while True:
random_number = random.randint(1, 100)
count = 0
while True:
# (생략) UP&DWON 게임 코드
re_game = input("다시 하시겠습니까? (y/n): ")
if re_game == "y":
print(f"이전 게임 플레이어 최고 시도 횟수: {count}")
continue
elif re_game == "n":
print("게임을 종료합니다")
break
else:
print("y 또는 n을 입력하세요")
re_game = input("다시 하시겠습니까? (y/n): ")
안쪽 무한 루프의 UP&DOWN 게임 코드가 돌아갈 때, 바깥쪽 루프의 random_numebr는 고정되고 새 게임을 시작하면 다시 바깥쪽 루프가 돌아가여 새 random_number를 받고 안쪽 루프인 UP&DOWN 게임 코드를 돌린다.
추가로 y/n을 제외한 다른 입력값이 들어갈 때 입력값을 다시 받을 수 있게 설정하고 마무리했다.
#완성 코드
import random
while True:
random_number = random.randint(1, 100)
count = 0
while True:
count += 1
try:
print("UP&DOWN! 1~100까지 숫자를 입력하세요!")
number = int(input("숫자 입력: "))
if not 1 <= number <= 100:
print("유효한 범위 내 숫자를 넣어주세요")
elif number < random_number:
print("UP")
elif number > random_number:
print("DOWN")
else:
print(f"딩동댕! 정답은 {random_number}입니다!")
print(f"시도한 횟수: {count}")
break
except ValueError:
print("유효한 범위 내 숫자를 넣어주세요")
re_game = input("다시 하시겠습니까? (y/n): ")
if re_game == "y":
print(f"이전 게임 플레이어 최고 시도 횟수: {count}")
continue
elif re_game == "n":
print("게임을 종료합니다")
break
else:
print("y 또는 n을 입력하세요")
re_game = input("다시 하시겠습니까? (y/n): ")
새로 알게 된 점은 무엇인가?
- in, not in 연산자의 결과는 bool 타입으로 리스트나 튜플 같은 iterable 한 데이터가 있으면 true 없으면 false이다. ( iterable: 반복가능한)
- 추가 except의 예외 논리 (한번쯤 복습하기)
- 무한 루프에 랜덤 요소를 넣으면 루프마다 랜덤 요소가 변화한다.
- Cording conventions: 코드 작성에도 규칙이 있다.
- 변수/함수를 네이밍 - snake 표기법: python_is_very_good
- Class를 네이밍 - Paskal 표기법: PythonIsVeryGood (camel 표기법: pythonIsVeryGood)
- 상수(절대 변하지 않는 수)는 대문자로 표기 (PIE = 3.14)
- list를 표기할 때는 복수를 사용 (반복문에서 단/복수 구별 용이)
- 함수를 네이밍 할 때는 역할 표기 (합 = sum)
무엇을 느꼈고 내일은 무엇을 할까?
파이썬으로 몰입했던 하루였다. 파이썬 심화 강의를 다 보고, 모르거나 애매하다고 할 수 있는 가려운 부분이 많이 해소되었다. 특히 서버 관련 쪽이 많이 도움이 되었다. 1번 개인 과제까지 마무리하는데 코드카타 문제를 풀거나 사전 캠프 때 파이썬 기본 강의를 들어서인지 기본적인 틀을 만들기엔 어렵지 않았다. (추가 도전 과제가 조금 힘들었지만)
내일은 2번 개인과제를 마무리하고, 밀린 코드카타 문제를 풀어보려 한다. 과제를 풀면서 느끼는 게 코드카타 문제로 알고리즘 적 사고를 많이 할 수 있었는데 요즘 다른 것에 집중한다고 조금 등한시했기 때문이다.
'WHAT I LEARN > TIL' 카테고리의 다른 글
[TIL][240704] class, Branch(PyCharm) (0) | 2024.07.04 |
---|---|
[TIL][240702] 가위 바위 보 게임, 다중 반복문 (0) | 2024.07.02 |
[TIL][240628] requests, 웹 스크래핑(크롤링), Flask, url_for, form, Database, SQLite (0) | 2024.06.28 |
[TIL][240627] 미니 프로젝트 발표, jQuery, API(GET), FETCH (0) | 2024.06.27 |
[TIL][240626] 미니 프로젝트, 필수 리눅스 명령어, Git & Github, pip install (0) | 2024.06.26 |