레이블이 프로그래밍인 게시물을 표시합니다. 모든 게시물 표시
레이블이 프로그래밍인 게시물을 표시합니다. 모든 게시물 표시
2021년 10월 30일 토요일

고도문명의 취약점


며칠 전, KT 전국망이 89분간 마비됐다. 유무선망이 모두 마비돼 통화는 물론 패킷을 이용하는 여러 서비스들도 일시적으로 이용불능상태가 되었다.

하필 점심 시간대라 문제는 더 컸다. 상점들의 카드 결제가 멈췄다. 질병청 서버도 멈춰서 백신 접종 확인 여부도 체크가 불가능 했고, 입구에서 찍고 들어가는 QR코드 증명시스템도 마비가 됐다. 단타 매매를 하는 주식투자자들도 HTS, MTS 이용이 불가능 해서 큰 불편을 호소했다.

처음에는 북한에서 DDOS 공격이 들어와서 전국 통신망이 마비됐다고 알려졌다. 그러나 나중에 KT에서 공식적으로 발표하길 부산국사에서 기업망 라우터를 교체하면서 EXIT 명령어 하나를 누락해서 발생한 일이라고 했다. 


이번 일은 물리적 라우터에서 벌어졌지만 요즘 세상은 대부분 소프트웨어 기반으로 돌아간다. 소프트웨어는 또 어떤가. 코드에 점 하나, 괄호하나, 띄어쓰기 하나만 틀려도 버그가 생기거나 오류를 뱉어낸다. 수만~수백만줄의 코드에 오타만 하나 있어도 그 코드는 사용불능이 된다.

물론, 그런 상황을 방지하기 위해 다양한 도구를 도입하여 사용하기는 한다. 개인 개발자 단계에서 코드를 잘 테스트 한 다음, 테스트 환경에서 코드를 돌리고, 실제 서비스에 내보내기 전과 동일한 환경에서 마지막 테스트를 한번 더 거친다. 그리고 다양한 오류 검출도구와 디버깅 도구를 사용한다. 마지막으로 사람 테스터들이 투입되어 최대한 오류가 없도록 테스트 단계를 거친다.

차라리 오류가 검출이라도 되면 다행이다. 검출되지 않지만 시스템에 잠재하는 리스크는 수도 없이 많다.

게다가 이번 KT사태와 같이 어느 한 부분에서 구멍이 뚫리면 이런 단계들은 얼마든지 무용지물이 될 수 있는 여지가 크다.

지금은 기본적으로 셀 수 없이 수 많은 코드와 통신망이 서로 긴요하게 맞물려 데이터를 주고 받으며 돌아가는 세상이다. 아주 사소한, 정말 사소한 오류 하나로 세상이 멈추거나 큰 사고로 이어질 수 있다.

물론, 내가 하드웨어를 잘 모르기 때문에 하드웨어에 대한 이야기는 하지 않았지만 하드웨어 분야도 비슷할 것이다. 전기, 전자분야든, 화학 분야든 안 그런 것이 없을 것이다. 정밀을 요하는 분야는 더욱 그럴것이고. 

전체 시스템의 99.99%가 옳게 만들어져 있어도 나머지 0.01%의 실수나 잘못으로 시스템은 엉망이 될수가 있다.

이것이 인간이 만든 고도문명의 큰 취약점 중 하나이다.

우리 몸도 여러 장기가 각자 역할을 충실히 한다. 그러면서 한명의 사람이 살아가는 것이다. 그러나 사람 몸은 어디 한 곳에 생채기가 난다거나 심지어 장기 한두개가 없다고 해서 죽지는 않는다. 그리고 자연치유 능력도 갖고 있다. 그러나 인간이 만든 문명과 기술은 그렇지 못하다. 거대한 기계의 나사 하나가 누락되어서, 큰 소프트웨어를 구성하는 코드의 점 하나 때문에 대참사가 일어날 수 있다.

약한 고리들이 느슨하게 연결되어 돌아가는게 현대사회다. 수 많은 고리 중 하나가 끊겨서도 안된다.

좀 생뚱맞은 이야기를 하자면 그러하기에 5단계 완전 자율주행은 과연 우리가 살아 있는 동안 구현이 가능할까 싶은 회의감이 크다. 비행기의 자동항법장치나 원자력 발전소를 운영하는 것과는 결이 다른 이야기다. 이번 KT망 오류에서 보듯이 자율주행차들이 5G망에 붙어서 상호통신을 하며 달려야 한다면 이번과 같은 통신장애 발생 시 도로위에 올라와 있는 모든 차량이 교통사고가 일어나는 초유의 상황을 맞이할 수도 있다.

물론, 그런 기초적인 것들이야 회피할 방법을 찾을 것이고 구더기 무서워서 장을 못 담그진 않을테니 인류는 어떤식으로든 진보는 하겠지만.

덧. 끊김없이 공급되는 전기와 그것을 관리하는 한전에 늘 감사하다. 사실 현대문명의 베이스는 전기라 해도 과언이 아닌데, 전기가 끊기면 정말 지옥문이 열리는 것이기에.


2021년 9월 26일 일요일

2020년 CSS 사용 경향

The State of ~ 시리즈의 2020년 자료를 조금만 훑어보고 정리하자. 시간이 조금 지났기는 했지만 지금도 유의미하게 도움이 될 것이다.

The State of CSS


먼저 The State of CSS다. 2020년도에 CSS 개발자들의 생각을 다양한 통계를 통해서 엿볼 수 있다.


우선 The State of CSS 설문에 참여한 사람들 대부분은 영미권에서 CSS를 다루는 개발자들이다. 이를 감안하고 아래의 통계를 들여다 보자.


설문에 참여한 사람 절반 정도가 프론트엔드엔지니어였다. 그 다음 27.5%가 자신을 풀스택 엔지니어라고 했으며 세번재로는 17.2%의 사람들이 웹개발자였다.

