파이썬의 두 가지 코딩 모드 – 셸 & 코드 편집기

파이썬의 설치에 대해서는 넘기도록 하겠습니다. 파이썬 홈페이지에서 다운로드 해서 설치하는 것이 너무 잘 나와있어서 굳이 똑같은 걸 쓸 이유는 모르겠군요.

일단 파이썬을 설치하게 되면 파이썬 인터프리터와 표준 라이브러리, 그리고 IDLE(아이들이라고 읽으시면 됩니다.)가 설치됩니다. 이 IDLE는 통합 개발 환경을 말합니다. IDLE은 대화형 파이썬 셸(Python Shell)과 코드 편집기 두 가지 모드로 사용이 가능합니다. 짧은 예시의 경우에는 간단하게 셸에서 작성하여도 되지만 코드가 길어지고 하다 보면 코드 편집기를 더더욱 활용하게 될 것입니다.

스크린샷 2017-03-30 오후 11.59.51

코딩 모드의 차이를 보여드리기 위해서 예시를 준비했습니다. 프로그램 시작시 간단하게 쓰는 Hello World를 출력하겠습니다. IDLE를 실행해주세요.

제 작업환경이 요즘 맥이라서 맥에서 보여드립니다. (어느 것이 더 편하다고는 말 못하겠습니다만 여러분에 파이썬 설치 후 PATH 설정까지 했다면 윈도우가 더 편할수도 있습니다. 쓰기 나름이죠.) 처음 뜨는 저 화면이 바로 파이썬 쉘 화면입니다. 쉘 화면에 >>> 표시가 뜨지 않으면 엔터키를 입력하면 뜰 겁니다. 그리고 여기에 print(“Hello World”) 라고 입력하고 엔터를 치면 그대로 결과가 출력됩니다. 세미콜론 입력 안해도 되는데 전 습관적으로 입력했군요.

print() 라는 함수는 그대로 해당 내용을 출력하라는 함수입니다. 그래서 안에 내용을 출력하였습니다. 그런데, 파이썬의 셸에서는 print의 도움 없이도 숫자나 텍스트를 출력할 수 있습니다. 숫자의 경우에는 그대로 입력하고 엔터를 치면 그대로 출력이 될 것이고, 텍스트의 경우에는 ‘ ‘, ” ” 안에 내용을 입력하여야 합니다. 그렇지 않으면 파이썬 코드인 줄 알고 실행했다가 에러를 발생합니다.

이 기능은 사실 변수 안에 어떤 값이 있는지 확인하기 위해서 자주 쓰입니다. 전용 셸이 있는 인터프리터 언어들은 대부분 이런 기능을 가지고 있습니다.

그럼 이제 코드 편집기를 실행해 보도록 하겠습니다. 코드 편집기는 IDLE 창에서 [file] -> [new file] 메뉴를 클릭하면 코드 편집기가 따로 나타납니다. 그리고 아래의 화면을 나타난 코드 편집기에 hello world를 출력하는 문장을 그대로 입력하였습니다.

그냥 파이썬의 소스 코드를 그대로 쭉 입력하여 파일로 저장하면 됩니다. 파이썬 코드의 확장자는 py입니다. 그리고 실행의 경우에는 코드 편집기 상태에서 F5 키를 누르거나 [run] -> [run module] 메뉴를 실행하면 실행할 수 있습니다. 아래 예시에서는 파일의 내용이 실행되는 것을 보여드리기 위해서 별도로 만들어서 실행하였습니다.

마지막으로 파이썬 코드를 작성한 다음에는, 각 운영체제의 커멘드 라인 인터페이스 환경에서 실행할 수 있습니다. 윈도우라면 명령 프롬프트에서, 리눅스, 유닉스, 맥에서는 터미널에서 실행할 수 있습니다. 해당 코드가 있는 위치로 이동하여 코드를 실행합니다.

이상으로 파이썬 코드의 실행에 대한 가장 기본적인 것을 살펴보았습니다. 파이썬은 은근 빨리빨리 나갈 수 있어서 금방 내용이 올라갈 것입니다.

43 – 포인터

