« 2006年08月 | メイン | 2006年10月 »

2006年09月30日

続:Pythonドキュメントの日英マッピングをするGreaseMonkey

西尾泰和のブログ: Pythonドキュメントの日英マッピングをするGreaseMonkeyの改良版。IDの付いているエレメント(関数の定義とか)全ての前にリンクが付いて、それをクリックすると対応する日本語ドキュメントの同じエレメントへジャンプ。 pyenjamapper2.user.js

// ==UserScript==
// @name          Python English-Japanese Mapper 2
// @namespace     http://www.nishiohirokazu.org/blog/2006/09/pyenjamapper2.html
// @description	  mapping English documents and Japanese documents
// @include       http://www.python.org/doc/2.4/*
// @include       http://www.python.jp/doc/release/*
// ==/UserScript==


// mapping
// [from, to, label]
mapping = [
  [
    "http://www.python.org/doc/2.4/",
    "http://www.python.jp/doc/release/", "[J]"
  ],
  [
    "http://www.python.jp/doc/release/",
    "http://www.python.org/doc/2.4/", "[E]"
  ],
]

loc = document.location.toString();

caption = "";
for(var i = 0; i < mapping.length; i++){
  var frm = mapping[i][0];
  if(loc.indexOf(frm) == 0){
    var url = loc.replace(frm, mapping[i][1]).split("#")[0];
    caption = mapping[i][2];
    break;
  }
}

tags = document.getElementsByTagName('*');
for(var i = 0; i < tags.length; i++){
  tag = tags[i];
	if(tag.id != ''){
		newTag = document.createElement('A');
		newTag.href = url + '#' + tag.id;
		newTag.appendChild(document.createTextNode(caption));
		tag.parentNode.insertBefore(newTag, tag);
		i++;
	}
}

対応づけられたサイトの切り替えをするブックマークレット

Pythonドキュメントの日英マッピングをするGreaseMonkeyの続編。enjamapper。 これをブックマークしておいて、 http://www.python.org/doc/2.4/* か http://www.python.jp/doc/release/* のどちらかで実行すると、もう片方のサイトにジャンプします。

実行されると即ジャンプするブックマークレットにすることで、HTMLを書き換えないでよくなるので、ターゲットのHTMLに対する依存性がなくなりました。サイトの対応付けの設定を書き換えるだけで、ファイルの配置が同じサイト間ならPythonのドキュメントに限らずジャンプできます。

サイトの対応付けをカスタマイズしたい場合や、僕のサイトに誰かが進入してスクリプトを有害な物に差し替えてしまう危険性を避けたい場合は enjamapper.js をダウンロードして自分の好きなところにおいてください。

使い方の具体例。 例えばPythonドキュメントの和訳中に 「positional arguments」はどう訳すのだろうと思ったとします。まず、Googleのsite:オプションを利用して「positional arguments site:http://www.python.org/doc/2.4/」と検索します。そうすると英文Pythonドキュメント中の「6.21.1.3 What are positional arguments for?」という項目がヒットします。これを開いて、enjamapperブックマークを実行すると、これに対応する日本語のページ「6.21.1.3 固定引数とは何か」にジャンプします。「positional arguments」は「固定引数」と訳せば他のドキュメントと統一できるということがわかりました。

ソースコードは以下。

// English-Japanese Mapper Bookmarklet
// see http://www.nishiohirokazu.org/blog/2006/09/enjamapper.html


mapping = [
  [
    "http://www.python.org/doc/2.4/",
    "http://www.python.jp/doc/release/"
  ]
]

loc = document.location.toString();
for(var i = 0; i < mapping.length; i++){
  var url1 = mapping[i][0];
  var url2 = mapping[i][1];
  if(loc.indexOf(url1) == 0){
    document.location = loc.replace(url1, url2);
  }else if(loc.indexOf(url2) == 0){
    document.location = loc.replace(url2, url1);
  }
}

Pythonドキュメントの日英マッピングをするGreaseMonkey

追記:これを改良して作った対応づけられたサイトの切り替えをするブックマークレットの方が便利かも知れません。


pyenjamapper。Firefoxを使っていて、GreaseMonkeyをインストールしていれば、このリンクをクリックするだけでインストールしてください。そうすると 2.2 Non-essential Built-in Functionsなどの英文ドキュメントのナビゲータの所に「Japanese」というリンクが表示されます。クリックすると日本語の2.2 非必須組み込み関数 (Non-essential Built-in Functions)へ飛びます。こちらにはEnglishというリンクが追加されていて、クリックすると英語の方のドキュメントに飛びます。

他のブラウザの人でもブックマークレットとして使えるかも。…でも、ブックマークレットにするなら「押したらリンク追加」より「押したらジャンプ」の方がいいですね。

以下ソースコード。

// ==UserScript==
// @name          English-Japanese Mapper
// @namespace     http://www.nishiohirokazu.org/blog/2006/09/pyenjamapper.html
// @description	  mapping English documents and Japanese documents
// @include       http://www.python.org/doc/2.4/*
// @include       http://www.python.jp/doc/release/*
// ==/UserScript==


// mapping
// [from, to, label]
mapping = [
  [
    "http://www.python.org/doc/2.4/",
    "http://www.python.jp/doc/release/", "Japanese"
  ],
  [
    "http://www.python.jp/doc/release/",
    "http://www.python.org/doc/2.4/", "English"
  ],
]

loc = document.location.toString();
anchorTag = "";
for(var i = 0; i < mapping.length; i++){
  var frm = mapping[i][0];
  if(loc.indexOf(frm) == 0){
    var url = loc.replace(frm, mapping[i][1]);
    anchorTag = "<a href = '" + url + "'>" + mapping[i][2] + "</a>";
    break;
  }
}

naviDiv = '<div class="online-navigation">';
document.body.innerHTML = document.body.innerHTML.replace(
  naviDiv, naviDiv + anchorTag
);

Python Developers Camp日記

listを継承したクラスを作ると何が変わるか。

>>> class MyList(list):
	pass

>>> dir(MyList())
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__dict__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__str__', '__weakref__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>> [x for x in _ if not(x in dir(list))]
['__dict__', '__module__', '__weakref__']

この3つが増えている。

>>> set(dir(MyList())) - set(dir(list()))
set(['__dict__', '__module__', '__weakref__'])

これでいいらしい。なるほど。


__ タプルの本質は括弧ではなく、カンマなのだけど、わかりにくいのでつまずきやすい。タプルの本質を括弧だととらえていると、(1, 2, 3)、 (1, 2)ときたら(1)と書きたくなってしまう。でもこれは1を括弧で囲ってあるだけ。 タプルの本質はカンマで、単に人間が見やすくするためだけに括弧が付いている。「not "a" in "abc"」でいいのに「not("a" in "abc")」と書いたりするのと同じ。要素が3つのタプルは「1, 2, 3」だけでなく「1, 2, 3,」でもOK。2個のは「1, 2」と「1, 2,」が可能だが、要素が1個のは「1」と書くとダメなので「1,」だけになる。


__ 「foo.setAge(20)」とやるべき所を「foo.setAge = 20」と間違えることが出来てしまうのがJavaの人にとっては罠。