예상대로 프론트엔드엔지니어들은 CSS를 능숙하게 다루어야 하니 가장 많은 사람이 CSS를 쓴다고 했다. 백엔드 개발자들은 고객과 만나는 최접점에 있는 화면단 기술인 CSS에는 무관심하였다. 의외로 UI/UX 디자이너들이 CSS를 다루는 사람이 적었다. 영미권에서도 이들은 그래픽 도구로 그림이나 화면 그리기만 끝내고 자신들의 할일을 끝내나보다.


70%에 가까운 사람들이 2010년 이후에 CSS를 다루기 시작한 사람들이다. 확실히 프론트엔드 쪽의 인기는 젊은 사람들에게 높다. 주니어들이 시니어들보다 더 잘 하는 분야이기도 하다. 10년에서 20년 정도 경력이면 나이대가 30대 후반에서 50대 초반인텐데 오랫동안 짬밥을 먹은 시니어들이다. 20년 이상인 사람들은 WWW이 시작할 때부터 이 분야에서 밥벌이를 한 사람들이다. 노년기에 접어든 사람들이 많을텐데 여전히 현역에서 뛰고 있는 게 대단하다. 우리나라도 이렇게 변해야 한다고 생각한다.


CSS 마스터 레벨 즉, CSS의 모든 선택자와 규칙에 대해서 90~100% 수준으로 다 알고 있다고 답한 사람이 5.5%나 된다. 정말 대단하다. CSS 마스터라고 자부하는 나도 가끔 신기한 선택자와 규칙들을 발견할 때가 있다. 그래서 100% 다 안다고는 절대로 말하지 못한다. 그런데 100%라고 대답하는 분들이 저렇게나 많다니 역시 세상은 넓고 고수는 많다.

지표를 보면 많은 CSS 개발자가 CSS의 전체 규칙 중에서 절반 조금 넘어서는 수준만을 알고 있거나 이해하고 있는 듯 하다. 물론, 실무를 하다보면 모든 걸 알아야 할 필요는 없다. 자주 사용하는 규칙들은 대부분 정해져 있고 한정적이다. 그래서 저 정도만 안다고 해서 특별히 실무를 하는데 큰 장애는 없을 것이다. 다만 하나라도 더 알면 어렵게 처리할 작업도 손쉽게 끝낼 수 있을 것이다.


분야별로 많이 쓰는 기능들을 묶은 것이다. 희미한 부분은 '기능을 사용하는 방법에 대해 알고 있다'는 것이고 그 안에 진하게 칠해진 것은 '실제 실무에서 사용한 적이 있다'는 것을 표시한다.

좀 의외인데 CSS를 다루는 사람들 대부분이 애니메이션과 관련된 기능을 굉장히 많이 알고 있고 또, 잘 쓰고 있다는 것이 놀랍다. CSS의 주된 기능은 일단 애니메이션 기능이 아니기 때문이다. 시맨틱하게 잘 구성된 네이키드 HTML 문서를 이용자들이 보기 좋게 옷을 입히는 것이 CSS 사용의 주된 목적이다.

그래서 기본적으로 당연히 사용해야 하는 font-family나 예전에는 float로 처리했지만 요즘은 레이아웃을 잡는데 flex를 많이 사용하니 저것들의 사용량이 높고 CSS 개발자들의 지식 수준이 높은 것도 이해는 한다. 애니메이션은 정말 의외였고, CSS를 이용해서 사용자 인터렉션이나 동적 효과를 주기 위해서 애니메이션을 조금 더 적극적으로 활용할 필요가 있겠다고 느꼈다.

Transitions, Transforms는 94%가 넘는 높은 사용률을 보였다. Animations도 91%가 넘는 이용자가 이용했다.


다른 건 나도 종종 쓰고 익숙한데 perspective라고 하는 신기한 프로퍼티가 보인다. 원근법이라고 하는데 완벽한 3D 기능을 구현할 수 있는 건 아니지만 이 기능을 사용하면 Z 축을 하나 만들어서 거리감을 표현할 수 있게 도와주는 것 같다. 나도 아직 완벽하게 이해는 안됐지만 대충 그런 것 같고 따로 시간을 내서 이 프로퍼티에 대해서 공부를 해봐야 할 것 같다. 잘 쓰면 재미있는 효과를 낼 수 있겠다. MDN Web DOC에 소개된 perspective


@font-face는 외부 폰트를 쓰려면 사용해야 하니 거의 대부분의 프로젝트에서 사용되는 듯 하다. line-break 프로퍼티는 CSS3에서 새로 추가된 것인데 CJK(한중일) 문장의 줄바꿈을 할 때 유용하다. 글자나 문자가 애매하게 잘리면 보기 싫게 되기 때문에.


calc()의 사용률이 92%에 육박할 정도로 올라왔다. 이제는 CSS 개발자들도 calc()를 능숙하게 쓰는 듯 하다. 예전에는 자바스크립트를 써야 했던 일부 계산을 calc()를 사용하면 CSS로 바로 처리할 수 있다. 예를들어서 가변적인 너비를 가진 컨테이너 안에 들어있는 block 엘리먼트의 너비가 컨테이너보다 항상 20픽셀 작은 상태에서 변동하길 원한다면 width: calc(100% - 20px)이라고 사용하면 된다. 정말 간단하다. +, - 기호 사이에는 공백이 있어야 한다.


사용하는 치수 단위는 당연하게도 고정값을 위한 px와 유동값을 위한 %가 가장 많다.

