정말 많이 삽질했다..ㅜ


sqlite3에서 좋은 점은 full-text searching 알고리즘을 제공한다는 점이다. 물론 모든 테이블에 적용 가능한 것은 아니고, virtual table을 memory에 fts3을 적용하여 만들고, 여기서 검색을 해야 한다.


근데 문제가 있는데... python을 설치하면서 따라온 sqlite3의 query syntax가 하필이면(!) "Standard Query Syntax"라는 점이다. 이게 표준이라고 이름이 붙었지만 MATCH 문법을 쓸 때의 operator에 제한이 있어 사용하기가 불편하다. 자세히 살펴보지 않았지만 sqlite3를 컴파일해서 설치할 때 옵션을 바꾸어주면 정말 편리한 "Enhanced Query Syntax (EQS)"를 사용할 수 있다고 한다. 


두 개의 Syntax 차이점 중 이번에 삽질하게 된 것은 바로 not operator이다. 


EQS의 경우 NOT operator를 따로 제공해준다. OR과 AND operator도 제공해주어 직관적으로 MATCH 문법의 쿼리를 짤 수 있다. 예를 들어, a, b, c 중 하나 이상을 포함하면서도 d, e 중 하나라도 들어있으면 안되는 상황을 생각해보자. 이 경우에 쿼리는 다음과 같이 만들어진다. 물론 EQS에서만... 


column_name MATCH '(a OR b OR C) NOT (d OR e)';


게다가 a, b, c..., e 와 같은 키워드들이 phrase여도 문제가 없다. 즉, "sony vaio" 처럼 주어진 구문의 매칭여부까지 포함한다. 


그런데 SQS의 경우 상황이 조금 다르다. 우선 NOT operator가 없다는게 가장 큰 함정. 대신 - 기호의 operator를 제공해준다. 이 놈의 역할은 NOT operator와 비슷한데 다른점이라면 phrase에서 적용되지 않는다는 점이다. -.-;;; 물론 AND operator 역시 없으며, 그냥 띄어쓰기가 이를 대신한다. 


만약 위와 같은 예제에서 매칭되는 키워드들이 모두 진짜 word라면, 


column_name MATCH '"a" OR "b" OR "c" (-d -e)';


뭐 이런식으로 써야 할 것 같다. (sqlite expert 프로그램에서는 안되네요..;;;) 그런데 문제는 d와 e가 word가 아닌 phrase일 경우... 이런 식의 쿼리문은 에러를 낸다. Stackoverflow에서 봤던 것 같은데, 이를 위해서는 결국 내부쿼리를 이용해서 이런 record들을 빼주는 식으로 처리해야 한다.


SELECT * from table WHERE column_name MATCH '"a" OR "b" OR "c"' and id not IN (SELECT id from table WHERE column_name MATCH '"d" OR "e"');


여기서 a, b, c, d, e 모두 phrase라고 생각해야 한다. 그냥 word였으면 위의 방법대로 되니까...ㅎ


이외에도 SQS와 EQS는 연산자의 순서도 다르다. 그래서 쿼리문을 짜놓고 헷갈리면... 엉뚱한 결과가 나올 수 있다. 자세한 것은 아래 링크에서... (영문)


http://www.sqlite.org/fts3.html#section_3_1



파이썬에서 print로 출력할 때, 줄바꿈 없이 print 내용이 업데이트하는 방법이다. 

출처는 역시 스택오버플로우~!

t's called the carriage return, or \r

Use

print i/len(some_list)*100," percent complete         \r",

The comma prevents print from adding a newline. (and the spaces will keep the line clear from prior output)

Also, don't forget to terminate with a print "" to get at least a finalizing newline!


http://stackoverflow.com/questions/3419984/print-to-the-same-line-and-not-a-new-line-in-python

여러 리스트들의 값을 가로가 아닌 세로로 출력해야 할 때가 있다. 다음과 같이...


A = [a, b, c]

B = [10, 20, 30, 40]

C = [뭐]

이를 아래처럼 출력

a    10    뭐

b    20    none

c    30    none

none    40    none


이렇게 하려고 세로로 출력하는 엄청 귀찮은 함수를 짜야 한다면... 다음과 같이 해보시라!!!


import itertools

list(itertools.izip_longest(a, b, c))


원래 파이썬에서는 zip이라는 함수가 존재하는데(Ref), 하는 일은 위의 itertools의 izip_longest와 똑같지만 주어진 list들 중 가장 짧은 애의 길이로 출력해준다. 그래서 위의 예제에서는 첫번째 행만 출력되는 안습상황이 펼쳐진다. 가장 긴 리스트의 길이로 맞추어 출력하고 싶다면, itertools의 izip_longest를 쓰시길!