드디어 올 것이 왔습니다. (빨라!)

포인터란 메모리의 주소를 값으로 갖는 변수를 말합니다. 메모리의 주소값은 하드웨어에 의해 정해지는 값이기 때문에 하드웨어를 제어하는 기능을 하게 됩니다. 이런 하드웨어를 제어하는 대부분의 시스템 소프트웨어들은 C언어로 개발하게 됩니다.

변수가 선언된 프로그램은 실행중에 메모리의 일정 영역에 해당 변수가 생성된다. 그런데 메모리에는 각 부분을 구분하기 위해 주소가 부여되어 있으므로 변수에는 대응되는 주소가 반드시 존재한다. C언어에서는 변수의 주소를 확인하려면 변수 이름 앞에 엠퍼샌드(&)를 붙이면 확인이 가능하다. 이를 아래의 예제와 같이 3개의 요소를 갖는 float형 배열 arr에 대한 주소를 출력하는 프로그램으로 확인할 수 있다.



C언어에서는 주소를 저장하는 변수를 사용할 수 있는데, 이러한 변수를 포인터 변수라고 한다. 포인터 변수를 선언하려면 다음과 같이 변수 이름 앞에 에스테리스크(*)를 붙이면 포인터 ㅂ녀수가 도니다.

데이터형 *변수이름

아래의 예시와 같이 포인터 변수를 선언하면 되는데, k 값의 경우에는 int형 데이터를 저장하고 있는 메모리 주소를 저장하는 변수고, l은 float형 데이터를 저장하고 있는 메모리 주소를 저장하는 포인터 변수다.

int *k;

float *l;

포인터 변수에 대한 개념을 아래의 예시 프로그램을 통해 다시 살펴보도록 하겠다.


i변수의 주소가 0x00001000이라고 할 때, 포인터 변수 ptr은 해당되는 주소를 가지고 있는 것이다. 알래의 그림은 좀 더 쉽게 설명하기 위해 그린 그림이다.


이런 식으로 ptr변수는 i변수의 주소를 직접 가지고 있기 때문에 i를 ptr로 제어할 수 있는 것이다.

그러나, 아래에 보면 선언문이 아닌 곳에서 에스테리스크를 붙이는 것을 볼 수 있는데, 이는 이 포인터 변수가 가리키는 곳의 내용을 의미하게 된다. 그래서 (*ptr)++을 실행할 때, ptr이 가리키는 변수 i값에 대해서 ++연산을 하게 된 것이다. 그래서 출력한 값이 11이 된 것이다.

포인터에서 중요하게 생각할 것은 다음과 같다.

  1. 변수 선언문에 붙어있는 에스테리스크는 포인터 변수를 선언할 때 사용된다.
  2. 선언문이 아닌 곳에 붙어있는 에스테리스크는 포인터 변수가 가리키는 실제 값을 가리킨다.
  3. 앰퍼센트가 붙어있으면 해당 변수의 주소를 확인할 수 있다.

일단 여기까지가 포인터에 대한 기본 정리이다.

유튜브 레드 – 오프라인에서 보는 거랑 모바일에서 백그라운드 재생이랑 광고 제거되는 거 외엔…

갠적인 감상이다. 유튜브를 많이 쓴다면 확실히 좋은 기능일지도 모르겠다.

근데 나한테는 그닥 오는 기능들은 없었다. 유튜브 뮤직은… 사실 유튜브에 저작권 갖다붙이면 구글 뮤직되는 건 한순간이니 걍 그러려니 하고 포기한 기능인지라… (원래 음원들 긁어모으면 원래 있는 정통음원 되는 건 이미 애플과 소니가 보여줌….)

광고 제거. 이건 확실히 유용할 듯 하다. 특히 모바일 사용자들! ㅇㅅㅇ! 연구실이던 집이던 PC가 자리에 기본 4~5대 정도 있으면 한대 정도는 유튜브로 BGM 영상 재생도 하는데, 크롬에 유튜브 광고 제거 플러그인이나 파폭, 오페라에 광고 제거하는 거 쓰면 광고는 볼 일이 없어서 그런지 그냥 그러려니 했지만, 이건 모바일에서는 꼭 필요하다. ㅇㅅㅇ!

