laclefblog logo

Sun, 16 Nov 2008

Pure

Q - Equational Programming Language の後継として、HaskellやMLに影響を受けまくった文法、レキシカルクロージャ、置き換えモデルによる評価等を特徴とする関数型言語。

流行?のLLVMを用いている。お陰でCライブラリとの連携が容易らしい。

プログラミング言語名でGoogle検索し難いのが難点。

Haskellで作成した関数をPythonから使う

漸くHaskellに慣れてきたが、Pythonの方が使い勝手が良いと感じることに変わりはない。

互いの良さを取り、上手く使い分けるために、HaskellとPythonのFII(Foreign Function Interface)を用いる。

Haskell/GHCでForeign.Cを用いてC共有ライブラリを作成し、Pythonからctypesで使用する。

まず、Haskellで関数を格納したモジュールを書く(hstopy.hs)。

module Htop where
import CString

fact :: Int -> Int
fact n = if n == 1 then 1 else (n * fact (n - 1))

factorial :: Int -> IO Int
factorial n = return (fact n)

mystring :: IO CString
mystring = newCString "hello haskell world!"

foreign export ccall factorial :: Int -> IO Int
foreign export ccall mystring :: IO CString

FFIの性質上、色々をIOモナドで包む必要がある。

次に、ランタイム初期化と脱初期化のためのエントリィポイント用コードを書く(必要最小限、hstopy_init.c)。

static void __attribute__ ((constructor)) mylib_init(void)
{
    hs_init(0, 0);
}

GHCでコンパイルする。

$ ghc -c hstopy.hs -fglasgow-exts
$ ls
hstopy.hi  hstopy.hs  hstopy.o  hstopy_init.c  hstopy_stub.c  hstopy_stub.h  hstopy_stub.o

GHCで共有ライブラリを作成する。

$ ghc -package unix -optl "-shared" -o libhstopy.so hstopy_init.c hstopy.o hstopy_stub.o
  # -package unix は今回は不要?
$ ls
hstopy.hi  hstopy.hs  hstopy.o  hstopy_init.c  hstopy_init.o  hstopy_stub.c  hstopy_stub.h  hstopy_stub.o  libhstopy.so

ctypesで共有ライブラリの関数を用いるために、関数ラッパを書く(hstopy.py)。

#!/usr/bin/python

import ctypes
_lib = ctypes.CDLL( './libhstopy.so')

_lib.factorial.argtypes = [ctypes.c_int]
_lib.factorial.restype = ctypes.c_int

_lib.mystring.argtypes = []
_lib.mystring.restype = ctypes.c_char_p

factorial = _lib.factorial
mystring = _lib.mystring

Pythonから使用する。

$ python
Python 2.5.2 (r252:60911, Oct  5 2008, 19:24:49)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import hstopy
>>> hstopy.mystring()
'hello haskell world!'
>>> hstopy.factorial(4)
24
>>> hstopy.factorial(5)
120

Foreign.Cでもctypesでもポインタも扱えるので、もう少し手の込んだことも出来る(はず)。

Sat, 11 Oct 2008

パーサライブラリ

最近HaskellのParsecで遊んでいて、Pythonの方のパーサライブラリが気になったのでGoogleで検索したら、ビンゴなページがあった。2004年9月に作成して、2008年7月に更新している。偉い。

Pythonで書かれているもの、多言語インタフェースを持っているもの、古いもの当たらしいもの列挙状態で、選択は利用者に委ねられている。

Wed, 10 Sep 2008

COBOL in 東京海上日動

COBOLで一生飯が食える、というのは、真実なのか。

この分野では、余計な呪文やお決まりごとが出来るだけ排除されていて、現場に基づいていて、正確であることが評価される様だ。成る程。汎用プログラミング言語には少し難しい。

Sat, 23 Aug 2008

Pythonでビデオデバイスにアクセス

ブログ他参考文献が割と豊富な [1] [2] VideoCapture - A Win32 Python Extension for Accessing Video Devices (e.g. a USB WebCam, a TV-Card, ...) はWindows専用ライブラリなので、Linuxでは使えない(これさえ使えれば簡単なのに)。

[1]gumuz’ devlog » Blog Archive » Python webcam fun - motion detection: http://web.archive.org/web/20070520024828/http://gumuz.looze.net/wordpress/index.php/archives/2005/06/06/python-webcam-fun-motion-detection/
[2]code and martial arts: motion capture in python: http://janto.blogspot.com/2006/01/motion-capture-in-python.html

Search results for python VideoCapture linux - MarkMail で調べると、やはり気にしていた人は居たみたい。

で、メーリングリストで示された代替案としては、以下のものがある。

