Kick Start Clojure

今日はShibuya.lispClojure尽くしを味わってきたわけで

感動のあまりこんなものまで買ってきてしまった.

プログラミングClojure

プログラミングClojure

というわけで,Closureをはじめてみる.

インストール

Unix系環境で,java6がインストールされている事を確認.

つぎに本家よりパッケージをダウンロードし

解凍して出来たフォルダごと'/usr/lcoal'あたりに移動する.

$ sudo mv closure-1.1.0 /usr/local/closure/

つぎにここを参照する実行ファイルを作っておく./usr/local/binに'clojure'をつくる.

#!/bin/sh

java -cp /usr/local/clojure/clojure-1.1.0/clojure.jar clojure.main $@

で実行パーミッションを与えておく.

これで

$ clojure
user=>

という具合にREPLが起動する.

そしたら,恒例Emacs用のモードのインストール

こちらでclosure-modeを作ってらっしゃるので

インストールする.

ゆるくベンチ

せっかくなので,ベンチマークとってみる.

比較として,Scheme(Gauche)と対決してみる.
(処理系の実装方式の違い,テストコードが思いつきな点,全てがいい加減なので参考程度にしてください)

以下のコードを走らせる.

fib.clj (Clojure用)

(defn fib [n]
  (loop [i 0 x 0 y 1]
    (if (= i n)
      x
      (recur (+ i 1) y (+ x y)))))

(fib 100000)

fib.scm (Scheme用)

(define (fib n)
  (let loop ((i 0) (x 0) (y 1))
    (if (= i n)
	x
	(loop (+ i 1) y (+ x y)))))

(fib 100000)

結果

$ time clojure fib.clj

real 0m1.514s
user 0m1.693s
sys 0m0.118s
$ time gosh fib.scm

real 0m0.948s
user 0m0.898s
sys 0m0.030s

なるほど,gaucheの方が早い訳ですね...

うーん,そもそも今回示したコードでは魅力が伝わりません.

次回はなんか面白い事を書こうと思います.続く...

OMakeで継続監視ビルド

OMakeを使うと,ファイルの更新を監視して,自動でビルドを行う事ができる.

LaTexのビルドを例にするとこんな感じ.

OMakeのインストール

ここからOMakeを落とす.

MacOSX(10.6 SnowLeopard)ならdmgバイナリを落としてインストールするだけでおk.

OMakefile

ビルドを行いたいディレクトリで

$ omake --install

を実行.すると'OMakefile'と'OMakeroot'が作られる.

texファイルを'main.tex'とするなら,こんな感じにOMakefileを書き換える.

LATEX = /usr/local/teTeX/bin/platex
LATEXFLAGS = --kanji=utf8
DVIPDFM = /usr/local/teTeX/bin/dvipdfmx
BIBTEX = /usr/local/teTeX/bin/jbibtex --kanji=utf8

LaTeXDocument(main, main)
document.dvi: ref.bib

.DEFAULT: main.pdf main.dvi

これだけでおk.

継続監視ビルドする

$ omake -P --verbose

だけ.

あとはお好きなエディタでtexファイルを編集すると,自動的にリビルドが走る.

MacOSXPreviewかなんかで開いてれば,pdfファイルの更新を読み取って自動的に反映されるので便利!

参考文献

pythonをつかって,XLSファイルをCSVに吐き出す

pyExceleratorをつかってXLSファイルをCSVファイルに吐き出すスクリプトこちらでみつけたのだが,

日本語関連でうまく動かなかったので,ちょっと手直しして自分にあったものにしてみた.

#!/usr/bin/python
# -*- coding: utf-8
"""
xls2csv.py - xls to csv converter

abstract

licence

"""

__author__="yamaneko <yamaneko1212@gmail.com>"
__date__ ="Sun Jan 31 20:45:30 2010"
__version__="$Revision: 0 $"
__credits__=""

import sys, csv

try:
    import pyExcelerator
except:
    sys.stderr.write ('this script needs pyExcelerator\n')
    sys.exit (1)

# count number
def number_of_sheets (xls_file):
    try:
        return len (pyExcelerator.parse_xls( xls_file ))
    except:
        sys.stderr.write ('failed opening or parsing file ' + xls_file + '\n')
        sys.exit (1)


