Forensic/혼공파 챌린지

혼공파 5주차 미션

Ron Weasley 2021. 8. 7. 19:33

벌써 5주차가 되어버렸네요!! 2주밖에 안남았는데...왜 실력이 안느는거같죠?? ㅎㅎㅎ 바로 5주차 해보겠습니다.

 

5주차 미션은 다음과 같습니다.

  우리는 이때까지 이러한 오류들을 프로그래밍을 하면서 자주 접했습니다. SyntaxError, IndexError ... 등등 그때마다 드는 생각은 왜...또 오류가 떴지?? 라는 생각을 하게됩니다. 하지만 오류를 수정하기에는 우리가 어려움을 매번 느꼈죠!! 하지만 이제 오류에 대한 종류를 배우면 아...여기서 오류가 발생한거구나 라는걸 쉽게 찾아낼 수 있을겁니다.

 

오류의 종류

  프로그래밍을 하면서 볼 수 있는 오류는 두 가지가 있습니다.

| 프로그램이 실행하기 전에 발생할 수 있는 오류 (구문 오류)

| 프로그램이 실행하고 나서 발생할 수 있는 오류 (예외 , 런타임 오류)

 

  그럼 두 가지 다른건가요?? 아니요 둘 다 오류라고 부릅니다. 전자를 구문 오류라고 칭하고, 후자를 예외 또는 런타임 오류라고 칭합니다. 전자부터 알아 보도록 하겠습니다.

 

구문 오류

  구문 오류는 괄호의 개수, 들여쓰기 문제 등으로 인해 프로그램이 실행하기 전 발생하는 오류입니다. 쉽게 말해서 프로그램이 실행이 안된다는것 입니다. 우리가 함수를 작성하면서 매개변수 때문에 많이 고생을 했을것입니다. 왜냐하면 처음 배우는 것이기 때문에 가변매개변수 뒤에 매개변수가 온다던지 하면 코드가 문제있다고 인터프리터가 인식을 하고 실행을 하지 않게됩니다. 즉, 코드에 문제가 있어서 실행조차 되지 않는 오류인것입니다. 예를 한번 보겠습니다.

  코드를 한번 볼게요!! 1행은 아무런 문제없이 출력이 될것입니다. 하지만 2행은 보는것과 같이 빨간 밑줄이 끄여있습니다. 이 밑줄은 에러가 있다고 설명을 하고있는것입니다. 그 이유는 문자열을 출력할 때 큰 따옴표("")를 통해 묶어줘야 하는데 2열은 따옴표가 없습니다. 즉 EOL(End Of Line)에 문제가 있다고 인터프리터는 말을 하고 프로그램을 실행 조차 안시킵니다. 한번 보시죠

  어라...? 1열은 아무런 문제가 없었는데 출력이 왜 출력이 안되나요?? 할 수 있지만 아까도 말했다시피 프로그램을 실행조차 시키기 않기 때문에 출력이 되지 않은것입니다!! 그럼 이제 예외(런타임 오류)를 배워보겠습니다.

 

예외(런타임 오류)

  예외 또는 런타임 오류는 실행 중에 발생하는 오류입니다. 쉽게 말해서 방금 설명했던 구문 오류와는 달리 프로그램은 실행이 되지만 중간에 오류가 발생하여 프로그램을 강제 종료 시키는것입니다. 바로 코드를 보러가겠습니다.

  코드를 보자면 위에서는 빨간색 밑줄인데 여기서는 노란색 밑줄입니다. 눈치가 빠르신분들은 차이를 바로 찾을 수 있습니다. 구문 오류가 된다면 프로그램이 실행조차 안되니까 빨간색으로 중요표시를 한것이고 노란색은 실행은 시켜주는데 오류가 난다. 라는 걸 개발자인 우리한테 미리 예고를 하는것입니다. 실행을 하면 이렇게 됩니다.

  1행은 출력이 되는것이 보일것 입니다. 하지만 바로 Traceback(moast recent call last)란 오류를 발생시킵니다. 이건 우리가 호출한 부분을 역추적하라는 의미입니다. 오류를 읽어보면 line 2, in <module> list_a[1]은 파일의 2행에 오류가 있다는 것을 의미하고 오류를 발생시킨 코드가 list_a[1] 라고 설명을 하는것입니다. NameError는 말 그대로 list_a가 정의되어 있지 않다는 말이니까 오류를 해결하려면 list_a = [1,2,3,4,5] 이렇게 정의를 해주면 되겠죠?? ㅎㅎㅎ

 

  그럼 이제 우리는 구문 오류와 예외에 대해서 배웠는데 너무 쉽게 끝난거 같지 않나요?? 이젠 깊게 배워보겠습니다. 우리는 프로그램을 만들다 보면 훨씬 복잡한 방법을 통해서 예외를 처리해야 하는 경우가 있습니다. 왜냐하면 방금까지 설명했던 내용들은 예제로 쉽게 보여주기 위해 그런것이고 이제는 우리도 개발자의 길을 걸어가고 있으니 코드의 양이 늘어나면서 한줄로 코드를 처리하는것은 쉽지 않기 때문입니다. 바로 배워보도록 하겠습니다.

 

