본문으로 이동

일반인을 위한 파이썬 지침서/디버깅

위키책, 위키책

디버깅이란 무엇인가?

[+/-]

프로그램을 시작하자 마자, 우리는 놀랍게도 우리가 생각했던대로의 프로그램을 가지는 것이 쉽지 않다는 것을 깨닫는다. 디버깅은 탐구되어져야만 하는 것이다. 나는 바로 그 때를 생생하게 기억한다. 내가 깨닫는 그 순간부터 나는 나의 인생의 대부분을 나의 프로그램에서 실수를 찾아 내는데에 사용하고 있었다.

- Maurice Wilkes discovers debugging, 1949

지금까지 여러분이 프로그램을 가지고 이리저리 놀다보면 프로그램이 때때로 여러분이 원하지 않았던 행동을 한다는 것을 아마도 여러분은 발견 할 것이다. 이것은 대단히 흔한 일이다. 디버깅은 컴퓨터가 무엇을 하는지 알아내는 처리과정이며 그리고 여러분이 원하는대로 프로그램이 실행되도록 하는 과정이다. 이것을 기술적일수도 있다. 한때 나는 거의 일주일이나 소비해서 버그를 추적하고 고친적이 있었는데 어떤 사람이 y가 있어야할 자리에 x를 넣어 놓아서 발생한 것이었다.

이 장은 전 장보다도 더욱 추상적이 될 것이다. 유용하다면 연락주세요.

프로그램은 무엇을 해야 하는가?

[+/-]

가장 먼저 해야할 일은(이것은 당연하게 보인다) 프로그램이 정확히 동작하지 않을 때 그 프로그램이 무엇을 해야하는지를 추산해 보는 것이다. 약간의 테스트용 상황들을 고안해 보고 무슨일이 일어나는지 살펴보라. 예를 들어 내가 사각형의 길이( 모든 변의 길이의 합)를 계산하는 프로그램이 있다고 하자. 나는 다음과 같은 테스트 상황을 가진다.

width height perimeter
3 4 14
2 3 10
4 4 16
2 2 8
5 1 12

이제 나는 프로그램을 모든 케이스에 대하여 실행시켜서 그 프로그램이 내가 예상한바를 그대로 실행하고 있는지 살펴본다. 만약 그렇지 못하다면 나는 컴퓨터가 무엇을 하고 있는지 알 필요가 있다.

많은 검증케이스들이 잘 작동하지만 어떤 것들은 그렇지 않다. 만약 그렇다면 여러분은 잘 작동하는 프로그램들의 공통점이 무엇인지 알도록 노력해야 한다. 예를 들어 여기에 변의 길이를 계산하는 프로그램이 있다.(잠시후에 보게 될겁니다.)

Height: 3
Width: 4
perimeter =  15

Height: 2
Width: 3
perimeter =  11

Height: 4
Width: 4
perimeter =  16

Height: 2
Width: 2
perimeter =  8

Height: 5
Width: 1
perimeter =  8

처음의 두 개의 입력에 대하여는 작동하지 않았음을 주목하라, 다음의 두개에는 잘 작동하고 마지막 한개에는 작동하지 않았다. 문제가 무엇인지 여러분이 알기만 한다면 원인을 찾아내는 것은 더욱 쉽다. 여러분의 프로그램을 가지고 필요하다면 더 많은 검증케이스들을 여러분은 시도해 보아야만 한다.

그 프로그램은 무엇을 하는가?

[+/-]

다음으로 해야할 일은 소스코드를 살펴보는 일이다. 프로그래밍을 하면서 해야할 가장 중요한 일은 소스를 읽는 것이다. 소스를 읽는 가장 좋은 방법은 코드를 훓어보는 것이다.

코드 훓어보기는 첫 번째 줄에서 시작해서, 프로그램이 끝날 때까지 아래로 진행된다. While 루프와 if 서술문이 뜻하는 바는 어떤 라인들은 실행되지 않을 것이고 어떤 라인들은 여러번 실행될 것이라는 것을 뜻한다. 각 라인에서 여러분은 파이썬이 무엇을 하였는지를 이해한다.

변의 길이를 계산하는 이 단순한 프로그램으로 시작해 보자. 타이프해 넣지 마시고 읽기만 하라. 실행하지 마라. 소스 코드는 이렇다.

height = input("Height: ")
width = input("Width: ")
print "perimeter = ",width+height+width+width

Question: 파이썬이 처음으로 실행하는 라인은 무엇인가? Answer: 첫 번째 라인이 항상 먼저 실행된다. 이경우에는 : height = input("Height: ") 이다.

