jythonでprocessing

Built with Processing [改訂版]が到着したので、これを手本にjythonで書いていく。

ProductName Built with Processing [改訂版]
前川 峻志,田中 孝太郎
ビー・エヌ・エヌ新社 / ¥ 3,570 ()


を参考にして、step 04-aを。

step 04-a

ソース。jythonだとswing呼んだりしないといけない。

from javax.swing import JFrame
from processing.core import PApplet

class Sketch(PApplet):
    def __init__(self):
        pass

    def setup(self):
        self.size(200, 200)

    def getField(self, name):
        return self.class.superclass.getDeclaredField(name).get(self)

    def draw(self):
        self.rectMode(PApplet.CENTER)
        self.colorMode(PApplet.HSB, 100)
        self.background(99)
        self.noStroke()
        self.smooth()

        self.fill(45, 60, 99)
        self.rect(100, 100, 100, 100)

        self.fill(45, 40, 99)
        self.rect(100, 100, 60, 60)

        self.fill(45, 20, 99)
        self.rect(100, 100, 20, 20)

        self.noFill()
        self.strokeWeight(60)

        self.stroke(80, 99, 99, 30)
        self.ellipse(50, 50, 200, 200)
        self.ellipse(150, 50, 200, 200)
        self.ellipse(50, 150, 200, 200)
        self.ellipse(150, 150, 200, 200)

def run(applet):
    frame = JFrame(title="Processing",
                   resizable = 0,
                   defaultCloseOperation=JFrame.EXIT_ON_CLOSE)
    frame.contentPane.add(applet)
    applet.init()
    frame.pack()
    frame.visible = 1

if __name__ == '__main__':
    run(Sketch())

video入力いじりたいからUSBカメラ買わなきゃ。

jythonでprocessing 080331

processingは繰り返しがfor(i=0;i<10;i++)のCっぽい書き方だけど、jythonだったらrangeが使えるのでお手軽でいいんじゃないか。

def setup(self):
    self.size(200, 200)
    self.colorMode(PApplet.HSB, 100)
    self.background(99)
    self.noStroke()

def draw(self):
    for y in range(10):
        for x in range(10):
            self.fill(x*10, 10 + y*10, 99)
            self.rect(x*20, y*20, 10, 10)

list2-6-b

jython+processingでpdfを生成

processingはpdfに出力できるらしい。同じことはjythonでも可能でしょう。

と思いつつ、三日くらいはまった。classpathにpdf.jarだけでなくitext.jarも設定しておかないといけなかったのがわからなかった。itextってのはフリーのpdfライブラリらしい。それにしても、classpathがどんどん長くなっていくのが気持ち悪いなぁ。もうちょっとスマートに記述する方法もあるんだろうな。

noise.line

from javax.swing import JFrame
from processing.core import PApplet
from random import randint
import processing.pdf


class Sketch(PApplet):
    def __init__(self):
        pass

    def setup(self):
        self.size(200, 200, PApplet.PDF,"noiseline.pdf")
        self.colorMode(PApplet.HSB, 100)
        self.noFill()
        self.fluc_color = 50

    def getField(self, name):
        return  self.class.superclass.getDeclaredField(name).get(self)

    def draw(self):
        self.background(0)
        for i in range(0, 200 ,5):
            self.fluc_color += randint(-10,10)
            self.stroke(self.fluc_color, 60, 90, 30)

            fluc_y = 0
            self.beginShape()

            for j in range(0, 200, 5):
                fluc_y += randint(-2, 2)
                self.vertex(j, i + fluc_y)

            self.endShape()
        self.exit()

def run(applet):
    frame = JFrame(title="Processing",
                   resizable = 1,
                   defaultCloseOperation=JFrame.EXIT_ON_CLOSE)
    frame.contentPane.add(applet)
    applet.init()
    frame.pack()
    frame.visible = 1

if __name__ == '__main__':
    run(Sketch())

実際に生成されるpdfはこれです。

processing + jythonでGainerを制御する

processing使ってGainerにアクセスするjythonスクリプト。gainer.jarだけではなく、serialフォルダのRXTXcomm.jarにもclasspathを通しておく。