def xls_to_csv (xls_file, csv_file='', delimiter='\t', sheet=0):

    # try to open and parse xls file
    try:
        xls_sheets = pyExcelerator.parse_xls( xls_file )
    except:
        sys.stderr.write ('failed opening or parsing file ' + xls_file + '\n')
        sys.exit (1)

    # check sheet number
    if not (sheet < len (xls_sheets)):
        sys.stderr.write ('invalid sheet number ' + str (sheet) + '\n')
        sys.stderr.write (xls_file + ' has just ' + str (len (xls_sheets)) + ' sheets\n')
        sys.exit (1)

    # set dest file
    if csv_file == '':
        csv_file = str (xls_sheets[sheet][0]) + '.csv'
    
    #for sheet_id in xls_sheets:
    cell_dict = xls_sheets[sheet][1]

    # set limitter row_max and column_max
    for which in (0, 1):
        exec ("""%s = max([cell_dict.keys()[key_index][which]"""
              """ for key_index in xrange(len(cell_dict.keys()))] )""") % \
                ["row_max", "column_max"][which]


    sys.stdout.write ('copying ' + xls_sheets[sheet][0] + ' of ' +\
                      xls_file + ' to ' + csv_file + '\n')

    # creating csv file.
    create_csv = csv.DictWriter(file(csv_file, "ab"),
                                fieldnames=range(column_max+1),
                                delimiter=delimiter)

    # copy data
    for row in xrange(row_max+1):
        create_csv.writerow(dict(
            enumerate([unicode (cell_dict.copy().get((row, column), '')).encode ('utf-8')
                       for column in xrange(column_max+1)])))

    sys.stdout.write ('finished writing to ' + csv_file + '\n')

# for all
def conv_all (src_file):
    for sheet_id in range (number_of_sheets (src_file)):
        xls_to_csv (src_file, sheet=sheet_id)
    sys.stdout.write(str (number_of_sheets (src_file)) + ' files are written\n')

# usage
def usage ():
    sys.stderr.write ('usage : python xls2csv.py src_xls_file\n')
    sys.stderr.write ('        python xls2csv.py src_xls_file sheet_number\n')
    sys.stderr.write ('        python xls2csv.py ' +\
                      'src_xls_file dest_xls_file sheet_number\n')
    return

if __name__ == "__main__":
    
    argc = len (sys.argv)
    
    if argc == 2:
        conv_all (sys.argv[1])
        
    elif argc == 3:
        try:
            sheet = int (sys.argv[2])
        except:
            sys.stderr.write ('invalid sheet number ' + str (sys.argv[2]) + '\n')
            usage ()
            sys.exit (1)
        
        xls_to_csv (sys.argv[1], sheet=sheet)
        
    elif argc == 4:
        try:
            sheet = int (sys.argv[3])
        except:
            sys.stderr.write ('invalid sheet number ' + str (sys.argv[2]) + '\n')
            usage ()
            sys.exit (1)

        src_file = sys.argv[1]
        dest_file = sys.argv[2]

        if (src_file == dest_file):
            sys.stderr.write ('source file and destination file are same name\n')
            usage ()
            sys.exit (1)
            
        xls_to_csv (src_file, csv_file=dest_file, sheet=sheet)
        
    else:
        usage ()
        sys.exit (1)
        
    sys.exit (0)

使うのはpyExceleratorをインストールしてから,

$ python xls2csv.py source.xls
$ python xls2csv.py source.xls 3
$ python xls2csv.py source.xls destination.csv 3

みたいにどうぞ.

年忘れコーディング

自動でtwitterに新年の挨拶を投稿するツール!

それではよいお年を!

#!/bin/sh
#
# auto-akeome.sh
#
# yamaneko <yamaneko1212@gmail.com>
# created at Thu Dec 31 23:18:50 2009
#

# twitter id
user="id"
# password
passwd="password"

# message for happy new year
message="あけおめことよろ!!!!!"

nowtime=`date +%s`
newyeartime='1262271600'

# check curl
while test ${nowtime} -lt ${newyeartime}
do
    nowtime=`date +%s`
    sleep 1
done

if ! curl -u ${user}:${passwd} -d status=${message} https://twitter.com/statuses/update.xml
then
    echo 'failed'
else
    echo 'ok'
fi

※ちょっと間違ってたので修正

Apache2.2onDebianLennyの実行ユーザ指定

こちらにあるように設定を書いたんだけど,これでいいのだろうか?

