기본 콘텐츠로 건너뛰기

[tool] vim 각종 설정들로 부터 귀차니즘을 벗어나자

이번에는 유닉스 계열의 텍스트 에디터인 vim을 커스텀하여 개선을 해보고자 한다. vim은 초심자가 적용하기가 쉽지않은 에디터다. 하지만 익숙해지면 굉장히 빨라진다 (라고 하지만 개인적으로 동의하지 않는 부분이다. 필자도 vim을 애용하지만 단지 IDE보다 가벼워서 사용하는 거지 개발 속도때문은 아니다) vim은  ~/.vimrc 을 통해 귀찮은 설정들을 미리 해줄 수 있다. :set nu :set ts=4 해당 두 명령어는 필자가 가장 많이 설정을 하는 셋팅이다. 좌측에 line number를 표시해주는 것과 탭 간격을 4space로 바꾸어 주는 것이다. 하지만 파일을 닫고 다시 열면 다시 셋팅을 해주어야 하는 귀찮음이 있는데 ~/.vimrc에 추가를 해주면 매번 셋팅을 할 필요가 없다. $ vi ~/.vimrc :set nu :set ts = 4 위 처럼 작성을 하고 저장을 시킨 후 vim을 열면 해당 설정이 적용된 상태로 빔이 켜졌음을 확인 할 수 있다. set hlsearch " 검색어 하이라이팅 set nu " 줄번호 set autoindent " 자동 들여쓰기 set scrolloff=2 set wildmode=longest,list set ts=4 "tag select set sts=4 "st select set sw=1 " 스크롤바 너비 set autowrite " 다른 파일로 넘어갈 때 자동 저장 set autoread " 작업 중인 파일 외부에서 변경됬을 경우 자동으로 불러옴 set cindent " C언어 자동 들여쓰기 set bs=eol,start,indent set history=256 set laststatus=2 " 상태바 표시 항상 "set paste " 붙여넣기 계단현상 없애기 set shiftwidth=4 " 자동 들여쓰기 너비 설정 set showmatch " 일치하는

[node.js] Jade Template Engine을 활용한 효율적 관리

node.js에서는 jade와 ejs라는 템플릿 엔진을 이용하여 html파일로 렌더링을 할 수 있습니다. 블로그 주인은  ejs 보다  jade 를 애용합니다. 이유는  { /%   /% } ,  <> 와 같은 특수 문자를 조금 덜 사용하는 jade를 선호합니다. 하지만 jade는  tab 과  space 로 구문을 해석하는 단점이 있습니다. 이번 시간에는 어떻게 하면 효율적인 html파일 관리를 할 수 있을지 설명을 해보도록 하겠습니다. (아래 내용은 100% 정답이 아니라 다양한 방식으로 사용해오면서 발전된 방법입니다. 앞으로도 계속 변할 것이고, 추후에 추가되거나 바뀌는 부분에 대해서는 추가적으로 포스팅을 하겠습니다.) jade의 문법적인 내용을 다루지 않습니다. express를 활용하여 프로젝트를 생성을 해보도록 하겠습니다. project create $ express helloWorld # CREATED helloWorld Directory $ cd helloWorld # MOVED helloWorld project structure +-- app.js +-- bin | +-- www +-- package.json +-- public | +-- javascript | +-- css | +-- images +-- routes | +-- user.js | +-- indexs.js +-- views | +-- error.jade | +-- index.jade | +-- layout.jade views를 집중적으로 탐구를 해 볼 것이다. error.jade extends layout block content h1= message h2= error.status pre #{error.stack} index.jade extends layout block content h1= title p Welcome to #{title} err

[javascript] javascript arrow function과 array.prototype의 조합

오늘은 javascript의  arrow function 을 좀더 간단하게 사용하는 방법에 대해서 알아보도록 하겠습니다. arrow function 은  => 의 형태로 함수를 표현하는 것을 의미 합니다. 함수 선언 함수 작성방법 1  : 일반적인 function 사용 let arrowFunctionTest = function ( arg1 ) { console . log ( arg1 ); return arg1 ; } arrowFunctionTest ( 'test' ); 함수 작성방법 2  : =>를 사용 let arrowFunctionTest = ( arg1 ) => { console . log ( arg1 ); return arg1 ; } arrowFunctionTest ( 'test' ); 2에서는 function대신에 =>를 사용하여 함수 표기를 하였습니다. 처음 보면 굉장히 어색할 수도 있지만 계속 보다보면 1번보다 2번이 더 익숙해 질 것입니다. callback 인자로 넘기기 자 그럼 이번에는 함수 선언이 아닌 arrow function을 callback인자로 넘겨보도록 하겠습니다. 콜백 인자 1  : 일반적인 function 사용 let list = [1, 2, 3, 4, 5]; let newList = list.map(function(item){ return item + 1; }); 콜백 인자 2  : =>를 사용 let list = [1, 2, 3, 4, 5]; let newList = list.map((item) => { return item + 1; }); javascript코드를 작성을 하다보면 리스트에서 값을 조작하여 새로운 리스트를 만드는 경우가 상당히 많습니다. 저는 이런 경우 코드를 아무리 잘 짜도 왠지 깔끔하지 않는것 같은 느낌이 들었

[DB]RDBMS vs NoSQL vs InMemory

어제 뉴스를 보면서 사람은 하루에 약 2Gb의 데이터를 자동차는 사람보다 더 많은 데이터를 비행기는 테라 바이트에 가까울 정도로 생산을 해낸다는 기사를 보았습니다. 저 또한 크롤러를 통해 하루에도 수많은 데이터를 만들어 내고 있습니다. 그렇다면 저 수많은 데이터를 관리를 해주는 곳이 필요할 텐데 그곳이 바로 database라는 시스템입니다. 하지만 데이터를 저장 하는 방식에 따라 크게 3가지의 종류로 나눠 볼 수 있습니다. 더 깊숙하게 들어가면 특정 어플리케이션에서만 사용하는 경량방식(SQLite)도 존재 하지만 이는 생략을 하도록 하겠습니다. 우선 빠르게 어떤 종류가 있는지 부터 훑어 보도록 하겠습니다. 이번 포스팅에서는 제가 여러 데이터 베이스를 사용하면서 각각의 데이터 베이스마다 어떤 식으로 데이터를 취급 하는지, 어떤 방식으로 데이터를 다뤄야 하는지 정리를 해보도록 하겠습니다. 1. 디비종류 1.1. RDB(Relational Database) oracle, mysql등으로 가장 많이 알려진 RDBMS 즉 RDB 입니다. 1.2. NoSQL 대표적인 예로 mongodb, hbase가 있습니다 mongodb같은 경우는 mean이 널리 퍼지면서 많이 알려진 db중 하나입니다. hbase같은 경우는 빅 데이터 처리를 한다면 누구나 한번쯤은 들어 봤을 겁니다. 1.3. In-Memory 대표적인 예로 redis가 있습니다 인 메모리 방식도 NoSQL방식에 속하지만 분리 해 보았습니다. 디비에서 가장 중요한 점은 각각의 데이터마다의 고유성을 만들어 내는 것입니다. 이것을 key 또는 Id 라고 합니다. 아마도 대부분이 Key라는 용어를 사용 할 겁니다. 하지만 디비에 따라 약간씩 Key를 부르는 용어가 다른데 rdb에서는 PK(Primary Key), FK(Foreign Key), nosql에서는 rowKey, partitionKey, sortingKey, id등으로 불리우고 있습

[python] 제너레이터(generator)를 통해 효율적인 코드작성