Question: 그 라인은 무엇을 하는가? Answer: Height: 를 출력하고, 사용자가 숫자 하나를 입력하기를 기다린다, 그리고 그것을 변수 height에 집어 넣는다.

Question: 다음으로 실행되는 라인은 무엇인가? Answer: 일반적으로, 'width = input("Width: ")' 아래의 라인이다.

Question: 그 라인은 무엇을 하는가? Answer: Width: 를 출력하고, 사용자가 숫자 하나를 입력하기를 기다려서, 그것을 변수 width에 집어 넣는다.

Question: 다음으로 실행되는 라인은 무엇인가? Answer: 다음의 라인이 현재의 라인보다 들여쓰기 혹은 내어쓰기 되어 있지만 않다면, 그것은 바로 다음의 라인이다. 그러므로 다음 라인은 : 'print "perimeter = ",width+height+width+width' 이다 (그것은 또한 현재라인에 있는 함수를 실행할지도 모르지만, 그것은 앞으로의 장에서 다루겠다.)

Question: 그 라인은 무엇을 하는가? Answer: 먼저 perimeter = 를 출력하고, 그리고 나서 width+height+width+width 를 출력한다.

Question: width+height+width+width는 길이를 적절히 계산하는가? Answer: 어디 보자, 사각형의 변의 길이의 합은 아랫변의 너비 더하기 좌변의 높이 더하기 윗변의 너비 더하기 우변의 (히?) 합이다. 가장 마지막 항목은 우변의 길이, 혹은 높이가 되어야 한다.

Question: 왜 어떤 때는 길이가 '정확하게' 계산되었는지 이해하는가? Answer: 너비와 높이가 같을 때는 정확하게 계산되었다.

우리가 거닐어 볼 다음 프로그램은 5개의 점을 화면에 출력하는 프로그램이다. 그렇지만, 이것이 그 프로그램이 출력 한것인데

그리고 이것이 그 프로그램이다.

number = 5
while number > 1:
    print ".",
    number = number - 1
print

이 프로그램은 이제 들여쓰기된 부분(또는 제어 구조)을 가지므로 살펴보기에 더욱 복잡할 것이다. 이제 시작해보자.

Question: 실행되어야 할 첫 번째 라인은 무엇인가? Answer: 이 파일에서 첫번째 라인은: number = 5 이다.

Question: 그것은 무엇을 하는가? Answer: 숫자 5를 number변수에 넣는다.

Question: 다음 라인은 무엇인가? Answer: 다음 라인은: while number > 1: 이다

Question: 그것은 무엇을 하는가? Answer: 에 , while 서술문은 일반적으로 자신의 서술문을 살펴 보고서, 만약 참이라면 다음의 들여쓰기된 코드를 실행하고, 그렇지 않으면 그 코드를 건너 뛴다.

Question: 그러면 그것은 지금 무엇을 하는가? Answer: 만약 'number > 1' 이 참이라면 다음의 두 라인이 실행될 것이다.

Question: 그러면 number > 1 인가? Answer: number에 넣어진 마지막 값이 5 이고 '5 > 1' 이므로 그렇다.

Question: 그럼 다음 라인은 무엇인가? Answer: while 이 참이므로 다음 라인은 : 'print ".",' 이다

Question: 그 라인은 무엇을 하는가? Answer: 한 개의 점을 찍는다. 그리고 서술문이 , 로 끝나므로 다음의 print서술문은 다음 라인에 출력되지 않을 것이다.

Question: 다음 라인은 무엇인가? Answer: number = number - 1 이다 왜냐하면 그것이 다음 라인이며 아무런 들여쓰기 변화도 없기 때문이다.

Question: 그것은 무엇을 하는가? Answer: 그것은 number - 1 을 계산한다, 그것은 number의 현재값 (5)이고 거기에서 1을 빼서, 그것을 number변수의 새로운 값으로 한다. 그래서 기본적으로 그것은 number의 값을 5 에서 4 로 변경한다.

Question: 다음 라인은 무엇인가? Answer: 음, 들여쓰기가 되었으므로 우리는 어떤 종류의 제어 구조인지를 살펴보아야 한다. 그것은 while 회돌이다, 그래서 우리는 while 절로 되돌아 가야한다. 그 구문은 while number > 1:이다.

Question: 그것은 무엇을 하는가? Answer: number 변수의 값을 살펴보고, 그 값은 4 인데, 그것과 1 을 비교해본다. '4 > ' 이므로 while 루프는 계속된다.