추가: 만약 리스트 하나에 A, B, C가 들어있다면 다음과 같이 합니다.


data = [A, B, C]

izip_longest(*data,fillvalue='')

http://stackoverflow.com/questions/10071342/python-how-to-write-blocks-of-data-in-columns


출처: http://stackoverflow.com/questions/1277278/python-zip-like-function-that-pads-to-longest-length

파이썬에서 networkx 패키지를 쓰다보면 그래프를 파일로 출력해야 할 때가 많습니다. 예전에는 pajek파일 형식(.net)으로 뽑았는데요. 이 형식에는 꽤 제약이 많은 것 같습니다. 무엇보다도 node의 id를 새로 정의해서 edgelist에 사용하기 때문에 상당히 헷갈리기 쉽지요.


그래서 저는 gexf 형식을 즐겨씁니다. 이 형식은 그래프를 위한 xml이라고 하는데요. 파일 용량이 조금 커지긴 하지만 그냥 에디터에서 읽어도, gephi에서 읽어도 모두 직관적으로 사용할 수 있습니다.


그러나 문제가 있는데 G[1]['class'] = "A" 등과 같이 attribute를 정해준 뒤에 gexf로 출력하라고 하면 다음과 같은 문제가 생깁니다. 


AttributeError: 'str' object has no attribute 'copy' 

에러의 발생위치는 write_gexf 함수.... -.-!!!!!


이를 해결하는 방법은 구글링하면 나오는데 생각보다 쉽습니다. Attribute를 정해줄 때 다음과 같이 해야합니다. 

(x) G[1]['class'] = "A"

(o) G.node[1]['class'] = "A"


두번째 방법으로 G.node를 직접 써주어야 합니다.


출처: https://groups.google.com/forum/#!msg/networkx-discuss/Irx4j6G-srs/yR8GFtMmQB8J

잘 쓰던 Word가 어느날부터 파일만 열면 비정상적으로 종료되는 때가 있습니다. 그리고 안전모드로 다시 실행하면 잘 열리긴 하지요.


제 노트북(SONY VIAO VPCSB36FK)에서 이런 일이 꼭 생기는데요. 사실 이미 잘 알려진 버그(??) 입니다. 특별히 무언가를 더 설치하거나 하지 않았다면 블루투스(Bluetooth)의 문제라고 하네요.


안전모드로 들어간 뒤에 파일 탭 > 옵션 버튼을 누릅니다. (잘 찾아보세요.)


여기서 추가기능 탭을 누른 뒤 맨 아래에 있는 관리 메뉴에서 COM 추가 기능으로 이동합니다. 그리고 여기서 Send to Bluetooth기능을 체크해제한 뒤에 확인을 눌러주면 됩니다.


그럼 감쪽같이 문제해결!


가끔 파이썬으로 한글을 처리할 때면 곤혹스러워진다. 바로 인코딩때문에 안그래도 없는 시간이 총알처럼 지나가기 때문이다. 인코딩 문제는 시간만 까먹고 해결해봐야 밑져야 본전인 일이다. 3.x 버전과 달리 특히 2.x 버전에서는 유니코드와 다른 문자열들이 혼재해 있어 더더더더더욱 환장할 때가 있다.


여기에 unicode와 UTF-8 간의 분쟁을 정리해보자!


1. unicode와 UTF-8은 뭐야?

사실 UTF-8이 Unicode이다. (-.-) 실제로 위키피디아에 검색을 해보자. UTF-8은 "유니코드를 위한 가변 길이 문자 인코딩 방식 중 하나"라고 되어있다. (여기) 그렇다면 이건 무슨 개소리인가. 사실 파이썬에는 인코딩이라는 무시무시한 불규칙 세상에서 모든 글자를 자유로이 쓰려는 노력이 담겨있다. (맞나...?) 그래서 파이썬에는 두가지 종류의 문자열이 있다. 

 (1) unicode 

 (2) byte code

 여기서 byte code란 정말 우리가 쓰는 글자열이 어떤 특정한 규칙을 통해 byte로 만들어진 것을 말한다. 그럼 unicode는 무엇이냐고? python에서 unicode란 그저 "문자열"이다. 즉, 컴퓨터에서 쓰는 특정한 규칙을 거치기 전, unicode라는 거대한 체계에서 정의된 "문자열"일 뿐이다.