__ 演算子オーバーロードなのか、オーバーライドなのか、という話題。 多重定義 - Wikipedia。Pythonでは「x + y」が「x.__add__(y)」というフックメソッドの呼び出しで多重定義されている。xが整数オブジェクトなのか文字列オブジェクトなのかによって異なるメソッドだから、多重定義。これが演算子オーバーロード。で、整数クラスを継承した自作のクラスでその__add__メソッドをオーバーライドすると、足し算の挙動が変わる。これは単に「親クラスのメソッドをオーバーライドすると挙動が変わる」ってだけ。 同時に似た名前のことをやっているので紛らわしい。


__ 出先ではJavaScriptのリファレンスがなくて不便。 Pythonのドキュメントは個々の関数の説明の前にアンカーが付いてたりしないかと期待したけど残念ながらそうではない。代わりに<tt id='l2h-8' xml:id='l2h-8' class="function">なんてのが付いていたりする。

西尾泰和のブログ: Pythonドキュメントの日英マッピングをするGreaseMonkeyできました。「リンク先のページのxml:id='l2h-8'があるところへジャンプ」ってのがJavaScriptで出来るといいんだけど、どうすればいいんだろう。


__ 西尾泰和のブログ: 対応づけられたサイトの切り替えをするブックマークレット に進化しました。 あー、でも実際のユースケースを考えると、Googleの検索画面から直接使える方が便利かもなぁ。


__ なんだかすごく遠回りをしてしまったけど、アンカータグじゃないタグでもid="xxx"ならurlに#xxxってつけるだけでその位置に飛べるようですね。少なくともIEとFirefoxでは。それなら、もっとうまい方法があるかも…。


__ オーバーライドすべきメソッドであることを示すためにassert 0, "some message"と書く手もあるようだ。raiseでもいいのだけど。


__ 「Googleで訳語のわからない英語を検索して対応する和文に飛んで訳語を確認」というのをやろうと思ってせっかくURLのマッピングをするjsを作ったのに、バージョン2.4の英文ドキュメントに対してGoogleで検索しても、なんか引っかかってこない。functionが3カ所しか使われていないとかあり得ない。何が起きているのだろう。

仕方ないなぁ。英文は全部まとめたzipが落ちていたのでローカルに置いてあるから、Googleデスクトップを入れてそこから検索するというのも一つの手だけどなぁ。ううむ。自前で検索するプログラムを作るというのも一つの手だけどなぁ。というかインデクスを作らない片っ端からファイルを開いて読んで検索する物ならすでに作ってあるのだけど、Pythonの標準出力にファイル名が出てもなぁ。リンクが出て要約もでてクリックすればジャンプできるGoogleっぽいのがいいんだけどな。


__ リモートを妹に変えると面白い単語。リモート監視システム。リモートとの同期/差分。リモートコントローラー。リモートメンテナンス。リモートアシスタント。リモートリポジトリ。リモートセンシング。インターネット を使ったリモート教育。【コラム】ツールエキスパート 第1回 リモート管理もユビキタス? - VNC(1) (MYCOMジャーナル)。リモートのグラフィカルデバッグ。Microsoft SQL Server 2000 がリモート攻撃者のDosマウントを容認する。


__ DjangoのWindowsへのインストールは小学生でもできるくらい簡単だった。ダウンロードしてダブルクリックするだけだし。開発用のサーバを立てるまでもチュートリアルを読んだら簡単。流し読んだけど対話的に色々試せるようですね。もう眠い。

エレメントのIDと、次のIDが振られたエレメントまでの文章がデータベースに入れてあり、クエリを指定するとデータベースからマッチする行を選択して、その英文サイトへのリンクと和文サイトへのリンクを表示すればいいのか。いや、IDと英文と和文をデータベースに入れて、サマリー部分で並べて表示すれば、場合によってはリンクをクリックして飛ぶ必要すらない。詳しく見たいときだけリンク先を見ればいいし。で、ビューとしては検索フォームと、検索結果の表示があればいいのかな。

2006年09月29日

Python Developer Camp日記

遅れてつきましたが、遅れる人が多かったので時間割自体がシフトしていました。

Twistedはネットワークプログラムを書くための物らしい。勝手にウェブアプリを作るフレームワークだと思ってました。

和訳プロジェクト

  • 標準ドキュメントのビルドシステムが結構いい感じに出来ている。ReSTとか。docutilsとか。
  • 和訳のメリット
    • 人と情報を引き寄せる
    • 試行錯誤のコードが減る→信頼性が増す
    • ScreenCast お得感
    • 正確な情報はソフトウェアの信頼性も高める
  • リーダースのCDのやつがいいらしい
  • リポジトリのあるドキュメントが訳しやすい
  • Wikiの物も多いけど、Wikiのは翻訳しにくい
    • Wikiをリポジトリで管理したらいいのか?
  • 私見は入れない
  • 1ビットも情報を落とさない
  • 完成していない物より、下手でも完結している物を。投げ出さないこと。


__ 翻訳スプリント。難しい。投げ出したくなってきた。

日記

ソニー製バッテリーまたリコール:レノボ・IBMの50万個以上で過熱の恐れ - Engadget Japanese

僕のはリコール対象じゃなかったけど、喜んでいいのかどうか…。


__ 京葉線は復活したみたい。


__ 新富士まで新幹線で行ってそこからタクシーで10分か。2時間ちょい。開始が16時だからあと1時間で出発。 それまでに床にこぼした豚丼の汁をなんとかしないと!(ぉ)


__ 結局当初の予定通り、17時過ぎてからこっちを出発して夕食終わったくらいに到着する雰囲気。


__ 楽天KCから電話があって、三井住友の楽天カードを楽天KCのカードに切り替えた時点で口座引き落としの効力が切れているので、口座に振り込めとのこと。Viewカードも同じことを言っていたなぁ。なんか最近そういう電話が色々かかってくるからややこしくなってきた。

2006年09月28日

どの文字をXORすれば目的の文字になるか?

とりあえず「Hello, world!」のどの文字をXORすれば目的の文字になるかを載せておきます。ここに書かれている以外の組み合わせでも目的の文字を作ることが出来る可能性は高く、その「別解」の方がコードが短くなる可能性も否定できません。そのあたりの研究はまだ手つかずです。