$ sudo ps aux | grep apache2
root 1179 0.0 0.5 13268 2752 ? Ss 03:41 0:00 /usr/sbin/apache2 -k start
******** 1180 0.0 0.3 13176 1976 ? S 03:41 0:00 /usr/sbin/apache2 -k start
******** 1181 0.0 0.6 234952 3352 ? Sl 03:41 0:00 /usr/sbin/apache2 -k start
******** 1186 0.0 0.6 234896 3260 ? Sl 03:41 0:00 /usr/sbin/apache2 -k start

rootが1つ走ってる...このrootがよくわからんからこうしてみる

$ sudo chmod 700 /var/www/index.html
$ wget http://localhost/index.html
--2009-11-26 03:56:37-- http://localhost/index.html
Resolving localhost... 127.0.0.1, ::1
Connecting to localhost|127.0.0.1|:80... connected.
HTTP request sent, awaiting response... 403 Forbidden
2009-11-26 03:56:37 ERROR 403: Forbidden.

どうやらrootでは走ってないようだ.これでよしとしよう.

emacsでscreenコマンドみたいにscreenを使い分けたい!

こちらでelscreenというelを公開されている.

絶句.

馬鹿な,自分は今までなんて馬鹿な事をしていたのか..

これでいくらでもスクリーンを作って並列に作業ができる.しかもバッファの切り替えなしで...

インストールは簡単でいつものようにelファイルを自分のsite-lispに入れてコンパイル

で,読み込み設定ついでにオフィシャルを参考に少し設定を追加.

;; elscreen.el
(load "elscreen" "ElScreen" t)

;; display list of screens on frame
(defun elscreen-frame-title-update ()
  (defun elscreen-status (screen)
    (let ((current-screen (elscreen-get-current-screen))
	  (previous-screen (elscreen-get-previous-screen)))
      (cond
       ((eq screen current-screen) t)
       ((eq screen previous-screen) nil)
       (t nil))))

  (when (elscreen-screen-modified-p 'elscreen-frame-title-update)
    (let* ((screen-list (sort (elscreen-get-screen-list) '<))
	   (screen-to-name-alist (elscreen-get-screen-to-name-alist))
	   (title-frame-list (mapconcat
			      (lambda (screen)
				(if (elscreen-status screen)
				    (format "<%d>"
					    screen)
				  (format "%d"
					  screen)))
			      screen-list ", "))
	   (title-header "Emacs : ")
	   (title (concat title-header title-frame-list)))
      (set-frame-name title))))

(eval-after-load "elscreen"
  '(add-hook 'elscreen-screen-update-hook 'elscreen-frame-title-update))

;; when there is only a screen, 
;; make new screen automatically by selecting next or previous tab
(defmacro elscreen-create-automatically (ad-do-it)
  `(if (not (elscreen-one-screen-p))
       ,ad-do-it
     (elscreen-create)
     (elscreen-notify-screen-modification 'force-immediately)
     (elscreen-message "New screen is automatically created")))

(defadvice elscreen-next (around elscreen-create-automatically activate)
  (elscreen-create-automatically ad-do-it))

(defadvice elscreen-previous (around elscreen-create-automatically activate)
  (elscreen-create-automatically ad-do-it))

(defadvice elscreen-toggle (around elscreen-create-automatically activate)
  (elscreen-create-automatically ad-do-it))

;; not display tab
(setq elscreen-display-tab nil)

ああ,幸せ!!

    • -

神は最初にアセンブラlispを書き,

carとcdrを最初に与えたもうた.

そしてbuildworldする為にemacsを書いたが,

emacsはでかすぎた為にbuildworldが完成しなかった.

そしてバグと未実装は仕様となった.

だから人間は不完全だ!

そしてemacsは最高だ!

EmacsのTermモードのサブモード切り替え

EmacsのTermモードでサブモードを切り替えたい時がある.

カーソルを自由に動かしたり,いろいろ.

そんなわけでこんな設定を書いておくとよい.

;; term-mode-map is assigned in line-mode
(define-key term-mode-map "\C-cl" '(lambda ()
				     (interactive)
				     (message "char-mode")
				     (term-char-mode)))

;; term-raw-map is assigned in char-mode
(define-key term-raw-map "\C-cl" '(lambda ()
				     (interactive)
				     (message "line-mode")
				     (term-line-mode)))

これでtermモード内でcharモードとlineモードを自由に切り替えられる.