Question: 다음 라인은 무엇인가? Answer: while 루프가 참이었으므로, 다음 라인은 : 'print ".",' 이다

Question: 그것은 무엇을 하는가? Answer: 그 라인에 두 번째 점 하나를 출력한다.

Question: 다음 라인은 무엇인가? Answer: 들여쓰기가 변하지 않았으므로 다음 라인은: 'number = number - 1' 이다

Question: 그러면 그것은 무엇을 하는가? Answer: 그것은 현재의 number 값(4)을 보여주고, 1을 number에서 뺀다, 그럼 3이 되고 그러면 결국에 3이 새로운 number의 값이 된다.

Question: 다음 라인은 무엇인가? Answer: while 회돌이의 마지막에 의해서 들여쓰기에 변화가 있으므로, 다음 라인은 : while number > 1: 이다.

Question: 그것은 무엇을 하는가? Answer: 그것은 number의 현재 값(3)을 1과 비교한다. 3 > 1 이므로 while 회돌이는 계속된다.

Question: 다음 라인은 무엇인가? Answer: while 회돌이 조건이 참이므로 다음 라인은 : print ".", 이다.

Question: 그리고 그것이 하는 바는? Answer: 세 번째의 점이 그 라인에 출력된다.

Question: 다음 라인은 무엇인가? Answer: 그것은 : number = number - 1 이다

Question: 그것은 무엇을 하나? Answer: 그것은 현재의 number 값(3)을 취해서 거기에서 1을 빼고 2를 새로운 number의 값으로 만든다.

Question: 다음 라인은 무엇인가? Answer: while 회돌이의 시작부분으로 되돌아 간다: while number > 1:

Question: 그것은 무엇을 하는가? Answer: 그것은 현재의 number 값(2)와 1을 비교한다. 2 > 1 이므로 while 회돌이는 계속된다.

Question: 다음 라인은 무엇인가? Answer: while 회돌이가 계속되므로 : print ".", 이다

Question: 그것은 무엇을 하는가? Answer: 그것은 삶의 의미와, 우주와 그리고 모든 것들을 탐구한다. 농담입니다. (여러분을 환기시키려고 흐흐~) 그 라인은 화면에 네 번째 점을 출력한다.

Question: 다음 라인은 무엇인가? Answer: 그것은: number = number - 1 이다.

Question: 그것은 무엇을 하는가? Answer: 현재의 number 값(2)를 취해서 거기에서 1 을 빼고 1 을 새로운 number의 값으로 만든다.

Question: 다음 라인은 무엇인가? Answer: while 회돌이로 다시 되돌아 간다: while number > 1:

Question: 그 라인은 무엇을 하는가? Answer: 그것은 현재의 number 값(1)을 1과 비교한다. 1 > 1 은 거짓이므로 (일은 일보다 크지 않다), while회돌이를 탈출한다.

Question: 다음 라인은 무엇인가? Answer: while 회돌이의 조건이 거짓이므로 다음 라인은 while 회돌이가 빠져 나온 이후의 라인이다, 또는: print

Question: 그 라인은 무엇을 하는가? Answer: 화면에서 다음 라인으로 이동시킨다.

Question: 왜 그 프로그램이 점 5개를 찍지 않는가? Answer: 회돌이가 1 점 빠르게 탈출한다.

Question: 어떻게 우리는 그것을 고칠 수 있나? Answer: 회돌이를 1점 나중에 탈출시킨다.

Question: 그럼 어떻게 우리는 그것을 하나? Answer: 여러가지 방법이 있다. 하나의 방법은 while 회돌이를 다음과 같이 바꾸는 것이다 : while number > 0: 또 다른 방법은 조건을 다음과 같이 바꾸는 것이다 : number >= 1 다른 방법도 많이 있다.

나는 어떻게 프로그램을 고치는가?

[+/-]

여러분은 프로그램이 무엇을 하는지를 이해할 필요가 있다. 여러분은 프로그램이 무엇을 해야하는지를 이해할 필요가 있다. 양자간의 차이점이 무엇인지를 이해해 보라. 디버깅은 반드시 배워야만 하는 기술이다. 여러분이 한시간이 지나도 이해할 수가 없어서 잠시 쉬고 있다면, 그 문제에 관하여 누군가와 상의 해보거나 고개를 푹 숙이고 숙고해 보라. 잠시 후에 돌아오면 여러분은 아마도 그 문제에 관하여 새로운 생각을 가지게 될 것이다. 행운을 빈다.