※ 이 글은 이상한모임에서 lemonade(현지환)님과 수다를 떨다가 "이런 내용의 책, 재밌지 않을까?" 라는 이야기가 나와서 쓰기 시작한 글입니다. 시리즈물로 제가 생각한 앞 부분만 살짝 연재해볼 생각입니다. 책으로 내보자는 이야기도 있었는데 제가 실력이 없으므로 안될겁니다. 근데 이 글이 계속 연재될진 알 수 없...

진짜 내 문제 찾기

프로그래밍 학습에서 가장 중요한 것은 자신이 무엇을 하고 싶은지 확실히 아는 것입니다. 무엇을 하고 싶은지가 확실해야 자신이 하려는 것을 하기 위해 무엇이 들어가는지 더 몰입해서 생각할 수 있습니다. 학교 공부가 재미없다던가, 이걸 배워서 뭐에 쓰나 하는 생각은 사용법만 알려줄 뿐 어떻게 쓸 수 있을지를 알려주지 않기 때문입니다. 이번 장에서는 제가 예전에 했던 고민거리를 직접 처리해보도록 하겠습니다.

동아리 회원명단 관리 - 문제 발견

※ 이 문제는 제가 예전에 겪었던 문제의 변형입니다.

A 대학교에서는 모든 동아리가 동아리 회원명부를 txt 파일에 저장해서 보관하고 있었습니다. 총학생회에서는 동아리에 대한 통계를 얻고 싶은데, 엑셀로 변환해서 작업하기엔 동아리의 수가 너무 많습니다.

총학생회는 다음 작업을 수행해야 합니다.

  1. 복사해서 붙여넣기를 반복했더니 중복돼서 입력되어있는 회원이 있습니다. 학번을 기준으로 중복을 모두 제거해야 합니다.
  2. txt 파일에는 술을 마셔도 되는지를 판단하기 위해 만 나이를 저장해놓았습니다. 하지만 매년 갱신하지 않았기 때문에 기재된 나이와 실제 나이가 맞지 않는 경우가 있는데 모두 수정해야 합니다.
  3. 1과 2를 수행한 모든 동아리별 자료를 한 파일에 몰아서 기록하고 싶습니다. 이때, 입력은 학번순으로 되어야 하고, 구분의 편의성을 위해 '동아리'가 들어가는 칸이 추가됩니다. 단, 저장할 정보는 학번, 이름, 생일, 나이, 재학 여부만이고 나머지 정보는 모두 버립니다.
  4. 현재 재학 중인 부원이 한 명도 없는 동아리가 어디인지 알고 싶습니다.

사실 이 문제는 동아리가 적다면 엑셀을 쓰면 간단히 해결할 수 있습니다. 하지만 동아리가 너무 많고, txt에 저장한 모양이 모두 달라서 한 번에 손으로 합치기엔 무리가 있다고 가정합니다.

예시 txt 파일 - 오버워치.txt

※ 오버워치의 등장인물 일부를 사용했습니다. 편의상 오버워치 동아리라고 명명합니다. 모든 값은 예시를 위해 임의의 값으로 설정했습니다.

num,name,birthday,age,status
19950102,솔져: 76,1876-04-26,10,휴학
19990202,윈스턴,1899-09-16,20,재학
20010302,레나 옥스턴,1927-12-11,30,재학
20020402,메르시,1939-03-16,40,졸업
20030402,메르시,1939-03-16,40,졸업

예시 txt 파일 - 롤.txt

※ 리그 오브 레전드의 등장 챔피언 일부를 사용했습니다. 편의상 롤 동아리라고 명명합니다. 모든 값은 예시를 위해 임의의 값으로 설정했습니다. (재학생 없음)

num,name,pos,age,birthday,status
20000305,녹턴,탑,10,1999-01-01,졸업
20010305,니달리,탑,20,1989-02-02,휴학
20010305,니달리,탑,20,1989-02-02,휴학
20050305,렝가,탑,30,2000-03-03,자퇴
20060305,르블랑,탑,40,1987-05-29,제적

원하는 결과값 - 전체 명단 (3번)

