CEDET

September 8, 2010

http://alexott.net/en/writings/emacs-devenv/EmacsCedet.html

CEDET
Collection of Emacs Development Environment Tools

어느 버전부터 들어갔는지 기억은 잘 안나지만, 최근 emacs package(23.x~)에는 bundle로도 탑재가 되어있다. Emacs package 중에서 dependency가 복잡하고, 동작하기 어려운 package 중이기도 하다.

C/C++/Java를 semantic package에서 지원한다. 필요한 Objective-C, python은 default로 지원이 되지 않고, 뭔가 설정이 더 필요하다. 설정을 좀 해 보다가 당분간 사용하지 않기로 했다. JDEE와 함께 Java development Environment로 사용할때도 유용하다.

로또 번호 생성기 using python

September 8, 2010

블로그 RSS를 읽다가 심심풀이로…

  1. 1부터 45까지의 숫자 중에 6개를 뽑는다. 6개의 값이 다 달라야 한다.
  2. 출력시 작은 숫자부터 순서대로 출력

코드는

import random
print sorted(random.sample(xrange(1,46),6))
sample(self, population, k)
method of random.Random instance Chooses k unique random elements from a population sequence.

Returns a new list containing elements from the population while leaving the original population unchanged. The resulting list is in selection order so that all sub-slices will also be valid random samples. This allows raffle winners (the sample) to be partitioned into grand prize and second place winners (the subslices).

Members of the population need not be hashable or unique. If the population contains repeats, then each occurrence is a possible selection in the sample.

To choose a sample in a range of integers, use xrange as an argument. This is especially fast and space efficient for sampling from a large population: sample(xrange(10000000), 60)

인터넷 라디오 녹음하여 PodCasting Service 하기

September 2, 2010

프로그램 다운로드

Mac

MacPorts에 mplayer-devel을 인스톨한다. Mplayer는 snow leopard에서는 컴파일이 되지 않아서 mplayer-devel 버젼을 인스톨해야 한다.

sudo port install mplayer-devel lame

Linux

sudo apt-get install mplayer lame

방송녹음

다음은 녹음할 라디오 방송 주소를 알아야 한다. 녹음할 EBS 교육방송 주소는 mms://211.218.209.124/L-FM_300k이다.

record.sh 파일을 만들어서 아래와 같이 저장한다.

#!/bin/sh
mplayer mms://211.218.209.124/L-FM_300k  -dumpfile `date +%Y%m%d%H%M`.mp3 -dumpstream &
sleep 600
kill $!

mplayer에 시간 간격을 정해서 녹음하는 기능이 없으므로, 백그라운드로 수행한 후, 10분 후에 process를 kill하는 방법을 사용한다.

chmod a+x record.sh 하여 실행 파일을 만든 후에, crontab 에 등록한다. 녹음된 소스는 20100901xxxx.mp3 와 같은 형태로 저장이 된다.

이렇게 저장한 파일은 mp3 format 파일인 경우에는 podcast로 읽어들여도 문제가 없는데, EBS 교육 방송은 asf 파일 포맷이다. 그래서 pcm 파일 format으로 저장한 다음, lame 프로그램을 이용하여 mp3로 변환하는 것이 좋다.

#!/bin/sh
cd /var/www/podcast
FILENAME=`date +%Y%m%d%H%M`.wav
mplayer mms://211.218.209.124/L-FM_300k -quiet -ao pcm:file=$FILENAME &
sleep 600
kill $!
lame $FILENAME `basename $FILENAME .wav`.mp3
rm $FILENAME
python rss.py

PodCast service

record.sh shell script에서 rss.py에 해당하는 부분이다.

RSS용 XML파일을 만들기 위해서 PyRSS2Gen이라는 package를 사용한다. 이 패키지는 easy_install PyRSS2Gen으로 인스톨한다.

만들어진 mp3를 podcasting용 xml 파일을 만들어주는 script이다. 현재 directory에서 mp3로 끝나는 파일을 읽어서 podcast.xml 파일을 만든다.

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Jaemok Jeong(jmjeong@gmail.com)
#
# [2010/09/01]

import PyRSS2Gen as RSS2
import datetime

import os,sys
url = "http://jmjeong.com/podcast/"