ボタンを押すと白黒するサンプルを書いてみた。

コード

from javax.swing import JFrame
from processing.core import PApplet
from processing.gainer import *

class Sketch(PApplet):
    def __init__(self):
        pass

    def setup(self):
        self.size(200, 200)
        self.gainer = Gainer(self,'COM8')

    def getField(self, name):
        return self.class.superclass.getDeclaredField(name).get(self)

    def draw(self):
        self.background(0)
        if(self.gainer.buttonPressed):
            self.background(255)

def run(applet):
    frame = JFrame(title="Processing",
                   resizable = 1,
                   defaultCloseOperation=JFrame.EXIT_ON_CLOSE)
    frame.contentPane.add(applet)
    applet.init()
    frame.pack()
    frame.visible = 1

if __name__ == '__main__':
    run(Sketch())

jython+processingでwebカメラで取り込むサンプル

usbカメラを買ったので早速遊んでいる。ちなみに奥に見える黄色いのはjython本じゃなくて独習C++とかいう本。

webcam

drawメソッドでピクセルをいじくると色々とエフェクトがかけられるわけです。

from javax.swing import JFrame
from processing.core import PApplet
from processing.video import *

class Sketch(PApplet):
    def __init__(self):
        pass

    def getField(self, name):
        return self.class.superclass.getDeclaredField(name).get(self)

    def setup(self):
        self.size(320, 240)
        self.camera = Capture(self, 320, 240, 12)

    def draw(self):
        self.camera.read()        
        self.image(self.camera, 0,0)

def run(applet):
    frame = JFrame(title="Processing camera",
                   resizable = 1,
                   defaultCloseOperation=JFrame.EXIT_ON_CLOSE)
    frame.contentPane.add(applet)
    applet.init()
    frame.pack()
    frame.visible = 1

if __name__ == '__main__':
    run(Sketch())

jython本が待ち遠しい。

ProductName Jythonプログラミング
西尾 泰和
毎日コミュニケーションズ / ¥ 3,150 ()
在庫あり。

jythonプログラミング読了

次の二つの章が特に面白かった。

  • 5 Pythonから見たオブジェクト指向
  • 7 Jythonの応用例

ProductName Jythonプログラミング
西尾 泰和
毎日コミュニケーションズ / ¥ 3,150 ()
在庫あり。

単なるjythonの使い方の本というよりは、jythonのような複数の言語を混ぜ合わせた処理系を通して見えるものを感じ取りましょう的な内容だったように思う。あとその場合に固さやわらかさの長所をうまくのばしてやるようなプログラミングのお作法はこんな感じですよみたいな指針。

perlでもInline系のモジュールを使えば直接他の言語を埋め込んだりできて他言語のライブラリを使えるけど、言語自体が両方の世界に干渉できるともっと楽ができる。

Inline::みたいなやり方でも、jythonみたいなシームレスな言語でも結局複数の言語を理解してないとうまいことやれないので、その分習得コストはかかると思うんだけど、シームレスな言語使うと楽しいのはスケッチするような感覚が得られることなのかなと思ってる。

そういう意味ではGainerも似たような感じかも。

ProductName Make: Technology on Your Time Volume 04
オライリー・ジャパン
オライリージャパン / ¥ 1,575 ()
在庫あり。

あとシームレスな言語を使うっていうことはそれにあわせてライブラリのほうも対応していかないといくのが望ましいのかなとPybel as a generic API for cheminformatics libraries - proof of concept using CDKというエントリを見てふと思った。

chemoinformaticsだとopenbabelっていうc++の大きいライブラリとCDKっていうjavaのライブラリがあって、その上にpython(とruby)がまたがっている感じなのだけど、さらにこれらでいじくったデータを解析にもっていくためにRが必要だったりとかするのでRpyが役に立ったりする。

jythonでopsinを使う

jythonがmacbookにインストールできなかったのでとりあえずlinuxで。

といってもgcjだとエラーを吐くので、sunのjavaをインストール。 ここみて設定。alternativeコマンドを使うとjavaの共存ができるのね。いままで、シンボリックリンクを上書きしてたのでめんどいなーと思ってたけど、これだとらくちん。