그럼 두 개의 차이는?


byte code는 출력이 자유롭다. 만약 여러분이 한글 윈도우에서 작업하고 있다면, system의 location code는 cp949 일 것이다. (거의 99.9%) 하지만 리눅스나 OSX일 경우, system의 location code는 UTF-8이 된다. 경험하신 분도 계시겠지만, 같은 문자도 다른 문자열 조합을 이용하면서 byte로 표현되는 방법이 바뀐다. 

좋은 예제는 여기에 가서 Omega가 어떻게 byte로 표현되는지 확인할 수 있다. 간단히 cp949와 UTF-8에서의 A를 찾아봐도 사실 많이 다르다.


UTF-8 에서의 A: 0x41

cp949에서의 A: 0xA3C1


따라서 byte code는 출력이 자유롭지만 현재 컴터의 기본 문자열 조합과 다른 경우, 글자가 깨진다. ㄷㄷㄷㄷ

반면 유니코드 문자열은 출력하거나 파일에 쓰는 방법이 딱히 없다. 그저 "문자열"일 뿐 이진수로 표현되지 않았기 때문이다. 그래서 우리는 문자열 코덱이 필요한거다.


2. python에서 유니코드와 이진문자 사용하기

파이썬에서는 사실 두 종류의 문자를 모두 사용할 수 있기 때문에 더욱 헷갈린다. 어려울 경우 console을 띄우고 차근차근 해보는게 좋다.

우선 이진문자의 경우 

>>> a = "한글"

이렇게 사용하면 된다. 그럼 a는 컴터의 로케일에 맞추어 알아서 문자열이 인코딩된다. 한글 윈도우는 cp-949 나머지는 보통 UTF-8이다.

유니코드로 사용하고 싶다면,

>>> a= u"한글"

이렇게 사용하면 된다. 


모두 출력은 

>>>print a

를 통해서 가능하다. print의 경우 유니코드는 알아서 컴터의 로케일 문자열로 변환해 보여준다. 만약 깨져보이면, 컴터의 로케일 문자열 셋과 다른 것으로 인코딩 된 것일뿐, 문자열이 이상해진건 아니니 걱정안해도 된다.


3. 차이점?

차이점은 있다. 바로 문자열의 비교나 연산(더하기 등등)에서 에러가 난다는 점이다. 생각해보면 조금 당연한데, 유니코드  문자열은 사실 이진문자가 아니므로 컴터가 어떻게 해줄 수가 없다....-.-

print 함수의 경우 착해서 문자열을 알아서 로케일 문자열 셋으로 변환해 보여준 것일 뿐.... 나머지 기능들은 그렇게 착하지 않다.


참고로 이진문자(byte code)끼리 혹은 유니코드 문자열끼리는 비교나 연산이 가능하다.


4. 변환하기

유니코드 문자와 이진 문자 혹은 서로 다른 문자열 셋으로 만들어진 이진문자를 처리해야 할 때가 있다. 이럴 때에는 프로그램 내에서 사용할 문자열의 셋을 정하자. UTF-8이 되었건 유니코드가 되었건 아니면 cp-949나 다른 셋이건 하나 정하고 통일해야 정신을 잃지 않는다.


간단한 함수 두 개만 잘 기억하자.

s = u.encode("UTF-8")

u = s.decode("UTF-8")


유니코드에서 특정 이진문자로 넘어가기 위해선 encode()를 이용한다. 중요한 점은, 여기에 argument로 들어가는 것이 바로 변환하고자 하는 이진문자의 문자열 셋이다. 이건 본인이 그때그때 적당하게 잡아주면 된다.

거꾸로 이진문자에서 유니코드로 넘어가고자 할 때에는 decode()를 이용한다. 여기서도 문자열 셋의 종류가 들어가는데, 이건 바꾸려는 대상인 이진문자의 문자열 셋이다. 이걸 모르면.... 정말 골치아픈데, 사실 한글은 cp949 혹은 UTF-8 둘 중 하나다. 잘못된 문자열 셋을 넣으면 에러나니까 주의!


decode() 함수 이외에도 유니코드로 가는 방법이 한가지 더 있다. u = unicode(s, "UTF-8") 등의 방법으로 유니코드로의 변환이 가능하다.


5, 데이터 쓰기

문자열을 신나게 처리하면 마지막에 기록을 해야 한다. 기록하는 방법 중 가장 간단한 방법은, 

>>> f = open("aaa.txt", 'w')

