• 2006-04-26

    Python Tips

    asyncore.dispatcher

    • 원래부터 nonblocking 이다.
    • set_socket 하는 시점에 map 에 등록된다.

    StringIO.readline()

    StringIO 는 file-like 객체이므로 readline() 을 지원한다. 그러나 write() 한 후 읽어들이면 None 을 리턴한다. 내부적으로 유지하는 offset 이 하나이기 때문인데, 만약 사용하려면 offset(0) 을 호출해서 포인터를 맨 앞으로 돌려줘야 한다. (너무 단순한가?)

    zipfile

    zip 포맷으로 특정 폴더를 압축하기 위해서는 다음과 같이 해야 한다. 이때 압축 포맷으로 ZIP_DEFLATED 를 사용해야 파일 크기가 작아진다.

    def zipdir(zfile,dir,base='.'):
    """zip directory recursively"""
    print '\nzip %s'%dir,
    
    global log
    log.write('zip %s...'%dir)
    
    for f in os.listdir(dir):
    nf = os.path.join(dir,f)
    if os.path.isdir(nf):
    zipdir(zfile,nf,os.path.basename(dir))
    else:
    print '.',
    zfile.write(nf,
    os.path.join( base, os.path.basename(dir), f),
    zipfile.ZIP_DEFLATED)
    

    dict(zip(seq1,seq2))

    keys와 values를 dict로 매치시킬 때 dict()와 zip()을 사용할 수 있다.

    >>> keys = [ 'aaa', 'bbb', 'ccc' ]
    >>> values = [ 1, 2, 3 ]
    >>> zip(keys,values)
    [('aaa', 1), ('bbb', 2), ('ccc', 3)]
    >>> dict(zip(keys,values))
    {'aaa': 1, 'bbb': 2, 'ccc': 3}
    

    re.findall

    스트링에서 특정 seperator 로 구분된 패턴으로 자를 때, string.split() 도 좋지만 re.findall() 을 강추

    >>> args = '"SELECT * FROM User","aaa,bbb,ccc,ddd"'
    >>> args.split('"')
    ['', 'SELECT * FROM User', ',', 'aaa,bbb,ccc,ddd', '']
    >>> re.findall('"(.+?)"',args)
    ['SELECT * FROM User', 'aaa,bbb,ccc,ddd']
    

    re 를 이용한 파일명 변경

    특정 폴더 안에 여러가지 파일명들을 바꾸기 위해서는 re 모듈을 잘 사용해야 한다. 다음은 파일명에 {{{[...]}}} 을 없엘 때 쓰는 스크립트이다.

    import os, re
    os.chdir(target_folder)
    for old_name in os.listdir('.'):
    new_name = re.sub('\[.+\]','',old_name)
    os.rename(old_name,new_name)
    
  • 2006-04-26

    Funny Memory Values

    from WFC Technical Note 006 - Funny Memory Values

    윈도우 환경에서 디버깅을 하다 보면 0XCDCD 라든지 0XDDDD 같은 특이한 값들을 만날 수 있는데, 이게 그냥 가비지가 아니라 각각마다 특유의 의미를 가지고 있었다. 가령 0xDDDD는 이미 지워진 포인터라든지 0xFDFD는 힙에 할당한 값의 앞뒤에 위치하는 경계값이라든지 말이다.

    한글로 된 설명은 요기요기가 제일 잘 되어 있으니 참고하시길.

  • 2006-04-25

    UDT : UDP-based Data Transfer Library

    UDT는 Internet2 혹은 기가비트 이더넷과 같이 빠른 네트워크에서 수십~수백 기가 바이트의 대용량 데이터를 전송할 때 TCP가 매우 느리다는 점때문에 시작된 오픈소스 프로젝트이다. 버클리 소켓 API를 그대로 유지하고 있어서 접근성이 좋고, TCP의 슬라이딩 윈도우 같은 Congestion Control 을 사용자가 상황에 맞게 조정할 수 있다는 장점이 있다. 2.0 버전까지는 UDP 스트림만을 지원했는데 3.0부터는 UDP 다이어그램과 중첩입출력(Overlapped)도 지원하기 시작했다. 현재 3.0 beta 가 나와 있는 상태이다.

    이번에 reliable UDP 라이브러리 조사 도중 탐지망에 걸려 들어서 검토한 결과, 하나의 소켓에 대해서 내부적으로 입력과 출력 쓰레드를 1개씩 사용하는 것을 발견했다. 원래부터 데이터 전송을 목적으로 구현되어서 그런 듯한데, 이를 수정하지 않고는 게임 서버에서 사용하기는 힘들다는 판단을 내렸다. 시간이 난다면 IOCP를 연동할 수 있게 살짝 고쳐 보고 싶지만, 누구 말마따나 게임 회사는 연구소가 아닌 관계로... OTL

    결국 다시 RakNet으로 가야 된단 말인가...

  • 2006-04-25

    CodeKeep

    codekeep.JPG
    Visual Studio Add-Ins Every Developer Should Download Now 에서 비주얼 스튜디오를 위한 10 가지 필수 플러그인들을 만나볼 수 있다. 그 중에서 제일 마음에 드는 것은, 함수를 선택하면 파라미터를 읽어서 자동적으로 XML 코멘트를 만들어주는 GhostDoc과, 웹에서 코드 조각들을 검색해서 내 코드에 넣을 수 있는 CodeKeep이라는 플러그인이다.

    단 GhostDoc은 아직 VS2005 영문판만 지원해서 CodeKeep만 구경해볼 수 있었는데, 아직은 기부된 코드의 양이 부족한 듯해서 아쉬웠다. del.icio.us처럼 많은 사람들이 사용해줘야 시너지 효과가 날텐데, 홈페이지만 웹2.0 디자인을 닮으려고 해서는 안될 것이다. 이런 식으로 팀 내부적으로 코드조각을 공유할 수 있는 솔루션이 있었으면 좋으련만... (누가 위키 기반으로 만들어주시게~~)

  • 2006-04-24

    ODBC Tips

    Timestamp -> C

    TIMESTAMP 값을 C 에서 받는 방법은 다양하다. 단순 SELECT 를 통해 날짜 스트링으로 받던가, SQL 문으로 적절히 CONVERT 한 변형된 스트링을 받던가, 아예 아래처럼 구조체로 바로 받을 수 있다.

    // SQL_C_TYPE_DATE
    struct tagDATE_STRUCT {
    SQLSMALLINT year;
    SQLUSMALLINT month;
    SQLUSMALLINT day;
    } DATE_STRUCT;
    
    // SQL_C_TYPE_TIME
    struct tagTIME_STRUCT {
    SQLUSMALLINT hour;
    SQLUSMALLINT minute;
    SQLUSMALLINT second;
    } TIME_STRUCT;
    
    // SQL_C_TYPE_TIMESTAMP
    struct tagTIMESTAMP_STRUCT {
    SQLSMALLINT year;
    SQLUSMALLINT month;
    SQLUSMALLINT day;
    SQLUSMALLINT hour;
    SQLUSMALLINT minute;
    SQLUSMALLINT second;
    SQLUINTEGER fraction;[b]
    } TIMESTAMP_STRUCT;
    

    see also: