99병의 맥주 파이썬

티스토리 블로그에 포스팅했던 99병의 맥주 파이썬 코드를 이 곳에 포스팅합니다.

for x in range(99, 0, -1):
	print("%d병의 맥주가 벽장에 있네, %d병의 맥주가 있네." % (x, x))
	print("한 병을 내려서 넘겼다네.", end=" ")
	txt = "%d병의 맥주가 벽장에 있네." % (x - 1) if x > 1 else "더 이상 벽장에 맥주는 없네."
	print(txt, end="\n\n")
 
print("더 이상 맥주가 벽장에 없네. 맥주는 더 이상 없네.")
print("가게에 가서 다시 사왔네. 99병의 맥주가 벽장에 있네.")

이 코드의 구조를 해설하자면 다음과 같습니다.

일단 1번 줄과 같이 for x in range(a, b, c): 식으로 쓰면 x의 값이 a부터 시작해서 c만큼 값이 증가(또는 감소)하다가 b에 다다르는 순간 반복이 끝난다는 것을 의미합니다. 여기서 c는 생략 가능하며 생략할 경우 1씩 증가합니다. 이 예제에서는 99부터 시작해서 1만큼 감소하다가 0이 되는 순간 블록을 빠져나가 다음 코드를 수행합니다.

다만 주의해야 할 점이 있는데, 파이썬의 for 문은 종료값에 다다르면 그 값의 블록을 수행하는 것이 아니라 그 즉시 종료하고 다음 코드를 수행한다는 점입니다. 예를 들어, for x in range(0, 10):으로 썼을 경우 실질적으로는 x의 값이 9가 될 때까지만 블록을 수행하고 10이 되면 그냥 빠져나갑니다. C언어의 for(x=0; x<10; x++) { ... }와 같다고 보면 됩니다.

파이썬에서는 { } 식으로 감싸거나 end 등의 블록 종료 선언 없이 들여쓰기로 구조로 블록을 표현합니다. 이 예제에서는 1번 줄의 for 문은 2번 줄부터 5번 줄까지 반복됩니다. 이 반복되는 부분의 코드를 해설하자면,

2번 줄에서는 print("%d병의 맥주가 벽장에 있네" % x) 식으로 print 함수문을 사용한 것을 볼 수 있습니다. 이처럼 print("문자열" % 변수) 식으로 쓸 경우 변수를 문자열의 치환자에 넣어서 표시합니다. C언어 등에서 쓰는 sprintf 함수와 같다고 생각하면 됩니다. 이 방식은 print 함수 뿐만 아니라 변수 대입 등에서도 사용할 수 있습니다. 이 예제처럼 복수의 치환자가 존재할 경우 print("%d병의 맥주가 벽장에 있네, %d병의 맥주가 있네." % (x, x))와 같이 변수 부분을 괄호로 감싸서 사용합니다.

3번 줄처럼 print("문자열", end=" ") 이렇게 쓰는 것은 Hello, world! 출력 예제에도 설명한 바와 같이 끝을 개행 문자가 아닌 공백 문자 하나로 처리합니다. 다음에 print 문이 올 때 공백 하나를 사이에 두고 같은 줄에서 이어서 표시합니다.

4번 줄은 변수 대입을 할 때 if ... else 문을 사이에 두고 두 가지 값을 동시에 대입선언하는데, 이 경우 그 조건문에 제시된 조건이 참이면 앞의 값을 대입하고 거짓이면 뒤의 값을 대입하는 것을 뜻합니다. 이 예제에서는 x의 값이 1보다 클 경우 txt 변수에 "n병의 맥주가 벽장에 있네"(n은 x에서 1을 뺀 값)를, 그 외는 "더 이상 벽장에 맥주는 없네"를 대입합니다.

5번 줄은 4번 줄에서 대입한 txt 변수의 내용을 출력합니다. end 값이 \n\n 이렇게 되어 있는데, 이는 출력할 문자열의 끝에 개행 문자를 두 번 넣겠다는 뜻입니다. 다음에 print 문이 올 때 한 줄이 더 띄어져서 출력됩니다.

6번 줄과 7번 줄은 들여쓰기가 없습니다. 이 부분은 앞의 반복문에 포함되지 않고 반복이 끝날 때 수행됩니다.

이 코드를 실행시키면 다음과 같습니다.

99병의 맥주가 벽장에 있네, 99병의 맥주가 있네.
한 병을 내려서 넘겼다네. 98병의 맥주가 벽장에 있네.

98병의 맥주가 벽장에 있네, 98병의 맥주가 있네.
한 병을 내려서 넘겼다네. 97병의 맥주가 벽장에 있네.

97병의 맥주가 벽장에 있네, 97병의 맥주가 있네.
한 병을 내려서 넘겼다네. 96병의 맥주가 벽장에 있네.

(... 중간생략 ...)

2병의 맥주가 벽장에 있네, 2병의 맥주가 있네.
한 병을 내려서 넘겼다네. 1병의 맥주가 벽장에 있네.

1병의 맥주가 벽장에 있네, 1병의 맥주가 있네.
한 병을 내려서 넘겼다네. 더 이상 벽장에 맥주는 없네.

더 이상 맥주가 벽장에 없네. 맥주는 더 이상 없네.
가게에 가서 다시 사왔네. 99병의 맥주가 벽장에 있네.

답글 남기기

이메일 주소는 공개되지 않습니다.