처럼 파일을 열고 여기에 쓰는 것이다. 해보면 알겠지만 여기에 아무 문자열 셋으로 만들어진 이진문자를 기록해도 상관이 없다!!!! 사실 파일에 쓰는 것은 byte에 쓰여진 이진수들일 뿐이니까 아무 상관이 없어야 하는게 맞다.

그래서 cp949로 된 문자열을 기록하면 그 문서는 cp949로 인코딩해서 열어야 제대로 보이고, UTF-8 이진문자를 기록한 파일은 UTF-8로 열어야 한다. Editplus같은 좋은 에디터들은 알아서 인코딩도 정해주니 얼마나 좋은가!


하지만 이렇게 파일을 열어서 쓰면 유니코드를 기록할 수 없다. 당연하지... 유니코드는 "문자열"일 뿐 어떤 이진문자로 표현될지 정해지지 않은 날 것 그대로이다. 그래서 문자열 셋을 정해서 인코딩 후 기록해야 한다.


혹은 이렇게 파일을 열 수 있는데, 

>>> f = codecs.open("codecs.txt", 'w', 'utf-8')

이 경우 맨 위에 import codecs를 해주어야 한다. 아무튼, 이렇게 파일을 열면 무조건 이 파일은 UTF-8로 작성이 된다. 그럼...?? 여기선 UTF-8로 인코딩된 문자열을 쓸 수 있어야 하지 않을까?

>>> f.write(a) ----> a는 UTF-8로 인코딩된 문자열

이러면 UnicodeDecodeError가 뜬다. -.-?????

사실 자세히 찾아볼 여유는 없었는데, codecs로 열면 반드시 작성할 때의 문자열은 유니코드여야 한다. 그래서 어떤 문자열 셋으로 변환된 문자들도 codecs를 통해 열게 된 파일에 쓰기가 안된다. 


사실 이런 에러들 때문에 python을 가끔 쓰다가 멘붕에 빠지기도 한다.


6. 서두에 붙이는  #-*- coding: utf-8 -*- 이건 뭥미?

가끔 한글 인코딩 이렇게 구글링을 하다보면 위의 문자열 셋 선언부를 보게 된다. 이걸 하고나서 누군가는 잘 되었다는데 나는 잘 안되고.... 하면서 멘붕이 지구 맨틀까지 닿을듯 몰려오는 떄가 있다.


저 선언부는 이 문서에 써져있는 한글이나 다른 문자열들이 utf-8로 쓰일 것이라는걸 미리 알려주는 것 뿐이다. 그래서 파일을 읽고 문자열을 처리하다가 생기는 에러는 위의 선언으로 고쳐질 수 없다.



새롭게 알게되는 내용이 있다면 또 포스팅해야겠다.


참고할만한 한글 문서들!!!

http://kldp.org/node/133996

http://coreapython.hosting.paran.com/boodebr/All%20About%20Python%20and%20Unicode%20%20boodebr_org.htm

http://lakhos.egloos.com/2899553

http://seorenn.blogspot.kr/2011/02/python-unicodeutf-8.html

http://www.i-fam.net/water/93


사실 구글링 잘 하면 맨 위에 나오는 문서들인데... 생각보다 다시 찾기는 쉽지 않다. ㅎㅎ


'Study > Computer' 카테고리의 다른 글

networkx에서 gexf 사용하기  (0) 2013.10.15
MS Word가 갑자기 비정상적으로 종료될 때  (0) 2013.10.01
networkx에서 link의 방향성  (0) 2013.09.19
연속된 숫자 뭉치를 뽑아내기.  (1) 2013.09.04
Amazon EC2 사용하기  (0) 2013.08.27

NetworkX 를 사용하다가 문득 확인해봤다.


혹시 아니면 어쩌지...하면서!


G = DiGraph() 로 네트워크 인스턴스를 생성 후에 다음과 같이 두 개의 링크를 추가해보았다.


>>>G.add_edge(1,2)

>>>G.add_edge(1,3)


그리고 나서 확인!

>>> G.in_edges(1)

[]

>>>G.out_edges(1)

[(1, 2), (1, 3)]


즉, G.add_edge(u,v)는 u -> v 인 방향의 링크를 만들어준다. 따라서 G[u][v]역시 u->v 인 링크의 attribute를 보여준다.

'Study > Computer' 카테고리의 다른 글