def main():
    """
    """

    mp3files = [file for file in os.listdir(".") if file.endswith(".mp3")]

    items = []
    for i in mp3files:
        items.append(RSS2.RSSItem(
            title = i,
            link = url+i,
            description = i,
            guid = RSS2.Guid(url+i),
            enclosure = RSS2.Enclosure(url+i, os.path.getsize(i), "audio/mpeg/"),
            pubDate = datetime.datetime.utcfromtimestamp(os.stat(i).st_ctime)))

    rss = RSS2.RSS2(
        title = "EBS podcast by jmjeong",
        link = "http://jmjeong.com/podcast/podcast.xml",
        description = "Internet EBS podcasting",
        lastBuildDate = datetime.datetime.utcnow(),

        items = items);

    rss.write_xml(open("podcast.xml", "w"), encoding = "utf-8")

if __name__ == '__main__':
    main()

Crontab에 등록

jmjeong@jmhost:/var/www/podcast$ crontab -e
50 6 * * * /var/www/podcast/record.sh 2>&1 /dev/null

FlashForward

September 2, 2010

http://upload.wikimedia.org/wikipedia/en/thumb/b/b4/FlashForward2.JPG/250px-FlashForward2.JPG

휴가기간 동안 재밌게 봤었다. 시청률 저조로 인해 시즌2는 더 이상 제작하지 않는다고 했다. 1999년 캐나다 작가인 Robert J.Sawyer에 의해 쓰여진 동명 소설을 TV 시리즈로 제작한 것이라고 했다.

드라마는 소설에서 plot만 가져오고, 세부적인 내용은 다시 각본을 만든 듯 했다. 소설에서는 21년 후의 미래를 다루고 있고, 드라마에서는 6개월 후의 미래를 다루고 있다.

전 인류가 2분 17초 동안 의식을 잃고 6개월 후의 미래를 본다는 가정하에서 드라마가 전개된다. 긍정적인 미래를 본 사람, 그렇지 않은 사람, 심지어는 이미 죽고 없어서 미래를 보지 못 하는 사람들의 이야기가 23편에 걸쳐서 펼쳐진다. 운명은 결정되어 있는 것인가, 인간의 자유의지로 극복 가능한 것인가에 대한 질문과 해답을 보여준다. 중간에 개연성 있는 설명이 부족하여 말이 안 되는 설정이 있긴 하지만 전체적으로 만족스러웠다.

관찰하는 사실 자체가 관찰당하는 사람에게 영향을 주고, 미래를 아는 것 자체가 그 미래로 흘러가게 되는 동인이 되기도 한다. 몇 년 후의 미래를 아는 것이 어쩌면 불행일지도 모른다는 생각이 들었다.

시리즈 1의 마지막에 애매모호하게 끝나서 2에 대한 기대감을 불러일으키기도 했지만, 시리즈 2가 제작되지 않는 것이 낫다는 생각도 든다. 재미는 있었지만 비슷한 플롯으로 욹어먹어서 실망했던 24, Heroes, Prison Break의 전철을 밟지 않을수도 있을테니깐…

회사에 도서 신청을 해 두었으니, 꼭 소설로도 한번 읽어봐야겠다.

DNS-323에서 파일 정리 with Python

September 2, 2010

XBMC에서 사용되는 TV Series와 Movie directory에 symbolic link를 만들기 위해 사용하는 script. Source directory에서 이미 처리가 되지 않는 파일이 있으면 어느쪽으로 symbolic link를 만들건지 물어보고 사용자 입력을 받아서 symbolic link를 만들어주는 간단한 프로그램이다.

DNS-323에서 파일 정리를 하기 위해 사용한다.

  #!/usr/bin/python
# -*- coding: utf-8 -*-

# cleanup dns-323 directory
# jmjeong@gmail.com ([2010-08-05 Thu])

import os,sys
import os.path
import cPickle

tvdir = "/mnt/HD_b2/TV"
moviedir = "/mnt/HD_b2/Movie"
sourcedir = "/mnt/HD_a2/Source"

dataFile = "/mnt/HD_a2/Source/ignore.dump"

def main():
    """
    """

    tv = os.listdir(tvdir)
    movie = os.listdir(moviedir)
    source = os.listdir(sourcedir)

    ignoreFiles = []

    try:
        ignoreFiles = cPickle.load(open(dataFile), 'r+')
    except IOError:
        pass

    processing = set(source) - set(tv) - set(movie) - set(ignoreFiles) 

    for f in processing:
        ans = ""
        try:
            print "[%s]" % f
            ans = raw_input("1.TV, 2.Movie, 3.Ignore ? (1..3): ")
        except:
            print str(sys.exc_info())

        if (ans == '1'):
            os.symlink(os.path.join(sourcedir,f), os.path.join(tvdir, f))
        elif (ans == '2'):
            os.symlink(os.path.join(sourcedir,f), os.path.join(moviedir, f))
        else:
            ignoreFiles.append(f)

    cPickle.dump(ignoreFiles, open(os.path.join(dataFile), 'w'))