num,name,group,birthday,age,status
19950102,솔져: 76,오버워치,1876-04-26,140,휴학
19990202,윈스턴,오버워치,1899-09-16,116,재학
20000305,녹턴,롤,1999-01-01,17,졸업
20010302,레나 옥스턴,오버워치,1927-12-11,88,재학
20010305,니달리,롤,20,1989-02-02,27,휴학
20020402,메르시,오버워치,1939-03-16,77,졸업
20050305,렝가,롤,30,2000-03-03,16,자퇴
20060305,르블랑,롤,40,1987-05-29,29,제적

원하는 결과값 - 재학중인 부원이 없는 동아리 (4번)

이거 너무 어렵지 않아요?

이 문제를 준비하면서 가장 염두에 둔 것은 현실성입니다. 현실성이 없는 문제는 풀어도 프로그래밍의 필요성에 대해 이해가 안 가기 때문입니다. 가령 남들 많이 하는 구구단 같은 것을 해본다 해도 현실에서 구구단을 필요해서 짤 일은 그리 없습니다. 현실적이지 않은 가상의 문제를 풀라고 강요하면 짜증 날 수밖에 없죠.

그에 비해 이 문제는 현실에서 직접 마주할 수 있는 경우이죠. 저는 이 문제를 직접 풀어보고 검토하는 용도로로 1,000개 이상의 파일을 이 문제가 끝나면 제공해서 자신의 코드가 맞는지 검사해볼 수 있도록 할 예정입니다. 1,000개 이상의 txt 파일을 일일이 열어서 엑셀에 맞춰 넣는 작업은 사람이 하기엔 매우 짜증 나는 작업입니다. 사람이라면 당연히 더 효율적인 방법을 찾고 싶어질 것입니다. 실제로 이런 작업을 해야 한다면 프로그래밍을 통해 처리할 수밖에 없죠.

동아리 회원명단 관리 - 천릿길도 한 걸음부터

이 문제가 어려워 보인다면, 그것은 아직 아는 것은 없고 모르는 것으로 가득한 상태이기 때문입니다. 모르는 것을 하나씩 알아가면 답에 다가갈 수 있습니다.

일단 파일을 하나 만들어봅시다. 파일명은 group.py라고 합시다. 그리고 아래 내용을 받아적어 봅시다. (복사해서 붙여넣기는 하지 마세요)

num = '19950102'
name = '솔져: 76'
birthday = '1876-04-26'
age = 10
status = '휴학'

print(name)
print('(학번 :')
print(num)
print(')의 생일은')
print(birthday)
print('이고,')
print(age)
print('살이며 현재')
print(status)
print('중입니다')

1~5번째 줄에서는 사람의 정보를 저장하고 있습니다. =를 기준으로 왼쪽에다가 오른쪽 값이 대입됩니다. 가령 첫 번째 줄에는 num이란 공간에 '19950102'가 저장되는 것입니다. 여기서 num과 같이 무언가를 저장하는 장소를 변수라고 합니다. 여기서 변수란, 변할 수 있는 값이라는 뜻입니다.

변수에 대입되는 값을 보면 ''으로 감싼 것이 있고, 그렇지 않은 것이 있습니다. ''로 감싸진 것은 문자열(str)형입니다. 감싸지 않고 숫자만 적은 것은 정수(int)입니다.

이 프로그램을 실행해보면 다음과 같이 나옵니다. Windows라면 cmd창에서, Linux와 Mac은 터미널에서 해당 파일이 있는 위치로 이동한 다음 python group.py라고 명령어를 입력하면 됩니다. 하지만 아직 원하는 파일 위치로 이동하는 방법을 알려드리지 않았으므로, 할 줄 모르겠다면 지금은 그냥 보기만 하셔도 됩니다.

솔져: 76
(학번 :
19950102
)의 생일은
1876-04-26
이고,
10
살이며 현재
휴학
중입니다

7번째 줄부터 나오는 print라고 하는 것은 출력을 담당하는 함수 이름입니다. 이것을 이용하면 원하는 값을 출력할 수 있습니다.

실제 출력과 비교해보면 이해하기 쉽습니다. 실제 프로그램에서 이름이 먼저 나왔는데, print 함수들 중``name``이 들어있는 것이 가장 처음 사용되고 있습니다. 그 뒤로 '(학번 :'이란 글자를, 그다음은 실제 학번(num)을 print 함수로 출력하고 있는것이죠.