!: !
": !^l^o
#:  ^l^o
$: H^l
%:  ^r^w
&: e^,^o
': H^o
(:  ^d^l
):  ^e^l
*:  ^e^o
+:  ^d^o
,: ,
-: e^H
.: e^H^l^o
/: l^,^o
0: e^H^o^r
1: ,^o^r
2:  ^e^w
3:  ^d^w
4: ,^o^w
5: e^H^o^w
6:  ^d^r
7:  ^e^r
8:  ^o^w
9: !^o^w
:: H^r
;:  ^l^w
<: !^o^r
=:  ^o^r
>:  ^l^r
?: H^w
@: l^,
A: e^H^l
B: e^H^o
C: ,^o
D:  ^d
E:  ^e
F:  ^e^l^o
G:  ^d^l^o
H: H
I: e^,
J:  ^o^r^w
K: H^l^o
L:  ^l
M: !^l
N: !^o
O:  ^o
P: H^o^w
Q:  ^l^o^r
R:  ^r
S: !^r
T:  ^l^o^w
U: H^o^r
V: !^w
W:  ^w
X:  ^e^o^r
Y:  ^d^o^r
Z: e^H^w
[: ,^w
\:  ^d^o^w
]:  ^e^o^w
^: ,^r
_: e^H^r
`:  ^l^,
a: !^l^,
b: !^,^o
c:  ^,^o
d: d
e: e
f: e^l^o
g: d^l^o
h:  ^H
i: !^H
j: o^r^w
k:  ^H^l^o
l: l
m:  ^!^l
n:  ^!^o
o: o
p:  ^H^o^w
q: l^o^r
r: r
s:  ^!^r
t: l^o^w
u:  ^H^o^r
v:  ^!^w
w: w
x: e^o^r
y: d^o^r
z: !^,^w
{:  ^,^w
|: d^o^w
}: e^o^w
~:  ^,^r

日記

渡辺さんの日記より、Kemuri/JavaScript

大歓迎です。確かにJavaScriptで作った方が手軽に試せますね。

とりあえず、対応表だけアップしときます。 西尾泰和のブログ: どの文字をXORすれば目的の文字になるか?


__ 台所漂白剤という物を使ってみたら目から鱗。洗いにくい隙間の汚れはこうやって落とすのかー。なるほど。


__ ぐち。JyConsole、バージョン1.2をダウンロードしたらファイル名に1.1と入っていて、解凍するとフォルダの名前はJyConsole 2.0。えー。

JyConsoleはQPL。GRINEditと静的にリンクするとライセンス上の問題が起こってしまうかも知れないなぁ。


__ NTTの「サツマイモで屋上緑化」っていいなぁ。芝より1.5倍吸収効率がいいらしい。コストは2倍かかるらしいけど。サツマイモは地面を這うから、屋上全部に土を敷き詰めなくてもいいそうな。


__ おなかすいた。 厚揚げとピーマンがある。 厚揚げは熱湯をかけて油を抜くらしい。 厚揚げとピーマンのみそ炒め


__ Python/Python病 - OreSign :: 俺だよ俺。それがオレSignクオリティ。

Javaでjava.util.regexやjava.lang.reflectをバリバリつかうようになる(もうリーマンプログラマじゃ読めねー)

あー、僕はPython病だったんだなぁ(笑)


__ あー。もう28時だ。 今日の夕方くらいにPython Developer Campに行かないといけないんだけどまだ場所がどこなのかいまいちわかってないぞ、むー。ラボで地図を印刷してくるのも忘れたし…。まぁ、なんとかなるだろう。


__ ちょっ、京葉線まだ復旧してないの!新木場~東京が運転見合わせって…。むー。秋葉原経由で行けばいいのかな。

2006年09月27日

log

短いことだから、整理されていないことだから、と開発日誌じゃなくて日記の方に書いてしまうと、 あとで集めて整理するのが大変なので全部開発日誌に書くようにしよう。

GRINEditのアーキテクチャ図を書いていて気がついたのだけど、 今はグラフオブジェクトが頂点オブジェクト、辺オブジェクト、物理法則オブジェクトを持っているけど、これはおかしいよね。グラフオブジェクトは頂点オブジェクト、辺オブジェクトを持っていて、整形エンジンオブジェクトが物理法則オブジェクトを持つべき。

そうすると、もし将来的に整形エンジンオブジェクトが複数個になりうるのであれば、「物理法則オブジェクトのセット」自体も複数個になりうる。難しい問題だなぁ。レンダリングエンジンを複数個使って、切り替えられるようにするニーズがどれほどあるのか…。


__ Graphクラスが持っていたlayoutStepとそれに関するメソッドをSimpleLayout implements ILayoutに移動。このlayoutStepは、引数にgraphを受け取って、それを破壊的に整形する。また、今までメインループでgraph.layoutStepと呼んでいたところを、Mediatorを介してmed.getLayoutEngine().layoutStepと呼ぶようにした。これでMediator.setLayoutEngineでレイアウトエンジンを指定することでグラフはそのまま整形方法を差し替えることが出来るようになった。


__ メインクラスGRINEditからデフォルトのGUIに関する処理を全てGRINEditDefaultGUIに移動。 でGRINEditクラスはnew GRINEditDefaultGUI()するだけ。 後はこのインスタンシエイト部分を能動的プラグインの読み込みに置き換えればOK。

ふむ。今GUI側にくくりだしたコードの部分にドラッグドロップのリスナとか、メニューの処理化スクリプトの呼び出しとかが入っているんだなぁ。

こういう機能をプラグインにくくり出すことを考えると、これはこのデフォルトのGUIを使うことが前提のプラグイン。ふむ。

日記

劇的ビフォーアフター。布団引く前に写真を撮った方がよかったですね。


__ 平石クリニックのニンニク注射というものを知って、打ってもらおうかと思って調べたんですけど、ニンニクが入っているわけではないんですね、これ。残念。


__ 404 Blog Not Found:かわいいからゆるす(c)Dr.秩父山から引用の引用

「インターネットとヤフーはどう違うんですか」と言われたら、要するに彼女は上位概念と下位概念を混同しているのだから、 「あなたの今の質問は、くだものとリンゴはどう違うんですか、と言っているのと同じです」 とか。

どうして誰もつっこんでいないのかそれが不思議なのですけど、この答えは「ここはひどいインターネットですね」と同じ間違いをしているような気がします。リンゴは果物ですけど、ヤフーはインターネットじゃないでしょう。果物とリンゴじゃなくて、スーパーとリンゴなのでは。


__ 明日というか今日は柏に行って貸しているMac miniをいじる予定。

2006年09月26日

日記あえ

おなかすいた…。

西尾泰和のブログ: How to make oneliner in Python?に英語のコメントが付いた。I afraid python would bite me!ってのは「Pythonスゲー!」ってニュアンスに解釈していいのかな??

もう9時回ってるし、10時のミーティングに間に合おうと思ったらうかうかしてられないね。


__ プロジェクトAとBとCがあって、AとBの締め切りが29日。Aから締め切りのないA'が派生したので捨てても構わなくなり、Bに注力していたらBはもう完了して後は数回のミーティングをのぞくと2ヶ月ほど放置しても構わない。で。今日はCの打ち合わせに行ってきて、漠然と「Bが終わったらそのノウハウを生かしてCをするのかな」と思っていたのが、予想に反してCがBの前に入ってきた。29日までAの完遂を目指して頑張り、29日からPythonDevelopersCampで、それが済んだらCかな。メインCでBと車輪の両輪で。

と思ったけどもやっぱり毛色の違うAに頭のリソースが向いていかないのでCと、Bの準備を。


__ 今朝、あごの関節がばきっといってしまって、ちょっと痛いような気もする。


__ 【防災】スーパーデリオス携帯用浄水器! - 総合防犯店マックスガレージ - livedoor デパート 意外と安いね。


__ なんか、仕事がはかどらないと思ったらもう1時半か。朝8時に起きて活動してウォッカ飲んで帰ってきてこの時間だったら、疲れて働けなくても当たり前。さっきからなんかふくらはぎや土踏まずが痛いと思っていたのだけど、僕はお酒を飲むと筋肉痛になる体質なのでそれがもう出始めているのだろう。

伏田君に教えてもらったWordの変更履歴表示機能が便利。彼に渡したドキュメントが変更箇所にびっしり赤が入って帰ってきたときにはぎょっとしたけど、自分の変更と人の変更で色が変わるし、変更を受け入れたり拒否して元に戻したり出来るし、なかなかいい。Wordで書類を出さないと行けなくて、複数人で文章をいじる場合にはかなり使える機能だと思った。

高市早苗沖縄北方少子化大臣の担当する内容は寿限無みたいに早口で一気に言えると面白そうです。沖縄及び北方対策、科学技術政策、イノベーション、少子化・男女共同参画、食品安全。

2006年09月25日

How to make oneliner in Python?

One day I fought on a boxing ring using my Thinkpad. It is a festival for nerds who loves lightweight language. (See Boxing in the LLRing?) My session was "Janken2.0", to make program to connect a server and play "Paper-Scissors-Rock". This entry is a FAQ, notFrequently Asked Question to make Python oneliner.

Is it difficult to make oneliners in Python?

You should learn Python more. Python use an indentation as a block. But what is the indentation? It is white region after "new line". No "new line" means no block, that is the most of syntax is disabled.

Is it impossible to make oneliners in Python?

No. See this. This is the "Paper-Scissors-Rock" agent.

jankenoneliner.png

How can I write "if" statement in a line?

"if" statement requires new line.

if condition:[new line]
    then-clause[new line]

if condition: then-clause[new line]

So, you can't use "if". Use "and" and "or".

condition and then-clause or else-clause

The right operand of "and" and "or" is evaluated lazily. But notice, if "bool(then-clause)" is False it doesn't work as you expected. You can envelope is with list

(a and [p(1)] or [p(2)])[0]

Given not-empty list as x, bool(x) is True.

How can I make a function?

"def" statement to make functions also requires "new line". So you must use "lamnda".

But lambda function can include expressions, not statements. You can't use assignments in lambda functions.

Oops, I can't use assignments?!

Don't worry. Python's great introspection allow you to remove assignment statements. The builtin function "globals()" returns global namespace as a dictionary. So when you want to do "x = 1", you just do "globals().__setitem__('x', 1)". Very easy. Sometimes you may use "locals()" for a local namespace and "x.__dict__" for a member of object x, but good programmers don't need them, because they use global namespace only.

How can I use "for" statements?

Why don't you use the list comprehension? I thought "for" statements were obsoleted.

>>> for i in range(5):
	print i

	
0
1
2
3
4
>>> import sys;[sys.stdout.write(str(i) + "\n") for i in range(5)]
0
1
2
3
4
[None, None, None, None, None]

[None, None, None, None, None] is the value of this expression. It is as True. You may have to use "and 0" to make it as False.

Is "while" statement replaced with recursive call?

Partially, yes. But if it loops too many times, it causes "RuntimeError: maximum recursion depth exceeded".

The other solution is lazy evaluation and infinite list. Import "ifilter" and "count" from itertools. "count" is a infinite list. "ifilter" creates a filtered list lazily. So "ifilter(bool, x).next()" evaluates x[0], x[1], x[2], ..., and stop iteration if x[n] is True.

>>> i = 1
>>> while i < 100:
	i *= 2

	
>>> i
128
>>> from itertools import ifilter, count; i = 1; ifilter(bool, ((i >= 100) or gl
obals().__setitem__("i", i * 2) for x in count())).next()
True
>>> i
128

How to substitute "break" statement and "else" clause?

It is very difficult. It is NOT difficult to write in Python, BUT difficult to write in English! "if condition: break" means "When the value of expression become paticular value, stop iteration". It is similar to the end of "while" statement. That is, the expression in "ifilter" should be as True when either the loop ended and the loop breaked. "else-clause" distinguish those two tarmination, so the value of expression must be different value.

I'll make this code to calculate prime numbers to oneliner.

>>> primes = []
>>> for i in range(2, 100):
	for p in primes:
		if i % p == 0:
			break
	else:
		primes.append(i)

>>> primes
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

First, substitute the "for" statement by a "while" statement.

>>> primes = []
>>> for i in range(2, 100):
	j = 0
	while j < len(primes):
		if i % primes[j] == 0:
			break
		j += 1
	else:
		primes.append(i)

		
>>> primes
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

I make the expression when "i % primes[j] == 0" the value becomes "BREAKED". When the loop tarminated without breaked, the value of loop become "True". After loop tarminated, if the value is "True", do "else-clause".

>>> globals().__setitem__("primes", []) or [
  globals().__setitem__("j", 0) or
  ifilter(bool,
    (
      not(j < len(primes)) or
      (i % primes[j] == 0 and "BREAKED") or
      globals().__setitem__("j", j + 1)
      for c in count()
    )
  ).next() == True and primes.append(i)
  for i in range(2, 100)
] and None
>>> primes
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

And I removed newlines and redundant spaces.

>>> globals().__setitem__("primes",[])or[globals().__setitem__("j", 0)or ifilter
(bool,(not(j<len(primes))or(i%primes[j]==0 and"BREAKED")or globals().__setite
m__("j",j+1)for c in count())).next()==True and primes.append(i)for i in range(2
,100)]and primes
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

How can I define a class?

There is no need to define your own class.

First, find a nice not read-only class or import it. Make an instance of the class. And push all fields and methods you need into it! Push, push, push!

If you need multiple instance, envelope the pushing code with lambda and make "builder function".

Here I wrote a sample to define a class.

>>> class Counter:
	def __init__(self):
		self.count = 0
	def __call__(self):
		self.count += 1
		return self.count

	
>>> c = Counter()
>>> c()
1
>>> c()
2

Import HTMLParser from HTMLParser, and push and push and push.

>>> from HTMLParser import HTMLParser; self = HTMLParser(); self.count = 0; self
.__call__ = lambda :self.__dict__.__setitem__("count", self.__dict__["count"] + 
1) or self.count
>>> self()
1
>>> self()
2

If you envelope them with lambda and assign it in global namespace, you can emulate the class definition.

>>> globals().__setitem__("Counter", lambda :(lambda self: self.__dict__.__setit
em__("count", 0) or self.__dict__.__setitem__("__call__", lambda :self.__dict__.
__setitem__("count", self.__dict__["count"] + 1) or self.count) or self)(__impor
t__("HTMLParser").HTMLParser()))
>>> c = Counter()
>>> c()
1
>>> c()
2
>>> c2 = Counter()
>>> c2()
1
>>> c()
3

How to "try" without "try...except"?

To catch a exception without try-statement is almost impossible. But I had to catch "Software caused connection abort" in my oneliner. I found a solution, it is not perfect substitution of "try...except", but it works.

Run the dengerous code as subprocess. When the subprocess dead, read its error message from the pipe and parse it.

    if sys.argv[3] == "CATCH":

        ifilterfalse(bool,
            (
                re.search("Software caused connection abort",
                    os.popen3(
                        r"python %s %s %s GO" % (
                            sys.argv[0],
                            sys.argv[1],
                            sys.argv[2]
                        )
                    )[2].read()
                )
                for x in count()
            )
        ).next()


    elif sys.argv[3] == "TRY":
        # dengerous code

It is work like following code.

while True:
    try:
        #  dengerous code
    except ....: # catch "Software caused connection abort" and ignore it
        pass

If you need some values from subprocess, you can use "cPickle" library. "cPickle.dumps(...)" and "globals.update(cPickle.loads(...))".

How to make import statements to expression?

Is it nessesary? If it is really nessesary, use built-in function __import__. But if you use global namespace only, you can simply import on the head of your code.

How to make short oneliner?

Find repeated string and make shorter. For example, "globals().__setitem__" is very frequent. Do "globals().__setitem__("g",globals().__setitem__)" or "globals().__setitem__("g",lambda x,y,z=globals():z.__setitem__(x,y))". If you have "not read-only and not callable" object x, try "x.__dict__.__setitem__("__call__", x.__dict__.__setitem__)".

Or compress it.

# Brainf*ck interpreter in Python Onliner Compressed
exec(reduce(lambda x,y:x.replace(y[0],y[1:]),'O1)q|Pz"t",|Qz"c",|Rimport |SY:zp,
|T)%256X|UY:z"c",c+1qp",p|V)or ifilter(bool,(|W)for x in count())).next()|Xqc",c
+1)q|Y",lambda|Z(globals().get(p,0)|q)or z"|zglobals().__setitem__('.split('|'),
'Rsys;from itertools Rcount,ifilter;[Q0qp",0qjY k:lambda:Z==0)^(k==-1)and(Pc+kqd
",1Vz"d",d+{"]":-1,"[":1}.get(s[t],0)*k)or d==0 or Pt+kWand Qt+1)or 1X>U+O<U-O+S
Z+1T-SZ+255T.Y:sys.stdout.write(chrZ)X,Sord(raw_input(">")[0]T[",j(O]",j(-Os",fi
le(sys.argv[1]).read()Vc==len(s)or(globals()[s[c]]()and 0W]'))

afterword

Thank you for reading this awful code written in English. I appreciate your patch to debug my English. Please feel easy to contact me!

KEMURI

This entry is an introduction of new programming language. Here is Japanese version.

KEMURI (means 'smoke' in Japanese) is proposed by NISHIO Hirokazu and OBINATA Daichi in the 39th symposium for young researcher of information science (jouhou kagaku wakate-no-kai in Japanese).

This is a code to print "Just Another Python Hacker," in KEMURI. Notice it is not the shortest code to print that. "^^"^^ can be replaced by ^"^^.

`"^^"^^^^"^^'"^^"^^'"^^"^^'"^^"^^"'"^^"^^`"^^"^^^^"^^"^^"^^"^^"^^'"^^"^^"'"^^"^^
`"^^'^^'"^^"^^'"^^"^^'"^^"^^'"^^"^^"'"^^"^^`'"^^"^^^^'"^^^'"^^"^^'"^^"^^'"^^"^^`
"^^"^^^^^^'"^^"^^'"^^"^^'"^^"^^`"^^"^^"^^'"^^^'"^^"^^'"^^"^^'"^^"^^^`'"^^"^^'"^^
"^^'"^^"^^'"^^"^^'"^^"^^'"^^"^^`"^^"^^^^"^^"^^'"^^"^^'"^^"^^'"^^"^^`"^^"^^^^'"^^
^'"^^"^^'"^^"^^'"^^^`"^^"^^^^'"^^"^^'"^^"^^'"^^"^^'"^^"^^`'"^^''^^'"^^"^^^'"^^"^
^'"^^"^^'"^^"^^`"^^"^^^^"^^"^^"^^^'"^^^'"^^"^^`"^^"^^^^"^^"^^"^^"^^''"^^^^'"^^"'
`'"^^"^^'"^^"^^'"^^"^^^^'"^^"^^'"^^"^^"'`"^^"^^^^"^^"^^'"^^"^^'"^^"^^'"^^"^^'"^^
"^^`"^^"^^^^"^^"^^"^^"^^"^^'"^^"^^"'"^^"^^`"^^'^^'"^^"^^'"^^"^^'"^^"^^'"^^"^^"'"
^^"^^`'"^^''^^'"^^"^^^'"^^"^^'"^^"^^'"^^"^^`"^^"^^^^"^^"^^"^^^'"^^^'"^^"^^`"^^"^
^^^'"^^"^^'"^^"^^'"^^"^^'"^^"^^`"^^"^^^^'"^^^'"^^"^^'"^^"^^'"^^^`^^'"^^"^^'"^^"^
^'"^^"^^'"^^"^^'"^^"^^`"^^"^^^^"^^"^^'"^^"^^'"^^"^^'"^^"^^`"^^"^^^^"^^"^^"^^^'"^
^^'"^^"^^`"^^"^^^^"^^"^^'"^^"^^^'"^^"^^^`'"^^"^^'"^^"^^'"^^^'"^^^^'"^^''`"^^"^^^
^"^^"^^^^^'"^^"^^'"^^"^^"'^"^^|