jythonをインストールしたら、あとはopsinのjarを落としてきてクラスパスに通す。

>>> import uk.ac.cam.ch.wwmm.opsin as opsin
>>> opsin.NameToStructure().parseToCML("4-iodobenzoic acid").toXML() 

二行でIUPAC名がCMLに。 すばらしい。

jrubyの例もある。

ちなみにjrubyはmacbookにさくっと入って、この例の通りにやれば動いた。

perlで同じ事をやる場合にはInline::Javaを使ってやればいいけど、Javaのライブラリを有効に利用するのはJavaで実装された言語処理系がやっぱ楽だ。

JRubyとかjythonとか

JRubyとかjythonとかはCGI書くのに苦労するよなとかつぶやいてみたけどjythonではSimpleHTTPSeverが使えることに気づいた。

% jython
Jython 2.2.1 on java1.6.0_06
Type "copyright", "credits" or "license" for more information.
>>> import SimpleHTTPServer
>>> SimpleHTTPServer.test()
Serving HTTP on 0:0:0:0:0:0:0:0 port 8000 ...
192.168.11.xx - - [26/Jun/2008 21:34:28] "GET / HTTP/1.1" 200 -
192.168.11.xx - - [26/Jun/2008 21:34:28] code 404, message File not found
192.168.11.xx - - [26/Jun/2008 21:34:28] "GET /favicon.ico HTTP/1.1" 404 -

あーでも、これだと、結局jythonスクリプトでCGI実行しないとあかんからうまくいかんわ。

というわけで、明日は会社にWebアプリ編を持ってってjythonでwebappサーバーつくるのにチャレンジ。

ProductName みんなのPython Webアプリ編 [みんなのシリーズ]
柴田 淳
ソフトバンククリエイティブ / ¥ 2,604 ()
在庫あり。

なんかやる気出てきた。

macbookでjython

trunk:4847はコンパイルが通った。

Jython 2.3a0+ (trunk:4847, 7 4 2008, 20:27:46) 
[Java HotSpot(TM) Client VM (Apple Inc.)] on java1.5.0_13
Type "help", "copyright", "credits" or "license" for more information.

これで遊べる。

jython+web.pyでお手軽Webアプリ

jython+web.pyがお手軽で、ちょっとしたことをやるならいい感じ。

jythonのosモジュールにはfstatがないのでtrunkのSimpleHTTPServerの静的ファイルの転送ができない。そのため、2.2.1のSimpleHTTPServerと入れ替えた。

import java.io.StringReader as StringReader
import org.openscience.cdk.interfaces.IMolecule
import org.openscience.cdk.io.CMLReader as CMLReader
import org.openscience.cdk.ChemFile as ChemFile
import org.openscience.cdk.layout.StructureDiagramGenerator as StructureDiagramGenerator
import uk.ac.cam.ch.wwmm.opsin as opsin
import net.sf.structure.cdk.util.ImageKit as ImageKit

import web

urls = (
    '/(.*)', 'img2d' 
)

class img2d:       
    def GET(self, name):
        cml = opsin.NameToStructure().parseToCML(name).toXML()

        str_reader = StringReader(cml);
        cmlr = CMLReader()
        cmlr.setReader(str_reader)
        chem = cmlr.read(ChemFile());
        mol = chem.getChemSequence(0).getChemModel(0).getSetOfMolecules().getMolecule(0)

        sdg = StructureDiagramGenerator()
        sdg.setMolecule(mol)
        sdg.generateCoordinates()
        mol = sdg.getMolecule()

        ImageKit.writePNG(mol, 300, 300, "./static/test.png")
        print '<h1>' + name + '</h1>' + '<img src="/static/test.png" />'

if __name__ == "__main__": web.run(urls, globals())

http://localhost:8080/(2,3-diethyl-benzyl)-isobutanolというURLにアクセスすると、IUPACを2次元構造に変換していい感じに描画して表示してくれる。

opsin_web

ImageKitが必ずファイルに出力するのでテンポラリのファイルを作ればいいのだけど、とりあえず動く事を確認したかったので決めうちの名前で。