if __name__ == '__main__':
    main()

PyRSS2Gen

September 2, 2010

Python으로 RSS를 만들기 위한 Package

import datetime
import PyRSS2Gen

rss = PyRSS2Gen.RSS2(
    title = "Andrew's PyRSS2Gen feed",
    link = "http://www.dalkescientific.com/Python/PyRSS2Gen.html",
    description = "The latest news about PyRSS2Gen, a "
                  "Python library for generating RSS2 feeds",

    lastBuildDate = datetime.datetime.now(),

    items = [
       PyRSS2Gen.RSSItem(
         title = "PyRSS2Gen-0.0 released",
         link = "http://www.dalkescientific.com/news/030906-PyRSS2Gen.html",
         description = "Dalke Scientific today announced PyRSS2Gen-0.0, "
                       "a library for generating RSS feeds for Python.  ",
         guid = PyRSS2Gen.Guid("http://www.dalkescientific.com/news/"
                          "030906-PyRSS2Gen.html"),
         pubDate = datetime.datetime(2003, 9, 6, 21, 31)),
       PyRSS2Gen.RSSItem(
         title = "Thoughts on RSS feeds for bioinformatics",
         link = "http://www.dalkescientific.com/writings/diary/"
                "archive/2003/09/06/RSS.html",
         description = "One of the reasons I wrote PyRSS2Gen was to "
                       "experiment with RSS for data collection in "
                       "bioinformatics.  Last year I came across...",
         guid = PyRSS2Gen.Guid("http://www.dalkescientific.com/writings/"
                               "diary/archive/2003/09/06/RSS.html"),
         pubDate = datetime.datetime(2003, 9, 6, 21, 49)),
    ])

rss.write_xml(open("pyrss2gen.xml", "w"))

Emacs에서 file type별로 자동 template 입력하기

August 19, 2010

각 file type별 header를 입력하기 위해 yasnippet를 활용했는데, emacs에도 (auto-type)을 위한 모드가 준비되어 있다. (auto-type) 관련 package는 emacs distribution과 같이 배포가 된다.

여기서는 (auto-type)에 있는 skeleton mode 대신, 이의 확장판인 file-template.el을 사용한다. file-template.el을 load-path에 두고 다음과 같이 설정을 하였다.