기본 예외 처리

  예뢰를 해결하는 보는 것을 예외 처리라고 부릅니다. 예외 처리는 두 가지로 나뉩니다.

| 조건문을 사용하는 방법

| try 구문을 사용하는 방법

 

Tip) 구문 오류는 프로그램이 실행조차 되지 않기 때문에 예외 처리 방법으로 처리할 수 없습니다. 문법적인 문제가 발생한 코드를 수정해 줘야 합니다.

 

조건문을 통해서 예외처리 하는 방법을 먼저 설명하겠습니다. 일단 예외가 발생할만한 코드를 보겠습니다.

코드를 설명하겠습니다. 먼저 1행은 정수 입력을 받을 변수 number_input_a를 int형으로 변환시켜 입력을 받습니다. 즉 숫자를 입력 받으면 정수형으로 변환시켜서 받는다는것이겠죠?? 그럼 이 프로그램을 작성한 개발자는 당연히 원의 넓이 둘레를 구하는줄 알고 숫자만 넣겠지?? 라고 생각을 할것입니다. 이런식으로 말이죠

그런데...만약에 장난끼가 많은 이용자라면 정수말고 다른것을 넣을수도있습니다. 이런식으로 말이죠

그럼 런타임 오류가 발생하는 것입니다. 이처럼 개발자의 의도와 다르게 사용하는 이용자가 있을 경우를 대비해서 예외처리를 해줘야합니다. 다른 프로그램을 예로 코드는 없지만 말로써 설명을 해보겠습니다. 주식을 사고 파는 프로그램이 있다고 가정해봅시다. 그럼 우리가 입금을 한 금액이 10만원이라고 가정하면 프로그램에서는 통장 잔고에 +10만원을 채울것입니다. 근데 만약 장난끼 있는 사람이 -10만원을 입력하면 어떻게될까요?? 바로 에러가 발생합니다. 왜냐하면 입금은 통장 잔고에서 +가 되는 부분인데 -가 들어갔으니 말이죠!! 이처럼 우리는 의도치 않은 상황에 대비를 해야하기 때문에 예외처리를 해줘야 하는 것입니다. 예외처리를 하는 방법 중 하나인 조건문을 먼저 배워보겠습니다.

 

  조건문은 앞에서 배웠다시피 if문입니다. if문을 통해서 어떻게 예외 처리를 할 수 있을까요?? 답은 쉽습니다. 파이썬에서 기본적으로 제공하는 isdigit()함수를 이용하면 됩니다. isdigit() 함수는 숫자로만 구성된 글자인지 확인하는 함수입니다. 바로 코드를 보겠습니다.

<제대로 된 이용자일 경우 해석>

① 정수를 하나 입력받습니다.

② 입력받은 정수가 isdigit()함수를 통해서 숫자로만 구성된 글자인지 확인합니다.

③ 숫자로만 구성된 글자이면 반지름, 둘레, 넓이가 출력됩니다.

 

<장난끼가 많은 이용자일 경우 해석>

① 정수를 하나 입력받습니다.

② 입력받은 정수가 숫자로만 구성된 글자인지 확인합니다.

③ 숫자로만 구성된 글자가 아닌 문자가 섞여있다면 else로 처리됩니다. (안녕?, 123안녕? 등등)

④ 프로그램이 정상적으로 종료되었습니다.

 