KEMURI is a Stack machine. You can push byte values (from 0 to 255) into stack. Each letter in KEMURI code is a command. There are only 6 commands in KEMURI syntax. The ^ pops two value from the stack and calculates XOR and pushes the result. The " duplicate the top value of the stack, that is, it pops a value and pushes itself twice. The ' pops three values x, y, z and pushes x, z, y. In other word, it rotates the top three values of the stack from xyz to yzx. The ~ pops a value and calculate NOT and pushes the result. The only command to push constant values into the stack is the `. It pushes 13 values 33, 100, 108, 114, 111, 119, 32, 44, 111, 108, 108, 101, 72 in this order. The | prints all values in the stack to standard output. It is strongly recommended to use it only once at the tail of your code.

To print "Hello, world!", you just type two keys as below. It is the shortest code to print "Hello, world!" all over the world, except for HQ9+.

`|

KEMURI has many advantages. It can print any character, which HQ9+ can't. It has only 6 commands so it is easier to learn Brainf*ck.

"l"(small L) and "*"(asterisk) are reserved for possibility to use as a command "Execute the stack as Brainf*ck" in future.

I wrote a KEMURI interpreter in Python.

class Kemuri(list):
    def push(self, x):
        self.append(x)

    def do(self, com):
        if com == "~":
            self.push(~self.pop())
        elif com == "^":
            x = self.pop()
            y = self.pop()
            self.push(x ^ y)
        elif com == '"':
            x = self.pop()
            self.push(x)
            self.push(x)
        elif com == "'": # xyz => yzx
            x = self.pop()
            y = self.pop()
            z = self.pop()
            self.push(x)
            self.push(z)
            self.push(y)
        elif com == "`":
            s = list("Hello, world!")
            s.reverse()
            for c in s:
                self.push(ord(c))
        elif com == "|":
            result = ""
            while len(self) > 0:
                result += chr(self.pop() % 256)

            print result

        elif len(com) > 1:
            for c in com:
                self.do(c)

        return self
            
    def inter(self):
        while True:
            code = raw_input("KEMURI> ")
            if code == "":
                break
            self.do(code)