그 다음 vh, vw, em, rem은 모바일 기기나 반응형 웹에 대응하기 위해 많이 사용하는 치수들이다. vh와 vw는 각각 높인와 너비를 100등분 하여 기기의 높이나 너비 대비 얼마의 치수를 만들 것이냐 하는 것이고, em과 rem은 루트 엘리먼트의 폰트 크기로 부터 폰트 사이즈를 상속받아 폰트 사이즈를 반응형으로 대응하는데 사용된다. 실제로 모바일 페이지를 만들 때, px와 em, rem이 표현하는 방식이 매우 다른데, 각자 장단점이 있으니 프로젝트 특성에 맞게 사용하면 된다.

vmin과 vmax는 브라우저 지원이 아직은 불안정하다. 그래서 사용률이 확 떨어지지만 잘 알고 있으면 유용하다. 너비와 높이 중 더 긴 것을 vmax, 더 짧은 것을 vmin에 대응한다. 따라서 너비 300픽셀, 높이 1000픽셀의 기기가 있다면 1vmin은 3픽셀 1vmax는 10픽셀을 반환한다. 다양한 기기에 대응해야 하고 이 기기들의 정확한 높이와 너비에 맞는 div를 씌우고자 한다면 100vmax, 100vmin을 적용하면 된다. 사용하기 까다로운 height: 100% 같은 것을 사용하지 않아도 되고, 스크립트를 쓰지 않아도 된다.


역시 Pseudo Element 중 가장 많이 사용하는 것은 :before와 :after다. 과거에는 브라우저 지원이 미비해서 무작정 사용하기가 애매했지만 이제는 대부분의 최신 브라우저에서 잘 지원한다. :before와 :after를 잘 사용하면 불필요한 마크업 낭비를 줄이고 다양한 기교를 부리고 가상의 디자인적 요소를 표현할 수 있다.


이 부분은 CSS의 이름에서 알 수 있듯이 Cascading의 핵심인 부분이다. 자손 연결자는 당연히 100%가 사용되어야 하는 거 아닌가 하는 생각이 들었지만 사용률이 98%였다. 나머지 2%의 사람들은 그냥 직접 클래스나 아이디 선택자를 사용하고 자손 연결자는 사용하지 않는 것 같다

직속 자식만을 선택하는 > 선택자는 진짜 오래전에 브라우저들이 CSS의 기능들을 어설프게 지원할 때 후임 한명이 저걸 쓰길래 쓰지 말라고 엄청 혼냈었던 기억이 난다. 이제는 브라우저들이 잘 지원하기 때문에 자유롭게 써도 된다.

마크업을 잘 구성하고 CSS 설계를 잘 하면 +와 ~를 사용할 일은 거의 없지만 알아두면 급할 때 요긴하게 쓸 수 있을 것이다.


:first-child, :last-child, :nth-child()도 이제는 정말 많이 쓰인다. 모두 90%가 넘는 사용률을 보인다. 불과 몇년 전 까지만 하더라도 여전히 구형 브라우저를 사용하는 사람들이 많았다. 그래서 이게 편리하고 좋은 걸 알면서도 쓰지 못했다. 그래서 불필요하게 클래스 네임을 지정해서 별도로 스타일시트 구문을 추가하거나 스크립트로 컨트롤을 해야했다.

그러나 이제는 간단하게 가장 첫번째 요소, 마지막 요소, 그리고 원하는 순서의 요소, 특정한 순서 패턴의 요소들을 CSS만으로 간단하고도 자유롭게 컨트롤 할 수 있게 되었다.

아래의 의사결정 클래스들도 정말 유용한 것이 많지만 아직 사용률이 낮은 것은 그만한 이유가 있다. 다양한 기기와 브라우저 대응이 아직은 어렵기 때문이다.


엘리먼트의 속성에 접근하는 선택자도 이제는 정말 많이 쓴다. ele[foo="bar"]의 사용률은 95%가 넘는다. ele[foo]도 브라우저 지원율이 높지만 ele[foo="bar"]가 더 많이 쓰이는 이유는 폼의 동적인 부분을 스크립트로 처리하지 않고 CSS만으로 처리할 수 있기 때문이다.

체크박스나 라디오버튼을 예로 들면, 박스가 체킹 되었을 때와 체킹이 해제되었을 때 디자인을 따로 적용할 수 있는데, 예전에는 이런 부분을 별도 CSS클래스를 작성하여 스크립트로 처리하였다.

그러나 지금은 checkbox[checked="checked"]와 같이 체크가 되었을 때 상태 한줄만 추가하면 된다. 폼 요소의 경우 이것마저 줄일 수 있는데 :checked로 간단하게 컨트롤이 가능하다.

이와 같은 방법으로 스크립트로 처리할 부분의 상당 부분을 CSS에서 처리할 수 있으니 UI 드로우 처리가 훨씬 빨라질 수 있고 개발도 편리하다.


:link, :visited와 같은 선택자는 설명할 것도 없이 유명하고 앵커 태그 등에서 웹 초창기부터 자주 쓰이던 고전적 선택자다. 


:hover, :focus:, :active 클래스는 엘리먼트가 마우스의 위에 올라 가 있는지, 엘리먼트에 포커싱이 되어 있는지를 감지하여 스타일링을 할 수 있다. 이 역시 오래도록 애용되고 있는 고전적인 선택자다. 앵커 태그에서는 상당히 잘 작동하지만 앵커 태그 이외의 엘리먼트에서는 일부 브라우저에서 동작이 되지 않을수도 있으니 체크하면서 작업을 해야한다.


폼 요소들의 상태를 체크할 수 있는 CSS 선택자들이다. :checked와 같은 것은 널리 쓰이고 있으며 자바스크립트를 사용하지 않고도 라디오 버튼이나 체크박스의 상태를 자유롭게 디자인 할 수 있기 때문에 편리하게 사용할 수 있다.

폼의 활성 상태를 체크하는 :enabled, :disabled와 같은 선택자도 유용하게 쓸 수 있으며 기본 요구사항을 감지하는 :required와 같은 선택자도 유용하게 사용할 수 있다. 대부분의 브라우저에서 잘 지원한다. 그러나 일부 선택자는 11이상의 높은 버전의 브라우저에서도 지원되지 않을 수 있으니 확인을 해가면서 사용을 할 필요가 있다.