libfgは Video4Linux のAPIを操作するためのライブラリ。Video4Linux2には未対応の様だ。

ならば GStreamer: open source multimedia framework [3] を使えば出来るかとも考えたが、いまいち情報が足りない。

[3]GStreamer - Wikipedia: http://ja.wikipedia.org/wiki/GStreamer

WebCamSpyはWebカメラを操作するためのライブラリ。wxPython、pyParallel、pySerialを外部ライブラリとして必要とする(面倒臭い)。

[4]OpenCV - Wikipedia: http://ja.wikipedia.org/wiki/OpenCV

通称、OpenCV。画像処理等に使われる、Intel製ライブラリ。Ubuntuのパッケージにpython-opencvってのがある。参考文献が多いし、これだな。

Sun, 03 Aug 2008

DRM_I830_CMDBUFFER: -22

まず、ノートPCでデュアルスクリーン(VGAコネクタを接続してデュアルディスプレィ)環境を構築する。

$ xrandr --output VGA --left-of LVDS

次に、pygletで、OpenGLコンテキストの異なる(コンテキストを共有しない)ウィンドウを2つ生成し、それぞれのスクリーンに表示するプログラムを作成し、実行する。

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

import pyglet

class TestWindow(pyglet.window.Window, object):
    def __init__(self, screen, **kwargs):
        template = pyglet.gl.Config(double_buffer=True, depth_size=24, stencil_size=8)
        config = screen.get_best_config(template)
        context = config.create_context(None)
        pyglet.window.Window.__init__(self, fullscreen=True, context=context, **kwargs)
        # pyglet.window.Window.__init__(self, fullscreen=True, **kwargs)

platform = pyglet.window.get_platform()
display = platform.get_default_display()
screens = display.get_screens()
# screen = display.get_default_screen()

window1 = TestWindow(screen=screens[0])
window2 = TestWindow(screen=screens[1])
label1 = pyglet.text.Label('Hello 1', font_name='vlgothic', font_size=55,
                      x=500, y=500, anchor_x='center', anchor_y='center',
                      color=(255, 255, 255, 255))
label2 = pyglet.text.Label('Hello 2', font_name='vlgothic', font_size=55,
                      x=500, y=500, anchor_x='center', anchor_y='center',
                      color=(255, 0, 0, 255))

@window1.event
def on_draw():
    window1.clear()
    label1.draw()

@window2.event
def on_draw():
    window2.clear()
    label2.draw()

pyglet.app.run()

このプログラムをコンソールから実行すると、ノートPC側画面には真っ黒なウィンドウが表示されるが、文字が表示されない。プログラムを終了すると、コンソールに以下の1行メッセージが残されている。

DRM_I830_CMDBUFFER: -22

dmesgを参照すると、関連していると思われるメッセージが残っている。

$ dmesg | tail -n 2
[ 5856.052388] [drm:i915_emit_box] *ERROR* Bad box 1024,0..1024,768
[ 5856.052397] [drm:i915_cmdbuffer] *ERROR* i915_dispatch_cmdbuffer failed

また、glxgearsをノートPC側画面で表示しようとすると、同じメッセージが出て、glxgearsが強制終了する。

Google様で検索すると、Ubuntuのlaunchpadに同メッセージのバグレポートがあった。

僕の使っているノートPCはLet'snote R5で、チップセットはモバイルインテル(R) 945GMS Expressなので、このエラーと原因は同じだと思う。

デュアルスクリーンのままXを再起動すると、時々正常に表示される事がある。いまいち再現性が確立し難い。

既に解決方法は示されている様だし、Statusが"In Progress"になっているので、待っていて良いのかしら。

Sat, 26 Jul 2008

Microsoftの片仮名用語表記

今更Microsoftにどうこう言われても気にすること無く、自分ルールというか森博嗣ルールというか laclefblog(2006-11-19) - 外来語表記 にも記述したルールの方が一貫性がある気がするので、ルール変更無しの方針。未だに表記揺れがあるから困る。

こんなに面倒な話になるなら、いっそ、外来語は全て英語表記とすれば良いんじゃないだろうか。

Mon, 14 Jul 2008

FFmpeg APIに触れる

日頃、携帯電話鑑賞用動画変換のために使用している FFmpeg のライブラリとしてのC言語による使用法。ごりごり。

Tue, 08 Jul 2008

Protocol Buffers公開

Sun, 06 Jul 2008

OSM解析

最近、日本語版も始まった OpenStreetMap のデータを解析して、 A* アルゴリズムを用いて任意の2地点間が最短距離となるような経路を発見するための、Pythonライブラリ。

画像出力機能付きという余裕っぷり。