변수? 문자열? 인자? 함수? 무슨 소린지 모르겠어요

일단 변수부터 알아봅시다. 변수라는 것은 변할 수 있는 값입니다. 1부터 10까지 더하는 프로그램을 생각해봅시다. 이 프로그램을 만든다고 하면 처음에 0이 어딘가에 있고, 거기에 1을 더하고, 그다음에 2를 더하고, 이런 식으로 10까지 더해야 할 것입니다. 처음에 0이 있고, 그 뒤에 값이 점점 바뀌어나가는 장소를 변수라고 합니다. 변수는 구분을 위해서 이름을 가지고 있습니다. 가령 위의 소스에서 num이나 name은 변수의 이름입니다.

문자열(str)이나 정수(int)같은 것은 다루는 자료의 유형을 말합니다. 식재료를 예로 들자면 사과나 배 같은 과일, 오이나 양파 같은 채소, 소고기나 닭고기 같은 고기 등등으로 종류가 나뉘듯, 컴퓨터에서 처리하는 자료도 종류가 다양한 것입니다.

인자와 함수는 같이 설명하도록 하겠습니다. 이 글을 읽는 대부분의 독자분들은 이미 중고등학교 과정에서 함수를 배우신 적이 있을 것입니다. 예를 들면 이런 것이죠.

f(x) = 2x + 3

우리는 f라는 함수에 1을 넣으면 x 자리가 1로 바뀌어서 2*1 + 3이 된다는 것을 알고 있습니다. 프로그래밍에서의 함수는 위의 예시에서 f에 해당하고, 인자는 x에 해당합니다.

그래도 모르겠어요

당연합니다. 지금 처음으로 컴퓨터와의 대화에 쓰이는 언어를 접한 것인데 처음부터 모든 게 귀에 들어올 리 없습니다. 처음 보는 언어, 처음 듣는 단어들이니까 지극히 당연한 현상입니다.

설명하는 입장에서도 독자분들에게 지금까지 나온 개념 중 그 어느 것도 더 깊은 설명을 해드릴 수 없는 상황입니다. 왜냐하면, 그것은 프로그래밍을 어느 정도 아는 사람에게만 설명이 가능한 것들로 구성되어 있기 때문입니다. 유치원생에게 1, 2, 3 같은 숫자는 가르치지만, 그때 1과 1/1, 2/2, 9/9, 0.99999…, √(1)은 같다는 것도, 1이 *에 대한 항등원이라는 사실도 알려주지 않는 것과 마찬가지입니다. 지금은 첫 시작이므로, 어떤 느낌으로 접근하고 있는지를 읽고 쓰는 데에 집중합시다.

숙제

  1. 위에서 만든 소스를 한벌을 더 만들어서, 자기 신상정보에 맞게 만들어보세요. (파일명 myinfo.py)
  2. 위에서 나온 소스 코드를 실행하기 위해서는 원하는 위치로 이동하는 법을 알아야 한다고 했습니다. 이동은 어떻게 하는지 조사해보세요. 찾는 데에 실패해도 상관없습니다. 찾아보려는 시도가 중요합니다.

후일담

이 시리즈는 사실 꾸준히 연재할 생각이었습니다. 하지만 제 몸 상태가 별로 좋지 않았던지라 5편까지 작성한 뒤로 6편을 계속 썼다가 지웠다가를 반복했습니다. 어느정도 내용 정리가 완료된 뒤로는 올려야겠다고 생각만 하고 계속 미루다보니 너무 늦어졌습니다. 그 사이 이 글의 시작점이 되었던 이제 현지환씨는 제이펍에 안 계시게 되어버렸고, 앞서 나왔던 Python 버전도 바뀌어버렸습니다. 저는 저 자신에게 이 글을 쓸 수 있는 역량이 있긴 한지 솔직히 의문스럽지만, 가끔 제 글을 인용해주시는 분을 본 것 같아서 짬짬이 계속 써볼 생각입니다. 오래 기다리게 해드려서 죄송하고(아무도 안 기다렸다고 한다), 앞으로는 블로그를 냉동시키지 않도록 노력하겠습니다.