폼 요소들의 상태를 체크하는 CSS 선택자는 잘 알아두고 활용하면 스크립트 작업 노가다 시간을 많이 줄일 수 있다.


Sass의 경우에는 설문에 참여한 대부분의 CSS 개발자가 만족하고 있으며 사용하고 있는 기술이라고 답변했다. 이것을 보면 이제는 단순한 퍼블리싱이든 전문 FE를 하던 세계적 추세는 FE 환경에서 CSS를 개발하고 또 Sass와 같은 전처리기를 쓰는 것이 대세를 넘어 기본이 되었음을 알 수 있다. Sass를 아직 안 써 본 CSS 개발자는 없겠지만, 혹시 계시면 써 보시길 추천한다. 정말 끝내준다! 한번 사용하면 CSS 날코딩의 세계로 돌아갈 수 없다.

한때 대세로 여겨졌던 BEM 방법론은 만족하는 사람이 많지만 모든 사람이 BEM 방법론을 따르는 것은 아니다. 부트스트랩 CSS 프레임워크는 아주 많은 사람들이 사용해 본 적이 있지만 만족도는 지극히 낮았다.

눈여겨 볼 것은 PostCSS와 Tailwind CSS다. 사용해 본 사람들은 만족도가 아주 높다고 답했다. 그러나 아직 덜 알려져 있어서 이를 사용해 보았다는 사람은 매우 적었다.

PostCSS는 300여개에 달하는 플러그인을 사용할 수 있도록 도와주는 도구인데 CSS의 문법을 확장하거나 CSS 코딩을 매우 편리하게 만들어주는 도구들을 지원한다.

Tailwind CSS는 부트스트랩과 비슷한 CSS 프레임워크다. 정해진 디자인이 일관적이라 유틸리티 퍼스트 개발에 유리하고, 부트스트랩에 비해서 커스타마이징이 용이해서 만족도가 높다.

이 부분에서 새롭게 공부할 기술들이 몇가지 추가되었는데, PostCSS에 대해서는 꼭 한번 들여다 봐야겠다.


전처리기를 사용하였다는 의견은 전반적으로 다 높아졌다. 갈수록 CSS 작업을 할 때 날코딩이 아니라 전처리기를 거치는 것이 자리 잡고 있음을 느낀다. Less를 제외한 Sass, Stylus, PostCSS가 모두 사용한다는 응답이 늘었으며 특히 PostCSS의 사용량이 빠르게 증가하고 있다.


전처리기 사용 만족도는 Sass보다 PostCSS가 더 높았다. 전처리기 사용을 한다면 Sass 또는 PostCSS를 사용하는 것이 좋겠다. 특히, PostCSS는 Sass의 만족도가 소폭 감소한 상황에서도 되레 만족도가 더 높아지는 경향을 보여주었다. PostCSS 공부 욕구가 뿜뿜하지 않는가?


CSS 개발자들은 Sass에 대해 거의 대부분 인지를 하고 있었고, PostCSS에 대한 인지도가 빠르게 올라오고 있는 것도 확인할 수 있다. 조만간 PostCSS가 Sass의 인기를 밀어낼지도 모르겠따. 둘은 특성이 조금 다르기는 하지만 교집합도 많다.


개인적으로 CSS 프레임워크를 사용하는 것은 좋아하지 않는다. 밑단부터 하나하나 만들어 올라가는 걸 좋아하는데 의외로 CSS 프레임워크도 많이들 사용하는 것 같다. 우선 앞에서도 이야기가 잠깐 나왔던 테일윈드 CSS 프레임워크의 만족도가 높다.


인지도만 놓고 보면 부트스트랩이 단연 압도적인데 사용 후 만족도는 높지 않았다. Tailwind CSS는 최근에 인지도를 급격히 키워나가고 있다. functional한 CSS 이용이 가능한 프레임워크라서 이 트렌드에 올라탄 것으로 보인다.


프로젝트에서 테일윈드를 사용했다는 응답이 2019년 6%에서 2020년에 무려 26%로 20%p나 증가했다. 만일 CSS 프레임워크를 도입할 예정이라면 현재 시점에서는 테일윈드 CSS에 대해서 검토해 보는 것이 좋겠다는 생각이 든다. 가볍게 잘 만든 프레임워크인 것 같다. https://tailwindcss.com/

물론 나는 CSS 프레임워크를 쓸 생각이 없지만.


현재 가장 널리 알려져 있고, 많이 사용되는 CSS 코딩 방법론은 BEM 방법론이다. 어느 정도 규율이 있는 개발팀이라면 BEM 방법론을 도입한 곳이 많을 것이다.


그런데 CSS개발자들이 가장 만족감을 느끼는 방법론은 Atomic CSS 방법론이라는 서베이 결과가 나왔다. 물론 만족도는 BEM 방법론도 이에 뒤지지 않게 높았다.

Atomic CSS 방법론은 최근에 주목 받고 있는데 간단히 몇가지 특징을 언급하면 다음과 같다. Atomic CSS 방법론의 철학은 마크업과 CSS 파일이 애초에 분리된 게 이상하지 않느냐? 기본으로 돌아와서 템플릿 작업을 하면서 한꺼번에 스타일 작업도 하는게 논리적으로 맞지 않느냐는 가치관을 가지고 있다.

클래스 하나에 CSS 밑단 속성 하나가 대응된다. 검정색 1픽셀 선을 표현하는 border: 1px solid #000이라는 속성이 있다고 하면 이것을 .b10이라는 형태의 클래스로 만들고, 이것을 템플릿에서 직접 사용하는 것이다. 클래스 하나에 두가지 이상의 스타일시트 속성이 들어가면 Atomic CSS 규칙 위반이다.

