« 2007年01月 | メイン | 2007年03月 »

2007年02月28日

ラーメンズ日記

プレゼン画面のキャプチャー動画、 よく考えてみると「普段は直前のフレームと同じ画像」なのだから、 もっと圧縮効率がよくてもおかしくないのになぁ。

で、突き詰めて考えていくと、 変化した時の差分とそのタイミングだけ記録しておけばいいと言うことに。 おっと、それってPowerPointでクリックのタイミングを記録すればいいだけじゃないか。

もちろんそれでは生デモとかに対応できない。


= うわーん。 通帳の銀行印の上にシールが貼ってあって、どれが銀行印かわかんないよー。
= 名古屋で日記など

「全文引用しない」というルールは 「スレッドを切るな(スレッドを意識しろ)」というルールとセットだと思う。 スレッドがつながっていなければ 前のメールの内容が何だったかわからなくなってしまうから。

で、「全文引用をする」というルールが力を持ってきたのは、 GMailが引用文を折りたたんでくれるからではなくて、 「メールのスレッド?は?なにそれ?」 という人が増えたからだと思う。

「メールのスレッド」がわからない人相手にメールを送る際には、 全文を引用してつけた方が親切。 そしてそういう人はb-mobileを使ったりしない (たいがい会社の自分の席でメールを読む) ので全文引用されることにデメリットがない。

以上、事務とのメールのやりとりの途中で、 あまりに長くなった末尾の全文引用を削除して 「一件が終わるまでは勝手に引用を削らないでください!」 と怒られた経験から推測。 彼らにとって「全文引用して返しているメールの引用を 削って返信する」という行為は、 かつてのメーリングリストなどで 「スレッドをぶちぶち切って返信する」 のに等しい行為なのだろう。


= Jython。 挙動を観察した結果
JythonはJavaのオブジェクトoに対して「o.foo = 1」という 書き込みアクセスをしているのにpublicなフィールドfooが見つからない場合には、 publicなsetFooというメソッドがあるかを探します。
という結論に至ったのだけど、 ソースのどこに記述してあるのかよくわからない。

で、探し回っていたのだけど、 冷静に考えるとこんなことをやっていたのではいつまでたっても完成しない。

「JythonはJavaのオブジェクトoに対して「o.foo = 1」という 書き込みアクセスをしているのにpublicなフィールドfooが見つからない場合には、 publicなsetFooというメソッドがあるかを探しているように思えます。」 と正直に書くのか 「JythonはJavaのオブジェクトoに対して「o.foo = 1」という 書き込みアクセスをしているのにpublicなフィールドfooが見つからない場合には、 publicなsetFooというメソッドがあるかを探します。」 と書くのか、 どうすべきなんだろうか。

ちなみにsetFooが引数を取らない場合は「AttributeError: read-only attr: foo」となる。 あとfooという名前のメソッドがあったりするとさらにややこしいことが起きる。

うーむ。少なくとも、 このいろいろな挙動をHello, worldの章で解説するのはよくない。 文章を書く心がけの 「全部を説明しなくてもいいのだ。説明が理解を妨げる場合だってある。くどすぎる説明が重要点をぼかしてしまうからだ。」に該当する。

とりあえず簡単な説明をして「細かいことは付録に」ってやろう。

ああっ、あったあった。 PyJavaClassの551行目だ。 そうか、インスタンスの属性にアクセスしたときにリフレクションで動的に探すのではなくて、 Javaのクラスのラッパーを作る際に解決しておくのか。 確かにJavaのクラスは動的に変化しないからそうする方がいいな。 なるほど。

そしてソースを読んでみると、返り値がbooleanの場合限定で、 getFooじゃなくてisFooでもgetterと見なしていることが判明。 さぁて、どう書こう。

やっぱりおおざっぱに書いておいて、詳細は書くとしたら付録かなぁ。 付録がどんどんふくれていっている罠。


= 思い切って消してみた。 いやまて、消す前にコミットしよう(ぉ)
= Python Developer CampについてLingrで。 Lingrで遊ぼうかなぁ。

YouTube動画埋め込みって。 動画の内容についてコメントするとどんどん流れていってしまうぞw。


= しまった。 もう28時だ。 LingrのYouTube埋め込みで思い出して、 以前作ったYouTubeダウンロードスクリプトを動くように直して、 シーク・拡大・プレイリストでの連続再生ができるFLVPってプレイヤーを入れて、 YouTubeに上がっているラーメンズの動画ばっかり連続再生できるようにしてみた。 後はこれをテレビ用マシンに入れるだけ。

2007年02月27日

ちまちま執筆日記

Matzにっき(2007-02-19) によれば、 PLoS(Principle of Least Surprise, 驚き最小の原則)に言及すると減点らしいです。 盛んにPLoSを喧伝していた頃のRubyも、けっこう驚きが多くて、 フィーリングが一致しないユーザーからは 「俺様のフィーリング最優先の原則」とか言われていたようですけど。 そういうPLoSを捨てるというのは好ましい方向の変化なのかも知れませんね。

驚き最小の原則 - Wikipedia


= Google Groupのページ作成機能を使っていて、 preに枠が付かないのが嫌なので何とかできないか試してみたんだけど、 linkタグは削除されるし、Java Scriptも無効化されるし、 なんとかならないもんかなぁ。
= 眠いのに眠れない29時。 やっぱり眠いのに眠れないのは昼間の運動不足がいけないんだろうか。 いや、確実にソレも原因の一つなんだろうけどねぇ。
= 朝。 とりあえず新居のお金を振り込まないといけないから出かけるか…。

ああ、そうだ、洗濯してたんだった。 干してから出かけないと。

新居はレオパレスじゃないから洗濯機も買わないといけないんだなぁ。 面倒だなぁ。


= asahi.com:リスニング試験機器、ソニー製開示を答申 関係者は既知  - 社会
答申は、ICプレーヤーにロゴマークが標記されていたことや、プレーヤーに装着されたメモリー媒体を開発したメーカーが国内に1社しかないことなどを指摘。「約50万人の受験生や受験関係者にとっては、既に知っている、あるいは容易に知ることができるもの」だと判断し、メーカー名が開示されても、センター試験で不正を起こすことが容易になるわけではない、とした。

センター試験のリスニング機器なんて、 うまく動いたら当たり前だといわれ、 うまく動かなかったら針小棒大に取り上げられ、 少しでもノイズがあったら自分のヒアリング能力を棚に上げた受験者に 「ノイズのせいで聞き取れなかった」 とバッシングされるであろうことは十分予想できたはず。 効果的に自社ブランドをおとしめてるねぇ。

なんかケチが付き通しで人ごとながら心配になる。


= Emacsで正規表現で置換する方法を調べた。 M-x query-replace-regexpってやる。 \tがタブの意味にならないので、C-q TABする。 SPCで「置換」、DELで「置換せずに次の候補へ」、ENTERで「終了」になる。
= 最新Pythonエクスプローラ~Django,TurboGears,Twisted,IronPython 完全攻略|gihyo.jp

3月2日店頭発売の予定だそうです。 僕が書いた原稿が店頭に並ぶ初のケースになります。 「8ページでPythonの学術系ライブラリを紹介する」というお題だったのですが、 あんな感じになりました(どんな感じだ)。 厳しめの意見を頂ければ今後の糧にしたいと思います。


= 逃避エネルギーを発揮して、 色々教えてもらいながらデスクトップのブロードキャスト配信を試す。 Windows Media Encoderを使ったのだけど、 Windowsのサーバーがないと使えないからなぁ。 あとせっかく動画を保存しても、YouTubeやGoogleVideoにアップすると 高周波成分を落とされるせいで読めないスライドになってしまう。 プレゼン画面のキャプチャなんかだと同じ色の領域がたくさんあるわけだから、 それを利用した圧縮をすると小さくなりそうなのに。
= フンデルトヴァッサー展|日本橋三越本店

2007年02月24日

GRINEditを使ってソースコードの可視化

控えめな Brainfuck コードを色づけする GM < 04 < September < 2006 < nulog, NULL::something : out of the headphoneを見て、唐突に思いついたので作ってみました。

可視化する対象のコードは、 竹迫さんのTAKESAKO @ Yet another Cybozu Labs: Brainf*ckで100までの素数を列挙してみるテストと、奥さんのKazuho@Cybozu Labs: brainf*ck でマジメに素数探索

まず、竹迫さんのコードの全体像。

そして一部拡大した物がこれ。 各頂点が1つの命令で、太い辺が命令の隣接関係、 細い辺が括弧の対応関係です。+が赤、-が青、.が緑になっています。

竹迫さんのコードは実は数字を作って表示するだけのコードなので、 大局的な構造がありません。 大まかに見ると「小さなループが所々にある1本の紐」です。 可視化する際も、頂点を徐々にy座標を増やしながら作るだけでこんな風に ほとんどもつれずに表示されました。

いっぽう奥さんのコードはこんな感じ。

ぱっとみで、竹迫さんのコードより緑の頂点が少ないことに気づきます。

一部拡大。

括弧のネストがあるために、複雑な構造をしています。

少し引っ張って見たのがこちら。 赤い頂点(+)が、かなり局在していることがわかります。

赤丸で囲んだ部分を拡大したのが次の図。

実はこの部分にしか緑の頂点がありません。 つまりこの固まりが「表示ルーチン」に相当する物だと考えられます。


= コードはPythonでXML-RPCを使って個々の頂点を投げる物で、 コード中に直接貼り付けたBrainf*ckのコードを除けば 50行程度。 GRINEditの次のリリースの時にでもサンプルの中に入れます。

思ったこと。 反発力を使った整形は、 こういう「長いヒモ」状の構造を整形するのにはあまりむいていません。 また、かりに十分時間をかけて整形させたとして、竹迫さんのコードのうねうね曲がっているヒモが、 一直線に伸びたら、それは本当に見やすい可視化なのだろうか?と言われると多少疑問です。 適切に折りたたまれている方が見やすいです。

竹迫さんのコードを適切に折りたたんで可視化するのは難しくないですね。 例えば20個おきの頂点に「左右に引っ張る力」を足してやれば、自然と折りたたまれるはずです。

問題は奥さんのコードの方です。 大局的な構造があるために、竹迫さんのコードを可視化する際に使った 「頂点の初期位置を順番にずらす」という方法ではきれいになりません。 かといって今の手動整形では頂点の移動しかできないので、つまんで引っ張っても 「隣の頂点が半分くらいの速度で付いてくる+ その隣の頂点がさらに半分の速度で付いてくる+ その隣の頂点がさらに半分の速度で付いてくる…」 となって、いまいちです。

これは今まで考えなかったわけではないのですけど、 いい「整形しづらさを感じるグラフ」が手元になかったので対策していませんでした。 これに対処する方法は、一つは前処理です。 ある種の性質を持っているグラフには、 見やすく表示することができる「静的なレイアウト」があります。 例えば今回の場合は平面グラフなので、 辺が交叉しないように平面に埋め込むアルゴリズムがあります。 実はそういう静的な処理を動的な整形の前に挟む機能がすでにGRINEditに実装されています。 今は「非連結グラフを連結成分ごとにばらして配置する」っていうシンプルな物だけですけども、 「平面グラフを交叉しないように埋め込む」っていう前処理は汎用性も高いので 用意しておくのもいいですね。

もう一つは、よりリッチな動的整形手法を作ること。 こちらの方がどちらかというと萌えます。 例えば頂点でマウスダウンした際に、 その頂点が紐の一部であることの判定や、 紐を構成する頂点を取得することは難しくありません。 そこで紐をドラッグ中だけ一時的に剛体化してしまうこともできます。 使い勝手は実装して試してみないとわかりませんが。

他のアイデア: 辺の間に角度バネをつけると、 反発力が届きにくいような長い構造でもきれいに伸びる、かも。 紐状の部分を一時的に1つの頂点に置き換えてしまう。 ソースコードのフォールディングみたいな感じ。 必要なときにダブルクリックすれば元通りに展開されるとか。 n本の辺からなるパスを自然長nの辺で置き換えてみると、 すばやく大局的な整形が行われる、かも。

Non-coding RNAs: Transfer-RNA (tRNA)

原稿書き日記

原稿が進まないのは、 全部の章を並行して書いているからかも知れない。 とりあえずノリと流れで前から順番に埋めていって、 後から読み直す方がいいのかも知れない。

TODOリストに複数のTODOが入っているときに、 どれから最初に着手するかの決定に時間をかけすぎてしまうケース。 普通のTODOでも、タスク同士が絡み合っていて 「タスクAをやってからタスクBをやると楽そう。 タスクBをやってからタスクAをやったほうがいいかも…」 なんて悩んでしまう。

作業を効率化しようとするために陥る罠。

優先度の判定として妥当な時間をかけても、 どちらを先にすべきか判断が付かないと言うことは、 今の僕の知識や力量では判断できないということだ。 だから考えてないで、どっちからでもいいから始めてしまうべき。 どちらから始めるか決心が付かないのならソートして前に来る方。 アイウエオ順でも章番号順でも。


= トリテク経由、 OLPC, Python...。 OLPCってGUIとかがPythonで作られてるんだそうな。 それがbestな解かどうかは少々疑問だけど、 まぁreasonableではあったのかも。
= おびなたのはてな日記 - ダーツ。 「投擲精度によって、狙うべき場所が変わる」ってのには同意。 たとえばゆらぎがすごく小さい場合は20のトリプルを狙うのが一番いいけども、 揺らぎがボードくらいのサイズである場合は 「ボードの上に外れて0点になるリスク」が大きいので、 なるべくはずれないように中心を狙った方がいい。

精度の向上に対して得点の期待値が単調増加かどうか、 という疑問には即答はできない。

で前話したときは 「モンテカルロシミュレーションしないとわからない」という結論だったわけだけど、 もっといい方法があるかも。 「狙った点から正規分布でランダムにある程度ずれた点に刺さって、 そこの点数が入る、それを集計する」ってのは、 ゆらぎを表現する正規分布が狙った位置にかかわらず一定なわけだから、 ただのたたみ込み積分なんじゃないかと。

でもって値域が2次元。 これって、画像処理の分野の言葉で言えば 「画像に対してガウシアンぼかしをかける」 じゃないかと。 つまり、256階調グレースケールの画像を用意して、 20のトリプルが240、1点の領域が4、番外は0、という得点に比例した色の塗り方をしておいて、 それをいろいろな半径でぼかしたときに一番値の高いピクセルはどれか、 またそのピクセルの値はいくらか、 って問題と同じなんじゃないかと。

