Tip:
Highlight text to annotate it
X
(번역 : Jisoon Lim) 앞의 비디오들에서 우리가 작성한 프로그램은
(번역 : Jisoon Lim) 사용자에게 어떤 숫자를 입력시키고,
입력받은 숫자에 대한 팩토리얼을 계산해서
화면에 출력했습니다.
쓸만하겠지요. 근데 실제로는 팩토리얼 계산을
여러 군데에서 해야 되거나,
서로 다른 여러 프로그램에서 해야 되거나,
여러분이 만든 프로그램 안에서
팩토리얼 계산을 여러 번 해야 될 수도 있어요.
그럴 때가 되면, 이 코드를 필요할 때마다
매~번 매~번 다시 타이핑하는 건
별로 하고 싶지 않은 일이겠죠?
그래서 이번 비디오에서는,
팩토리얼을 계산하는 함수를 하나 정의하고
우리가 팩토리얼을 계산해야 될 때마다
그 함수를 사용하는 방법을 알려줄게요.
자 ... 이 함수가 뭘 할 건가 하면 ...
여~기 이 코드들을 전부,
이 코드들을 전~부 다
한 군데에 모아놓고,
다른 프로그램에서 팩토리얼을 계산하고 싶으면
이 코드를 그냥 호출하는 거에요.
이걸 다시 타이핑할 필요가 없어요.
자, 이게 무슨 말인지 다시 설명해볼게요.
함수 이름을 하나 정의하고 ...
파이썬에서 쓰는 키워드를 앞에 놓습니다.
이 키워드가 어디에 쓰는 거냐면,
뭔가 특별한 일을 벌릴 거라고
인터프리터에게 알려주기 위한 겁니다.
파이썬에서 함수를 정의할 때 쓰는 키워드는 "def" 입니다.
자, 그러니까 이렇게 함수를 정의하고
이걸 팩토리얼 함수라고 부를게요.
보통 그 함수가 실제로 하는 일에 따라서
함수 이름을 붙이는 게 좋습니다.
가끔 초보 프로그래머들을 보면
함수나 변수 이름을 "x245" 뭐 이런 식으로 정하는데요,
나중에 다른 사람이 그 코드를 보면
당췌 그게 뭘 하는 건지 전혀 알 도리가 없겠지요.
당췌 그게 뭘 하는 건지 전혀 알 도리가 없겠지요.
그러니까 왠만하면 이름을 정할 때
그게 무엇을 뜻하는지에 관련지어서 정하는 게 좋아요.
제 함수 이름은 팩토리얼이고,
사용자가 팩토리얼 함수를 호출할 땐,
팩토리얼 함수에게 어떤 수의 팩토리얼을 취할 지
그 수를 알려줘야 됩니다.
사용자는 그걸 인자 형태로 전달할 거고 ... 이름은 "number" 로 정하겠습니다
지금 쓰는 단어들이 좀 헷갈린다면
짧은 시간 안에 다 설명드릴 수 있을 텐데요,
뭐, 그냥 자주 접하고 듣다 보면은
익숙해지고 이해할 수 있게 될 겁니다.
자, 함수 사용자들은 숫자를 전달하고
그럼 함수는 자기를 호출한 프로그램에게
반환값을 돌려주는 겁니다.
정확히 말하자면
사용자가 숫자를 전달하는 게 아니고
함수를 호출하는 프로그램이 숫자를 함수에 전달하고,
함수는 그 숫자의 팩토리얼 계산값을
호출한 프로그램에 반환하는 겁니다.
자, 주석을 좀 달아 볼게요.
"number" 인자의 팩토리얼값을 반환하고
아, 가끔은 인자라는 단어 대신에
매개변수라는 단어를 쓰기도 합니다. 같은 거에요.
함수를 정의하는 코드를 짤 때에는
좀 더 공식적 표현으로 매개변수란 단어를 씁니다.
"Number" 는 팩토리얼 함수의 매개변수 중 하나가 되는 겁니다.
"Number" 는 팩토리얼 함수의 매개변수 중 하나가 되는 겁니다.
자, 그럼 실제로 다른 누군가가 숫자를 넘긴다 치고
누군가 함수를 호출하면서 "3"을 넣는다고 합시다.
그러니까 인자로 3이 입력된 거에요
그럼 함수는 인자 "number"의 팩토리얼값을 반환하니까
바로 여기 이게 인자 "number" 죠?
숫자라는 뜻의 "number" 를 말하는 게 아니라
여기 제가 코드상에서 이름붙인 "number" 를 말하는겁니다.
인자 "number" 라고 하는 편이 낫겠네요
확실히 하기 위해서
여기 이건 인자고,
일반적인 숫자를 말하는게 아니라고 써야겠어요.
자, 그럼 정의해봅시다.
우리는 동일한 코드를 그대로 쓸 겁니다.
그러니까 ... 이렇게 긁어 붙이기를 합시다!
자주 하게 될 거에요.
여기 이 부분을 잘라내고
이걸 여기다 다시 붙여넣고
하지만 여기서 들여쓰기에 주의해야 됩니다.
왜냐면, 파이썬에서 들여쓰기란
인터프리터가 구조를 확인하기 위한 방법이거든요.
그러니까 함수 정의에 있어서 함수의 내용은
들여쓰기가 되어야 됩니다. 우리는 4칸을 쓸 겁니다.
1 .. 2 .. 3 .. 4
여기도 4칸 줍시다
1 .. 2 .. 3 .. 4
그리고 이건 for loop 죠?
1.. 2.. 3.. 4
자 그럼 이제까지 뭘 했는지 보자구요
어떤 숫자가 전달될거고,
여기 정의한 이 "product" 라는 변수에는 1을 대입했지요
변수의 스코프에 대해서는 나중에 더 얘기할건데,
일단 이 "product" 변수는 팩토리얼 함수 안에서만 쓸 수 있다고 알아두세요.
일단 이 "product" 변수는 팩토리얼 함수 안에서만 쓸 수 있다고 알아두세요.
왜냐하면 이 녀석을 정의한 부분이
이 함수 안쪽에 있으니까요.
변수의 스코프에 대해서는 나중에 더 다루기로 하고,
여기선 전에 한번 다룬 로직을 사용합니다.
"for i in range(number)" 이죠
이제 숫자를 input 함수를 통해서 넣는 게 아니라
함수를 통해서 전달될 거고요,
그럼 "product" 에는 "product" x ("i" + 1) 이 대입됩니다
전에 쓴 로직과 같지요.
그럼 이 for loop 를 통과하고 나면,
통과하고 나면,
딱 "number" 의 수만큼 반복하는 거에요.
그럼 "product" 에 담긴 값은 "number" 의 팩토리얼이 되고요,
그 값을 바로 출력하는 게 아니라
반환하게 됩니다.
호출한 프로그램에 반환하는 거지요.
다음 비디오에서는 이 과정에 대한 다이어그램을 그려서
좀 헷갈릴 수 있는 부분을 명확하게 해 줄게요.
자, "product" 를 반환했습니다.
결국 이건 전에 짠 코드와 똑같은 역할을 하지만
함수라는 형태로 포장된 겁니다.
우리는 함수를 정의했습니다.
그 함수는 "number" 라는 매개변수를 받는데,
만약 3의 팩토리얼을 원한다면!
팩토리얼 3을 구한다 치면...
3이 그 매개 변수가 되는 거고요
그 값이 변수 "number" 에 들어가거나
"number" 가 참조하는 값이 들어가는 거에요.
그리고 이 "product" 는 처음에 1로 정의되었고
여기 "for i in range(number)" 형태로 만든 for loop 에서
"number" 횟수만큼 반복 연산됩니다.
그 로직에 대해서는 저번 시간에 설명했지요.
항상 1로 시작하고,
1 x 1 해서 1 이 되고,
그럼 "product" 는 1이 되고,
반면 그때 "i" 는 1이 되죠
"i"는 0 부터 시작하니까,
1 x (0 + 1) 은 1이 되고,
그리고 "i" 는 2가 되고, 그럼 1 x 1 이 되어서
죄송, "i" 는 1이네요
그럼 1 x (1 + 1) 이 되고, 그니까 1 x 2 지요
그럼 2가 되는 겁니다.
이런 식으로 계속 증가하는 거죠.
다 저번 시간에 얘기한 겁니다.
그리고 결국 마지막에 이 "product" 를 반환하지요.
그래서 전과 똑같은 프로그램을 짜는데 있어서
이 함수라는 형태를 써야 한다면요,
어떻게 할 수 있냐면 ...
여전히 입력값이 있고, 그리고 여기 함수 정의가 있습니다.
반면 우리의 메인 프로그램에서
우리는 이미 함수를 정의했으니까요
이렇게 하는 겁니다.
"야, 사용자한테서 팩토리얼 취할 자연수를 받아와"
"야, 사용자한테서 팩토리얼 취할 자연수를 받아와"
그럼 그 받아올 값을
"user_input" 이란 이름의 변수로 합시다.
이제 그럼 ... 뭘 하냐면요
"factorialofuser_input" 이라는
다른 변수를 하나 정의합니다.
여기서 재미있어지는데요.
함수를 여기서 호출하면,
이게 결국은 사용자가 입력한 값의
팩토리얼값이 됩니다.
여기 있는 변수 "user_input" 의 팩토리얼이죠.
여기 있는 변수 "user_input" 의 팩토리얼이죠.
사용자가 입력한 값의 팩토리얼이요.
그럼 "factorialofuser_input" 은 그 값을 저장하고,
결국 결론은 이거지요
이렇게 하면 전과 똑같은 기능을 구현한 거고
출력까지 끝낸 거에요.
"factorialofuser_input" 를 출력한 겁니다.
이 변수가 문장처럼 보이지만
정해진 변수 이름이에요.
이렇게 명확하게 이름지으면
그 안에 뭐가 들어있는지,
혹은 그 변수가 뭘 가르키는 지 알기 쉬우니까요.
그래서 "factorialofuser_input" 입니다.
자, 진실의 순간이 왔어요.
실행하기 전에 프로그램을 저장하고,
자, 한번 돌려서 뭐가 나오는지 볼까요?
어떻게 되나 봅시다.
아직까진 문제가 없는 듯 한데,
자, 이쯤에서
한번 더 짚고 넘어갈게요.
여기서 정의한 이녀석은
사용자와 뭘 주고받는 게 아니에요.
그러니까 아직까지 아무 처리를 안 했고
함수만 선언된 거에요. 밑에 여기로 오면
"그래, 사용한테 입력 좀 받아와" 라고 하고
그 다음에 우리가 하려던 일을 합니다.
수를 여기 입력하고
그럼 실제로 그 수를 가지고 함수를 호출할 텐데
우리가 넣은 그 수는
"user_input" 에 들어가겠죠
그럼 "user_input" 을 인수로 해서
팩토리얼을 호출할 겁니다.
3으로 해 봅시다.
안 되네요! (ㅎㅎㅎ)
아, 왜 안되는지 알겠네...
예전 프로그램을 여기 그대로 남겨놨잖아요.
지금 이렇게 되면 말이 안 되죠.
이 부분을 없앨게요.
보통 한 번에 일이 되진 않는다는
적절한 교훈입니다.
다시 해 봅시다!
말도 안 되는 코드였는데 저는
밑에 뭐가 있었는지도 모르고 있었네요
다시 해 보겠습니다.
다시 3으로 ...
오, 답이 나왔습니다.
3의 팩토리얼이 나왔고요
이게 좋은 게 말이죠,
이제 이 파이썬 인터프리터가
함수가 정의된 걸 알았고
그럼 인터프리터에서 그냥 함수를 호출할 수 있게 되요.
다른 프로그램을 가지고 있으면
이걸 여러 번 호출할 수도 있고요
그럼 완전 땡큐겠죠,
다 함수를 정의해 놨기 때문에
계산할 수 있는 겁니다
팩토리얼 함수를 정의한 덕이에요.
그럼 이제 4의 팩토리얼을 계산할 수도 있죠.
24네요.
5의 팩토리얼에서 3의 팩토리얼을 빼면
114 군요.
12의 팩토리얼도 구할 수 있고요
그리고 컴퓨터에게
여기선 계속 인터프리터로 돌리지만,
나중에 인터프리터 코드와 컴파일 코드에 대해 다시 얘기할 건데,
이게 훨씬 빠릅니다.
우리가 논할 수 없을 정도로 빨라요.
매번 이 코드를 다시 쓸 필요가 없다는 것,
이게 이 함수의 진짜 좋은 점입니다
서로 다른 인자로 호출할 수도 있고요.
팩토리얼 2 ... 프로그램을 다시 돌리지 않고도
계속 할 수가 있어요.
팩토리얼을 쓰는 다른 프로그램을 짠다면,
뭐 이를테면 조합 계산하는 걸 짠다면,
이 함수를 그대로 다시 써도 됩니다.
사실상 이 함수 안에 뭐가 들었는지
알 필요도 없고요.
이것도 함수의 좋은 점입니다.
만약 제가 프로그램들을 엄청 짰고
그 프로그램이 이 팩토리얼을 호출하는데
다른 사람은 이 부분을 그대로 갖다가
코드를 짜는 식으로 짤 수도 있어요.
서로 다른 방식으로 프로그램이 돌아가고 있어도
서로 다른 방식으로 프로그램이 돌아가고 있어도
사실 사용자는 알 바 아닙니다.
그니까 더 빠르거나 간단한 방법을 쓰는 게 낫죠.
그니까 더 빠르거나 간단한 방법을 쓰는 게 낫죠.
이런 식으로 하면 메모리나 CPU 전력도 아낄 수 있고
나중에 이 부분을 대체해서
다른 프로그램이 호출한다면,
잘 돌아가기만 하면
다른 프로그램에서도 잘 돌아갈 겁니다.
그럼 그 편이 훨씬 낫겠죠.