if __name__ == "__main__":
    Kemuri().inter()

日記

ローズマリーのシネオールってなんだっけと思ったら、ユーカリの香りの主成分ですね。そしてローズマリーって軟膏みたいなにおいだと思ったら主成分がカンファー・シネオールなんて書いてある。

カンファーは樟脳で、クスノキに多く含まれる。シネオールはユーカリや月桂樹に含まれる。他にピネンも含まれているけど、これはテレピン油(マツ科の樹木から取った製油)の主成分。うわー。ローズマリーって名前の「ローズ」から勝手に花系の香りを連想していたけど、思いっきり樹木系じゃん。

そしてこれにブレンドしたのがヒノキとジュニパー(Juniper - Wikipedia, the free encyclopedia)。思いっきり樹木。

でもこれをかぐと脳の中のもやもやがすっきりするんです。昨日、アロマショップから漂う香りに引かれて買ってきました。

なるほど、こういうのはウッディな香りっていうのか。

あと最近、疲労と取る効果があるとか喧伝されている青葉アルコールはシス-3-ヘキサノールらしい。ゼラニウムの精油に含まれているとか、スミレの精油に含まれているとか書いてあったけども裏は取れていない。青臭い香り自体はグリーンノートと呼ぶのがアロマテラピストっぽいらしい


__ とかそんなことを調べながら10時にかかってくるはずだった電話を待っているのにまだかかってこない。むー。