장점은 CSS 작업을 할 필요없이 템플릿 작업과 동시에 스타일 작업을 할 수 있다는 것이다. 그리고 죽은 CSS 코드가 거의 발생하지 않고, CSS의 크기도 줄일 수 있다. 그리고 functional 하기 때문에 직관적이다.

단점은 구현하고자 하는 CSS 스타일이 미리 다 구현이 되어 있어야 한다는 점이다. 그리고 사용하고자 하는 속성에 대응되는 클래스 이름을 모두 사전에 인지하고 있어야 하므로 익숙해 지기 전까지는 러닝 커브가 높다는 점이다.


역시 에디터는 Visual Studio Code가 대세!


브라우저 테스트는 역시 크롬 사용률이 압도적이다. 여전히 파이어폭스를 개발 테스트용 브라우저로 많이 쓰는 것은 신기하다. 익스플로러는 이제 거의 사장되어 가는 분위기다. MS에서도 더 이상 지원을 안한다고 하였으니. 여러모로 프론트엔드 개발자들에게는 다행이고 신나는 시절일 것이다. 옛날에 IE 6, 7, 8 맞추던 시절이 정말 최악인 시절로 기억될 것이다.


2021년 8월 29일 일요일

파이썬의 기본 문법

컴퓨터 공부는 '백물이 불여일타'. 어려운 말들 늘어놓고 이말 저말 암기하려고 하면 공부하기가 힘듭니다. 컴퓨터 공부는 일단 두드려 보고, 만들어 보는 것이 가장 빠르게 학습을 하는 길이라고 생각합니다. 파이썬 공부를 처음 시작하시는 분들을 위해서 만든 포스팅입니다. 파이썬 언어의 특징, 자료 구조 등등 이론적 토대는 별도로 공부를 하시길 바랍니다.

온라인 컴파일러


파이썬 문법 공부는 아래의 사이트를 통해서 진행하시면 됩니다. 실제로는 파이썬을 설치해서 사용해야 하지만 그것은 나중에 꼭 필요할 때 하시는 것으로 하고, 일단 문법 공부를 간단하게 하는 정도는 온라인 컴파일러를 사용하시는 것을 추천합니다. 

맥북이나 맥에는 파이썬이 기본적으로 깔려 있습니다. 터미널 사용법을 아시는 분은 터미널에서 파이썬을 구동해서 공부해도 됩니다.

일단 파이썬 설치를 못 하는 분들을 위해서 3개의 사이트를 추천해 드리겠습니다. 취향에 맞는 곳에서 공부하시면 됩니다.


기초문법


이제부터는 글을 평어체로 쓰겠습니다.

변수와 자료형


파이썬은 변수 선언을 할 때 데이터 타입을 명시하지 않는다. 또한, 자바스크립트의 변수 선언부처럼 'var'와 같은 것도 사용할 필요가 없다.
a = 10
위와 같이 사용하면 그만이다. 변수 a는 int값 10을 갖게 되었다.
a = 10
print(a)
print(type(a))
변수 a에 담긴 값과 데이터 타입을 확인해 보면 그 결과는 다음과 같다.




변수 a에는 숫자 10이라는 값이 담겨 있으며 데이터 타입은 int형임을 알 수 있다. 어디서나 이렇게 유연하게 변수 선언을 하면 된다.
count = 20
math, english = (90, 100)
name = "Jongsik"
option = True
memo = "Good morning"
score = 90.5
companies = ["LG", "Samsung", "Hyundai"]

print(count, math, name, option, memo, score, companies)
print(type(count), type(math), type(name), type(option), type(memo), type(score), type(companies))
자료형을 몇가지 더 사용해보았다. 위에서 아래로 count, math, name 등의 변수를 선언하였다. 순서대로 정수형, 정수형(튜플 이용), 문자열, 불리언, 문자열, 실수형, 리스트 형태의 자료가 사용되었다.

변수가 가진 값들을 그대로 print한 것과 각 변수의 자료형태를 print한 결과는 다음과 같다.


이처럼 파이썬은 자료형을 별도로 설정하지 않아도 들어가는 값에 따라 자동으로 자료형태가 설정된다.

주석

"""
파이썬입니다!
기본적인 변수 사용법에 대한 연습장
여러줄 주석은 이렇게 사용합니다
"""

# 리스트 타입 (한줄 주석)
companies = ["LG", "Samsung", "Hyundai", "Google", "Amazon"]

print(companies)
print(companies[0])
print(companies[2])
print(companies[3][0])
print(companies[3] + companies[4])
이번에는 주석문을 사용하였다. 한줄 주석은 #을 사용하면 된다. 주석문을 여러줄로 사용하고 싶은 경우에는 홑따옴표나 쌍따옴표를 3개 연속으로 사용하고 이것으로 감싸주면 된다. 보통 IDE를 사용할 경우에는 윈도우는 Ctrl + / 맥은 Option + / 키를 사용하면 편리하다.

리스트와 딕셔너리


리스트 타입을 다룰일이 많을테니 리스트 타입을 다루는 아주 기본적인 방법 몇가지만 짚고 넘어가보자. 위의 코드를 실행하면 5개의 print문이 아래와 같이 출력된다.





companies라는 변수는 5개의 회사 이름이 각각의 원소로 존재하는 리스트를 갖고 있다. 이것을 그냥 print문으로 출력하면 목록과 목록이 가진 원소값들 그러니까 회사 이름이 그대로 출력된다.

다른 언어들이 배열을 다룰 때 처럼 대괄호를 사용하면 특정한 원소값만 출력할 수 있다. 가장 앞에 있는 원소값 즉, companies[0]을 출력하면 목록에서 가장 앞에 있는 'LG'가 출력된다. 당연히 companies[2]를 출력하면 3번째에 있는 'Hyundai'가 출력된다.