이해가 되셨나요?? 아까 위에서 설명할 때는 프로그램이 바로 죽었지만 지금은 정상적인 종료를 한것입니다. 이처럼 프로그램을 작성할 때는 예외적인 상황까지 모두 생각하는 습관을 길렀으면 좋겠습니다. (저는 그러지 못하지만요 ㅎㅎㅎㅎㅎㅎ)

 

다음으로 알아볼 구문은 try except 구문입니다.

 

try except구문

  과거의 우리는 조건문으로만 예외를 처리했습니다. 하지만 예외가 발생할 상황을 모두 예측하고 모두 조건문으로 처리하는 것은 매우 힘든 일입니다. 그래서 나온 구문이 try except구문입니다. 쉽게 말하면 switch case문 같이 ①번 이면 ①번 케이스 ②번이면 ②번 케이스 ...등등 똑같은 방식입니다. 기본적인 구조를 바로 보겠습니다.

try:
  예외가 발생할 가능성이 있는 코드
except:
  예외가 발생했을 때 실행할 코드

구조를 살펴보니 간단하죠?? 바로 예제 코드로 가보겠습니다.

앞에 if 조건문으로 예외 처리한것과 동일한 기능을 제공합니다.

 

이처럼 조건문으로도 할 수 있고, try execpt문으로도 할 수 있습니다. 하나의 예외 처리를 더 해볼까요?? 도형은 음수가 존재하지 않습니다. 음수를 입력할 경우 예외 처리하는것을 보여드리겠습니다. 이번에는 if try except else를 써볼게요!!

코드가 더러워 보일 수 있는데요...해설을 보도록 합시다

<해설>

① int형으로 형 변환을 시킨 정수를 하나 입력을 받습니다.

② 조건문을 비교하는데요, 입력받은 정수가 0보다 크면 try구문 실행을 하고 예외가 발생했을 때는 pass를 합니다.

③ 조건문이 거짓일 경우 else문을 실행을 합니다.

양수를 입력한 값과 음수를 입력한 값의 차이가 보이시나요?? 여러분들은 지금 배운 try except구문을 두 개를 합쳐서 정수를 입력받고 문자면 정수가 아닙니다를 출력하고 음수면 음수가 아닙니다를 출력하는 프로그램을 작성해보세요!!! 그럼 실력이 엄청 빨리 늘것입니다.

 

마지막으로 try except finally구문을 해보겠습니다.

try:
    예외가 발생할 가능성이 있는 코드
except:
    예외가 발생했을 때 실행할 코드
else:
    예외가 발생하지 않았을 때 실행할 코드
finally:
    무조건 실행할 코드

finally구문은 예외 처리 구문에서 가장 마지막에 사용할 수 있는 구문으로 예외가 발생하든 예외가 발생하지 않든 무조건 실행할 때 사용하는 코드입니다. 방금 위에서 문제를 준 문자면 정수가 아닙니다를 출력하고. 음수면 음수가 아닙니다를 출력하는 프로그램을 제가 짠 코드로 보겠습니다. 정답은 아니지만 저보다 이쁘게 숏코드로 잘 짜시는분들이 많으니까 참고만 해주세요!!!

이렇게 코드를 짤 수 있는데요 출력 결과를 한번 보겠습니다.

finally구문 양수입력
finally구문 음수입력
finally구문 문자

출력 결과를 보면 제가 내줬던 문제랑 같은 출력값이 나오는게 보이시나요??? 이처럼 코드는 이때까지 배운것을 하나씩 활용하면서 원하는 프로그램을 만들어보는 시간을 가졌으면 좋겠습니다. 그럼 지금까지 예외와 에러에 대해서 배워보았습니다.

 

<기본미션>

p291쪽 문제는 위에서 이미 다 설명을 한 것이라 따로 설명을 하지 않겠습니다.

구문오류와 예외의 차이는 프로그램이 실행이 되고 안되고의 차이입니다.

 

<선택미션>

① output = 10 + "개" # TypeError : int형과 str형은 + 연산자가 불가능하다.

② int("안녕하세요") # ValueError : 문자열을 정수로 바꾸려고 int형을 사용하니까 에러가 납니다.

③ cursor.close) #  SyntaxError : 괄호가 없습니다.

④ [1,2,3,4,5][10] # IndexError : 리스트의 인덱스가 범위를 벗어났습니다.

 

이로써 5주차 포스팅을 마치도록 하겠습니다 !!!!