ライブドアに入りました。

そして出てきました。

あとで書く。


= ライブドアに入る前はサイボウズラボにいました。 CNET Japan Blog - 江島健太郎 / Kenn's Clairvoyance:Lingr and Comet - 技術解説編

Kazuho@Cybozu Labs: Comet の正しい使い方

スケールアウトとは 【scale out】 - 意味・解説 : IT用語辞典 e-Words

FrontPage - FreeStyleWiki

oberhumer.com: LZO real-time data compression library。 しかしLZOというネーミングはLZ0と紛らわしい。

すごく速いらしい。辞書式なので圧縮を使ったクラスタリングにも使えるだろう。


= P1060936
P1060936

(R)まで作ってある。もしかして勝手に撮影して公開すると登録商標の不正使用になる?

MFPM (My Favorite Perl Modules)

中略メソッドという物があるらしい。

Boofyが最も(中略)なフレームワーク。

柔軟性と拡張性が大事。 拡張性も柔軟性の一部かも知れない。 どの部分が柔軟か。

プラグインを受け入れることができるような拡張性が必要なわけか…。

Wikipediaは意外な記事が意外なほど詳細。

Senna 組み込み型全文検索エンジン - Senna 組み込み型全文検索エンジン

あとオフレコとかオフレコとかオフレコとか。

総武線の最終電車が酷かった。 アスパラガスでももうちょっとやさしく運ばれている。 揉んじゃダメだよ。傷むから。


= そうそう、 アークヒルズ - Wikipedia六本木ヒルズ - Wikipedia とは別物だそうだ。知らなかった(ぉ) 六本木ヒルズのあのクモの化け物みたいなオブジェは「ママン」と言うらしい…。

2007年02月23日

起きられなかった日記

目覚ましをかけ忘れたのか、起きたら15時。 うむむ。 普段ならたとえ朝の6時に寝たとしても、 8時間後の14時には目が覚めるのに。 誤差プラスマイナス1時間くらいで8時間睡眠なのに。 うむむ。 4時には寝たはずなのに…。
= 英語漬け、英語レベルE。orz。 how machとかthenk youとか、活字で見ると間違っているのがわかるのに、 手で書くと間違えて書いてしまう。
= 西尾泰和のブログ: 言語融合の時代 をプレゼン資料にまとめると、話の筋道もまとまる。 PythonDeveloper'sCampの資料も作らないといけないんだけど、まだまだ。

言語融合の時代のスライドだけで27時になっちゃった。寝よう。

あっ、手帳手帳。スケジュール確認。 メール見ただけでスルーしたら忘れてしまう。 26~28日の間で引っ越し先の契約。 それまでに代金の振り込み。 2~4がPythonDeveloper'sCamp。 CampまでにJythonの説明がある程度の形になってるといいなぁ。 そしたら興味のある人には読んでもらえるしなぁ。 Campまでにプレゼン資料も作らないといけない、と。 あと事務から今年度の予算をさっさと使い切れという催促が。 39,370円。何を買ったらいいでしょうか。

2007年02月22日

PythonでRubyっぽいmap

思いつきでやった。
>>> Array([1, 2, 3, 4, 5])
[1, 2, 3, 4, 5]
>>> _.map("""|x|
	if x % 2 == 0:
		return x / 2
	else:
		return x * 3 + 1""")
[4, 1, 10, 2, 16]

種明かしは下記

>>> class Array(list):
	def map(self, code):
		import re
		m = re.match("\|(.*?)\|(.*)", code, re.DOTALL)
		d = {}
		exec("def foo(%s):\n%s" % m.groups(), d)
		return map(d["foo"], self)

2007年02月21日

脱ひきこもり野菜日記

ピーマンとほうれん草を買ってきた。

野菜を食べないから元気がなくなったのか、 元気がなかったから食生活が乱れたのか、 どっちだろう。 どっちにしてもポジティブフィードバック。


= 教育用プログラミング言語ワークショップ2007 -ワープロ07- - 情報処理学会 初等中等情報教育委員会

面白そうではあるし、 一昨年の夏のプロシンで発表したNarVisualizerを発表する手もあるけども、 発表するならGRINEditの上に移植したいしなぁ。 うーん。 やっぱり今回はスルーするべきだなぁ。 さっさと本の原稿を完成させないと。


= (財)日本鯨類研究所からいくつか引用。

(リストから一部抜粋)
2007.2.09 日新丸のすぐ脇に接近したシーシェパード船「ロバート・ハンター号」から発煙弾などが投げ込まれる(Part.2)
2007.2.09 シーシェパード船「ロバート・ハンター号」が日新丸のプロペラを破壊しようと、船の前でロープを投げ込む
2007.2.12 シーシェパード船「ロバート・ハンター号」から放たれたゾディアック・ボートが目視専門船海幸丸のプロペラを破壊しようと、船の前で網を投げ込む映像(Part.1)
2007.2.12 シーシェパード船「ロバート・ハンター号」が目視専門船海幸丸に衝突する(Part.1)
鯨類捕獲調査に対する不法なハラスメント及びテロリズム

2月15日未明に南極海で発生した鯨類捕獲調査母船日新丸の火災で、乗組員避難時に行方不明となっていた共同船舶(株)の牧田和孝製造員(27才)が、本日日本時間05:20に、火災現場を捜索していた乗組員により遺体で発見されました。
行方不明者の発見について

ちなみに直接的な因果関係はあるのかどうかは不明です。

グリーンピース及びシーシェパードは、互いに連携して、我が国が国際捕鯨取締条約に基づき実施している鯨類捕獲調査に対し、執拗な妨害活動を繰り返しています。
 このような行為は、決して平和的行動などではなく、断じて許すことの出来ない危険なテロ行為です。
 我々は両団体に対し、今後一切このようなテロ活動をしないように強く抗議しています。この抗議に賛同する方は、以下のリンクにて抗議書にご署名をお願いします。
日本の鯨類捕獲調査を妨害するグリーンピース及びシーシェパードに対する抗議書-署名のお願い
= アルゴリズムが生む表現。 面白そう。どこのカリキュラムだろう。武蔵野美術大学か。

2005年度シラバス案。 他の授業も面白そう。

美大ってこういうことをやっているのかー。

ATOKは武蔵美を一発で変換してくれてびっくりしました。 ムササビ。ムササビは変換しないのか…。 あー、候補にはあって、機種依存文字マークが付いている…。 親切だなぁ、ATOK。

野菜引きこもり日記

キッチン用漂白剤を使えば野菜クズなどのぬめりもつけておくだけでなくなる。 それじゃ食器なんか洗わなくてもいいのではないか、と思って試してみました。 食べた後しばらく放置して乾燥したお皿を漂白剤につける。 結論から言うと、ご飯粒やお皿にへばりついていた野菜はきれいに取れます。 真っ白なお皿になって、一見きれいになったように見えます。 触ってみると「うわー、あぶらー」。 脂質は分解されないらしい。

最近ひきこもりぎみです。 軽いデプレッションモード。

うつ病 - Wikipedia によれば、体を動かさないことはリスクファクターの一つなんだそうな。 やっぱ運動しないといけないんだなぁ。 たぷたぷ

野菜をほとんど摂取していないことに気がついたので、 今日はバーミヤンで野菜を多めに摂取してきました。 冷蔵庫にオクラはあるんだけどな。

はっ。 最近毎日のように夜中にコンビニに出かけて大福とおかきを買ってきたり、 十分寝ているはずなのに眠かったりするのは、 あからさまに冬季うつ病の症状じゃないか!なんで今まで気づかなかったんだ! 冬季うつ病には光療法が効果的。とにかく日中に光を浴びない生活を改善しないと!

今晩はドリエルを飲んで早めに寝て、 明日早く起きて日中に光をたくさん浴びよう。そうしよう。


= とりあえず確定申告で検索してみて、3月15日までだと言うことを確認。
= 人力検索はてな - 有能なプログラマが嗜んでいる言語・技法・テクニックとは何ですか? この場合の、"有能なプログラマ"の定義については以下のURLをご覧ください。 http://d.hatena.ne.jp/f..

興味深い。細々した解答はさておき 「生産性の高いプログラマは「生産性を上げる事」そのものに無上の喜びを見いだしてる」とか 「道具をブラックボックスとして使うのではなく、  中の挙動を理解して使う」とか。


= 確定申告よくわからない。 大体、学振ポスドクという立場が意味不明。 学術振興会からは「雇用関係はない」と言われているし、 かといってもらっているお金は源泉徴収されている。 源泉徴収 - Wikipedia。 はっ、そうか。「所得税が源泉徴収されている」ってのは 別にその所得が給与所得かどうかとは無関係か。 雑所得として源泉徴収されてるのかも知れないな。 っていうかどういう徴収のされ方をしているのかってどうやったらわかるんだろう。 謎。

源泉徴収票ってのをもらっているはずだそうな。 確かにアントラッドからはもらってた。 0って書いてあるだけの紙切れを何に使うのかわからなかったのでとりあえずファイルしてあった。 これが源泉徴収に役に立つのかー。 学術振興会の方は手元にはないけど、順当に考えると実家の方に届いているんだろうな。 学校側に届いているのなら何か言ってくるだろうし。

「学術振興会 源泉徴収票」で検索。 「JSPSは外国人研究者と雇用関係を結んでいないので、源泉徴収票の発行はできません。」 ポスドク研究員とも雇用関係は結んでいないので、 充当に推理すると源泉徴収票はもらえないことになるなぁ。 源泉徴収票がもらえない場合はどうなるんだろう。 ややこしいなぁ。 書類キライ。

今までPh. D.って書いていたけどDoctor of Scienceだなぁ。

FAQ (in earning Ph.D at MEIP, Univ. of Tokyo, 2002)

学振から振り込まれる「研究奨励金」は,税法上は「給与収入」になります.だから,所得税が源泉徴収されていますし,確定申告する場合は,給与収入にカウントすることになります.

あー、船井若手奨励賞の賞金は雑所得になるのか。 これも申請が必要なんだろうか。ややこしいなぁ。 表彰は4月の予定なのかぁ。じゃぁ来年忘れずに申請しないといけないわけだな。

絶対忘れると思う。

うーむ、とりあえず学術振興会からの源泉徴収票は手元にはないなぁ。


= スラッシュドット ジャパン | 開発プロジェクトで使える(かもしれない)アニメの名台詞
  • 「謀ったなchar!!」(バグの原因がchar型だったときにどうぞ)
  • 「立ったぁ、フラグが立ったァ!」(ハイジ)
  • 「バグラッシュ‥‥‥僕もう疲れたよ。それに、なんだかとっても眠いんだ‥‥‥。」
  • ♪男には 自分の 世界がある ♪例えるなら 修羅場続く ひと月のデスマーチ~
    • やな世界だw
  • ナウシカ
    • 蟲達が居ない。なんだろう、胸がドキドキする。
    • 綺麗なコードと仕様では、バグが出ないとわかったの。汚れているのは、クライアントなんです。
    • だめよ!そんな品質でサービスに入ったら!!
    • 姫様の画面、青地に異国の文字が表示されているの。
面白おかしい。 天空のプログラマ 風の谷のプログラマ(ARCHIVE by CROSSBREED)
「バルス!」
Are you sure? (Y/N)
「リ-テ・ラトバリタ・ウルス・アリアロス・バル・ネトリ-ル 」
How many robots ?(0-15)
面白おかしい。

こんなのを読んでいる場合じゃない。


= 平成教育委員会DSを買ってしまった。 いろいろ不満が。 入力方法を勘違いしてわかっている算数問題が不正解になった上に 「よくわかる解説」をスキップする方法がない…。 理科の問題で体の断面図を出すのはいいけど、 脊椎は体の外に露出していないし、人間には肋骨があります。 おかげで算数も理科も0問なのが悔しすぎる。

あとBGMもSEもOFFにできない。 音自体はミュートにすればいいだけだからいいんだけど、 いちいち時間がかかるのが困りもの。 平方数の数列が一部穴あきになっているだけの問題に答えて、 いちいち「プレイヤー君の答え!」とか再生されて、 よくわかる解説まで出されると正直だるい。 タレントの間違えた答えとかも削りたい。 番組の雰囲気を再現したゲームが欲しかったのじゃなくて、 ああいう問題を次々と解きたいだけなのだが…。


= [Python-3000] Refactoring tool available (work in progress) via steps to phantasien t(2007-02-05) 。 Guido本人の書いたPythonリファクタリングツール。 これはよさそう。 プラグイン的に整形手法を追加することができる設計になっているらしいので、 空白の使い方を厳密化するエイプリルフールPEPにそうような変換とか、 ワンライナーへの変換とかができてしまいそうな気配。

2007年02月19日

豚丼がないのでDS liteを買いました日記

僕の主食は家の近くのすきやの豚丼なのですが、 なんだか牛丼祭りとか言って豚丼がメニューから外されてしまいました。 仕方がないのでこの前ランニング中に見つけたココイチに行ってきました。 帰りにゲームソフトとかCDとかを売っているお店の前を通りかかったら 「DS liteあります」と書いてありました。 普通に売っていました。 昨日の日記は訂正。 DS liteは普通に買えます。 ヨドバシアキバに行くのがいけなかったんだと思いました。 客の流量が多いから入荷時期を外すと売り切れになってしまう。 ドンキホーテとかGEOとかトイザらスがいいんだそうな。

漢字検定のソフトは2種類合ったので迷ったけど、 「200万人の漢検」の方が対応しているレベルが1級までと広かったのでそちらを購入、 「漢検DS」は2級まで。

さっそくプレイしてみたら2級まではクリアできたので、この判断は正しかったと思いたいが、 「200万人の漢検」は問題数が少ない…。1級問題が少ないだけなのか全部少ないのか。 「漢検DS」と比べてどうなのかは知らないが、とにかく少ない。 書き取り問題で、 7%未出題の状態から3問未出題の問題が出て未出題0%になった。 不正解率70%の状態から4問正解して不正解率が60%になった。 つまり問題数は40~42問くらいしかないと言うことだ。

あと字が小さい。 わからなかった漢字の解答が表示されても小さくて潰れていて辛い。 お年寄りには絶対勧められない。