그리고 모바일에서의 백그라운드 재생! 이건 진짜 음악 감상을 위해선 꼭 필요한 거니 당연히..!

마지막으로 오프라인 임시저장. 이건 좋은 기능인지 아닌지 솔직히 모르겠다.

서비스 한지도 상당히 오래되긴 했다만… 그 덕에 유튜브에서 듣던 몇몇 음원들도 저작권 땜에 싹 다 날아갔다. 명암이 확실한 서비스이다. ㅇㅅㅇ;

42 – 배열의 종류(3차원 배열)

3차원 배열은 별도의 예시를 들어서 처리하진 않겠다. 첨자를 3개 사용하는 배열로, 2차원 배열에 면이라는 것이 추가된 개념이다. 행, 열, 면으로 구성되어 있으며, 구성 순서는 [면][행][열] 순서이다. 이렇게 구성된 3차원 배열을 그림으로 보면 다음과 같이 구성된다.

int A[2][3][2];

41 – 배열의 종류(2차원 배열)

2차원 배열은 첨자 두 개를 사용하는 배열로, 같은 데이터형 변수가 행과 열을 나타내는데, 이러한 2차원적 행렬을 가리켜서 2차원 행렬이라고 한다. C, 코볼, 파스칼 같은 대부분의 언어에서는 첫번째가 행을, 두번째가 열을 가리킨다. 단, 포트란은 반대다.

선언은 다음과 같이 진행을 하는데, 선언하고 나면 그 밑에 있는 형태로 나타내진다.

int A[3][2];

배열은 저번 글에서와 같이 선언과 동시에 초기화를 할 수 있다. 2차원 배열을 초기화를 할 때, 다음과 같이 초기화를 하면 배열의 구조가 어떻게 초기화 되는지를 그림으로 보여주려고 한다.

int A[3][2] = {1, 2, 3, 4, 5);

순서대로 선언하면 아래의 그림과 같이 처리된다.

행 단위로 묶어서 처리할 수도 있는데, 그럴 때에는 이렇게 선언해준다.

int A[3][2] = {{1}, {2, 3}, {4, 5}};

선언 방식에 따라서 어떻게 삽입이 되는지를 확인할 수 있다.

2차원 배열을 이용한 예시를 구현해보았다. 해당 요소의 합들을 가장 바깥쪽에 삽입하여 처리해주는 구조인데, 배열의 선언과 2차원 배열을 이용할 때 이용하는 이중 반복문(for문을 이중으로 작성함)의 사용법을 주로 확인해서 따라해보면 좋다.

프로그래밍(혹은 코딩) 배운다는 이유로 비싼 컴 사달라고 하지 말자..?

항상 이시기만 되면 꼭 나오는 이야기들 중 하나인 거 같다. 대학 갓 입학했는데 노트북 추천해 달라는 이야기…. 뭐, 지름병하고도 엮이는 이야기라서 솔직히 적고 싶진 않았다만 이전에 느끼던 것과 지금와서 느끼는 것이 다르다는 걸 확실히 느껴서 이 기회에 또 적어본다.

요즘 컴공 오는 애들이나 프로그래밍 배우기 시작하는 애들이 많다. 그러면 이런 이야기들이 많이 오간다. “프로그래밍 하니깐 좋은 노트북 있어야 한다.” “사양 낮은 노트북 쓰면 나중에 버벅거려서 작업 못한다” 라는 소리 하면서 막 엄청 좋은 노트북 들고 다니는 애들 많다. (게이밍 노트북이 잘팔리는 이유 중 하나이기도 하다.)

근데 굳이 프로그래밍을 “배우는” 입장에서는 그렇게까지 비싼 노트북 사야되나란 의문 든다. 좋은 사양이 좀 더 개발툴 쓰기 편한 건 있다. 테스트 돌리기도 편하고, 나중에 리눅스 배운다고 가상머신 깔고 그려면 또 사양에 대해서 생각하게 된다.

