클라이언트/ 서버/ 엔지니어 " 게임 개발자"를 향한 매일의 공부일지

에러 읽고 대처하기 3 - 자주 접하는 에러 코드 및 에러 피하기 본문

웹 · 앱 개발/디버깅

에러 읽고 대처하기 3 - 자주 접하는 에러 코드 및 에러 피하기

huenuri 2024. 7. 30. 10:57

에러 읽고 대처하기 마지막 단원이다. 조금 전에 방 청소도 했고 아침에 1시간 정도 공부할 시간이 더 남아있다. 최대한 빠르게 학습을 진행해볼 것이다.

바로 이어서 시작해본다!



 

이론 7 - 자주 접하는 에러 코드 6 : Recursion error

 

Recursion은 우리말로는 재귀함수이다. 재귀함수는 함수 안에서 자기 스스로를 부르는 함수이다. 코드를 짧고 간결하게 작성하기 위해 사용하는 경우가 많다.
예시를 보면 sum_to는 0부터 n까지 합을 구하는 함수이다. 4를 넣으면 10이 나올 것을 기대하지만 실제로는 오류가 뜬다.

 

 

만약 5까지의 합을 구할 때는, 일단 0부터 4까지의 합을 구하고 마지막에 5를 더해 10으로 계산한다. 이런 식으로 자신에서 뺀 것을 먼저 계산하고 자신 값을 더하는데 오류 메시지를 보면 이 과정을 997번 생성했다고 뜬다.

왜 그런지 한번 살펴보자. sum(5)를 계산하기 위해 sum(0)에서 1, 2, 3.. 이렇게 더하는 과정을 반복했다. 하지만 sum(0)을 계산하기 위해 sum(-1)을 계산하고 계속 이러한 과정이 반복되고 있다.

 

 

 

제대로된 코드를 짜려면 이 함수가 종료되는 조건을 설정해주어야 한다. 0이 들어올 때는 0이라고 반환하고, 그 이상인 경우에만 출력이 되도록 해야 하는 것이다.



 

실습 3 - 재귀 디버깅

 

실행을 해보면 이러한 에러가 발생한다. 재귀함수는 언젠가는 스스로를 호출하는 것을 멈추고 끝나야 하는데 이러한 에러는 종료 조건이 없을 때 나타나는 문제이다.

감을 잡지 못할 때는 여기에 print(n)을 찍어보는 방법이 있다. 그러면 n의 값이 어떻게 변하는지 확인해보자.

 

 

n이 10에서 시작해서 -986까지 내려감을 볼 수 있다. 이럴 때는 언젠가는 종료하도록 종료 조건을 넣어주어야 한다.
재귀함수에서 오류가 발생했을 때 제일 먼저 확인해야 할 것은 이 종료 조건이 있는지이다.

 

 

이렇게 1부터 10까지의 합을 출력할 수 있게 되었다.



 

이론 8 - 에러 피하기 try, except

이것은 어떤 예외 상황이 발생할 때 미리 안전망을 설치해줄 수 있는 문법이다.

 

average라는 함수는 합을 길이로 나눈 결과를 출력하고 있다.

 

 

 

하지만 여기에 빈 리스트가 들어오면 Zero division 에러가 발생한므로, 이러한 조건을 만들어주었다.
이 코드를 다음과 같이 다른 상황에서 쓸 수도 있다.

 

 

 

일단 이 코드를 시도해본다. sum(numbers)에 숫자들이 들어있다면 잘 실행이 될 것이다. 예외 상황이 발생한다면 다음 블럭을 실행해달라는 조건을 만들어준다.

두 코드가 작동되는 방식은 다르지만 결과물은 같다. 앞에서는 길이가 0보다 큰 경우에만 이 계산을 했다면, 뒤의 코드에서는 계산을 일단 하고 에러가 난다면 예외 조건이 찍히는 것이다.

어떤 것을 선택할지는 프로그래머의 선택이다.



 

실습 4 - 성적 정리 3

 

 

 

똑같은 코드를 다른 방식으로 짜는 것은 몇 가지 이유가 있다. 대표적으로는 이해하기 좋은 코드를 짜기 위해서이다. 똑같은 코드를 다른 문법으로 짜면 더 읽기 좋아지는 경우가 있다.
try와 except를 사용하면 어떤 예외 코드가 발생하는지 명시해주기 때문에 코드를 이해하기 쉬워진다.

결과물은 이것과 똑같이 나와야 한다.

조금 전부터 이 코드가 이해가 되지 않아서 헬퍼에게 물어보았다.

 

point = int(score[:-1])

 

 

 

문자열의 처음부터 마지막 글자 전까지 정수로 변환된다는 뜻이다. 0이 아니라 -1이라 무슨 뜻인가 했다. 여기서는 점이 마지막 글자이므로 이전까지의 글자만 불러오는 것이다. 즉 점이 삭제된다.

 

 

예외 처리 1 : value

다시 문제로 돌아와서 try, except를 써주기 위해 sum_scores가 point의 값이 더해지니 이 식을 적어준다. 만약 성공했다면 valid_score_count의 값도 올려준다.
만약 ValueError가 발생한다면, 아무것도 실행이 되지 않으면 되는데 파이썬에서는 이를 pass라는 예약어를 사용한다. pass를 쓰지 않으면 syntax 애러가 발생한다.

try 블럭에서 except이 발생하면 그 다음 코드로 넘어간다.

 
 

예외처리 2 : zero division

두번째는 zero division 에러가 발생하는 경우를 try, except로 잡아주어야 한다. 만약 이 에러가 발생하지 않는다면 점수를 찍어준다.

 

 

아래 코드를 지우고 실행시켰는데 점수가 달라졌다. 그 이유가 뭘까? 영상을 반복해서 시청했지만 왜 값이 달라졌는지 그 이유를 찾지 못했다.
우선은 그냥 넘어가기로 했다. 아직 디버깅 문제를 잘 이해한 상태는 아니니까 복습을 하면서 더 배울 수 있을 것 같다.

 

 

문제는 블록 지정을 잘못한 거였다. for문 안에다가 썼는데, 밖에 써주야 try와 except이 다른 경우도 만들어질 수 있다. 안에 쓰면 이전의 결과에서 한번 더 try와 except을 하는 것이다.
이렇게 고쳐보았다.

 



세번째 단원 학습을 마치고

미션 문제가 하나 있는데 코드가 100줄이나 되고 너무 어려워서 지금은 못 풀 것 같았다. 다음에 시간이 날때 한번 시도해볼 것이다. 지금은 기초 공부를 하기에도 빠듯한 시간이니..
그래도 미학습으로 남아있는 것은 좀 걸려서 다음 포스트에 이어서 학습해보기로 했다. 모르는 건 헬퍼에게 물어보면서 진행해봐야지!

여기까지 하고 오후에 3주차 학습을 시작해볼 것이다.