= 確定申告のシーズンらしいのだけど、 僕は自分が申告すべきかどうかがよくわかっていません。 あー、そんなことを言ってだらだら先延ばしにしているうちに締めきられそうな雰囲気。
= おびなたくんとこ経由で 松本クリエイターズナイト
■プレゼン内容について
 
・まず、楽しいプレゼンであること!
・10枚、15枚、20枚のいずれかの枚数の静止画スライドショー
・1枚につき20秒で自動的に切り替わります(止められないし、やり直しも出来ません!)
これはなかなか面白いアプローチかも。
= 「東大脳」という言葉を聞いて、「ゲーム脳」のような悪い意味の言葉だと思ってしまった。 例えば「東大に入れば大手企業に入社できて 給料いっぱいもらえて人生順風満帆で幸せな人生を楽に送れると思ったのに… あれー、なんかうまくいかないぞ?なんでだろう?うまく行かないのは社会が悪いんだ!」 みたいな脳。
= 昨日作ったウダー録音ソフトは宇田君からのバグレポートを元に さりげに1.2までバージョンが上がっていたりします。
= お風呂に入って上がって、息抜きに「200万人の漢検」の続きをプレイしたら ラストの「準一級/一級」の検定をクリアしてしまったorz

正解率100%を目指すくらいしかすることがなくなってしまった。 とりあえずカバンに入れておいて、暇なときとかにやろう。

英語漬けも買おうかなぁ。

Amazon.co.jp: やわらかあたま塾: ゲームAmazon.co.jp: ELECTROPLANKTON エレクトロプランクトン: ゲームAmazon.co.jp: 英語が苦手な大人のDSトレーニング えいご漬け: ゲーム


= とりあえず次々ソフトを買うのはよくないので 「200万人の漢検」をコンプリートしてからにしよう。 コンプリートしたらエレクトロプランクトンと英語漬けを買おう。

ニンテンドーDS用の英語トレーニングソフト発売 - 語学のアルクと共同開発 (MYCOMジャーナル)

インターチャネル・ホロンはアルクと共同開発したニンテンドーDS用ソフト『アルクの10分間英語マスター 初級』『同 中級』『同上級』を2007年3月8日に同時発売する。価格はそれぞれ3,990円。35年以上に渡り英語教材を制作し続けているアルクだけに、ソフトの内容はかなり本格的だ。
これも買おう。

2007年02月18日

週末音楽日記-JythonでMIDIの録音

溺死寸前の万歩計を辛くも救出いたしました!(洗濯機から)

帝都高速度交通営団。珍走団っぽい名前。 http://www.tokyooooooooooo.net/。


= 明るいうちに買い物に出かけようかと思ったけど、 洗濯物を回したのでちょっとハック。
= Jythonのモジュールって、 Javaの何に一番近いかって言われると、 もしかしてユーティリティクラスなんじゃないだろうか。 インスタンス化されることを想定していない、 staticでpublicなメンバをたくさん持ったクラス。
= なるほどなぁ。 NintendoDSを希望小売価格の16800円で手に入れて アマゾンで20480円で売れば3000円くらいは儲かるわけか。 自分で販路を持っていなくてもアマゾンが客を見つけてきてくれるし、 古本とかに比べれば、体積あたりの利益率もいい。 となると組織的に転売して利益を上げている団体がいてもおかしくないね。

あとふと思ったのは、 電車の中でDS liteを使っている人って 男女比がかなり女性に偏っていませんか? 気のせい? 僕は自分で使うのでアマゾンで調べてみても 「4000円も高いのか、もうちょっと待ってからでいいか」 と思うのだけども、 これがもし女性へのプレゼントだとしたらためらわずに即カートに入れていると思う。 きっとそういう需要がつきないから転売価格が値下がりせず、 値下がりしないので転売屋が群がってきて…というフィードバックが起きているに違いない。

ホワイトデー過ぎたら値下がりするかな?


= 指定された文字列をクリップボードに入れるFlashが動かなくなっちゃって困っていた問題、 Javaアプレットでやろうか、ActiveScriptを勉強しようかと悩んでいたけど、 すごく当たり前な解決方法を思いついた。

クリップボードに入れられないんだから、画面に出して自分でコピーすればいいじゃん。

javascript: '&lt;a href="' + location.href + '">' + document.title + '&lt;/a>'
こんだけ。なーんだ。
= 宇田君にウダーのファームウェアの初期化部分のソースコードをもらって、 こちらでもソフトウェア的に初期化ができるようになりました。

ノートオンのメッセージは来ているけども、 ノートオフのメッセージは来ていない。 ノートオンでベロシティを0にするとノートオフになるので、 それかと思ったけどそうでもないみたい。 なんかピッチベンドで0が来ている。

謎は解けた。 コントロールメッセージを表示させてみたら、 音が鳴っている間は11(エクスプレッション)が送られてくるんだけども、 鳴り終わったときには123(オールノートオフ)が送られてきている。

音が生まれてから死ぬまで。

NOTEON   1 71 127
PITCHBND 1 596
EXPRESS  1 2
PITCHBND 1 664
EXPRESS  1 5
PITCHBND 1 652
EXPRESS  1 9
PITCHBND 1 672
EXPRESS  1 15
EXPRESS  1 24
PITCHBND 1 664
EXPRESS  1 31
PITCHBND 1 656
(中略)
NOTEOFF  1
PITCHBND 1 -8192
EXPRESS  1 5
ここで「NOTEOFF 1」ってのはチャンネル1に対するオールノートオフ。 ピッチベンドは8192を引いた値を表示している。 音を鳴らしたときに、必ずしも一番近い音階からスタートするとは限らないようだ。 最初からピッチベンドが596になっている。 596っていうと、半音上の13セント下だが…。おそらく切り捨てで計算しているんだろう。
= Jythonで、当たり前だけどJavaっぽくないこと。

Pythonでクラスのインスタンスを作成するのは、 Javaみたいにnewとかがなくて、一見単なる関数呼び出しのように見える。

つまり、当然だけど リストのそれぞれの値をコンストラクタに渡して作った インスタンスのリストを「map(ClassName, argList)」で作れる。


= 一応、ウダーの演奏をMIDIに保存することはできた。 MIDIファイル 。 (追記:WINAMPでは聞けたけどFirefoxからQuickTimeで聞くと聞こえ方が違うな…)

昨日はウダーから来たメッセージを初期化メッセージも含めて全部記録して失敗したのだけど、 今回は中継ソフトウェアが初期化メッセージを投げつつ、 トラックに必要そうな初期化メッセージだけ追加する形で実装。

ただ、シーケンスの初期化の際のパラメータがまだよくわからない。 下記コードの☆印の2カ所。 SMPTE_25を指定すると、1秒あたり25フレームになって、 その隣のresolution = 400で1フレームあたりのティックを指定できると書いてある。 (Sequence (Java 2 プラットフォーム SE v1.4.0))

でウダーから来るメッセージのtickを表示させてみると 「17603000」なんて数字でいつも1000の倍数なので、 これはマイクロ秒だと思う。

だからSMPTE_25でresolutionを40000にすればいいと思ったのだけど、 それをやると間延びした曲が録音される。 で、resolutionを40にして、二つめの☆のところで1000で割ってやると、 今度はつまりすぎて再生できない。

適当に聞こえるようにアドホックに決めうちしてみるとこんな感じになった。


= PPQ(四分音符あたりのティック数)方式に変更してみた。 アドホックな調節なしでも期待通りの音が出るようになった。 時間軸方向にはQuickTimeでも期待通りの挙動をする。

ただ、QuickTimeでは一度押した音が全部次の音を押したときにも鳴ってしまう。 うーん。 オールノートオフを普通のノートオフに変換してみるか…。

できたっぽい。

うは、長めの曲を弾いたらTICKの計算部分でオーバーフローしたw

今度こそできた。 聖者の行進


= 東京マラソンってすごいイベントだったんだなぁ。 銀座が5時間にわたって通行止めって。

マラソンとか興味なかったけど、ニュースで見ていると面白そう。

来年もまたあるんだったら参加できるといいなぁ。 今の体力では完走できない気がするけど。


= JythonでJavaのアクセス制限を無視する設定は常時ONにしてはいけない。 理由1:jythoncが失敗するようになる。 理由2:さっきまで動いていたプログラムが動かないと思ったら、 そうと気づかずにprotectedなコンストラクタを呼んでいた。 これはイクナイ。
ShortMessage([status, data1, data2])
s = ShortMessage()
s.setMessage(status, data1, data2)
と書き換えるだけではあるので修正は面倒ではないけども、 アクセスされないつもりで作られたものを、 「うっかり気づかずに」アクセスするのはよくない。 アクセス制限は、故意に無視したいときだけ一時的にONにするようにしないと。

うわっと、 0xF0はShortMessageとしては扱えないと怒られた。 SysexMessageを使うべきだったようだ。 これはまずい。 使うべきクラスを間違えていることに気づかないのは非常にまずい。

むむ。0xFEのメッセージはSysexでもMetaでもないのか…。

データ領域が両方0のShortMessageでいいようだ。


= テラカナシス。 ウダー録音ソフトを他の人も使えるようにしようと 色々わかりやすいメッセージを表示するようにしたのに、 jythoncでコンパイルしたら日本語化けるんだったorz。

望み薄だけどJython2.2 betaでコンパイルしてみるか…。

ぐは。 PyListからbyte[]への変換が効かなくなってるじゃん…。 やっぱりjython2.2はまだまだベータ版ということか。

スタックトレースの行番号が全部0だな…。


= できた。 UdahRec version 1.0

一応Jython単体で作った初の実用的ソフトウェア。 今まではJavaにエンベッドしてたから。 規模としてはudahLib:142行 + udahInit:88行 + udahRec:24行、で254行。 もちろん1行で書こうと思えば書けてしまうのでバイト数でいえば、6938バイト。


= 後輩がGRINEditから拡張性をそぎ落としたソフトを、 GRINEditCと呼んでいるのを今知った。 確かにソースは渡したけどさ。 GRINEditって名前まで使われるとは思わなかったなぁ。

あー。GRINEditCって名前で論文書いてIPSJ Digital Courierに載ってるじゃん…。 知らない間に…。 6月に僕の知らない間に発表者に僕の名前も入れて発表申し込んでたときも 「一言くらい連絡くれてもいいのに」ってつっこんだのに…。

This is an upgraded version of GRINEdit which has been developed previously in our laboratory for visualizing complicated networks.

ふーん。XML-RPCを積む前のGRINEditから拡張性を取っ払って、 タンパク質間相互作用の可視化に特化したソフトウェアがupgrade versionかぁ。 ふーん。

まぁいいけど。ようするに「蛋白間相互作用の可視化が簡単である」という特徴が 付け加わったからupgradeってことなんだろう。価値観の違いだ。

うーん。 スルーすべきなのかそうではないのか。 僕の知らない間に論文の著者に名前を入れられて、 「僕のソフトウェアを僕の意に沿わない形で変更したものを upgrade versionと呼ぶ」 っていう僕が認めるはずがない主張をされているって言うのは。

このことを教えてくれた人と色々話をして 「GRINEditのソースを利用しただけのソフトウェアがGRINEditの改良版と名乗っている」という問題だけじゃなくて、 「GRINEdit which has been developed previously in our laboratory」が「GRINEditの著作権がラボにあるかのように誤解されうる」という問題、 そして「その論文に僕が共著者として入っているせいで、僕が『GRINEditの著作権はラボに帰属する』と認めているかのように見える」という問題もあることは理解した。「君はもっと怒っていい」とも言われた。 どうするべきか、いろんな人に聞いてみようと思う。