하지만 생각해보자. 코딩을 배우는 사람이 만드는 프로그램이 규모가 크면 얼마나 클까? 오히려 다른 사람들이 만들어서 제공해주는 프레임워크들이 여러모로 좀 복잡해서 사양을 크게 잡아먹으면 모를까, 본인이 만든 프로그램의 크기가 그렇게까지 큰 경우가 있을까?

아, 머신러닝 하세요? 그럼 본인이 필요로 하는 최소한의 사양부터 알아보고 시작할 수 있을 꺼라 봅니다. 첨부터 제온 E-5에 램 풀뱅 박고 1080 달아야지만 최소한의 사양으로 시작한다는 건 아니잖아요.

특히 초, 중, 고에서 요즘 코딩교육이라면서 자기는 노트북 사야 된다 그러는 애들 좀 있다고 들었다. 근데 그런 애들은 꼭 그거 하면서 인강이며 뭐며 해야 하니 더 좋은 거 있어야 한다면서 자기들 하는 게임 돌리기 좋은 사양의 노트북 들고 오는 케이스 많은데… 이건 좀 알고 조정해야 한다.

게임 개발 툴은 좀 사양이 필요한 경우가 많아서 그런 경우는 좀 빼도록 하겠다. 하지만, 게임 개발이 하고 싶은건지 그냥 게임 하는 게 좋은건지를 구분 못하고 자기 세뇌에 빠져서 그러는 거라면 진지하게 생각해보고, 시작한다면 작은 게임부터 하나 둘 시작해 보는 것도 나쁘지 않을 것이라 본다.

사양이 더 필요하면 나중에 사양 더 좋은 노트북이나 컴으로 질러도 된다고 본다. 굳이 처음부터 비싼 거 질렀다가 나중에는 프로그램 개발은 커녕 기초적인 코딩과는 전혀 관계도 없는 일 하는 사람들 하나 둘 보는 것도 아니고…(오히려 은근 많아서 놀랐다)

그렇다고 사양이 또 너무 낮은 걸 지르라는 건 아니다. 그냥 적당한 사양대의 노트북… 한 60~100 정도만 되어도(요즘 80 내외에도 i3나 i5 달린 녀석들이 좀 있다. 시기가 지나서 가격이 떨어진 것들이라고 해도..) 프로그래밍 공부할 때 쓰는 것들은 개발툴 막 돌리고 자료 뒤지고 뭐하고 하는 데 있어서 문제는 없는 사양이긴 하다.

p.s. 현업에서 좀 굴렀던 분들은 자신이 필요한 사양이 어느정도인지는 알게 되느니 그런 분들은 패스합니다.

40 – 배열의 종류 (1차원 배열)

배열은 첨자의 수에 따라 지속적으로 쓸 수 있고, 필자는 gcc 환경에서는 7차원까지 되는 것으로 알고 있다. 그러나, 실제로 프로그래밍에서 많이 사용되는 1차원, 2차원, 3차원 배열과 그 사용법에 대한 것만 하나하나 정리하고 넘어가기로 하자. (배열은 앞으로도 보고 쓸 일이 엄청 많을 것이다.)

1차원 배열이란 첨자를 하나만 사용하는 배열로, 같은 데이터형의 변수가 일직선으로 이어진 것이다. A[5] 배열을 만들었다면 그 배열의 표현은 다음과 같다.

선언하는 방법은 전에도 봤듯이 간단하다. 선언하고자 하는 타입을 적고 선언하는 건 똑같다.

int A[5];

초기화를 시키는 방법이 있는데, 여러 가지가 있다. 선언해두고 나서 일일이 하나하나 지정해서 초기화를 해도 되고, 중괄호로 묶어서 초기화를 해도 된다. 중괄호로 묶어서 초기화를 할 경우, 두 가지 방법을 이용하는데 다음과 같은 예시문을 확인하자.

int A[5] = {10, 20, 30, 40, 50};
int A[] = {10, 20, 30, 40, 50};

배열의 크기를 적고 그에 해당하는 초기값을 중괄호로 적는 것으로 초기화가 되는데, 배열 크기를 먼저 상정하지 않고도 중괄호 안의 값의 숫자로 크기가 지정되기도 한다.