MS Word가 갑자기 비정상적으로 종료될 때  (0) 2013.10.01
골치덩어리 unicode와 UTF-8  (1) 2013.09.23
연속된 숫자 뭉치를 뽑아내기.  (1) 2013.09.04
Amazon EC2 사용하기  (0) 2013.08.27
BeautifulSoup4 사용하기  (0) 2013.08.23

우선 Heatmap을 matrix 형태의 데이터로부터 그리는 방법부더 살펴보자.


gnuplot에서


set pm3d map 

set pm3d interpolate 0,0

splot "./aaa.txt" matrix every ::4 


첫째 줄은 pm3d 형태의 map을 그리겠다고 설정해준 것이고, 두번째는 그림의 내삽을 할지말지 정하는 것이다. 보통 안하는게 데이터를 눈으로 보기에 좋다.

세번째로 그림을 그리는 부분인데, matrix 를 꼭 붙여야 한다! 안그러면 x, y, z 축으로 각 컬럼을 인식한다...

every명령어는 이 블로그 어딘가에 있는데, 지금 저건 4번째 column부터 그리라는 의미.


color bar의 색을 바꾸려면,


set palette defined (0 "green", 1 "red")


이렇게 해주면 녹색부터 빨간색까지로 바뀐다. 정말 쉬운 방법인데, 자신이 색을 직접 rgb로 정해주거나 내장된 다른 팔래트를 이용할 수도 있다. 이건 나중에 구글링...


color bar의 range를 바꿀 수도 있다.


set cbrange[10:100]


이렇게 쓰면 colorbar의 색 범위를 정해주는데, 예시에서는 10~100까지로 정해주었다.

'Study > Gnuplot' 카테고리의 다른 글

density plot 그리기  (0) 2014.05.18
gnuplot 에서 그림에 한글 사용하기  (0) 2013.07.02
data에서 원하는 줄만 골라 그리기  (0) 2013.05.27
Fitting parameter를 출력하기  (0) 2013.05.21
Line과 Point의 Style 지정해주기  (0) 2012.07.29

하다보니 필요한 기능이어서 만들어봤다. 쉬운데 막상 짜려고 하면 귀찮고 시간도 잡아먹는 그런 예제들.

생각나는대로 이런 애들을 만들게 되면 블로그에 소스를 공개해야겠다.


파이썬으로 만들었고, queue를 이용했다. 물론 queue 라이브러리를 import하지는 않았다. 그래도 queue처럼 만들긴 쉽다.


queue = [2,3, 6, 7, 10, 11, 12, 15, 16, 17, 21, 22, 30]


packet = []

tmp = []

v = queue.pop(0)

tmp.append(v)

print(v)

while(len(queue)>0):

vv = queue.pop(0)

print(vv)

if v+1 == vv:

tmp.append(vv)

v = vv

else:

packet.append(tmp)

tmp = []

tmp.append(vv)

v = vv


packet.append(tmp)


print(packet)


결과는 여러분이 생각한대로!ㅋㅋ

'Study > Computer' 카테고리의 다른 글

골치덩어리 unicode와 UTF-8  (1) 2013.09.23
networkx에서 link의 방향성  (0) 2013.09.19
Amazon EC2 사용하기  (0) 2013.08.27
BeautifulSoup4 사용하기  (0) 2013.08.23
윈도우에서 easy_install, pip 사용하기.  (3) 2013.08.23

아마존에서 제공하는 Elastic Cloud computer (맞나?)를 쓰는 방법들이 자세히 소개된 사이트들을 소개하겠다.

시간되면 포스팅하기로 하고....ㅜㅜ


1. Amazon EC2에 가입한 후 컴퓨터 얻기. (Instances 얻기.)

http://opentutorials.org/course/608/3053


** 발급된 키 파일은 잃어버리면 안되는데, 한번 접속 후에 설정을 바꾸어주면 키 없어도 잘 접속할 수 있다.

** Xshell 괜찮네...ㄷㄷㄷ


2. Amazon EC2에 gnome 설치하기

http://michaelhallsmoore.com/blog/Desktop-Ubuntu-in-Amazon-EC2-The-Right-Way


3. 접속할 때 gnome-fallback 에러가 나면?

http://www.dickson.me.uk/2012/06/18/installing-freenx-server-on-12-04-precise-pangolin/


** 글에 함정이 있는데, 저렇게 한다고 해서 되는게 아니었다. 코멘트를 읽어보면 아래와 같은 말이...ㄷㄷㄷ

이걸 설치한 후 article대로 설정파일을 수정하면 된다.

I was missing out on this: sudo apt-get install gnome-session-fallback



+ Recent posts