오늘은 generator에 대해서 알아볼까 합니다 우선 generator는 python말고도 javascript es6에서도 새롭게 추가된 부분이기도 합니다. 우선 python docs의 generator에 대한 정의를 봅시다. generator A function which returns an ierator. It looks like a normal function except that it comtains yield statements for producting a series of values usable in a for-loop that can be retrieved one at a time with the next() function. Each yield temporarily suspends processing, remembering the location execution state (including local variables and pending try-statements). When the generator resumes, it picks-up where it left-off (in contrast to functions which start fresh on every invocation). 첫 줄에 한 줄로 정의가 됐다.  반복자를 반환하는 함수 모든 호출에서 새롭게 시작되는 함수가 아닌 위치를 기억하는 함수 즉 특정 위치를 기억하여 루프를 돌릴 수 있도록 반환을 하는 것이다. 해당 함수는 next()를 이용하여 호출이 가능. 간단한 코드를 통해 generator의 사용방법을 알아보자. # app.py def generator(n): i = 0 while i < n: yield i i += 1 _generator = generator(10) print(_generator) for i in _generator: print(

[python] 간단한 getter와 setter를 구현할 때는 property, 복잡해질 경우 descriptor를 사용하자

http://meonggae.blogspot.kr/2016/11/python-getter-setter-property-setter.html 필자가 전에 한번 getter와 setter에 관련되서 글을 쓴 적이 있다. 이때 getter와 setter함수를 구현하지 말고 @property를 이용해서 구현을 하라고 했다 하지만 코드를 작성하다보면 @property가 복잡해지는 경우가 발생을 할 것이다. 이럴떄는 descriptor를 사용을 하여 코드를 좀더 깔끔하게 할 수 있다. class test: @property def t(self): return self._t @t.setter def t(self, value): print('setter 작동') self._t = 10 a = test() a.t = 10 property를 이용하여 코드를 작성을 할 수 있습니다. property를 이용하영 외부에서 _t를 접근 할 수 있도록 하였습니다. $ python3 app.py setter 작동 외부에서 t를 접근 할 때 정상적으로 t()가 실행 됬음을 확인 할 수 있습니다. 그런데 이는 외부 뿐 아니라 내부에서 접근을 할 때에도 실행이 됩니다. class test: def __init__(self): self.t = 1 @property def t(self): return self._t @t.setter def t(self, value): print('setter 작동') self._t = 10 a = test() a.t = 10 해당 코드를 실행을 시켜봅시다. $ python3 app.py setter작동 setter작동 t()가 두번 실행됬습니다. test()에서 __init__이 호출이 되면서 내부적으로 self

[알고리즘] snake게임 알고리즘

막무가네로 알고리즘을 공부하면 재미가 없으니 게임을 접목하여 다루어 보도록 하겠습니다. 게임의 대상은 스네이크 게임입니다. 많은 사람들은 어릴 때 뱀게임을 많이 해봤을 것 입니다. 이번에 다뤄볼 주제는 뱀이 움직임을 어떻게 구현을 할지 알아보겠습니다. 뱀은 크게 3가지의 경우가 있습니다 1. 가장 중요한 뱀을 움직이기 2. 음식먹기 이때 뱀은 크기가 늘어나야 합니다. 3. 뱀이 움직이는 정책   - 뱀이 움직이지 못하는 경우는 : 우측방향에서 좌측 방향으로 OR 위에 아래 방향고 같이 180도 반전되는 움직임은 막겠습니다. 순수한 알고리즘을 만드는 과정이기 때문에 음식을 먹었는지 안먹었는지 판단하는 부분은 랜덤으로 판단을 하도록 하겠습니다. def is_eat(): return random.choice([1, 0]) 랜덤으로 1, 0을 반환을 해줍니다. 실제로 게임을 만든다면 해당 함수는 뱀의 머리가 음식의 좌표와 같은지 검사를 해주면 되겠습니다. key_position_map = { 'w': [-1, 0], # up 's': [1, 0], # down 'a': [0, -1], # left 'd': [0, 1] # right } direction = key_position_map.get('d') 다음으로는 키맵핑을 한 오브젝트 입니다. direction은 현재 뱀의 방향을 나타냅니다. snake_body = [[2, 3], [1, 3],[1, 2], [1, 1]] 주인공이 되는 뱀의 좌표들 입니다. while True: key = input() new_direction = key_position_map.get(key) if new_direction and direction_check(direction, new_direction): directi