companies[3][0] 이 부분이 재미있다. 다른 언어에서는 2차원 배열에 속한 원소값을 꺼내올 때 이렇게 사용한다. 위의 예제에서는 'G'가 출력된다. 4번째에 있는 원소 'Google'에서 다시 첫번째에 있는 글자인 'G'를 추출한 것이다.

마지막으로 4번째 원소와 5번째 원소를 단순히 더하기 하면 결과값은 'GoogleAmazon'이다. 위의 예제에서 리스트에 포함된 모든 원소는 문자열이기 때문에 문자열을 더하면 단순히 문자열이 합해진 값이 결과로 출력된다.
a = "We are Korean!"

print(a)
print(a[:])
print(a[0])
print(a[:5])
print(a[4:8])
변수 a에 담긴 값은 단순한 문자열이다. 파이썬은 유연해서 단순 문자열에 포함된 각 문자도 하나의 원소로 취급할 수 있다.

리스트를 다룰때와 마찬가지로 대괄호 []를 사용하여 문자열에 포함된 특정한 문자를 추출할 수 있다. 파이썬은 리스트에 포함된 원소를 추출하거나 슬라이싱 하기 위해서 콜론을 이용한다. 독특하고 편리하게 원하는 값을 추출할 수 있다.

[:]를 사용하면 리스트의 모든 값을 출력한다. [:5]는 [0:5]와 동일하다. 첫번째 글자부터 6번째 글자까지 슬라이스 하여 추출하라는 의미이다. [4:8]은 5번째 글자부터 9번째 글자까지 출력하라는 의미이다. [4:]라고 하면 5번째 글자부터 마지막까지 모두 출력하라는 의미이다. 위의 예제를 실행하면 결과값은 아래와 같다.






이상에서 소개한 자료형 외에도 파이썬은 다양한 자료형을 제공한다. 복소수 형태라던가 딕셔너리도 제공한다. 복소수는 사용할 일이 많을지 모르겠지만 딕셔너리는 이야기가 나온김에 간단하게 살펴보고 넘어가자.
user = { "name": "Jongsik", "age": 39, "sex": "male" }

print(user)
print(user["name"])
print(user["age"])
딕셔너리는 "키:밸류" 쌍으로 이루어진 값들의 집합이다. JSON을 많이 사용해 보았다면 익숙한 형태일 것이다. 파이썬의 딕셔너리는 JSON으로 다시 JSON은 딕셔너리로 입출력이 편리하다.




위의 예제를 출력한 결과값은 이와 같다. 다른 프로그래밍 언어에서 딕셔너리를 다루는 법과 거의 동일하다.

분기처리 제어문, if


이제 제어문의 기본적인 형태를 살펴보자.
a = True

if a == True:
    print("결과는 참")
else:
    print("결과는 거짓")
    
------------------------
>> 결과는 참
변수 a에 불리언 값 True를 주었다. if문을 사용해서 a의 값이 참이면 '결과는 참'이라는 문장을 출력하고 거짓이면 '결과는 거짓'이라는 문장을 출력하는 아주 간단한 코드이다.

다른 프로그래밍 언어와 별달리 다른 점은 없다. 다만, 파이썬만의 특성이 몇가지 있는데 그 부분만 짚고 넘어가면 되겠다.

우선 파이썬의 제어문에는 보통의 다른 언어와 달리 괄호가 없다. 그냥 조건문을 작성하고 콜론(:)을 사용하여 해당 문장을 마무리하면 된다. 콜론을 빠뜨리면 에러가 난다.

그리고 조건문 이후에 오는 문장은 인덴테이션을 받드시 해주어야 한다. 파이썬은 문장의 끝을 알리는 세미콜론(;)을 사용하지 않는 만큼 정확한 인덴테이션을 요구한다. 따라서, 인덴테이션을 제대로 해주지 않아도 구문 오류가 난다. 주석문 조차도 마음대로 달련 오류가 나니 인덴테이션을 제대로 맞춰주도록 한다.
age = 39

if age >= 10 and age <= 19:
    print("당신은 10대입니다")
elif age >= 20 and age <= 29:
    print("당신은 20대입니다")
elif age >= 30 and age <= 39:
    print("당신은 30대입니다")
else:
    print("당신은 청년은 아닙니다")
    
------------------------
>> 당신은 30대입니다
이번에는 변수 a에 39라는 정수를 어싸인하였다. 변수 a에 있는 값으로 현재 세대를 판정하는 간단한 if ~ elif ~ else 제어문이다.

이것도 다른 프로그래밍 언어와 별로 다른 부분은 없지만 파이썬의 특징이 몇가지 있다. 우선 파이썬은 &&, || 와 같은 연산자를 사용하지 않는다. 파이썬에서는 해당 연산자를 곧이 곧대로 and, or 라고 사용하면 된다.

그리고 조건이 여러가지인 경우에 다른 언어에서의 else if 문을 파이썬에서는 elif로 사용한다. 일단은 이 부분만 중점적으로 숙지하면 된다.
car = {"benz", "bmw", "audi"}

if "benz" in car:
    print("독일차 명단에 존재합니다")

--------------------------------
독일차 명단에 존재합니다
딕셔너리나 목록에 특정한 값이 포함되어 있는지 in 을 사용하여 간단하게 체크할 수 있다.
member = { "Jinsu", "Mihee", "Sohee" }

if "Jongsik" not in member:
    print("Jongsik은 멤버가 아닙니다")
위와 같이 not을 사용하여 목록에 포함되지 않은 값을 처리할 수도 있다. 다른 프로그래밍 언어 경험이 있다면 !in과 같은 방법을 시도하는 분도 있을텐데 이 구문은 잘못된 구문으로 오류를 뱉는다. not in이라고 정확하게 쓰자.

반복문, for