배열을 사용한 예시 프로그램을 아래와 같이 작성하였다. 20개의 요소를 갖는 1차 배열에 데이터를 입력하고 이를 역으로 출력하는 프로그램이다. 여기에 있는 #define에 대해서는 좀 더 이후에 또 설명을 넣겠다만, 특정한 값에 대해서 매크로 같이 정의해 놓는 것이다.

39 – 배열

배열이란 데이터 구조의 한 방식이다. 동일한 데이터형의 요소가 같은 크기로 순서대로 나열되어 있는 집합이다. 즉, 같은 이름을 사용하지만 첨자(대괄호 안에 있는 숫자. 배열의 크기를 나타낸다.)로 서로 구분되는 집단적인 데이터 저장 영역을 의미한다. 따라서 데이터마다 변수 이름을 따로 두지 않으므로 처리가 훨씬 수월하게 진행될 수 있다.

n개의 요소로 이루어진 배열 a[n]이 있다면, 선언을 할 때에는 다음과 같이 선언한다.

int a[n];

이러면 첫 번째 요소는 a[0], 두 번째 요소는 a[1], …, n 번째 요소는 a[n-1]로 나타낸다. 즉, 요소의 시작은 0부터 시작해서 n-1까지 존재하게 되는 것이다.

배열의 첨자는 보통의 경우에 따라 다르지만 최대 7개까지 사용될 수 있다. (gcc의 경우로 알고있음. 오류가 있으면 지적 부탁합니다.) 배열의 첨자가 두개가 있으면 a[n][m] 과 같은 형식으로 적고, 이러한 배열은 2차원 배열이라고 한다. 셋이 있으면 3차원 배열(a[n][m][o])이라고 한다.

배열을 이용하면 데이터마다 변수의 이름을 따로 두지 않아도 되므로 처리가 용이하다고 했다. 이것이 어떤 의미인지를 살펴보자.

예를 들어, 5명의 학생의 쪽지시험 평균을 저장하는 변수가 있다고 하자. 이를 배열을 사용하지 않으면 다음과 같이 선언하여 사용할 것이다.

int avg1, avg2, avg3, avg4, avg5;

그리고 학생 수가 증가하면 증가하는 분 만큼의 변수를 추가하여 사용할 것이고, 그만큼의 변수를 위해 수많은 선언을 해야 할 것이다. 그러나 배열을 사용하면 다음과 같이 된다.

int avg[5];

변수의 추가가 필요하다면 배열의 크기를 늘리면 되고, 그에 따른 것도 자동으로 된다.

실행문에 대한 것도 깔끔해진다. 앞의 예시처럼 있는 경우에서, 표준 입력장치인 scanf로 성적을 입력받아 저장할 때, 배열을 사용하지 않는다면 그 문장을 다음과 같이 적어야 할 것이다.

scanf(“%d”, &avg1);
scanf(“%d”, &avg2);
scanf(“%d”, &avg3);
scanf(“%d”, &avg4);
scanf(“%d”, &avg5);

출력 또한 printf문으로 이렇게 한 줄 한 줄 노가다를 해야 할 것이다. 그러나 배열을 사용하면 다음과 같이 쓸 수 있다.

for(int i=0; i < n; i++)
scanf(“%d”, &avg[i]);

상당히 문장아 간단해진 것을 볼 수 있다. 변수가 많으면 많을수록 확실히 큰 효과를 볼 수 있다.

38 – 제어문(continue)

continue 문은 반복문의 현재 반복을 멈추고 다음 반복을 하게 한다. 즉, break문과 달리 반복문에서만 사용할 수 있고, 반복문의 처음으로 돌아가게 하는 제어문이다. 그래서 switch에서는 사용할 수 없다.

예시 프로그램을 보여주고 설명하는 것이 좋겠다. 예시 프로그램은 if조건이 참이면 continue 문에 의해 바로 for문의 다음 반복을 처리하게 된다. 그렇게 하여 1~30 중 5의 배수를 출력하는 프로그램이다.