=
  • 事実の補足
    • 論文のreceivedは2006-08-25、GRINEdit alpha0.10の公開は2006-06-10
    • GRINEditのライセンスはLGPL
    • 研究室での研究とは無関係のソフト:修論にもD論にもそのソフトへの言及がない
    • 論文投稿後ではあるが、一応共著で出す旨のメールは受け取っていた
  • うーん。 LGPLで論文よりも先に公開されているのはSourceForgeを見ればわかるから、 著作権に関しては問題なさそうだ。 共著の件も、事後ではあるけど一応原稿が送られてきているから、 その時にきちんと読んでいれば少なくとももっと早い時点で 「GRINEditCって名前はやめて」と言えたはずだなぁ。 とりあえず今回のソフトに関してGRINEditCと呼ぶのはしかたないけど、 今後はGRINEditという名前は使わないでもらうということでいいのかなぁ。

    週末音楽日記-JythonでMIDIいじり

    今日は楽器で演奏したデータをシンセサイザーに中継するプログラムを書いてみようと思う。
    >>> import javax.sound.midi.MidiSystem as MS
    >>> MS.getMidiDeviceInfo()
    array([YAMAHA USB IN 0-1, Microsoft MIDI ?}?b?p?[, YAMAHA XG WDM SoftSynthesizer
    , Microsoft GS Wavetable SW Synth, YAMAHA USB OUT 0-1, Real Time Sequencer, Java
     Sound Synthesizer], javax.sound.midi.MidiDevice$Info)
    >>> ds = _
    >>> midiIn = ds[0]
    >>> ds[2]
    YAMAHA XG WDM SoftSynthesizer
    >>> midiOut = _
    
    入口と出口は取得できた。 しかしリフレクションでメソッドを眺めても次に呼ぶべきメソッドがわからない。 あ、そうか、MidiSystemを使うのか。
    >>> MS.getMidiDevice(midiIn)
    com.sun.media.sound.MidiInDevice@473f4c
    >>> midiIn = _
    >>> midiOut = MS.getMidiDevice(midiOut)
    
    getMidiDeviceInfoで取得できるのはあくまでデバイスの情報だけであって、 いろいろなメソッドは getMidiDeviceで取得したMidiDeviceクラスのオブジェクトが持っている。

    さて、デバイスは取れた。 楽器を演奏すると外部の機器からMIDIメッセージが送られてくる、と。 それを取得する方法はまぁ順当に考えてリスナを登録してコールバックしてもらう方法だろう、と。

    >>> midiIn.receiver
    javax.sound.midi.MidiUnavailableException: MIDI IN receiver not available
    (中略)
    >>> midiIn.transmitter
    com.sun.media.sound.MidiInDevice$MidiInTransmitter@3b6dbd
    >>> midiInTrans = _
    
    レシーバーじゃなくてトランスミッタを取得するんだそうな。 インタフェース Transmitter インタフェース Receiver 。 レシーバを作成してこのトランスミッタに登録すればよさそう。
    >>> from javax.sound.midi import *
    >>> class MyRecv(Receiver):
    ...     def send(self, msg, time):
    ...             print msg, time
    ...
    >>> midiInTrans.receiver = MyRecv()
    
    何も起きない…。
    >>> midiIn.isOpen()
    0
    
    デバイスを開いていないじゃん!w
    >>> midiIn.open()
    >>> com.sun.media.sound.FastShortMessage@18430a5 4293265700000
    
    お、メッセージが表示された。 でもこの一つだけで、楽器を操作しても続きが表示されない…。

    やりなおし。 デバイスを開いてからレシーバを登録する方針で。

    >>> from javax.sound.midi import *
    >>> MidiSystem.getMidiDeviceInfo()
    array([YAMAHA USB IN 0-1, Microsoft MIDI ?}?b?p?[, YAMAHA XG WDM SoftSynthesizer
    , Microsoft GS Wavetable SW Synth, YAMAHA USB OUT 0-1, Real Time Sequencer, Java
     Sound Synthesizer], javax.sound.midi.MidiDevice$Info)
    >>> midiIn = _[0]
    >>> midiIn = MidiSystem.getMidiDevice(midiIn)
    >>> midiIn.open()
    >>> class MyRecv(Receiver):
    ...     def send(self, msg, time):
    ...             print ",",
    ...
    >>> midiIn.transmitter.receiver = MyRecv()
    >>> , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
    , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
    , , ,
    
    おー、定期的にメッセージが送られてきている。

    楽器を操作すると一気にたくさん表示される。 とりあえずこれをどうしようか。

    >>> from javax.sound.midi import *
    >>> MidiSystem.getMidiDeviceInfo()
    array([YAMAHA USB IN 0-1, Microsoft MIDI ?}?b?p?[, YAMAHA XG WDM SoftSynthesizer
    , Microsoft GS Wavetable SW Synth, YAMAHA USB OUT 0-1, Real Time Sequencer, Java
     Sound Synthesizer], javax.sound.midi.MidiDevice$Info)
    >>> midiIn = _[0]
    >>> midiOut = _[2]
    >>> midiIn, midiOut = map(MidiSystem.getMidiDevice, (midiIn, midiOut))
    >>> [x.open() for x in (midiIn, midiOut)]
    [None, None]
    >>> midiOut.receiver
    com.sun.media.sound.MidiOutDevice$MidiOutReceiver@186d315
    >>> midiOutRecv = _
    >>> class MyRecv(Receiver):
    ...     def send(self, msg, time):
    ...             midiOutRecv.send(msg, time)
    ...
    >>> midiIn.transmitter.receiver = MyRecv()
    
    おー、音が鳴った!

    第 15 章: MIDI サービスの提供

    >>> mySeq = Sequence(Sequence.SMPTE_24, 48)
    >>> mySeq.tracks
    []
    >>> mySeq.createTrack()
    javax.sound.midi.Track@1feab48
    >>> mySeq.tracks
    [javax.sound.midi.Track@1feab48]
    >>> myTrack = _[0]
    >>> class MyRecv(Receiver):
    ...     def send(self, msg, time):
    ...             myTrack.add(MidiEvent(msg, time))
    ...
    >>> midiIn.transmitter.receiver = MyRecv()
    >>> myTrack.size()
    163
    >>> myTrack.size()
    565
    
    演奏するとトラックのサイズが増える。 記録できてそう。
    >>> MidiSystem.getMidiFileTypes(mySeq)
    array([1, 0], int)
    >>> import java.io.File as File
    >>> MidiSystem.write(mySeq, 1, File(r"c:\foo.mid"))
    2129
    >>> midiIn.close()
    >>> midiOut.close()
    
    MidiSystemのwriteを使ったらMIDIファイルができた。 とりあえず再生してみる。…なんか期待していたものと違う。 しかもなぜかFastShortMessageのキャストエラーで保存に失敗したりする。

    とりあえずメッセージをリストに保存しておいて見てみることにした。

    >>> [hex(m[0].command) for m in messages[-20:]]
    ['0xe0', '0xe0', '0xb0', '0xb0', '0xb0', '0xe0', '0xe0', '0xe0', '0xb0', '0xb0',
     '0xb0', '0xe0', '0xe0', '0xb0', '0xe0', '0xb0', '0xb0', '0xe0', '0xe0', '0xb0']
    

    コントロールチェンジとピッチベンドチェンジがたくさん来ている…。

    >>> foo = []
    >>> for m in messages:
    ...     com = hex(m[0].command)
    ...     if not com in foo: foo.append(com)
    ...
    >>> len(foo)
    4
    >>> foo
    ['0xf0', '0x90', '0xe0', '0xb0']
    
    その他はノートオンとエクスクルーシブだけみたいだ。 特に不審なものは…あっ、そうか、わかった。 最初に保存に成功したときにはウダーの初期化をしなかったけど、 失敗した二回目には初期化をしたんだった。 で、今回もただのテストだからと初期化をしなかったんだ。 初期化の時にはSysexMessageが送られるはずだ。 FastShortMessage「の」キャストに失敗したんじゃなくて、 SysexMessageのFastShortMessageへのキャストに失敗したんだな、きっと。

    むむむ、違うのか? わからなくなってきた。 ドキュメントもないし…。 ソースコードを読もう。

    ソース無かったorz。 com.sun.media.sound.StandardMidiFileWriter。

    とりあえずウダーを初期化しなかった場合はMIDIファイルの出力は成功する。 でも実際の演奏よりかなり間延びをした記録のされ方をしている。


    = あうー。 毎回ウダーのケーブルを抜き差しして初期化するのが面倒なので、 ソフトウェア的に初期化できるようにしようと、 ウダーが初期化するときに送っているメッセージをそのまま ソフトウェア的に送ってみたんだが、期待通りの結果にならない。

    ピッチベンドがどうなっているのかを出力させながら演奏してみた。 普段は8192くらいの値にいて、音をずらしていくと値が上がっていく。 ただ、てっきり隣の音の領域に入ったら0になるんだと思っていたら、 ずいずい上がって行くよこれ。

    あー。 ピッチベンドの仕組み で説明されているとおりのメッセージが送られている。 1オクターブピッチベンドで移動できるのか…。


    = どうも、グリッサンドしたときにはずっと同じ音符のようだ。 「ド」の鍵盤を押したときに、「ド」になるときと 「ド#」の低めのピッチベンドになるときとの違いがよくわからない。

    もう疲れた。


    = 走ってきた。
    = http://la.ma.la/misc/js/setclipboard.txtを使って、 リンクを貼りたいページで起動するとタイトルとURLからAタグを作ってクリップボードに入れてくれる ブックマークレットを作って使っていたのだけど、今日は全然動かない。 なんでだろう…? と考えて今やっと気がついた。 今日再起動したときにFLASHのアップデートが入った記憶が…。 ぁぅぁぅ。

    なんかいい方法ないもんかなぁ。 署名付きJavaアプレットだったらクリップボードにアクセスできるかな? それなら自分のサーバに自分の署名したアプレットをおけばいいのかな?

    ActionScriptを勉強して自分で新しいバージョンのを作るのと Javaアプレットで作るのとどっちが早いだろう。


    = 今日のまとめ。

    Jythonなら24行で「MIDI楽器から入ってきたMIDI信号を ソフトウェアシンセサイザに中継するプログラム」が書ける。 ただし今のところMIDI機器が決めうち。

    ウダー練習ソフトでは、MIDIの中継と一緒に画面の描画処理もしているが、 こちらは単純に中継するだけなので負荷が軽い。 前者は僕のマシンでCPU使用率100%だけど、後者は50%くらい。 負荷が軽いので遅延も起こりにくいはず。 もっともウダー練習ソフトのほうでも優先度を最大限に上げれば 遅延は起こらないように思えるけども。

    ピッチベンドを使うと 上下1オクターブのグリッサンドが可能な上に、 音の解像度は半音の600分の1。

    MIDIの生演奏の保存は思ったほど簡単ではなかった。 トラックの解像度の指定とかを適当にしたのがよくない。 あとSysexが悪さをしていると思うのだけど情報不足。

    走ると膝が痛い。 いい運動靴を買うべきか。 ナイキの。 センサーが入っていてiPodと通信するアレ。 買おうかなぁ、本当に。

    リンクを貼るブックマークレットが動かなくなったのがすごく不便。

    2007年02月17日

    執筆日記9

    Yet Another COINS-snapshot Viewer
    COINSとGRINEditを使って,プログラムのフローグラフ等を描画する(まだ可遊化には至っていない)ツールです.

    おお、自分以外がGRINEditを使っているのを初めて見た!


    = 「6ヶ月と1日前」って何だろう。 9月1日の「6ヶ月と1日前」は2月28日なんだろうか? 8月31日の「6ヶ月と1日前」も2月28日なんだろうか? 8月29日の「6ヶ月と1日前」も2月28日なんだろうか?

    気になったのでつっこんでいたらもう3時半だ…。 お腹空いた…。


    = 向かいのホームのお姉さんが、 片方は膝下、片方は膝上の靴下をはいていたのですけど、 あれが流行のアシンメトリーってやつですか?
    = 「東松戸~ 東松戸~」

    はあっ?! 何?! ここどこ?!(だから東松戸だって)

    原稿書いていたらいつの間にか変なところにいた…。


    = 章があって、章リードがあって、 節があって、節リードがある、 という構造の文章は書き慣れていない。 「3時間で覚えるPython」のノリで 「5時間で覚えるJython」を作ったのだけども、 書籍としてはダメな感じ。 適当な長さで切って節リードを入れないと。 Webと違ってページがあるから、 刻むことも考えないと。 難しい。

    D論とかの時は、TeXで自分で組版していたので、 最終版がどういう見え方になるのか自分で確認できた。 書籍の場合は組版をするのが専門の人なので、 僕の手元ではテキストファイルで原稿を書くように言われている。 イメージがわかないのでHTMLに変換するプログラムを書いた。

    でも、このHTMLは 実際に本になった時のイメージとはかけ離れている。 もらったレイアウトのサンプルを参考にして、 少し近づけてみるか…。 せめて章扉、章リード、節見出し、節リードだけでも。 今のただのH2タグのではイメージがわかない。


    = 今年の植村直己賞の受賞者がテレビに映って、 「あれ、ずいぶん若いお姉さんだな」 と思ったら24歳だった。年下だった。

    たぶんこの人と腕相撲したり長距離走で競ったりしたら負けるんだろうなぁ。

    萌え。(ぇ


    = すごいなぁ。高潮の侵入を防ぐための 340キロのステンレスの防潮扉が盗まれたんだそうな。 SFなんかで「鉄を食べる細菌が増殖して鉄が使えなくなった時代」なんて設定があったりするけど、 現実はもうちょっと夢がないようで、 高価な資源は監視していないと消えて無くなる時代。

    バブル時代に作られたけいはんな研究都市のチタン製3億円の日時計はいつ盗まれることやら。 あれだけ巨大なものを盗むと、ただの窃盗じゃなくて怪盗になる。

    お、あの日時計、ギネスにも載っているらしい。


    = 「自分がダメな子だと感じるか」という質問に対して、 外で遊んでいる子は4.4%、外で遊んでいない子は22%だそうな。 何が影響しているんだろうな。

    番組宣伝でこういう数字紹介したときに、 番組宣伝の中でソースの紹介をする余裕がないのは理解できるけども、 番組の公式ページにくらい載せてくれてもいいのではないかと思う。


    = スタイルシートと原稿のレンダリングエンジンをいじって それっぽい見かけにした&原稿のコンパイル時にTOCを出力するようにしてみた。

    うーん。 今までに書いた原稿は基本的に、一つの章を一つのまとまりと考えて書いていたから 章が「イントロ、中身、中身、中身、まとめ」という構造になっている。 でも章の中に節が入るとすると、イントロの節をどうすればいいかがよくわからなくなる。

    イントロが2段落くらいなのが問題なのであって、 もうちょっと削ってしまえは章リーダーに入れられるし、 もっと増やせば単独の節にできる。 Webと違って紙の本にはページという概念があるから、 コンテンツの役割によって適度な分量がある。 論文と違ってデザインが絡んでくるので、 制約の種類も増えている。

    ああ、同じことを何度も言っている気がするけども、 一本のつながった糸として作った文章を、 節単位に刻むのはなんだか…。 でも量がここまで増えたら刻んだ方がいいんだろうなぁ。

    循環参照が起きたときにはどうしたらいいのだろう。 名前空間の説明ではクラスのインスタンスの名前空間に言及したいが、 名前空間は辞書のところで言及したくて、 で辞書はクラスより前に来て欲しい。さぁ困った。


    = マイクロソフトさん、パッチを当てるたびにMS-IMEをデフォルトのIMEにするのは勘弁してください。 ATOKユーザなので。

    2007年02月15日

    Pythonにおけるタプルの存在意義 リターンズ

    書き足しているうちに長くなったので日記から転載しました。 昔書いたよくない説明→Pythonにおけるタプルの存在意義

    __ タプルの分かりやすい説明 ? Weboo! Returns.。 なるほど、本とリフィルにたとえるのですね。

    僕のJython本の解説では袋と真空パックになっています。

    おおざっぱなイメージとしては 「リストはいくつものモノを入れることのできる長細い袋で、 タプルはいくつかのモノの入った真空パックだ」と言えます。
    でも最近はもうタプルとリストの違いを説明するのに飽きてきて、 なんでタプルなんかがあるのかとこちらが問いたい気分。 全部リストでいいじゃないか、と。 タプルが必要なところだけ勝手に変換すればいいじゃないか、と。 要素が1個のタプルが美しくないよ、と。 タイムマシンでPythonが公開される前に戻れるのなら、 「タプルはやめて」と進言したい(笑)

    mutable、immutableという言葉を使った説明も僕のJython本ではしない予定。 だって変更可能なものはハッシュのキーになれませんとか言うけど、

    >>> class Foo:
    ...     value = []
    ...
    >>> {Foo: 1}
    {<class __main__.Foo at 21859329>: 1}
    >>> Foo.x = 1
    >>> Foo.value.append(2)
    
    どう見てもこのFooってオブジェクトは変更可能に見えるでしょう。 少なくともJythonの実装では、クラスオブジェクトPyClassは __hash__をPyObjectクラスから継承していたりするので、 PyListが同じことをできない技術的な理由は全くないわけです。

    おそらく 「{[]: 1, []: 2}」 という状態が起きるのを快く思わなかったのでしょう。 リストもタプルも、2つ作れば2つとも別のインスタンスなので、 PyObjectと同じidベースのハッシュ関数ではこういう状態が起きてしまいます。 それを避けるために「中身を見て同じなら同じと判断する」 という「特殊なリスト」(後のタプルである)をつくったのでしょう。

    今になって思えば、この「タプルとリストって何が違うんだ」という質問の多さを考えると 「{[]: 1, [], 2}」を許容してしまった方がよかったのではないかと。 「なんで同じ[]をキーにして複数のエントリがあるんですか?」 「あー、たまたま両方とも空っぽだから同じに見えるけど別のオブジェクトだからね。 片方に何かをappendしてももう片方は影響受けないでしょー」

    >>> a = []
    >>> b = []
    >>> a is b
    0
    >>> a.append(1)
    >>> a
    [1]
    >>> b
    []
    
    こっちの説明のほうがよっぽど楽です。

    __ あっ、ダメだ。その仕様だとdata[(1, 2)] = 3ってやってから後でprint data[(1, 2)]ってやってもKeyErrorになってしまう…。言語の設計は難しい…。

    執筆日記8

    情報処理技術と刑事事件に関する共同シンポジウム。 講演者を殺害するという内容の脅迫状が届いたそうです。 大変だなぁ。
    =

    昨日は、

    バレンタインデーだからというわけではないですが、

    ふと、とある女性に連絡しようと思ったのです。

    でも、

    連絡先を探したのだけども、

    どこへ行ってしまったのか…

    まったく見つかりませんでした。

    がっかり。

    いや、相手は掃除のおばちゃんなんだけどね。


    = JythonでインタラクティブにMIDIで音を鳴らしてみる。
    >>> from javax.sound.midi import *
    >>> MidiSystem.getSynthesizer()
    com.sun.media.sound.MixerSynth@fc63be
    >>> synthe = _
    >>> synthe.open()
    >>> synthe.channels[0]
    com.sun.media.sound.MixerMidiChannel@4120aa
    >>> c = _
    >>> synthe.defaultSoundbank.instruments[0]
    Instrument Piano (bank 0 program 0)
    >>> synthe.loadInstrument(_)
    1
    >>> from time import sleep
    >>> for i in range(48, 60):
    ...     c.noteOn(i, 100)
    ...     sleep(0.25)
    ...     c.noteOff(i)
    >>> synthe.close()
    

    なんだ、超かんたんだ。 import *しなくてもMidiSystemだけでいいし、そぎ落とせばもっと短くなるし。 とりあえずPython使いに「Jythonのどこがいいの」と言われたら 「Javaのライブラリが全部使えるからねー、インタラクティブにMIDIで音が鳴らせるよ?」 と答えればいい、と。

    JythonでJavaのライブラリをインポートして使うという説明で、 なにをインポートしたら楽しいかなぁと考えた結果がこれ。 最初はSwingで窓を出していたのだけど、 行数的に大差がないからこっちを使おう。 こっちのほうがきっと楽しい。


    = 今日は東西線で三鷹まで往復しながら執筆。 参考書に付箋を貼ってその上で文章書き。 筆が進むときは下の英文は無視して書き連ねて、 筆が止まったら英文を読み進めてインスピレーションを得る。
    = ご飯を炊くときに、水の代わりに杜仲茶を入れてみたらすごい色になった。 そぼろ。
    = ここにあった文章は 西尾泰和のブログ: Pythonにおけるタプルの存在意義 リターンズ に転載。
    = 生駒日記(2007-02-13)

    知り合いのことを知らない人が書いている日記って面白い(ぇ)

    バレンタインデー日記

    「Pythonのprivateモドキはほげほげするとアクセスできてしまうから真のprivateではない」 というJava使いの言葉を耳にすることもありますが、 Javaだってほげほげすればprivateなフィールドにアクセスできてしまいますね。 意外と簡単。
    String s = "Jython";
    Field f = s.getClass().getDeclaredField("value");
    f.setAccessible(true);
    System.out.println(f.get(s));
    

    = バレンタインデー - Wikipedia
    祭りの前日、娘たちは紙に名前を入れた札を桶の中に入れることになっていた。翌日、男たちは桶から札を1枚ひいた。ひいた男と札の名の娘は、祭りの間パートナーとして一緒にいることと定められていた。そして多くのパートナーたちはそのまま恋に落ち、そして結婚した。

    えー。 再現しようよ(ぇ)

    冗談はさておき、これって女性が男性より多くないと 「あれー、僕の分の札がない!」 ってことになってしまうね。


    = おおおおおおおおおおっ! 8ヶ月間行方不明だった実家の鍵が見つかった!

    えっと、「鍵を適当なところに入れるとわからなくなるから、 かばんとかポケットじゃなくて、箱に入れたはず」 というのは正解。 ただし、貴重品を入れている箱でも、鍵を入れる箱でもなく、 「引っ越しぎりぎりまで必要だった書類や本が入っている箱」 の中にあった。 引っ越してきて「鍵を置く場所」が無くなったタイミングで、 その書類入れの中に入れてしまったのだろう。 行方不明だった今の住居の2つ目の鍵も同じ場所で見つかった。 これで退室時に追加料金を取られずに済む。


    = Javaのリフレクションを使えば、 private finalなフィールドをいじることもできるけども、 static finalなフィールドはいじることができないようだ。 ググってみたら [JavaSpecialists 096] - Java 5 - "final" is not final anymore に同じことが書いてあった。
    = 「,」という名前のフォルダにパスを通す、 というLifeHackを先日のグラスホッパーの会で(意図せず)披露したのだけど、 今日はそこにccd.batという名前で下のような内容を保存してみた。
    @echo off
    cmd /k cd %1
    
    これで「Win+R ccd フォルダ名」とやるとそのフォルダがコマンドプロンプトで開かれる。
    = ささださんじょうほう。

    ⊂⌒⊃。Д。)⊃カジ速≡≡≡⊂⌒つ゚Д゚)つFull Auto | 新ジャンル「ツンギレ」

    ツンギレ。


    = 「開発合宿にあるといいものってなんだろう?」と聞かれて 「癒し系の女の子」と即答。

    「お金で解決できるもので!」と言われて 「お金で解決できそうだよ?」と答えたら 「お金で雇う女の子では癒されない!」と言われた。 なんて贅沢な。

    でも人選がむずかしい。 うっかりすると開発に集中できなくなりそう。


    = 気がついた! ウダー立てれば回さなくても裏が見える!

    今日は何の日~? 写真共有「フォト蔵」

    バレンタインデーだからそれにふさわしい曲を弾いてみました(ぇ

    音が割れたりとかしないでうまく撮る方法はないものかなぁ。

    2007年02月13日

    差分リストを作るには

    問:空欄を埋めて、与えられた数値のリストrawdataから、差分のリストdiffdataを作成せよ(via [Python-ml-jp 3850] リスト要素の差分リストの求め方)
    >>> rawdata = [3, 1, 4, 1, 5, 9, 2, 6, 5]
    (空欄)
    >>> d = 0
    >>> for diff in diffdata:
    	d += diff
    	print d,
    
    	
    3 1 4 1 5 9 2 6 5
    
    for文でそうやってアクセスするだけなのであれば、 僕ならこう書くかな。
    >>> rawdata = [3, 1, 4, 1, 5, 9, 2, 6, 5]
    >>> def diffGen(aList):
    	yield aList[0]
    	for i in range(1, len(aList)):
    		yield aList[i] - aList[i - 1]
    
    		
    >>> diffdata = diffGen(rawdata)
    >>> d = 0
    >>> for diff in diffdata:
    	d += diff
    	print d,
    
    	
    3 1 4 1 5 9 2 6 5
    
    もし添え字を指定してアクセスしたいのであればこうかな。
    >>> class DiffList:
    	def __init__(self, base):
    		self.base = base
    	def __getitem__(self, i):
    		if i == 0:
    			return self.base[0]
    		else:
    			return self.base[i] - self.base[i - 1]
    
    		
    >>> diffdata = DiffList(rawdata)
    >>> d = 0
    >>> for diff in diffdata:
    	d += diff
    	print d,
    
    	
    3 1 4 1 5 9 2 6 5
    >>> diffdata[2]
    3
    

    でまぁ、オチのワンライナーはこんな感じ。

    >>> [(i == 0 and [rawdata[0]] or [rawdata[i] - rawdata[i - 1]])[0]\
            for i in range(len(rawdata))]
    [3, -2, 3, -3, 4, 4, -7, 4, -1]
    >>> diffdata = _
    >>> d = 0
    >>> for diff in diffdata:
    	d += diff
    	print d,
    
    	
    3 1 4 1 5 9 2 6 5
    

    MIDI音源はどこで売っているのだ日記

    MIDI音源を買おうと、 仕事帰りに秋葉原によってMusicVoxとヨドバシアキバに行ったのだけども、 「SC-8820はもうメーカーにすらないので入手できません」と言われてしまった。 うーむ。

    楽天で検索。うーむ、SC-8820は全部売り切れになっているなぁ。


    = 20時を回っていたので、久しぶりにじゃんがらラーメンに行ってきました。 何ヶ月かラーメン断ちをしていたのだけども。ダイエットのために。 久しぶりに食べるこってり豚骨ラーメンはおいしゅうございました。

    そして今28時なんだけども、胃が苦しくて大変です(汗)

    帰ってきて即寝て起きたのが27時。


    = そういえばデブサミの参加登録の方法がよくわからなくて保留していたのを、 今更思い出して、もう一度チャレンジしてみようと思ったら 「参加登録の受付は 2月13日(火) 18:00 迄」だそうな。 がっかり。

    週末音楽日記その4

    Wikipediaに行ったら「あなたにメッセージがあります」とな。 何かと思ったら僕と同じIPアドレスのIPユーザがなんかやらかしたらしくて 編集ブロックされているとな。 まぁ、調べてみたら初期に取ったアカウントがちゃんと生きていたので 万が一書き込みたくなったらそれを使うから実害はない。

    ぎょっとしたり、あわてたりする人が出そうではあるけどなぁ。


    = テキスト音楽サクラでMIDIからMMLへの変換した際に、 ものによってはパートがずれて始まってしまう問題、 どうも間に長い無音部分がある場合に、 その直前の音を長く伸ばした上で、 無音部分相当の休符も入れてしまうようだ。
    = ドから4つ上は何か、と言われたらミだとすぐわかるのだけども、 そこからさらに4つ上は何かと言われてもすぐにはわからない。(正解はソシャープ)

    で、せっかくウダー用の楽譜を作ったのに、 頭の中でついつい「ドレミ」に翻訳しようとしてしまう、 これはよくないので、ドレミに変わる音の呼び方を決めようと思う。

    ドが0なのでレ(ちょっ

    レイニサシゴロナハクエビ。これで決まり(ぇー

    チューリップはドレミドレミソミレドレミレじゃなくて レニシレニシナシニレニシニ。

    なんか意外と違和感がない(ぇ)

    とりあえずウダーに貼ったドレミシールをはがしてレイニシールを貼ろう。

    あと、メジャーの和音だのマイナーの和音だのは、 一番低い音(根音?)を0とすると0,4,7の和音と0,3,7の和音なので、 シナの和音とサナの和音と呼ぶことにしてみる。 そうするとサから始めるシナの和音はサナエになるわけだ。簡単。 これをレシャープから始めるメジャーの和音って言われてもすぐにはわからない。

    あ、でももちろん12の割り算は頭に入っている必要があるのか。 クから始めるシナの和音はクビシ。合ってるかな?合ってない。 クイシか…。やはり10進数に慣れた人間にとって12進数はちょっと戸惑うなぁ。 まぁ、一桁の足し算だからそのうち慣れるだろう。 バッドノウハウまみれの既存の音楽理論を覚えるよりはよっぽど楽なはず。

    やっぱりMIDI音源を買おうかなぁ。 サクラを使っているとウダーが使えず、 ウダーをつなぐたびに初期化作業をするのが面倒で、 今日はウダーで試さずにたくさん楽譜を作ったのだけども、 いざ弾いてみると、修正したいのがあったりして。


    = どこかで 運動不足の解消法について 「週末に10キロほど走っているけど、1時間程度だから大して負担でもない」 という主張を見かけた。 結局のところ「座業だから運動不足だ」 「ジムとかに行って運動する時間がもったいない」 っていうのはいいわけに過ぎないと言うことがわかったので、 とりあえず走ってきた。疲れた。 1時間ちょい走ったのに4キロって表示されているなぁ。 万歩計だから徒歩の歩幅で計算されているかも知れない。

    2007年02月11日

    週末音楽日記その3

    今日は4月から住むところを見てきました。 お好み焼きを焼いた後で「あっ、ソースがない!」と気づいても、 冷めないうちにソースを買ってこれるような立地。自炊しやすそう。

    この前飲み会の前に作業したらすごくはかどったのだけど、 やはり「~時までに出ないといけない」という締め切り効果が生産性を上げるのだろう。 特にイベントがない限り決まった時間に帰るようにした方が 「これが終わったら帰ろう」というのより高い生産性を維持できるのかも知れない。

    つまり4月になったら晩ご飯を自炊しようかなぁと(何日続くやら)


    =

    帰りの電車の中で、七線譜を改良。

    7senhu_jupiter.png

    オクターブを超える際に補助音符を表示するのはあまり評判がよくなかったので削除。 西尾泰和のブログ: 週末音楽日記で作ったものに比べて格段にコンパクトになりました。

    曲は木星(組曲惑星)。


    = よし。MIDIファイルを読み込んで、音符の長さを反映するようにしました。 MMLでの入力を止めたのは、音の指定方法まで含めてパーサを作ると一仕事だと思ったから。 あと和音もサポート。

    7senhu_kogeyo.png

    曲はこげよマイケル。

    MIDIを一応は読めるけども、 作るのに使ったツールなどによって四分音符が何ティックなのかが異なるので とりあえずテキスト音楽サクラで作ったMIDIに仮に合わせてある。

    MIDI Forum : MIDIあそびによれば「タイムベース」というらしい。 タイムベースは頭のほうのメタメッセージとかの中で指定されているのかなぁ?

    MIDIファイルの基礎知識。 タイムベースはヘッダに書かれているそうな。 ということは…

    Sequence#resolution。これかな? うんうん、サクラで作ったMIDIだと96で、やたら長くて困った拾いもののMIDIだと3424だ。


    = 折り返しも実装できた。

    7senhu_shinsekai.png


    = パッヘルベルのカノン 、デキター!

    7senhu_pachelbel.png

    つい10分前まで、ウダーを練習してパッヘルベルのカノンを弾くつもりでいたけども、 そしてそのためにこうやって「ウダーで弾きやすい形の楽譜」で パッヘルベルのカノンを出力したわけだけど…、 …、 …これはさすがに弾けない気がする。 おとなしくもっと簡単な曲を練習した方がよさそうだ。


    = あーーーー! 今気づいたけど、テキスト音楽サクラにMIDIからMMLを生成する機能が付いているじゃん! わずかにバグがあって声部ごとにずれてぐちゃぐちゃになってしまうけど、 そこを手作業でなおせば…。
    = なにぶん今日は眼精疲労気味なので目を使う作業はもうおしまいにしよう。

    2007年02月10日

    貼り忘れ日記

    「どういうきっかけでPythonラブになったのか」なんていう 質問が来るので、Pythonラブじゃないですよ、 こういう言語があったら乗り換えますよ、という話を書いてみる。
    • 基本Python
    • 辞書リテラルの表現{key: value}をなくす
    • {~}をブロックにする。ブロックは任意個の式や文を含むことができる。progn。
    • 文は全部Noneかなんかを返す式に変える。すべてが式。
      • 代入文を式にする
    • ラムダ構文を{lambda x, y: x + y}とか{^x, y: x + y}とかにする
      • もちろん{lambda x: if(x % 2== 0){"even"}else{"odd"}}が可能。間に改行やインデントを入れてもOK
    • 関数オブジェクトをシリアライズ可能に
    • foldlとfoldrを組み込み関数に追加
    • 連結リストを組み込み型に
      • for文などを連結リストのイテレーションに対応させる
    • JythonのようにJavaVM上で動き、Javaのライブラリは全部使える
    • IronPythonのように.NETフレームワーク上で動き、.NETのライブラリは全部使える
    • 無償のIDEがある(CPythonのIDLEのように)
      • Emacs LispやEclipseのように「正しいスタイルに整形」してくれる機能が付いている
    • GUIをVBやDelphiみたいにお絵かきで作れる
    • ブロック構造をインデントで表現する、タブとスペースを混在しない、その他もろもろの「正しい作法」は sys.strict = Trueとした場合にエラーとなる。(ただしデフォルトでTrueにしておく)
    • JSON(JavaScript Object Notation)とほぼ同じなんだけど、PON(Python Object Notation)を作って 高速なパーサを標準添付&他言語から利用できるライブラリを公開
    • 識別子名に!と?を許可。
    • イントロスペクションで、ある関数が副作用を持つかどうか判定できる。
    • タプルとリストを共通化。タプルの最後のカンマの省略を禁止(strictモード)もしくはタプルのリテラル表記自体をなくす。
    • print文は組み込みの関数print!の呼び出しのシンタックスシュガーにする。print >>fo, x, y, z, は print!(x, y, z, newline = False, output = fo)
    • 末尾再帰の最適化
    • ジェネレータ閉包はただの括弧かと思っていたらいきなりforが来てびっくりするので{gen x: x in someList}とかにしたらいいんじゃないだろうか。

    思いつくままに書いてみたけど、どうだろうこれ。 だいぶ無茶な注文が混じっている気がする。 どの程度実現可能なのかなぁ。


    = ヒープ領域 - Wikipedia 「ヒープ領域(ヒープりょういき)とは(中略) データ構造のヒープとは直接的な関係が無い。」

    がーん。ヒープ構造になっているんだと思っていた。


    = Skypeのスケッチパッド(ホワイトボードを共有できる)を試してみたのだけど、 なんだかなぁ。 ペイント機能があるのはまぁいいのだけど、 ドロー機能がないんじゃちょっと使い物にならないというか何というか。 直線とか円とか楕円とかスプラインとか書けないとなぁ。

    SkypeのExtraはどうやって作るんだろうか。 ちょっと調べてみたけどすぐにはわからなかったし、 とりあえずGRINEditをネットワーク越しに共有するのができてから考えればいいかと思ったので保留。


    = 深刻なセキュリティホール。 男性に深刻なセキュリティホール─人生乗っ取られる恐れ : bogusnews。 やばい、これはやばい。 Xデーが刻一刻と近づいてきているお!
    = 平行線の作図による角の三等分法。 学校の幾何の授業も、教えられた方法を正確に繰り返す練習ばっかりじゃなくて、 このページの主張のどこがおかしいのかを考えたりとかをやればいいと思う。

    「背景色の選び方がおかしい」ってのはなしで。

    で時間内に答えがわからなかった生徒は ギリシアの三大作図問題1 [物理のかぎしっぽ] を読んでくるのが宿題。

    大体、問題を解く上でのルールを破っている時点で無意味なのに、 さらに求めているのが「与えられた角の三等分」じゃなくて「与えられた角の三倍」だったりする。 角の三倍なんてルール破りをしなくても簡単に求まるのに、と。


    = 普段、Pythonスクリプトは大体100行未満になるように、 Javaのコードでも300行未満になるように気をつけているのだけど、 原稿のテキストファイルが一つの章で1500行を超えて、 そろそろ管理が大変に…。

    TeXで論文を書いていた頃も思ったのだけど、 長文を管理するシステムは十分発達しているとは言えないなぁ。

    どうなるのが正しい進化なのかビジョンがさほど明確ではないけど、 アウトラインプロセッサがツリー構造と一次元的構造をマッピングしているように、 筆者が持っている概念のネットワークと一次元構造とのマッピングだったりするのかなぁ。 結城さんは[結] 2007年2月 - 結城浩の日記で「集合に全順序を入れる」という表現を使ってらっしゃる。 僕は集合の要素がばらばらではなく、 文章を紡ぐ前から僕の頭の中でネットワーク状の構造を形成していると思う。 それを文章にする作業って言うのは「どの頂点から始めて、どうたどっていくか」 という問題だ。ケーニヒスベルグの橋の問題みたいに。 場合によってはうまくたどれない頂点をあきらめてみたり、 「あ、こういう文章を補えばうまくつながるぞ」と 橋を建設したりする。

    本当にそういう方法で文章を作る場合には、 なんかいい可視化の方法がないとやってられないだろうなぁ…。


    = Music Psychology 「音楽心理学への御招待」 面白い。
    = Nose-Foobar法って、今までずっと「ノーズ・フーバー法」だと思っていた。 IBM 科学の扉-科学者が語る科学の楽しみ-能勢 修一 - Japan。 日本人だった。
    = スラッシュドット ジャパン | ユーザー参加型検索エンジン『netPlant』。 あれ?うねうね動く画面はなし? あれ?ヒットする件数が少なかったときに自動的にGoogleで検索した結果を取ってくる機能は? あれれ…。 公開する上で障害になっちゃったのかなぁ。
    = このー木なんの木きになる木、の映像を独占的に利用する権利を日立製作所が取得。 年間5000万円程度と見られる。 (日経)

    2007年02月09日

    校正日記

    原稿を読み上げる。といってもラボで読み上げると迷惑なので声を出さずに。 やっぱり読み上げるとリズムの悪いところとかがあるのでそれを修正。 基本的に削る方向だけども、たまに「その」とか入れてみたり。 「もの」とか入れてみたり。

    あー、でも僕定型発達者じゃないから 僕にとって読みやすいリズムって定型発達者にとっても読みやすいとはかぎんないよなぁ。 そもそも僕は幼稚園に入った日に絵本を黙読してて泣いているのかと思われたらしいので、 文章を音の連続としてとらえる習慣に乏しいのだよなぁ。

    それでか。 音として考えていい形になるように文章を書き換えていくと、 なんかプレゼンっぽくなるのは。


    = ささださんに聞かれて試したコード。
    >>> import thread
    >>> import time
    >>> def foo():
    	while True:
    		time.sleep(1)
    
    		
    >>> i = 0
    >>> while True:
    	dum = thread.start_new_thread(foo, ())
    	i += 1
    	if i % 10 == 0: print i,
    
    10 20 30 (中略) 990 1000 1010 1020
    
    Traceback (most recent call last):
      File "", line 2, in -toplevel-
        dum = thread.start_new_thread(foo, ())
    error: can't start new thread	
    
    スレッドの作成に上限があるとは知らなかった。
    = 53平均律 - Wikipedia。 興味深い。 もう眠い。 28時だし。

    2007年02月07日

    野蛮人日記

    BigDecimalを試す。 BigIntegerがPyLong相当。というかPyLongが内部で使っている。 BigDecimalで1/3を計算したら「 java.lang.ArithmeticException: java.lang.ArithmeticException: Non-terminating de cimal expansion; no exact representable decimal result. 」だって。循環小数くらい実装すればいいのに。簡単なのに。
    = Jythonでは自動的にlongへの昇格が行われないが、 最近のCPythonでは行われる、という話題で、 別にごくごく最近の話でもないけども、 バージョン番号を特定すべきなのだろうか。 いや、そこまでのことは求められてないだろう。 Jython本だし。

    でもそんな前からCPythonにある機能がなぜJythonに搭載されていないのか。 型の関係でややこしいのか?いや、そんなこともないだろうし…。


    = あー。 getMethodsはJavaのメソッドだからprivateなメソッドは返してくれないのか…。 アクセス制御を無視するモードにして Jythonのdirを使えば全部見える。

    野蛮なこと。

    >>> import java.lang.String as String
    >>> dir(String)
    ['CASE_INSENSITIVE_ORDER', 'bytes', 'checkBounds', 'codePointAt', 'codePointBefo
    re', 'codePointCount', 'compareTo', 'compareToIgnoreCase', 'concat', 'contains',
     'contentEquals', 'copyValueOf', 'count', 'endsWith', 'equalsIgnoreCase', 'forma
    t', 'getBytes', 'getChars', 'hash', 'indexOf', 'intern', 'lastIndexOf', 'matches
    ', 'offset', 'offsetByCodePoints', 'regionMatches', 'replace', 'replaceAll', 're
    placeFirst', 'serialPersistentFields', 'serialVersionUID', 'split', 'startsWith'
    , 'substring', 'toCharArray', 'toLowerCase', 'toUpperCase', 'trim', 'value', 'va
    lueOf']
    >>> s = String("Hello")
    >>> s.length()
    5
    >>> print s
    Hello
    >>> s.count = 3
    >>> print s
    Hel
    >>> s.value
    array(['H', 'e', 'l', 'l', 'o'], char)
    >>> s.value[2] = '!'
    >>> s.value
    array(['H', 'e', '!', 'l', 'o'], char)
    >>> print s
    He!
    

    野蛮だ…。 軽く説明すると、s.valueは 「private final char value[];」でs.countは 「private final int count;」です。 privateだけじゃなくてfinalも無視できるのね。 Stringクラスはイミュータブルという仕様なのに、 思いっきり無視。


    = 混乱しています。

    以前、僕の日記にコメントをつけまくる人がいて、 コメントスパムよりも迷惑だと感じ、 そういうコメントを機械的にはじく方法はないだろうと考え、 それで今のような 「コメントが管理者の承認を受けるまで表示されないシステム」を導入しました。 しかし、とある人から「迷惑だからもうコメント書くな」という最後通牒を受け取り、 愕然としました。

    悲しいとか、寂しいとかではなく、愕然とした、というのが正直な気持ち。 自分自身が、自分の不快に思った人とまったく同じことをしてしまい、 そして言われるまでそのことにまったく気がついていなかったこと、 相手が不快になるとはまったく思わなかったこと、 そういうことに愕然としました。

    どうしてそういうことをしてしまったのか。 どうして気づくことができなかったのか。

    それはおそらく僕がアスペルガー症候群 - Wikipedia だからなのでしょう。参考文献:大人のアスペルガー症候群 Asperger's syndrome : autism

    鬱病は「心の風邪」などと表現されることもあるように、 もともと正常なものが一時的に病んでいる状態です。 治療をすればなおるものです。 しかしアスペルガー症候群は 生まれつきの器質的な(ハードウェア的な)障害です。 治療法はありません。

    今回のような失敗を、僕は生きている限り繰り返していくのだろう。 今回の失敗から何一つ学ぶことができないままに。 それが悲しい。


    = そんなことを考えつつ、帰り道に何気なくコンビニにより、 普段読まないのに何気なく少年誌を手に取り、 何気なく開いたページから読み始めたら、 数ページで「僕はアスペルガー症候群だったんだ!」というでかいセリフが出てきて、 驚いて閉じて帰ってきてしまった。

    「単なる偶然だ」という見方もあるだろうし、 「これぞ神のお導きだ!!」という見方もあるだろう。 僕はまだ神の存在は信じられないけども、 とりあえず「流れ」に従って上のような文章を書いてみた。 今からもう一度コンビニに行って買って問題のマンガを帰ってくることにする。

    立ち読みで全部読んでしまったけど、 値段を見たら250円だったので資料として買ってきた。 マンガ雑誌って安いんだねぇ。 内容としては、きちんと正しい説明をしようとしている点と、 ちゃんと理解されるように具体例などを使って説明している点が いいと思いました。

    2007年02月06日

    だらけMIDI日記

    Erik Mongrainはすごい。 YouTube - "AirTap!"
    = 土曜日に「ヴァイオリンで弾こうのだめカンタービレの世界」を買って 日曜日にMMLで打ち込んで、 ミにシャープが付いていたり、 楽譜の頭でレにシャープが付いているのにさらに付いていたり、 書いてあるとおりに打ち込んだのに聞いてみるとつながってないところがあったり…。 なんなんでしょうねー、これ。

    小中学校の音楽の教科書って買えないですかね。


    = 詳説MIDI規格。 前回読んだMIDIファイルがノートオンばっかりだったのは、 ベロシティが0のノートオンでノートオフを代用できる (しかもサイズが節約できる)からだということが判明。

    和音をじゃんじゃん鳴らされている上に、ノートオフまで音符と認識されちゃ、 そりゃ聞けるMMLが出力されないわけだわ。


    = マシンの調子が悪い原因の一つに、 ハードディスクの残量が少ないことが挙げられるのではないか。 というわけでいらないものをアンインストール。 Javaってアップデートしていくと古いのがまるまる残るんでしょうか。 そんな雰囲気。 最新の以外を全部消す。 1個300メガ弱あるので結構なサイズだ。
    = 今日は全般的にかなりだらけた雰囲気の一日になってしまった。 明日は早起きして即シャワー浴びて冷水かぶってラボに行こう。 明日歓迎会だけど。飲むのか…。夜作業できないな…。

    2007年02月05日

    週末音楽日記その2

    他人の作ったMIDIファイルを読んでみるの巻。

    META: [99, 104, 111, 112, 105, 110, 32, 101, 116, 117, 100, 101, 49, 50, 91, 82,
     101, 118, 111, 108, 117, 116, 105, 111, 110, 97, 114, 121, 93, 32, 99, 32, 109,
     111, 108, 108, 32, 111, 112, 49, 48, 45, 49]
    META: [4, 2, 24, 8]
    META: [-3, 0]
    META: [5, -72, -40]
    META: [6, -118, 27]
    コントロール チェンジ 0 Control# 0 Data 0
    コントロール チェンジ 0 Control# 32 Data 0
    プログラムチェンジ 0: 0
    コントロール チェンジ 0 Control# 93 Data 42
    ノートオン 0: 71
    ノートオン 0: 83
    ノートオン 0: 77
    ノートオン 0: 74
    ノートオン 0: 79
    コントロール チェンジ 0 Control# 0 Data 0
    コントロール チェンジ 0 Control# 32 Data 0
    プログラムチェンジ 0: 0
    コントロール チェンジ 0 Control# 91 Data 123
    コントロール チェンジ 0 Control# 91 Data 127
    コントロール チェンジ 0 Control# 93 Data 42
    コントロール チェンジ 0 Control# 93 Data 42
    コントロール チェンジ 0 Control# 91 Data 125
    コントロール チェンジ 0 Control# 91 Data 127
    コントロール チェンジ 0 Control# 93 Data 40
    コントロール チェンジ 0 Control# 91 Data 127
    META: [6, 26, -128]
    ノートオン 0: 68
    ノートオン 0: 68
    ノートオン 0: 67
    (中略)
    ノートオン 0: 79
    ノートオン 0: 62
    META: [5, -72, -40]
    ノートオン 0: 59
    ノートオン 0: 59
    (中略)
    ノートオン 0: 31
    ノートオン 0: 31
    META: [5, -24, 24]
    ノートオン 0: 77
    ノートオン 0: 75
    ノートオン 0: 80
    (以下略)
    

    所々に挟まるメタメッセージはなにものだろう。 どうしてノートオンばっかりでノートオフがないんだろう。 コントロールチェンジ - Wikipedia ってのは何だろう。調べてみたところ 91がリバーブとか93がコーラスとかそういうものらしい。 あとノートオンのメッセージ自体には音の長さは書いていないので、 タイミングの情報がどこか別の場所にあるはず…。

    とりあえずノートオンのところだけ取り出して音階表示

    o5 b o6 b o6 e+ o6 d o6 g o5 g+ o5 g+ o5 g o5 g o5 e+ o5 e+ o5 d o5 d o5 d+ o5 d
    + o5 d o5 b o6 b o6 e+ o6 d o6 g o5 d o4 b o4 b o4 g o4 g o4 g+ o4 g+ o4 g o4 g
    o4 e+ o4 e+ o4 d o4 d o4 d+ o4 d+ o4 d o4 d o3 b o3 b o3 g o3 g o3 g+ o3 g+ o3 g
     o3 g o3 e+ o3 e+ o3 d o3 d o3 d+ o3 d+ o3 d o3 d o3 c o3 c o2 g o2 g o3 c o3 c
    o2 g o2 g o6 e+ o6 d+ o6 g+ o5 g+ o3 c o3 c o2 g o2 g o3 c o6 e+ o6 d+ o6 g+ o5
    
    ずいぶん音階が上下するなぁ…あ、そうかいくつものチャンネルが混ざっているのか。

    チャンネルごとにわけて表示

    channel 0:
    o5 b o6 b e+ d g o5 b o6 b e+ d g e+ d+ g+ o5 g+ o6 e+ d+ g+ o5 g+
    channel 1:
    o5 g+ g+ g g e+ e+ d d d+ d+ d d o4 b b g g g+ g+ g g e+ e+ d d d+ d+ d d o3 b b
     g g g+ g+ g g e+ e+ d d d+ d+ d d c c o2 g g o3 c c o2 g g o3 c c o2 g g o3 c
    
    うーん。 いい感じの旋律になってくれない。 和音で奏でられているとかだろうか。
    = 左脳ばっかり使って疲れたので次は右脳を使う番。 Pachelbel Streetの楽譜で12小節目まで。 カノン練習中(~12小節目) 写真共有「フォト蔵」

    たぶんここが中ボス。16分音符の連打になって、 平然と1オクターブ超の一方通行が出てきたりする。 ケーブルが絡まって一方通行の最後の方がうまく押せなくなってしまったけど、 おそらくこれは一方通行の最中にウダーを回してはいけないんだ。 2~3音見ないで裏側で押しさえすればウダーを一周回す必要はないわけだから。

    もちろん大ボスは19小節目からの32分音符なんだけども、 実はそれをクリアしてほっとした後の27小節目あたりが難関かも。 あとゴール寸前の53小節目の反復横跳び。


    = 親指が2,3本あればいいのに。

    組曲惑星の木星をちょっと練習。 カノンよりはだいぶ楽そうだ。

    2007年02月03日

    週末音楽日記

    スピーカーを買ってみた(新世界より) 写真共有「フォト蔵」

    Thinkpadの内蔵スピーカーでは音量不足で、カメラに全然音が入ってくれないからスピーカーを買ってみました。 店ではそんなに大きく見えなかったのに、持って帰ってみるとずいぶん大きい…。


    = ひさしぶりにカリンバを持ち出してみる。 カリンバでいつかのメリクリ 写真共有「フォト蔵」

    J△SR△Cに怒られたら消します。

    カリンバにはまっていた当時に書いた楽譜が↓。

    note.png


    = 和音ができないわけではないんですよ。 和音の練習(2音:こげよマイケル) 写真共有「フォト蔵」。 ただ、やっぱり1音でちゃんと弾けるようになってから和音だと思うので余り練習していないだけで。
    = うわっ、GMailの未読がぞろ目だ!4444件!(ぉ)
    = ちょっと眠い。
    = 「読みやすい楽譜」は「七線譜」と呼ぶことにしました。 1オクターブの12半音を7本の線で表現。 MIDIファイルから読むか、サクラのコードから読むか、という点は、 将来的にはMIDIファイルから読む方がいいだろうけど、 とりあえずプロトタイプとしてサクラから読む方針で。
    = できました。 パッヘルベルのカノンの冒頭部分。

    7senhu.png

    • 音の長さは今回はとりあえず表記しないことにしてみた。
    • シャープとかが付くととっさにどれだけ指を動かせばいいかわからないので濃い線の間隔一つ分で全音。濃い線だけを見ると七本あるので七線譜。間の薄い補助線は無くてもいいかもしれない。
    • オクターブに関係なく同じ音階の音は同じ高さに書く。
    • オクターブは音符(の黒い部分)の大きさで表現。小さい方が音が高い。ウダーのらせんが4巻きなので4種類のサイズがある。
    • 「ドシド」などの時に指は半音しか動かないけど、音階だけで表現すると1オクターブ近く動くかのように表記されてしまう。それを避けるためにオクターブが変わるときだけ七線譜の外に補助の音符を表示する。

    説明されなくても七線譜に見えるバージョン。半音の補助線はなくても問題なさそうですね。 さらに修正して横方向のスペースもつめてみました。これで問題なさそう。

    7senhu.png


    = あとは本当は横幅を指定しておくと折り返してくれる機能が欲しいかも。 MIDIファイルの読み込みも。
    = JythonでインタラクティブにMIDIの勉強。
    C:\jython-2.1>jython
    Jython 2.1 on java1.5.0_05 (JIT: null)
    Type "copyright", "credits" or "license" for more information.
    >>> import javax.sound.midi.MidiFileFormat as MFF
    
    違った。
    >>> import javax.sound.midi.MidiSystem as MS
    >>> MS.getMidiFileFormat(r"c:\home\canon\canon_fast.mid")
    Traceback (innermost last):
      File "", line 1, in ?
    TypeError: getMidiFileFormat(): 1st arg can't be coerced to java.io.InputStream,
     java.net.URL or java.io.File
    
    Fileじゃないって言われた。
    >>> import java.io.File as File
    >>> MS.getMidiFileFormat(File(r"c:\home\canon\canon_fast.mid"))
    javax.sound.midi.MidiFileFormat@13bcbc8
    
    MidiFileFormatが取れたけど、これを取っても意味がなかった。
    >>> MS.getSequence(File(r"c:\home\canon\canon_fast.mid"))
    javax.sound.midi.Sequence@d03a00
    >>> seq = _
    
    Sequenceを取ってみた。
    >>> seq.getTracks()
    array([javax.sound.midi.Track@1dfeb30, javax.sound.midi.Track@1c9b6eb], javax.so
    und.midi.Track)
    >>> seq.getTracks()[0]
    javax.sound.midi.Track@1dfeb30
    
    トラックが2つあるのが見えたのでとりあえず最初のを見てみることにした。
    >>> track = _
    >>> track.get(0)
    javax.sound.midi.MidiEvent@5476a7
    >>> me = _
    >>> me.getMessage()
    javax.sound.midi.MetaMessage@cfc659
    >>> mm = _
    >>> mm.data
    array([2, 0], byte)
    >>> mm.length
    5
    
    MetaMessageの中身を見たけど意味がよくわからない。
    >>> track.get(1).getMessage().data
    array([7, -95, 32], byte)
    >>> track.get(2).getMessage().data
    array([], byte)
    >>> track.get(3).getMessage().data
    Traceback (innermost last):
      File "", line 1, in ?
    java.lang.ArrayIndexOutOfBoundsException: Index: 3, Size: 3
            at javax.sound.midi.Track.get(Unknown Source)
    (中略)
    
    java.lang.ArrayIndexOutOfBoundsException: java.lang.ArrayIndexOutOfBoundsExcepti
    on: Index: 3, Size: 3
    
    他のを見ようとしていたらエラー。このトラックにはもうデータがないようだ。 もう片方のトラックを見ることにする。
    >>> track = seq.getTracks()[1]
    >>> track.size()
    1189
    >>> seq.getTracks()[0].size()
    3
    
    なるほど、さっきのトラックは中身が3個しかないけど、 こっちは1189個ある。こっちがメロディラインで、さっきのはなんか制御用のトラックなんだろう。
    >>> track.get(0).getMessage().data
    Traceback (innermost last):
      File "", line 1, in ?
    AttributeError: instance of 'com.sun.media.sound.FastShortMessage' has no attrib
    ute 'data'
    >>> track.get(0).getMessage()
    com.sun.media.sound.FastShortMessage@16bc75c
    
    おっと、さっきはMetaMessageだったけど、今度はなんか別のモノだ。
    >>> fsm = _
    >>> dir(fsm)
    []
    >>> fsm.getClass()
    <jclass com.sun.media.sound.FastShortMessage at 12355216>
    >>> fsm.getClass().getMethods()
    array([public void com.sun.media.sound.FastShortMessage.setMessage(int,int,int)
    throws javax.sound.midi.InvalidMidiDataException, public void com.sun.media.soun
    (中略)
    .lang.Object.toString()], java.lang.reflect.Method)
    >>> fsm.getClass().getFields()
    array([public static final int javax.sound.midi.ShortMessage.MIDI_TIME_CODE, pub
    lic static final int javax.sound.midi.ShortMessage.SONG_POSITION_POINTER, public
    (中略)
    und.midi.ShortMessage.CHANNEL_PRESSURE, public static final int javax.sound.midi
    .ShortMessage.PITCH_BEND], java.lang.reflect.Field)
    
    JavaはPythonと違ってgetMethodsとかの結果がぐちゃぐちゃしてて読みにくい。 素直にJavadocを読む。 getData1とかgetData2を使うらしい。
    >>> fsm.getData1()
    66
    >>> fsm.getData2()
    100
    >>> track.get(3).getMessage()
    com.sun.media.sound.FastShortMessage@1553743
    >>> _.getData1(), _.getData2()
    (64, 100)
    >>> for i in range(20):
    ...     print track.get(i).getMessage().getData1(),
    ...
    66 66 64 64 62 62 61 61 59 59 57 57 59 59 61 61 62 62 61 61 >>>
    
    ふむふむ。 詳説MIDI規格:メッセージ分類表 とあわせて考えると、この数字の列が音程だな。 同じのが二つずつあるのはノートオンとノートオフだろう。

    というわけでJavaでMIDIファイルから音程を取得する方法は大体わかったので、 今度気が向いたときにMIDIファイルを読んで七線譜を出力するプログラムを作ることにしよう。


    = 七線譜出力プログラムのソースコード。
    # -*- coding: cp932 -*-
    #
    # 7senfu.py ストトン表記から七線譜を作る
    #
    
    rawdata = u"""
    音符2
    ファミレ  ド↓シラシ↑ド
    レド↓シラ ソファソミ
    
    音符4
    レファラソ ファレファミ
    レ"シレラソシラソ
    
    ファレミ↑ド レファラ↓ラ
    シソラファ  レ↑レレ.ド8
    """
    
    note = u"ドレミフソラシ"
    noteMap = {}
    for (i, n) in enumerate(note):
        noteMap[n] = [1, 2, 4, 6, 7, 9, 11][i]
    
    data = []
    
    tmpOffset = 0
    offset = 24
    for c in rawdata:
        if c in note:
            v = noteMap[c] + tmpOffset + offset
            if v < 0: print "音程低すぎ"
            if v > 48: print "音程高すぎ"
            data.append(v)
            tmpOffset = 0
        elif c == u"↑":
            offset += 12
        elif c == u"↓":
            offset -= 12
        elif c == u"\"":
            tmpOffset = -12
        elif c == u"`":
            tmpOffset = 12
        elif c == "#":
            data[-1] += 1
        elif c == "♭":
            data[-1] += 1
    
    import Image, ImageDraw
    LEN = len(data)
    H_STEP = 18
    V_STEP = 9
    HEIGHT = V_STEP * 24
    BASE_HEIGHT = V_STEP * 18
    BASE_LEFT = H_STEP
    WIDTH = BASE_LEFT * 2 + LEN * H_STEP
    
    LIGHT_GRAY = 0xE0
    GRAY = 0xC0
    
    def getHLineColor(note):
        if note % 2:
            return 0xFF #LIGHT_GRAY
        else:
            return GRAY
    
    image = Image.new("L", (WIDTH, HEIGHT), 0xFF)
    draw = ImageDraw.Draw(image)
    
    for i in range(13):
        y = BASE_HEIGHT - i * V_STEP
        draw.line((0, y, WIDTH, y), getHLineColor(i))
    
    def drawNote(x, note, octave):
        if not(-6 <= note <= 18):
            return # 離れすぎ
        if not(0 <= note <= 12):
            # 七線譜の外なので補助線を引く
            cur = note
            if note < 0:
                step = 1
            else:
                step = -1
            while not 0 <= cur <= 12:
                _y = BASE_HEIGHT - cur * V_STEP
                draw.line((x - H_STEP , _y, x + H_STEP , _y),
                          getHLineColor(cur))
                cur += step
    
        y = BASE_HEIGHT - note * V_STEP
        color = [GRAY, 0xFF, GRAY, 0xFF, GRAY, 0xFF, GRAY]
        color[octave * 2] = 0x00
        for i in range(7):
            r = 7 - i
            draw.rectangle((x - r, y - r, x + r, y + r), color[i])
    
    prev = None
    for (i, d) in enumerate(data):
        note = d % 12
        x = BASE_LEFT + i * H_STEP
        octave = d / 12
        drawNote(x, note, octave)
        if prev != None and prev[2] != octave:
            # ドをまたぐときのための補助音符表示
            diff = (prev[2] - octave) * 12
            drawNote(x, note - diff, octave)
            drawNote(prev[0], prev[1] + diff, prev[2])
            aida = x - H_STEP / 2
            draw.line((aida, 0, aida, HEIGHT), LIGHT_GRAY)
        prev = [x, note, octave]
        
    image.save(r"c:\7senhu.png", "PNG")
    

    = なんとなくわかってきた。 慣れればド→ソの+7ジャンプもわざわざ裏返さずにできるようになる。 というかド→ソは簡単か。裏の次だから。 ド→ラは-3してオクターブ上げるのでソ→ミと同じ。 そう考えるとたいがいの跳躍はできるようになる。 後は+2や+1で1オクターブ駆け抜けるのをできるようになれば…。 ケーブルが絡まるんだよなぁ。

    2007年02月02日

    もっと執筆日記

    昨日の「jythoncが生成するデフォルト・パッケージにクラスの入ったJarファイルを ビルドパスに入れても中のクラスが使えない」という問題。 1.4 の1.3.xとの互換性の説明によれば 「コンパイラは、名前のないネームスペースから型をインポートする import 文を拒否するようになりました。」 とのこと。やはり。

    というわけで「Pythonで部品を作ってjythoncでJarにし、Javaから使う」という筋道は かなり面倒だ。 「大変だけど一応やる方法がある」と書くのか 「大変なのでおすすめしない」と書いて詳細を割愛するのか、 どっちがいいのやら。

    基本に立ち返って考えよう。 まず「何を伝えたいのか」を考えるんだっけ。 Jythonを既存のJavaプロジェクトに入れると、 実行時に生のオブジェクトをいじれたりして楽しい、ということ。 Pythonで開発をしていると、ちょっと疑問に思ったことをすぐに対話的インタプリタで確認できるが、 Javaでは修正とコンパイルの作業が必要だった。 Jythonを使えばある程度は対話的に確認できるようになる。

    そう考えるとjythoncの話はどう考えても余談だよなぁ。


    = 行きの電車の中で多人数翻訳システムのことを考えていた。 4月になったらDjangoを勉強してプロトタイプを作ろう。
    = うわーん。 昨日はうまく動いたはずのプログラムがうまく動かないー。 何が変わったんだー。 でるエラーがNoClassDefFoundErrorだからさっぱりわからないぞ。

    そして手首が痛くなってきた…。腱鞘炎気味。うーん。

    帰ろう…。 昨日動いたはずのプログラムがちゃんと動いたら 原稿が完成して気分よく帰れるはずなんだけどな(´・ω・`) でも動くはずのものが動かないと言うことは僕の理解が足りていないと言うことで… うーん。


    = 外に出て冷たい風に当たったら冷静になった。 そもそも昨日動いたと思ったのが勘違いじゃないだろうか。 それとも夢でも見ていたのではないだろうか。 どう考えても昨日動いた方法で動くはずがないように思う。

    そして必死になって再現しようとしていたけど、 そんな必要はないのではないだろうか。 「可能だけども、~という理由で使わない方がよい」 と言っている、その方法の説明で、 一応動くけどもJava1.3のソースレベルにしないとコンパイルが通らないと言うだけ。 それでいいじゃないかと。 それを回避するための方法を発見したと思ったけど再現しないー、って悩んでたけど、 そんなところに完璧を求める必要は無いじゃないか。 「この方法はおすすめしませんが、一応可能です。ただし1.3じゃないとコンパイルできません」 で何の問題があるのかと。


    = 帰ってきたら日付変わってるし。
    = 宇田君から先日の 「曲のある音と次の音の間が2度上がるのか3度上がるのかが重要」 という表現は間違っているとのつっこみが。 音程 - Wikipedia。 「3度 二つの音の間に半音が3つの時、短3度と呼ぶ。半音が4つの時、長3度と呼ぶ。」 うわー。なにその意味不明な定義…。
    = 疲れた。

    「ダブルクリックで実行するのを試してみましょう」 →「ダブルクリックでの実行を試してみましょう」

    … 「ダブルクリックで実行してみましょう」の方がいいか?

    「自動的に依存しているライブラリもJARに含められるので、」 → 「依存しているライブラリは自動的にJARに含められるので、」

    「うまくいきましたか?」 → 読者はどういう状態がうまく行った状態かわからない。具体的に 「虹色にHello, Applet!と表示されましたか?」とか書くべき。

    「の」に注意。 特に「のが」「のは」

    「~しないといけないわけです。」→「~しないといけません。」

    原稿ができたら印刷してチェックする。 行き帰りの電車の中とか、執筆時と違う環境でチェックする。 声帯を使ってチェックする。 赤ペンで修正する。 修正を原稿に反映したらすぐ捨てるか、 半分に折って反映済みだという印にする。


    = 今日のウダー。 全然練習できてないので全然うまくなっていません。 でもさすがに第6小節までは楽譜を暗唱できます。 口では言えないけどウダーの運指でなら。

    先日のウダー改造で、側面に3個おきにシールを貼ったりしたのですが … … … わかんないって。 ビニールテープにドレミって書いて貼ろう…。

    サクラで作ったパッヘルベルのカノンをPythonで処理して楽譜を作ろうかと思ったのだけど、 どうせならMIDIを読んで作る方が汎用性が高いなぁと思って、まだ着手せず。

    Pythonでウダー用の見やすい楽譜を作って、 ウダーにシールで目印をつけたら もっと弾けると思う…。

    パッヘルベルのカノン練習中 写真共有「フォト蔵」

    2007年02月01日

    Jython執筆日記(執筆と言うより調査)

    Pythonではselfが省略できないのが微妙。 特にJavaとセットで使う場合。 thisが省略されていることがわかっていない人は 「あれー、なんで自分のメソッドなのに呼べないんだ?」 とか思うのかも。
    = jythoncで化ける、 どうしようもないのか?

    jythonc -all

    署名にはkeytoolを使う。 JDKの中に入っている。 パスを通してあるならばcmdでkeytoolってやるだけ

    ktkr! アプレットでPythonインタプリタが動く!

    いや、キタコレはさておき、 せっかく*.cerとかいう証明書を作ったのに 「信用しますか?」ってダイアログに対してうっかりyesを押してしまったために 証明書の出番が無いまま信用されてしまった。

    日本語は使えないなぁ(´・ω・`)

    結局*.cerの使い方がわからない。 ユーザーにインポートさせれば 「信用しますか?」というダイアログが出ないようになるということはわかったけど、 発行者が自分で署名したような証明書をインポートしちゃいけない気がする。


    = ウダーを使って思ったこと。 ドレミはどうでもよくて、 曲のある音と次の音の間が2度上がるのか3度上がるのか2つ離れているのか3つ離れているのかが重要。 パッフェルベルのカノンなら、 2,2,2,1,2,2,2,2。 始めるポイントはどうでもいい。

    そして気づいたこと。 僕の演奏は0.5半音正しい音程から低く演奏していた! 溝の部分がドレミだと思っていたけど、実際は板の部分だった! それでも曲になるところがさすがウダー(ぇ

    ウダーをちょっと改造。 持ち手を削って(僕は宇田君より指が短いので)、 側面に目印のネイルシールを貼り付け。 さっきもう一つ改造方法を思いついたので明日試してみよう。


    = おなかすいた…。

    明日はGRINEditをいじって、デモして、お酒を飲む予定。


    = 心臓が…。
    = 次の日。 GRINEditにマウス操作で頂点と辺を追加する機能を追加。 50インチタッチパネルでデモ。 面白い。

    コーリャン酒は強すぎる。


    = さらに次の日。

    Googleにつながらない。 仕事にならない。


    = 人力検索はてな - Googleにどうやったら入社できるでしょうか。職種は研究開発(新卒採用)を希望です。現在、IT系の大学1年生でプログラミング経験は全くありません。次年度からWebプログラ..。 こんなことまで聞いちゃう時代。 すごい。
    = 酸素濃度を測定して、一定以下に下がると警告してくれる機械が欲しい。
    = 「届出」と「屈由」ってよく似ているじゃん(屈理屁)

    まぁ、手帳に書かれた「キムラ」って誰のことかと思ったら 「払う」だったこともありましたっけ。


    = Googleにつながらなかったときに検索しようとした内容を、 つながるようになってもすっかり検索し忘れていた。 で、思い出して検索。 JDK1.4以降では、 デフォルト・パッケージからのインポートができない、 という噂。未確認。

    さて、どうしようか。jythoncで作成したJarでは ユーザーの作ったクラスはデフォルト・パッケージに入る。 かといってjythoncで作ったJarを使うプログラムではパッケージをわけない、 ってのもめちゃくちゃな話だし。 デフォルトパッケージに入っちゃってるJarを(解凍していじったりしないで) 特定のパッケージに入れたりできるかなぁ。できるという話は聞いたことがないなぁ。

    jythoncでPythonコードをコンパイルしてJarを作って、 解凍してフォルダ作ってクラスファイルを移動してzipで圧縮して、 拡張子をjarに変えてビルドパスに追加してインポートしたら一応使えた。 (追記:夢でも見てたのじゃないだろうか)

    個人的にはJythonで部品を作ってそれをJavaから使おうという発想が 「筋の悪い手」だと思っているのであんまり解決するモチベーションが沸かない。 これの他にも色々問題点があるので。コード中で日本語使えないし。 メソッドシグニチャがないのを特殊なコメントで補わないといけないし。 そういう問題点の色々ある「いばらの道」であっておすすめはしない、と書くか。


    = 人力検索はてな - 【ゲーム】私の血液型を当ててください。 ルール:最初の15件の回答で、私の血液型を推理するための逆質問をしてください。 その後の回答で、私の血液型をずばり当ててくだ..
    あなたの両親の血液型は何ですか?
    解説が不十分でした。 正攻法で当てようとするのは、なしです。すみません。 一応答えておきます。両親のうちの片方、または両方は、私と同じ血液型です。(これ、ヒントになってませんよね?)
    問い:このヒントの情報量はいくらか。ただし計算の簡便化のため、 O,A,B,ABの人口比は4:5:5:2としてよい。 また「同じ血液型」とは「O,A,B,ABの4つに分類した場合に同じカテゴリに入る」という意味だとする。

    なんて問題はどうでしょう。

    人口比からOO:AO:AA:BO:BB:AB = 4:4:1:4:1:2と決まるわけですが、 子供がOO型の場合、両親とも血液型が違うのは両親がAOまたはBOの場合の1/4だから 4/16 * 4/16 * 1/4 = 4/256。 子供がAO型の場合、Aを供給する親がA型ではいけないのでAB型とOO型の組み合わせに限定され 2 * 2/16 * 4/16 * 1/2 = 8/256。 子供がAA型の場合、両親ともABでなければいけないので 2/16 * 2/16 * 1/4 = 1/256。 子供がAB型の場合は、片親がAで片親がB。AAとBBの場合 2 * 1/16 * 1/16 * 1/1 = 2/256。 A0とBBの場合 2 * 4/16 * 1/16 * 1/2 = 4/256。 AAとB0の場合も同様に4/256。 AOとBOの場合 2 * 4/16 * 4/16 * 1/4 = 8/256。 合計、18/256。 全部の合計は40/256になるので「両親とも自分と血液型が違います」と聞いた後の分布は AB型18/40、A型9/40、B型9/40、O型4/40。 あ、逆だ。 AB:A:B:0はもともと2:5:5:4だったので、 32/256:80/256:80/256:64/256。ここから上の値を引いて 14/256:71/256:71/256:60/256。 合計が216。 エントロピーを計算すると

    >>> from math import log
    >>> [x/216.0 * log(x/216.0) / log(2) for x in [14, 71, 71, 60]]
    [-0.25585859315500975, -0.52761558874432346, -0.52761558874432346, -0.51333247404304172]
    >>> -sum(_)
    1.8244222446866982
    >>> [x/16.0 * log(x/16.0) / log(2) for x in [2, 5, 5, 4]]
    [-0.375, -0.52439747034769935, -0.52439747034769935, -0.5]
    >>> -sum(_)
    1.9237949406953987
    

    つまり元は1.92だったエントロピーが、このヒントによって1.82に減ったので、 0.1ビットの情報が与えられたと言うことになる。

    あってんのかな、自分。