この前も12時にあう約束だったのに半時間以上送れて来たしなぁ。 こういう細かな約束を守れないと社会人としての信用を失いますね。

ごめんなさい、人のこと言えません。僕も頑張ります(ぉ


__ 秋元@サイボウズ研究所プログラマーBlog: iHack - 脆弱なHTMLフォームの突破ゲームで紹介されているiHackが面白いのでおすすめです。 ただし仕事をしているブラウザがタブブラウザの場合は別のブラウザを立ち上げることをおすすめします(というか仕事中にやるなって?)。リンク先を見て、Level1がものすごく簡単だ、とLevel2に進んだ瞬間、無限ループでalertするページで他のタブに移れなくなりました(^^;。IEを立ち上げてview-sourceしようとしたらいつの間にか使えなくなっていて(XPのSP2かららしい)びっくり。

そんなこんなでLevel3までは到達できたのだけど、Level3はどうすればクリアできるのでしょうか。ブルートフォース以外の方法が思いつかない…。


__ シャープペンシルみたいな形で、先はボールペンで、後ろのキャップを外すと中にアロマオイルを仕込めるような物が欲しい。仕事に疲れたらキャップを外して香りをかぐの。


__ Matzにっき(2006-09-15)

hama (2006-09-23 16:05)

真のAIを実現するプログラミング言語があるとしたら、 それはLispかLisp的なものだと思いません?

まつもと (2006-09-23 17:41)

思いませんね。> 真のAIの実装言語 真のAIのコアがどんな言語で実装させるか想像も付きませんが、Lisp(的)でなければならない理由はあまり思いつきません。Lispは素敵な機能がテンコ盛りの言語ではありますが、生産性の少々の違いはともかく、普通の言語でしょう。 むしろ、真のAIの本質は(将来存在できるとしたら)、様々な経験を通じた学習でしょうし、それはいかなるプログラミング言語とも関係ないでしょう。J・P・ホーガン「未来の二つの顔」参照。

僕が考える、「真の(またはそれにより近い)AI」は、新しいマシン(細胞)を買ってきて、TrueAI_OSをインストールして他のマシンとIP reachableにしておくと、勝手にネットワークを形成して、全体として一つの知性体として動くようなもの。外部の知性体(例えば人間)とのプロトコルはもちろん相手の知性体の一番使いやすい物をつかう(日本人なら日本語ね)。Lispを使うのは「よりすぐれた知性体である人間様が、より劣った知性体であるコンピュータにわかりやすいように構文木を直接書き下してやる」と言っているような物で、人間の方が上位だから真のAIとは認めたくない。真のAIは人間よりも優れているのだ。

で、現在その真のAIに一番近いものがGoogleなのです。ほら、人間の出力した自然言語の文章を読んで、人間と自然言語に近いプロトコルで対話してるでしょ。毎日いくつもの細胞(マシン)が死滅していて、しかもそれ以上のスピードで新しい細胞(マシン)を追加しているあたりとかまさに生命。


__ 書類書き終わった。 眠い。 自転車乗ってこよう。


__ 昨日と同じくらいの時間に昨日と同じ店に行ったのだけど、平日なのでもう閉まってましたorz

しょんぼりして帰ってきたら おびなたのはてな日記 - KEMURIコンパイラ が出来ていたw

mixiのKEMURIコミュニティまで出来ていたのでとりあえず入ってみたw

ちょっと元気が出たかも。

で、英語版の紹介記事を作ったw 西尾泰和のブログ: KEMURI


__ 調子に乗って西尾泰和のブログ: How to write oneliner in Python?まで作ってしまった。さすがに3時間がかかった。明日10時に秋葉原で打ち合わせなのになー。8時間寝たらぎりぎりじゃん…。せっかくお酒飲んで寝ようと思ったのに、完全にさめちゃったよ…。


__ Python Developers Camp 2006夏のライトニングトークでワンライナーの話をするとして、LLRingどまりだとLLRingに行った人がつまらないし、新しいPython Oneliner CompressedやBrainf*ck Interpreter in Python Oneliner Compressedを話すとしたらたぶんBrainf*ckの説明を入れる必要が出てくるだろう。やっぱりばっさり割愛してJythonの話だけにしよう。


__ とりあえず一番大きな仕事を片付けたので、明日から何をするかは明日きちんとメタ仕事して決めよう。選択肢は3つくらいあるなぁ。

2006年09月24日

GRINEditドキュメントの種

将来ドキュメントを書くときに使えそうな文章をためておく場所です。

GRINEdit用語集

  • MouseOperation:各種マウス操作を受け持つクラス、またはそのオブジェクト。MouseOperationクラスの子クラスである。

よくある失敗、FAQ

  • AddVertexではなくてaddVertex。基本的にメソッド(関数)の名前は頭が小文字、"CircleVertex"などのクラス(物の種類)の名前は頭が大文字
  • addVertexなどの1番目の引数は文字列。addVertex(CircleVertex, {})ではなくaddVertex("CircleVertex", {})

maven

IT-Walker on hatenaを参考にしてmavenのpom.xmlに<addClasspath>true</addClasspath>と書き足す。

試験管のなかのコード :: Maven2 で JAR の Manifest ファイルを設定する方法をメモを参考にして<classpathPrefix>dependency</classpathPrefix>と指定してやればよいようです。

Eclipseとの連携 Maven -TECHSCORE-を参考にしてM2_REPOに正しい値を入れたらEclipseでもビルドが通るようになりました。

コマンドラインで「mvn dependency:copy-dependencies」とやってみたらtargetフォルダの中にdependencyフォルダが生成され、中にはjarファイルが入っていました。うまく動いたようです。

SWTの新しいライブラリはmaven2のリポジトリに入っていないので、 SWTのサイトからダウンロードして展開し、jarはローカルリポジトリに、 dllは/src/main/resourceに入れる。 Eclipse側では/src/main/resourceを実行時の作業ディレクトリに指定する。

設計

grinedit_structure.png

左がGRINEdit0.10時点の設計、右がGRINEdit0.20で目指す設計です。 XML-RPCやJythonなどいろいろな方法でアクセスできるようにする上で、そのそれぞれに違う入り口を作っていたのでは大変なことになるので一つにまとめようという発想です。そうしておかないと「Jythonで頂点を追加するのは~~~だけど、これはまだXML-RPCではサポートされていないから古い~~を使ってね」なんていうダメダメな事態が発生しそうだからです。一方で、JavaやJythonなどの「Javaオブジェクトに直接さわれる方法」で操作したい人にとっては、間にクッションが入ってしまうともどかしいので、より直接的にいじることが出来る方法を提供します。

基本的にXML-RPCから追加できるすべてのオブジェクトは文字列型のnameというフィールドを持っています。addVertexなどのadd*系メソッドは新しいオブジェクトを作成してそのnameを返します。nameはシステム側が一意になるように振ります。ただし人間の可読性のためにプレフィクスをつけます。addVertexするとVertexというプレフィクスがつきます。

getObjects("Vertex")で頂点の一覧が名前とパラメータのマッピングとして取得できます

log

西尾泰和のブログ: 日記から移動。

JSON形式での保存と読み込みのテスト。 頂点と辺はきちんと復元されることを確認。 たしか追加で入れた物理法則が再現されない状態だったはず。 頂点のアンカーは外れてしまうことを確認。

使い勝手の悪い、コンソールでコマンドを入力するタイプだけども、一応マインドマップを作って保存/読み込みできる。

「ゆるいバネ」を作ろうかな。自然長以上に引っ張ったときは引力を発生させるけど、逆に圧縮されたときは反発しない。あと一定以上に強く引っ張られたらへたって引力が弱くなる。あー、でも一度へたってしまっても、しばらく近づけておいておくとだんだん元に戻って欲しいなぁ。その方が気持ちいいはず。

InvocationTargetExceptionはタイミングの問題で発生するようだ。 InvocationTargetException (Java 2 プラットフォーム SE v1.4.0) ラップされた例外だそうなので、中身を表示させる。

ああ、boundか…。 現状では頂点を作成したときにboundはnullになっていて、 renderが呼ばれた場合にboundがnullなら再計算する仕組みになっています。 これはboundの計算にグラフィックコンテキストが必要だからです。で、タイミングの問題で、普段は十分に描画が早いためにaddVertexとgetParamsの間にrenderの呼び出しが入るためにboundがnullではなくなるのですが、早いプログラムで一気に頂点を足した場合に稀にrenderが呼ばれる前にgetParamsが呼ばれてしまい、nullをVectorに変換しようとしてNullPointerExceptionを投げているわけです。さて、どうしましょうか。

  • boundをnullではない値で初期化する。[-1, -1]とか。
  • 変換メソッドの中で返すべき値がnullの場合に代わりに何か返す。
    • ユーザが「失敗したこと」に気づかずにその値を使って、正だと思っていた値が負だったりして面倒なバグを引き起こしそう。
  • NullPointerExceptionを投げる。XML-RPCのクエリを投げた側はその例外を受け取ってうまく行かなかったことを知る。
    • java.lang.NullPointerException
      	at org.nishiohirokazu.grinEdit.UtilCast.point2Vector(UtilCast.java:150)
      	at org.nishiohirokazu.graph.BoxVertex.getParams(BoxVertex.java:62)
      
      と言われて、Javaのソースを見ないと原因がわからない。
  • っていうか今positionの値が必要なだけなのに全部のパラメータをまとめて返してくるAPIが悪いんじゃない?
    • まぁ、今フィールドの数だけsetterがあるのに、さらにgetterも作ることになるけど…まぁ、これはやるべきことかも。
      • 面倒だからsetter/getter生成スクリプトをPythonで書く。
    • これをやっても、やっぱりboundの値をユーザが取得しようとして失敗する可能性は残っているから今回の問題の本質的な解決にはなってない。
    • 明日デモするプログラムにそんな広い範囲の修正は掛けたくない。
      • とりあえず今日はboundの値を返すコードだけコメントアウトでいいんじゃない?セーブ/ロード時にboundの値が欠けるけど、欠けたら自動的に再計算されるわけだし。

座標をデフォルトの値に戻すコマンドが欲しいかも。

たかだか300頂点で15FPSまで落ちてしまうことがある。長い紐状のグラフがぐるぐる巻きの状態になってしまったときに、外側の頂点の拡散を辺の引っ張る力が邪魔をするために、頂点が密集した負荷の高い状態が持続してしまう現象。

デフォルトの物理演算は、イヤならはがせるわけだから、機能てんこ盛り路線でいいのかも。それなら「反発力がなかなか減らないときには拡散を加速する」という物理法則を入れる手がある。

log

GRINEditの過去のログを読んでダイジェスト版を作ろうと思ったのですが、想像以上に一杯でうまく整理できていません。

プラグインのON/OFF、「プラグインを入れるときに読み込むプラグインを設定に書き加える」という選択肢は「解凍してフォルダーにコピーするだけで!」と言えなくなるのでイヤだったのだけど、発想を転換すれば両方出来ることに気がつきました。つまり「無視するプラグイン」という設定ファイルを作るのです。コピーした時点でデフォルトONで、もし一時的にOFFしたければ無視するプラグインファイルに書き足せばいい。

書き殴り文章、箇条書き、きちんとした文章、高橋メソッドのプレゼン、箇条書きのプレゼン、箇条書き風のマインドマップ、グラフ上のマインドマップ(ブレインダンプ?)、などなどを、相互に変換できるといいなぁ。

文章で書き殴っているときと箇条書きで書き殴っているときとあるけど、 本当はグラフで書き殴りたい。

JavaのリフレクションでメソッドにくっついているJavadocコメント取れるかな。取れそうな気がする。取れるんだったらJavadocに頼らないでももっと楽しいことが出来るよね。

無理っぽいなぁ。残念。Javadocはソースコードをパースしているんだろうか。例えばhogeというメソッドの説明はHashtable docHogeに{"ja": "日本語の説明", "en": "English description"}なんて感じで入れる、なんてのはJavaで書くのは面倒だよねぇ…。Javaで文字列の中で改行したらどうなるんだっけ。あー、Eclipseが勝手に+で繋いでくれる。ふむふむString docHoge = "@ja: 日本語の説明 @en: English description";ならOKだろうか。

文章での殴り書きは、後から読み直して「いや、それは違うだろう」とつっこんでキャンセルしやすい。箇条書きにしてしまうと理由なしにしなければ行けないことに見えてしまってキャンセルしにくい。そういう問題点。

箇条書きにする際に、やることだけを書くのではなく「なぜそれをやる必要があると思ったか」を書けば済む話?

西尾泰和のブログ: TODO がすごいことになってしまった。把握できない。

CPANのようなライブラリを作って、GRINEditプラグインを登録・検索できるようにしよう、と考えて、じゃぁドキュメントもプラグインから自動生成して検索対象にしたらいいんじゃないかと気がついた。

はっ、レンダリングの順番の問題、今はまず辺を書いてから頂点を書く、という決めうちだけど、ここがカスタマイズできれば全て解決するのではないか。XML-RPCで。グループごとにZオーダーを指定できればいろいろな問題が全て解決するのでは。 そうするとアンカーされた頂点にピン留めマークをつけるってのも、頂点クラスをいじるのではなく、アンカー物理演算に頂点より前でアンカーしている座標にピンの絵を描けばいいだけ。おー、シンプル。美しい。これが正解に違いない!

でも一応、今のバージョンを上書きするのではなく共存できるようにするためには…。 いまメインループ内でgraph.renderを呼んでいるのを、レンダリングエンジンオブジェクトのrenderを呼ぶようにして、Graph#renderをそっちに移して、CommonGatewayからそれを変更できるようにして、init.pyからそれを設定するようにすればOKかな。

今気づいたけど、makeTableとかvertexDictとか、名前に混乱が見られる。実態はHashtableだけど、抽象的にはMap。

UtilXMLRPC#makeObjForNameがMediatorに移ればいいのでは。移した。

間違い。 SubversionでRevert。右クリックして選ぶだけ。やりなおしも超簡単。

正しくは、UtilXMLRPC#makeObjForNameがMediatorに移動するのではなく、文字列からクラスオブジェクトを返す処理だけをMediatorに移すのだ。 名前はloadClassでいいかなー。

もう28時だ。エンバグしそうなので寝よう。

日記

Could It Be A Big World After All?。抄訳&意訳なので正確を期す人は原文を読んでください。

Stanley Milgramの実験によって証明された「「知り合いの知り合いの…」とたった6回繰り返すだけですべての人がつながる」という理論は教養のある人の間ではもはや常識になっている。しかし、Milgramの論文とかをよく読んでみると、この理論は根拠に乏しく、それどころか例の実験結果はむしろ「我々の生きている社会は人種や階層の違いといった社会的な壁によって区切られている」ということを示唆している。

ちょっ、w。

続き:

この論文で私は、「我々はたかだか6回知人をたどるだけでつながりあう『小さな世界』に住んでいる」という愉快な考えは、もしかすると学術的にはただの都市伝説かもしれない、と主張する。要点は下記
  • Milgramの「小さな世界」に関する出版物は、他の研究者によって追試がされていない。さらに、私がエール大学の図書館から見つけたMilgramの論文に載っている、出版されていない「最初のSmallWolrd実験」は「人々は6回でつながる」という有名な解釈の根拠としては不十分である。一言で言えば、一つの市に収まらないような実験は、ほとんど鎖が完成していない。
  • 「人々は6回でつながる」という考えの驚くべき受け入れられ具合は、それ自身心理学者にとって興味深い現象である。なぜこのような直感に反する発見がこうもたやすく受け入れられるのか。そして、このことは我々の理性がどうやって働くのかについて何を教えてくれるのだろうか。
  • 数学をはじめ、病気の流行から神経科学まで広い分野で"small world problem"が見直されている。 この引き金を引いたのはsmall worldの概念に数学的な基礎付けを提案したWatts & StrogatzのNature論文である。 学術およびメディアの関心は高まっているが、"small world problem"はすでに心理学の分野に落ちている。つまり、数学者が無視するような、認知や感情の問題を扱う分野だ。

個人的には、一時期この思想は面白いと思って色々シミュレーションもしてみたんですけど、色々よくわからない所があったのでほりだしてしまいました。まず平均パス長がなぜか加算平均を使っているので、グラフが連結していないとそもそも平均パス長を求められない点が謎。なんで調和平均を使わないのか。あと、非連結だと平均パス長が求められないから、とか言って連結なグラフだけ取り出したらすでにランダムグラフじゃないじゃないか、とか。そもそもそのランダムグラフの作り方だと同型なグラフを何度も数えていて、グラフの形によって重複して数えられる回数が異なるから平均が偏るじゃん、とか。そもそも「多くのグラフにSmallWorld性があって、ランダムグラフとレギュラーグラフにはない」のじゃなくて「ランダムグラフとレギュラーグラフには逆の特徴があり、そのほかのグラフはその間にある」ってだけじゃないのか、とか、ランダムグラフが離散距離空間上の点の分布に距離に応じた確率で辺を張った物と考えて、もっと一般的な距離空間上でSmallWorld性が出るか出ないか見るべきじゃないか、とか、そもそもSmallWorld性の有無はどうやって定量的に評価するんだ?とか色々考えたのですよ。ちなみに、上に書いたようなことはきちんと勉強してない一介の学生が隅っこでぼやいていただけのことなのでまじめに研究している人の成果を否定する物ではありません。

やはり有る物を否定する作業は嫌がる人が多く喜ぶ人は少ないので楽しくない。ない物を作り出す方がみんな喜んでくれるからやりがいがもてる。人生の時間は限られているので幸せな方をやりたいなぁ、と思ったわけです。それが僕がSmallWorld性の研究を進めなかった理由。


__ 眠い。

How to make Python OnelinerとかBrainf*ck Interpreter in Python OnelinerとかKEMURIとか英語の記事を書くべきですよね。 広報上。上みたいな適当な和訳している場合じゃないですよね。


__ 今日、たまたま笠井正博 - Google イメージ検索という人の作品を見たのだけど、なんかこういうのいいね。どうやったらコンピュータで自動生成できるか考えてしまう(ぉ)

実は冗談ではなくて、本気です。

そうか、インタラクティブ性がなかったのがいけないんだ。単純なランダムではなく、物理法則に従った規則性があり、かつ規則だけではない揺らぎがある、というところまではインタラクティブ性がなくても可能だけども、そこにインタラクティブ性が入ることで「ゆらぎ+規則性+人間の意図」という三位一体の攻撃が出来るわけですな。やった。これGRINEditで(ぇ)

GRINEditの今は白に固定されている背景色を変えられるようにして、 半透明頂点を実装して、合成が加算になるようにすればいいんだよね。(本気)

Java 2D による半透明描画

出来そう。

Pythonで指定したディレクトリの中を再帰的にdiff

Pythonで、指定した二つのフォルダの中身を全部比較して変更されたところを表示するスクリプトを書いてみましたが、diffに-rというずばりそういうことをするためのオプションがありましたorz

とりあえず、なんかの参考になるかも知れないので載せておきます。あと、これは「新しいプロジェクト」ディレクトリ内になくて「古いプロジェクト」ディレクトリ内にあるファイルは無視します。僕はそれでよかったので。diff -rの挙動がどうなのかは調べていません。

#
# diff between old project and new project
#

import difflib, os, sys
diff = difflib.Differ()

OLD_PATH = r"C:\Home\workspace\rel-visualizer\GRINEditAlpha\src" 
NEW_PATH = r"C:\Home\workspace\grinedit-app\src\main\java"

def getNewPath(path):
    return os.path.join(NEW_PATH, path)

def getOldPath(path):
    return os.path.join(OLD_PATH, path)

for (root, dirs, files) in os.walk(NEW_PATH):
    p = root[len(NEW_PATH)+1:]
    for filename in files:
        path = os.path.join(p, filename)

        data = os.popen(r"c:\cygwin\bin\diff %s %s" % (
            getOldPath(path),
            getNewPath(path))).read()

        if data != "":
            print path        
            print data

2006年09月23日

日記

もやもやして仕事がはかどらない日。

いつものことだとか言わないで!


__ 「リモートリポジトリにないJarをローカルリポジトリに入れる方法」という文章は「りもTABにないJarをろーTABに入れる方法」と書ける。ATOKの補完機能で。ATOKユーザがなでしこでプログラムを書くと変数とか補完できてうれしいのかも知れない。というか僕も試しにPythonのコードをATOKオンで書いてみるか…ダメだ、インデントするのにTAB使ってるからどっちかのキーアサインを変えないと。


__ 不安に負けそう。


__ 僕なんかに出来るのかなぁ、という不安がふくらむ一方。

力を尽くして狭き門より入れ>自分


__ 6.2 os.path -- 共通のパス名操作

パスがシンボリックリンクを含んでいるかによって意味が変わることに注意してください。

11.1 os.path -- Common pathname manipulations

It should be understood that this may change the meaning of the path if it contains symbolic links!

「パスがシンボリックリンクを含んでいる場合には、この操作によってパスの意味が変わってしまうかも知れないということに注意してください。」 ですかな。 もっと言えば 「パスがシンボリックリンクを含んでいる場合には、この操作によってパスの意味が変わりうるということを理解して使うべきです。」なんだけど、日本語としてはあんまりそういう激しい言い方はしないかな、と。


__ ブラウザ上で、本文の左や右にメニューが入っているせいで本文の幅が短くてディスプレイを有効活用できていないページをワンクリックで全画面表示にしたい。さらにワンボタンできれいに1ページずつめくりたい。さらに、同じ体裁でいくつものページに分かれていたらそれも全画面表示したい。

bookmark this

JavaWorld Online - J2SE 5.0の新機能 ――第4回 Javaのprintfとかで試してみてください。あー。marginが設定されていると、marginの分だけはみ出すのか…。あとこのブログみたいに背景色が濃い場合は背景と文字とのコントラストが低くて読みにくい。背景は薄緑固定でもいいのかなぁ。