프로그래밍 언어에서 사용하는 제어문의 양대산맥 중 하나인 if문을 이용한 분기처리 문법에 대해서 수박 겉핥기로 알아보았다. 이제 나머지 한쪽 산맥인 반복문에 대해서 알아보자.

여러가지 형태의 반복문 중 단연 많이 쓰이는 것은 for문이다.
for i in range(0, 5):
    print(i)

결과:----------------------
0
1
2
3
4
가장 간단한 형태의 for문이다. 0에서 시작해서 4까지 총 5바퀴를 돌면서 i값을 출력하는 코드다. 다른 언어와는 조금 다른 점이 보이는데 하나씩 짚어보자.

우선 range라는 부분이 독특하게 여겨질 것이다. range는 다음과 같이 사용한다. range(시작숫자, 끝나는 숫자, 증가값). 여기서 시작숫자와 증가값은 생략할 수 있다. 시작숫자를 생략하면 0에서 끝 숫자까지 도는 것이고, 증가값을 제외하면 다른 언어의 ++과 비슷한 효과를 가지며 한바퀴 돌 때 마다 값을 1씩 증가시킨다.

for문도 if문과 마찬가지로 선언문이 끝나는 부분에 세미콜론(:)을 사용해주고, 그 다음줄부터는 들여쓰기(인덴테이션)를 제대로 맞추어 주저야 한다. 그렇지 않으면 구문 오류로 코드가 실행되지 않는다.

위의 예제는 for 문을 돌리면서 선언한 변수 i에 한바퀴 돌 때마다 0에서 4까지 숫자를 1씩 증가시키면서 i를 i++ 처리하는 예제다. range의 끝나는 숫자 바로 앞의 숫자까지 for문이 돈다.
numbers = [1, 3, 7, 9, 12]

for i in numbers:
    print(i)
    
결과:----------------------
1
3
7
9
12
리스트에 있는 원소의 숫자만큼 for문을 돌고 각 원소를 하나씩 꺼내서 뿌려주는 코드다.

반복문, while


while은 조건이 참인 경우에 루프를 도는 반복문이다. 기본적인 문법은 다음과 같다.

while 조건문:
    실행되는 코드
For 문과 달리 튜플을 돌거나 변수 생성을 하지 않느다. 조건문이 True인지 False인지를 체크하고 조건문의 결과가 True인 경우에만 루프를 돈다.
debt = 1000
due = 0
while debt > 0:
    debt = debt - 100
    due = due + 1
    print("상환 {0}개월차, 빚 100만원을 갚았습니다".format(due))
    print("남은 빚은 {0}만 원입니다".format(debt))
    
    if debt == 0:
        print("모든 빚을 갚았습니다")

결과: -----------------------------
상환 1개월차, 빚 100만원을 갚았습니다
남은 빚은 900만 원입니다
상환 2개월차, 빚 100만원을 갚았습니다
남은 빚은 800만 원입니다
상환 3개월차, 빚 100만원을 갚았습니다
남은 빚은 700만 원입니다
상환 4개월차, 빚 100만원을 갚았습니다
남은 빚은 600만 원입니다
상환 5개월차, 빚 100만원을 갚았습니다
남은 빚은 500만 원입니다
상환 6개월차, 빚 100만원을 갚았습니다
남은 빚은 400만 원입니다
상환 7개월차, 빚 100만원을 갚았습니다
남은 빚은 300만 원입니다
상환 8개월차, 빚 100만원을 갚았습니다
남은 빚은 200만 원입니다
상환 9개월차, 빚 100만원을 갚았습니다
남은 빚은 100만 원입니다
상환 10개월차, 빚 100만원을 갚았습니다
남은 빚은 0만 원입니다
모든 빚을 갚았습니다
빚 1000만 원을 변수 debt가 갖고 있다. while 문은 빚을 모두 값아서 0원이 될 때까지 루프문을 돈다. 루프를 한바퀴 돌 때 마다 빚을 100만원 씩 갚아 나가고, 기간을 1개월씩 증가시킨다. 최종적으로 빚을 모두 갚으면 빚을 모두 갚았다는 문구를 출력하고 루프문을 종료하는 간단한 코드이다.

continue, break, pass


continue : 반복문의 초반으로 돌아가서 다음 반복문을 계속 실행한다.
break : 반복문의 실행을 중단하고 빠져나간다.
pass : 처리될 구문은 있지만 처리할 일은 없을 때 익셉션을 방지하기 위해 사용한다.

먼저 break는 제어문을 탈출할 때 사용한다. 간단한 사용 방법은 다음과 같다.
for a in range(0 ,10):
    if a == 3:
        break
    print(a)

결과:--------------------
0
1
2
위의 구문은 변수 a에 0부터 9까지 총 10바퀴를 돌면서 숫자를 할당하고 출력하게 하는 코드이다. if 문 안에 break가 걸려있다. for문이 3바퀴를 돌고나면 break가 걸리면서 이 루프문은 종료된다. break는 이렇게 루프를 종료하고 빠져나가는 역할을 갖고 있다.
for a in range(0 ,10):
    if a == 3:
        continue
    print(a)
결과:--------------------
0
1
2
4
5
6
7
8
9
이 구문은  앞의 구문과 동일하다. break가 있던 부분에 continue가 들어간 것만 다르다. break와 달리 continue는 루프를 계속 돈다. 파이썬 인터프리터가 continue를 만나는 순간 아래에 있는 코드는 무시하고 곧장 다시 루프문의 다음 바퀴를 돌기 위해 올라간다. 그리고 다시 루프를 계속 돈다.

결과를 보면 0에서 9까지 10바퀴의 루프를 도는 동안 3번은 print가 되지 않은 것을 확인할 수 있다. 3바퀴째에 print 구문에 도달하기 전에 continue를 만났기 때문이다.
def test(a):
    
print (test("안녕!"))

결과:----------------------
File "<string>", line 3
    print (test("안녕!"))
    ^