(require 'file-template)

;; (setq file-template-paths "~/my-dot-elisp/template")
(setq file-template-paths (concat elisp-root-dir "/template"))
(setq file-template-insert-automatically 'ask)

(setq file-template-mapping-alist
      (cons  '("\\.m$" . "template.m") file-template-mapping-alist))

template이 위치하는 directory 밑에 각 파일 확장자별로 template 파일을 둔다.

http://blog.jmjeong.com/wp-content/uploads/template.png

기본 설정에서 file-template-mapping-alist에 .el .c .h .sh. .pl .py 등이 세팅되어 있다. Objective-c에 해당하는 templete.m을 추가하였다.

template.m파일은 아래와 같다.

//
//   %b
//   %[Project Name: %]
//
//   Created by %u on %y. %m. %d..
//   Copyright %Y __MyCompanyName__. All rights reserved.
// 

%@

.m 확장자의 새로운 파일을 만들 때, 자동으로 다음과 같은 template를 추가한다.

//
//   test.m
//   TracViewer
// 
//   Created by jmjeong on 10. 08. 18..
//   Copyright 2010 __MyCompanyName__. All rights reserved.
// 

프로젝트 명인 TracViewer는 사용자로부터 입력을 받는다.

file-template.el파일에서 default로 다음과 같은 macro를 설정 가능하다.

%u       user's login name
%U       user's full name
%a       user's mail address (from the variable `user-mail-address')
%f       file name with path
%b       file name without path
%n       file name without path and extension
%N       file name without path and extension, capitalized
%e       file extension
%E       file extension capitalized
%p       file directory
%d       day
%m       month
%M       abbreviated month name
%y       last two digits of year
%Y       year
%q       `fill-paragraph'
%[ %]    prompt user for a string
%1-%9    refer to the nth strings prompted for with %[ %]
%( %)    elisp form to be evaluated
%%       inserts %
%@       sets the final position of `point'")

새로운 파일을 생성할 때 file-template-insert-automatically 변수 값에 따라서 자동으로 template 파일을 입력해 준다. template.m 파일은 xcode 기본 설정과 같은 template이 생성되도록 하였다.

Obj-c에서 자주 쓰는 code snippet 입력 macro

August 18, 2010

Objective-C에서 singleton용 소스 입력 yasnippet

# -*- mode: snippet -*-
# name: singleton
# --

#pragma mark -
#pragma mark Singleton

static ${1:ClassName} *_shared${1:$(yas/substr text "[^: ]*")} = nil;

+(${1:$(yas/substr text "[^: ]*")} *) shared${1:$(yas/substr text "[^: ]*")};
{
    @synchronized([${1:$(yas/substr text "[^: ]*")} class]) {
        if (_shared${1:$(yas/substr text "[^: ]*")} == nil) {
            [[self alloc] init];
        }

        return _shared${1:$(yas/substr text "[^: ]*")};
    }

    return nil;
}

+(id) alloc
{
    @synchronized([${1:$(yas/substr text "[^: ]*")} class]) {
        NSAssert(_shared${1:$(yas/substr text "[^: ]*")} == nil, @"Attempted to allocate a second instance of a singleton.");
        _shared${1:$(yas/substr text "[^: ]*")} = [[super alloc] init];
        return _shared${1:$(yas/substr text "[^: ]*")};
    }

    return nil;
}

-(id) init
{
    self = [super init];
    if (self) {
        // initialize code
        ${2:}
    }
    return self;
}

-(void) dealloc
{
    [super dealloc];
}

Objective-C mode에서 singleton를 입력하고 <TAB>을 누르면 된다.

SQLitePersistentObject

August 18, 2010

개요

Objective-C class를 persistent하게 만들어 주는 class.

c-strings, void pointers, structs, union등의 데이타에 대해서는 저장이 안 된다. Scalar 변수(int, float)와 Cocoa object들은 저장된다. 또한 NSDate, NSString, NSData, NSMutableData, NSNumber, NSObject 등이 저장된다.

사용법

Projects에 zip 파일을 풀어 넣고, libsqlite3.dylib을 link한다.

#import <foundation/foundation.h>
#import "SQLitePersistentObject.h"

@interface PersistablePerson : SQLitePersistentObject {
    NSString *lastName;
    NSString *firstName;
}

@perperty (nonatomic, retain) NSString *lastName;
@perperty (nonatomic, retain) NSString *firstName;
@end

Objects는 다음과 같이 생성한다.

PersistentPerson *person = [[PersistentPerson alloc] init];
person.firstName = @"Joe";
person.lastName = @"Smith";

만들어진 object는 [person save];를 통하여 저장한다.

저장된 object를 다시 읽는 것도 쉽다. 모든 persistent objects는 검색을 위한 dynamic class method를 갖게된다. 예를 들어 “Smith”라는 last name을 가진 record를 찾아서 읽어올 수 있다:

NSArray *people = [PersistentPerson findByLastName:@"Smith"];

좀 더 자세한 검색을 위해서는 findFirstByCriteria를 이용한다.

PersistentPeople *joeSmith = [PersistentPeople findFirstByCriteria:@"WHERE last_name='Smith' and first_name='Joe'"];

모든 camel case는 underscore로 구분된 단어(예 LastName -> last_name)로 바뀌게 된다.

Python : itertools.groupby

August 16, 2010

Python의 groupby는 unix의 sort & uniq와 같은 기능을 할 수 있다.

>>> from itertools import *
>>> letters = 'abracadabra'
>>> [g for k, g in groupby(letters)]                # grouped
[['a', 'a', 'a', 'a', 'a'], ['r', 'r'], ['b', 'b'], ['c'], ['d']]
>>> [k for k, g in groupby(letters)]                # uniq
['a', 'r', 'b', 'c', 'd']
>>> [(k, len(g)) for k, g in groupby(letters)]      # uniq -c
[('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)]
>>> [k for k, g in groupby(letters) if len(g) > 1]  # uniq -d
['a', 'r', 'b']
|  groupby(iterable[, keyfunc]) -> create an iterator which returns
|  (key, sub-iterator) grouped by each value of key(value).
 
Powered by Wordpress and MySQL. Theme by Shlomi Noach, openark.org