IndentationError: expected an indented block
위의 코드는 test라는 함수를 만들어서 print 구문을 통해서 test 함수를 호출한다. test 함수 안에는 아무런 내용도 없다. 그래서 코드를 실행하면 블럭에 코드가 비어 있다고 에러를 뱉는다. 이런 에러를 방지하기 위해서 pass를 사용한다.
def test(a):
    pass
    
print (test("안녕!"))

결과:----------------------
None
함수 블럭은 생성되었지만 할 일이 없는 경우에 pass를 사용하여 indented block 익셉션을 방지하였다.

외부 모듈 불러오기(import)


자바나 타입스크립트와 같이 파이썬도 import라는 구문을 사용할 수 있다. import를 사용하면 외부의 모듈을 가져와서 사용할 수 있다.
import 모듈명
이렇게 사용하면 해당 모듈을 모두 가져온다.
from 모듈명 import 기능명
이렇게 사용하면 모듈안에 있는 특정한 기능만 꺼내서 가져온다. 모듈은 파이썬이 제공하는 기본 모듈들이 있고, 세계의 여러 개발자들이 만들어 둔 오픈소스 모듈들도 있을거고 또 우리가 만드는 확장자 .py 파일도 외부 모듈로써 필요할 때는 언제든 외부의 .py 파일을 import 해서 사용할 수 있다.

기본모듈


파이썬에는 수 많은 기본 모듈이 제공된다. 파이썬에 내장된 기본모듈이므로 별도로 설치를 할 필요가 없다. 파이썬에서 제공하는 기본 모듈을 잘 활용하면 프로그램을 만들 때 매우 유용하게 사용할 수 있다. 그 중에서 몇 가지 표준 모듈만 살펴보자.

우선 math 모듈을 사용한 예제다. math 모듈은 복잡한 수학 계산을 편리하게 처리할 수 있도록 도와주는 함수들을 제공한다. 복소수는 cmath 모듈에서 지원한다.
import math

print(math.fabs(-99))    # 절대값 반환
print(math.factorial(4)) # 팩토리얼값 반환
print(math.isnan(10))    # 숫자이면 False 반환
print(math.isqrt(16))    # 제곱근 반환
print(math.log(24))      # 자연로그 반환(밑 e)
print(math.pow(3, 3))    # 거듭제곱 반환

결과:-------------------------
99.0
24
False
4
3.1780538303479458
27.0
math 모듈에서 지원하는 함수 몇가지만 사용해 본 예제다. 위와 같이 사용하면 된다.

json을 인코딩/디코딩 할 때 매우 편리하게 사용할 수 있는 json 모듈 등 유용한 기본 모듈이 상당히 많이 지원되고 있다. 표준 라이브러리 목록과 사용 방법은 내용이 방대하므로 파이썬 공식 홈페이지에서 제공하는 매뉴얼을 참고하는 것을 추천한다. 

표준 라이브러리 매뉴얼 주소 : https://docs.python.org/ko/3/library/index.html

파이썬에는 멋진 외부 모듈도 많다. 대표적으로 선형대수 라이브러리인 넘파이와 같은 외부 모듈도 꼭 활용해보면 좋겠다. 파이썬의 기본 연산 속도가 느리다고 생각되면 이 모듈을 쓰면 대규모 숫자들의 빠른 연산이 가능하다. 그리고 표준편차, 분산, 푸리에 변환 등을 빠르고 편리하게 계산하고 사용할 수 있다.

넘파이에 대한 이야기가 나왔으니 넘파이에 대해서 정리를 잘 해둔 블로그가 있어서 링크를 해두니 참고하자.

f-string 포맷팅


파이썬2까지는 문자열을 다룰 때 C에서 썼던 %-포맷팅 방법을 쓰거나 위의 while문 예제에서 사용했던 {}.format() 포맷팅 방식을 썼다. 그러나 파이썬3에서는 가독성이 떨어지는 이런 방법을 쓰지 않고도 f-string 포맷팅 방법을 사용할 수 있게 되어서 가독성이 좋아졌다.

간단한 사용법은 다음과 같다.
name = "송종식"
age = 38
memo = f"안녕하세요. 제 이름은 {name}입니다. {age}살이에요."
print(memo)

결과:--------------------------
안녕하세요. 제 이름은 송종식입니다. 38살이에요.
리액트, Vue와 같은 프론트엔드 프레임워크에서 사용하는 보간자와 비슷한 방법으로 사용하면 된다.
price = 1000
amount = 5
memo = f"사과{amount}개에 {amount*price}입니다"
print(memo)

결과:--------------------------
사과5개에 5000입니다
이런식으로 f-string을 이용해서 바로 연산을 처리할 수도 있다.
profile = {"name": "Jongsik Song", "age": 38}
data = f'이름은 {profile["name"]}이고 나이는 {profile["age"]}살 입니다'
print(data)

결과:--------------------------
이름은 Jongsik Song이고 나이는 38입니다
리스트와 딕셔너리를 활용할 때는 이와 같이 처리하면 된다. 홑따옴표와 쌍따옴표 사용에 주의하자. f-string은 날짜처리를 비롯해서 더욱 다양한 기능을 지원한다. 잘 활용하면 정말 편리한 기능이니 숙지하자. 

f-string 포맷팅에 대한 더 많은 정보는 다음 링크를 통해서 확인하자.

형변환


파이썬은 형변환이 유연하다.
a = 10
print(type(a))
a = "10"
print(type(a))

결과:-----------------
<class 'int'>
<class 'str'>
변수에 들어가는 값의 자료형이 바뀌면 변수에 자료형 변경을 가하는 작업을 하지 않아도 자동으로 변수형이 변한다. 변수 a가 int형에서 string형으로 자료형이 변한 것을 확인할 수 있다.

이상으로 파이썬을 다루기 위한 가장 기초적인 문법에 대해서 다루어 보았다.