pip と Python 3.3

以下, メモレベルで.

発端

「Python3 で Sphinx って使えるんだっけー?」と思って, 試しにインストールしてみたときに気付いた. Jinja2 を pip でインストールするときに, 不思議なエラーが出る. インストール自体は成功する.

やりとり

清水川さんと色々やりとり

というわけで, distribute の easy_install 使って入れてみたら, さっきのエラーは出ずに無事インストールできた.

原因がさっぱり予想付かなかったけど, 稲田さんによるとこんなことらしい.

pip けっこう過激な対応してますね……

(追記 2013/02/16 22:50) この点について稲田さんが Pull Request を作成しています → https://github.com/pypa/pip/pull/810

distribute じゃなくて pip 使ってる理由は uninstall コマンドが使えることなんだけど, また清水川さんから教わる.

easy_install で入れたものが, pip freeze -l でも認識されてるし, pip uninstall でもちゃんと egg を消してくれた.

venv

venv + distribute での Shpinx のインストールを試す (予定)

use JavaFX from Jython

I love Python, even on JVM! So, I decided to use JavaFX from Jython.

This article is a 20th day of JavaFX Advent Calendar 2012

I started translating Java code on this article into Jython.

Setting up Environment

We need JavaFX SDK and Jython which can use it. A following sequence is actual processes I went through.

To obtain JavaFX developing environment, I installed JavaFX for Java SE 7.

Following this instruction, I made Java 7 as a default JDK.

$ sudo mv /System/Library/Java/JavaVirtualMachines/1.6.0.jdk /System/Library/Java/JavaVirtualMachines/1.6.0.jdk.bak
$ sudo ln -s /Library/Java/JavaVirtualMachines/1.7.0.jdk /System/Library/Java/JavaVirtualMachines/1.6.0.jdk
$ java -version
java version "1.7.0_04"
Java(TM) SE Runtime Environment (build 1.7.0_04-b21)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)

Next I compiled Jython with Java 7.

$ hg clone https://bitbucket.org/jython/jython
$ cd jython
$ ant
$ ls dist/bin/jython

The result jython executable exists at dist/bin/jython. When I compiled, the Mercurial changeset ID is 6898:2ccd73a00a86 and Jython version is 2.7.0a2+.

Now, all had been set up.

Hello, World!

Since ...

Scalaz の Functor trait を初心者が実装してみた

Scalaz Advent Calendar の 10 日目の記事として書いています.

前回の記事 では Functor の構造について数学の定義を対比させながら書きました. 今日は Scalaz を使ったプログラムを書いて Functor の実装をしてみましょう.

準備

今回の実装をするために sbt で管理している Scala プロジェクトを作成しました. 同じ環境を作成して色々触ってみると楽しいと思います. 実際, 私は自分で実装してみて Functor の使い方がより分かるようになりました.

私は以下の環境で作業しました. (scala, scalaz は sbt で取得するので, sbt のバージョンさえ合っていれば同じ作業ができるはずです)

sbt 0.12.1
scala 2.10.0-M7
scalaz 7.0.0-M3
Giter8 0.4.5

Giter8 についてはこちらを参照してください. http://blog.twiwt.org/e/f12c0f

前置き

説明を簡単にするために implicit なものは使っていません. 対象を函手で写すときには, implicit conversion を使うと綺麗に書けるのですが, 今回はそこが本題ではないので敢えて使っていません.

今回は以下のページを参考にしました.

環境準備

g8 typesafehub/scala-sbt コマンドを実行して, パッケージ名など適宜答えていきましょう. scala のバージョンを聞かれたら 2.10.0-M7 としておいてください.

<project_root>/project/<project_name>.scala に sbt の設定を追加して, scalaz が利用できるようにします.

resolvers += "Typesafe Snapshots" at "http://repo.typesafe.com/typesafe/snapshots/",

libraryDependencies ++= Seq(
  "org.scalaz" % "scalaz-core" % "7.0.0-M3" cross CrossVersion.full
),

scalacOptions += "-feature",

initialCommands in console := "import scalaz._, Scalaz._"

実際のファイルは https://bitbucket.org/cocoatomo/scalazsample/src/e5efd3d7b750/project/ScalazsampleBuild.scala?at=default を見てください.

次に <project_root>/src/main/scala/<package_hierarchy>/なんとか.scala に以下の import 文を追加します.

import scalaz.Functor

ソースコードは https://bitbucket.org/cocoatomo/scalazsample/src/a451998f4f2fa9ab09771622a333e9dd9fbe64b9/src/main/scala/net/elliptium/Scalazsample.scala?at=default を見てください.

そして最後にコンソールに戻って sbt run コマンドを実行すると, scalaz-core の取得が行われ, プログラムが動きます. g8 コマンドの引数に typesafehub/scala-sbt を指定してプロジェクトを作成した場合, "Hello, <project_name>" メッセージが出力されるだけのプログラムになっているはずです.

作成する Functor

今回作成する Functor は Important という名前にします. 普通の「クラスの圏」から「重要なクラスの圏」への函手というイメージになります. 今回持ち上げる射の例として length というものを選びます. 図式を書くと以下のようになります.

              lift(length)
Important[String] → Important[Int]
       ↑                ↑
       ↑                ↑
       ↑                ↑
     String       →     Int
                length

length: String => Int 函数は名前の通り「文字列の長さ」を返すものです. Important という Functor は「2重にする」函手です. 実体は Tuple2 に似た case class で, toString をちょっとイジってあります. これはソースコードを見た方が理解が早いでしょう.

実装

Important

これが Important[T] の実装です.

case class Important[T](val value: T) extends Product2[T, T] {

  def _1: T = value
  def _2: T = value

  override def toString: String = value.toString + ", " + value.toString

}

このクラスのコンストラクタで「普通のクラス T 」を「重要なクラス Important[T] 」に持ち上げています. 図式の以下の矢印にあたります.

Important[String]    Important[Int]
       ↑                ↑
       ↑                ↑
       ↑                ↑
     String ...

Scalaz の Functor.scala を初心者が読んでみた

Scalaz Advent Calendar の 6 日目の記事として書いています.

準備

今回解説するソースコードは scalaz/Functor.scala です.

scalaz-seven ブランチのものであることに注意してください.

前置き

数学 (代数) は一応やってはいたものの, Scala や Scalaz のことを全然分からない状態からこの記事を書いています. そんな人間が Scalaz を読んだらどう見えるか? という実験記録のようなものがこの記事です.

圏論については「圏論の基礎」を参照しています. 用語などはそちらに倣いました.

数学の函手とは

最初にざっと圏論の概念の定義を並べておきます.

圏 (category) の定義

  • 圏とは対象 (object) と対象の間の射 (arrow) の集まり

    • f はある対象 a とある対象 b を結び付けるもの

      この射は方向を持っているので f: a → b のように表記することが多いです

      この af のドメイン (domain, source), bf のコドメイン (codomain, target) と言います

  • 各対象 c には id c という c から c への射 (恒等射, identity) が存在する

  • f: a → b, g: b → c があったとき, それらをつないだ合成射 (composite) g・f: a → c も存在する

    • 恒等射 id c: c → c と合成の関係は以下の通り

      • f: b → c, g: c → d としたとき (id c)・f = f, g・(id c) = g

        つまり恒等射は合成 (composition) 演算の両側単位元です

    • 複数の合成がつながっている場合合成の順序は問わない

      f: a → b, g: b → c, h: c → d があったとき, (h・g)・f = h・(g・f)

      いわゆる結合則 (associative law) です

つまり圏とは群と群の間の準同型の集まり, のようなものです. この喩えでは, 対象が群という1つの集合なのですが, 圏論では群の元1つ1つについて直接扱わない流儀を採ります.

圏を図で書くと, 圏は対象をノードとし, 射をエッジとする有向グラフになります. これを図式 (diagram) とかと呼んで, 圏の説明で使ったりします.

函手 (functor) の定義

この対象と射を含む圏どうしの間にも対応付け (函手, functor) を考えることができます. 射が対象どうしの対応付けだったのに対し, この函手は圏どうしの対応付けになっていて 1 段上のメタなものになっています.

  • 函手とは圏と圏の間の対応付けで, 対象を対象に, 射を射に対応付ける

    型を考えると対象を写すものと, 射を写すものは別の関数になるのですが, 同じ記号で書いても混ざることは無いので同じ記号を援用したりします

    • 函手 T が写した対象と射の関係は以下の通り

      • T(id c) = id Tc

        恒等射を恒等射に写します

      • T(f・g) = T(f)・T(g)

        合成を保ちます

この函手を大雑把に説明すると, 圏の中にある図式を別の圏に写すものです.

Scalaz の Functor とは

ここまでを踏まえて Scalaz の Functor が数学の函手になっているのか見ていきましょう.

実装

まず Functor の先頭部分は以下のようになっています.

trait Functor[F[_]]  { self =>
  ////

  /** Lift `f` into `F` and apply to `F[A]`. */
  def map[A, B](fa: F[A])(f: A => B): F[B]

  // derived functions
  ...

F という Functor を宣言し, map というメソッドの型が定義されています.

他のメソッドは Functor#map メソッドを使って実装されているので, 最低限 Functor#map だけ実装すれば良さそうです. (このあたりはまた後日追い掛けます)

数学の定義と対比して

Scalaz の Functor はいったいどんな函手なのかを見てみましょう.

Functor#map の型を見てみると以下のようになっています.

/** Lift `f` into `F` and apply to `F[A]`. */
def map[A, B](fa: F[A])(f: A => B): F[B]

これから map メソッドは fa: F[A]f: A => B を受け取って, F[B] 型のインスタンスを返すのが分かります. 意図としては, f という関数を持ち上げて fa に適用しています.

図式として書くと以下のようになります.

F[A] → F[B]
 ↑      ↑
 A   →  B

函手のドメインである圏には AB が対象として存在し, f が射として存在しています. 下の段の矢印が射 f です.

A → B
  f

対象 A, B をそれぞれ持ち上げているのが型パラメータを 1 つだけ受け取る型クラス F です.

  F[A]   F[B]
F ↑    F ↑
  A ...

CentOS 6.3 に Emacs 24 をインストールした記録

scala-mode2 を使いたかったけど, CentOS 6.3 の yum では Emacs 23 までしか用意されておらず, scala-mode2 が動かなかったので, 自前で入れた手順の記録.

GNU の mirror (http://ftp.jaist.ac.jp/pub/GNU/emacs/ とか) から tar ball を落とす. ここでは wget 使ってます.

$ wget http://ftp.jaist.ac.jp/pub/GNU/emacs/emacs-24.3.tar.gz
$ tar xvf emacs-24.3.tar.gz
$ cd emacs-24.3
$ ./configure --with-x-toolkit=gtk
$ make
$ ./src/emacs
起動確認
$ sudo make install

X でビルドしてみたけど GUI が古臭かったので gtk にした. configure のときに色々ライブラリの不足で失敗するけど, その都度インストールした.

無事に Emacs 24 が動作し, scala-mode2 も動いている. めでたしめでたし.

Full Metal Jacket & Black Hawk Down again

前にも Black Hawk Down を観たよという 記事 を書いた.

ふとまた観たくなって Full Metal Jacket と一緒に借りてみた.

両作品ともに, 思想や主題の主張を極力抑え, 事実の描写にのみ留めているために, 思考を巡らせる材料として優れていると思う. (Full Metal Jacket はフィクションだけどベトナムでの状況の描写は南北どちらの思想にも肩入れはしていない)

以下, ネタバレありなのでまだ観てない方はご注意を.

ネタバレ

ネタバ

ネタ

Full Metal Jacket

前半部はハートマン軍曹無双だった. 噂に違わぬキャラでハートマン軍曹以外の訓練生のことはほとんど印象に残ってない. しかし, あれが 本物の軍人 だというのには驚いた. 訓練風景も実際はあんなふうなんだろうか.

後半部は淡々とベトナムでの戦闘の推移を描いていく.

下の Black Hawk Down ほどではないが, 指揮官が死亡してしまった後の混乱ぶりが傍観者の視点で描かれていく. チームの階級上のリーダーと精神的な (実質の) リーダーが食い違ってしまった状態の混乱がよく描かれている.

突然, 現場でリーダーになってしまったカウボーイは良い判断をしていたが, なにぶんチームメンバーと「リーダー=メンバー」の関係を作り上げるための時間が無かった. そのためエースとして描かれているメンバーの意見になびきやすい, 危うい集団が出来上がってしまった.

しかし現場ではその集団の空気には逆らえないだろう. 対策を打つとすれば, 前もってリーダー離脱時 (もしくは死亡時) の次期リーダーを決め, 訓練をしておくしかないだろう.

その混乱の1つの表れとして, たった1人の狙撃手に対して大量の弾薬と2人の兵士の命が犠牲として捧げられてしまった.

最後のベトナム兵の声と表情が不気味に頭に残る映画だ.

Black Hawk Down

一度観ているだけに, 前半部のお気楽な雰囲気が逆に後半部の地獄を思い出させて, 不安がただただ募っていった.

元々, 少数精鋭, 短時間の一撃離脱戦法, 最小限の戦果のための最小限の作戦だったはずなのに, 短時間で離脱できなかった時点で作戦そのものを考え直す必要がある. (もちろん最小限だからと言って, 簡単だとは限らない) 指揮官は状況報告を受けつつ緊急救援の手を探していく. 最前線の兵士は, 各自が最善と思う判断をしつつ行動していく. もちろん全体像が見えているわけではないので, 局所的な最善だが. 墜落現場が見事にゴキブリホイホイになっているのは, 現場での視点を想像すると責められるものでもない.

やたらと大量に出てくる一般兵に囲まれる感じは, 真・三國無双2の最強モードを思い出させる. じりじりと手元の資源を削られていく戦闘は, 少数精鋭部隊との相性は悪い. いくら優秀な人間とはいえ, 目は2つしか無いし, 頭は1つしかない. 焦りもあるし, 疲労もある. ゲームと違って敵大将もいないし, 仮にいたとしても大将を倒しても戦場を離脱できるわけでもない.

最後の方でデルタのチームが活躍するが, そもそもこのような戦闘が起きること自体が失敗の証だろう.

ちょっとこの映画で分からないのは, 指揮官が最悪のパターンをどこまで考え, どのようにその準備をしていたかだ. 人員の逐次投入や増援の調整を戦闘中に行っているところを見ると, 想定の範囲外だったような印象を受ける. となると, 相手の戦力も読めていなかったわけで「そんなんでいいのか?」と思う. 戦力が読めなければ, 戦力を読むための作戦を行うべきだ. (まぁ結局「べき論」になって卑怯な物言いなのだが)

そして相変わらず,「この戦闘を終結させたもの」が描かれると虚しさを倍増させる……

とにかく「リソース (装備, 人員, 時間など) を余裕を持って確保しておくことは大事ですね」としか言いようが無い. 30分の作戦に厚い装備を用意するデルタフォースの姿を忘れずにいるしかない.

Heroku 上の Django アプリで django_session が溢れた

ある日 HHTQA が 500 を返して動かなくなってた.

$ heroku logs

の末尾にあやしいメッセージが.

OperationalError: (1142, "INSERT command denied to user 'user'@'hostname' for table 'django_session'")

MySQL の権限が変わるわけがない (ClearDB という add-on なので, ユーザとかは俺はいじれない) し, MySQLWorkbench では同じユーザで見れているので, 権限が根本原因ではない.

MySQLWorkbench で色々見てみると django_session というテーブルが肥大化している. テーブル名や expire_date というカラム名から, 明らかに不要なデータが溜まっている.

SELECT count(*) FROM django_session; -- 15677

このテーブル名で検索すると https://docs.djangoproject.com/en/dev/topics/http/sessions/?from=olddocs/#clearing-the-session-table という情報が見付かり, 手作業で削除することもできるそうだ.

heroku コマンド使って, Heroku 上の環境で削除操作を行った.

$ heroku run find / -name django-admin.py
Running find / -name django-admin.py attached to terminal... up, run.1
find: `/proc/tty/driver': Permission denied
find: `/proc/1/task/1/fd': Permission denied
find: `/proc/1/task/1/fdinfo': Permission denied
find: `/proc/1/fd': Permission denied
find: `/proc/1/fdinfo': Permission denied
find: `/lost+found': Permission denied
find: `/etc/ssl/private': Permission denied
/app/.heroku/venv/bin/django-admin.py
/app/.heroku/venv/lib/python2.7/site-packages/django/bin/django-admin.py

$ heroku run .heroku/venv/bin/django-admin.py cleanup
DJANGO_SETTINGS_MODULE が無いと怒られるので設定.

あくまでモジュール名. ファイル名ではないので注意.
$ heroku config:add DJANGO_SETTINGS_MODULE=settings
$ heroku run ls '$DJANGO_SETTINGS_MODULE'
確認
$ heroku run .heroku/venv/bin/django-admin.py cleanup
SELECT count(*) FROM django_session; -- 1933

予想通り django_session テーブルが小さくなったので, Heroku アプリを再起動.

$ heroku restart
$ heroku logs

まだ何かエラーが出る. 以下 heroku logs の結果.

2012-07-14T12:52:29+00:00 heroku[web.1]: Starting process with command `python manage.py run_gunicorn 0.0.0.0:33646`
2012-07-14T12:52:30+00:00 app[web.1]: Unknown command: 'run_gunicorn'
2012-07-14T12:52:30+00:00 app[web.1 ...

s3:// と s3n:// の違いとは??

現在クラウドサービスと呼ばれるものには色々あり賑やかですが, 今回の話は Amazon Web Services (AWS) が提供する Elastic MapRecude (EMR) と Simple Strage Service (S3) の小ネタです.

S3 は文字通りディスクのようにファイルの保存先として使えます. Apache Hadoop でも入出力先として S3 が使えるようになっていて, Apache Hadoop を使っている EMR でも, もちろんこの S3 が利用できます.

その S3 のファイルパスの先頭にスキーマ名が付くのですが, Elastic MapReduce (EMR) の文書では s3://s3n:// が混在しています. (ここのコマンドとか) 何か違うのかどうか色々検索してみたり, 以下の本にあたってみたりしたところ, 特に違いは無いそうです.

本家の EMR の資料に「Apache Hadoop では違いがあるけど, EMR では特に違いは無いよ」という記述があります. → http://docs.amazonwebservices.com/ElasticMapReduce/latest/DeveloperGuide/FileSystemConfig.html ちなみに Apache Hadoop での s3://s3n:// についてはこちら → http://wiki.apache.org/hadoop/AmazonS3 AWS の本家の資料はかなりしっかりしているので, サービスを使う前に舐めるように全部読むべきでした. 反省.

結論ですが,「EMR では別にどっちを使っても構わなくって, Apache Hadoop の s3:// のようにしたければ hdfs:/// (こっちはスラッシュ3つ) を指定しなさい」ということでした. (http://docs.amazonwebservices.com/ElasticMapReduce/latest/DeveloperGuide/CLI_CreateStreaming.html#API の Note)

ちゃんちゃん.

「Java 開発者のための関数プログラミング」を読んで

Java 開発者のための関数プログラミング という本をとんぷーが翻訳した (「Java開発者ための関数プログラミング」が出版されました) というので ePub で買って読んでみた. 前からとんぷーが何か本を翻訳している話は聞いていたし, タイトルにすごく惹かれたので, 出てすぐに買い iPod touch に放り込んで主に寝ながら読んでいた.

(特にアプリは入れずに iBooks で読んでたけど, 本文に対してメモが取れるところが便利.)

内容について

おおよそタイトルから想像した通りの内容だったが, Java の動くソースコードをちゃんと書いて説明しているところにこの本の価値を感じる. 余談だが, bleis さんの Java の語彙で Maybe を説明してみる という記事も近いものに思う.

通常の Java クラスをモジュールとして使ったり, 継承を使った多態を否定して使わなかったり, Java プログラムとしては挑戦的な作りになっている. こういう「無茶しやがって」感が面白い. いわゆる関数型プログラミング言語に出てくる仕組みを別の仕組みを持つ Java で実装してみるというのは, その仕組みを複数の視点から見てより理解を深めることになる. Java で無理して関数プログラミングをすることで, 関数プログラミングのスタイルがどんなもので, どれだけ Java がそのスタイルに向いてないかが良く分かる.

内容が「関数プログラミングで書くと何が良いか?」という一貫した視点で書かれていて読み易い. 色んな論点を網羅的に扱っているところも有難い. もちろん翻訳された日本語に不自然さがないところも素晴しい. 通しで読めば1日で読めてしまうのではないだろうか?

(内容も文体もどことなくブログ記事っぽく感じるのは何故なのだろう)

クスッとしたとこ

意図的かは分からないが, 原著のタイトルの "functional programming" を「関数型プログラミング」でなく「関数プログラミング」と訳したのはけっこう好き. たぶんとんぷーのことなので意図的なんだろう.

「Customerクラスは顧客に関するすべての情報を突っ込む福袋のようになっていました」というところ.「福袋」という表現がぴったりハマっていて小粋なところがにくい.

「Nullとはなんだったのか」という節のタイトル. よくブログ記事とかで見るが, null の面倒さを知ってるとウンウンと頷くタイトルだ.

本筋とは全く関係無いが, クラス NaturalNumbers に定数 (public static final なフィールド) ZERO があるということは, 著者は「0 は自然数」の人なんですね. そうなんですね.

誤植

「本書で使用されている表記規則」

半角の閉じ括弧 (")") が余計.

固定幅文字(Constant width))
                          ^

System Message: WARNING/2 (<string>, line 43)

Literal block ends without a blank line; unexpected unindent.

「コンビネータ関数:コレクションの強力なツール」

組版ツールの関係だろうが, 何やら不思議な文字列が残っている. たぶん "@" というのが特殊記号なのだろう.

filterは「head」と@「<tt>{filter}をtailに適用した結果」
                  ^  ^^^^^^^^^^^^

(指摘されるとけっこう凹むのだが, 気付いてしまったので一応報告)

おわりに

Java で関数プログラミングをしてみる, という1つの発想から書かれた本ですごく読み易い. 関数プログラミングの仕組みについて頭を整理するのにも良い.

既に関数プログラミングを理解している人は読む必要はあまり無いが, 既存の解説読んでもピンと来なかった人が読むと良いかもしれない. 人によって理解が進む解説は様々なので, 色々なスタイルの解説があることはとてもよいことだ.

こういった文章を書いて, プログラミングをする人達に貢献していくことも素敵なことだと思う.

とにかく読んでて楽しい本でした.

Heroku の動作変更? Django の DATABASES 設定でコケた

以前 この記事 で書きましたが, Heroku の上で OSQA という Django アプリを動かしました.

最近また Heroku に静的ファイルを追加するため, git レポジトリにファイルを追加し, Heroku に再デプロイ (git push) しました.

これでアプリが再起動され, 無事動くはずだったのですが, Internal Server Error が出てしまいほとほと困りました.

heroku logs で見てみると不可解なことに, 使ってないはずの PostgreSQL に接続しようとしてエラーになっています.

2012-06-10T04:04:13+00:00 app[web.1]: /app/.heroku/venv/lib/python2.7/site-packages/gunicorn/glogging.py TIME: 2012-06-10 13:04:13,215 MSG: glogging.py:exception:143 Error handling request
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 99, in handle_request
2012-06-10T04:04:13+00:00 app[web.1]:     respiter = self.wsgi(environ, resp.start_response)
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/contrib/staticfiles/handlers.py", line 68, in __call__
2012-06-10T04:04:13+00:00 app[web.1]:     return self.application(environ, start_response)
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 250, in __call__
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 45, in load_middleware
2012-06-10T04:04:13+00:00 app[web.1]:     self.load_middleware()
2012-06-10T04:04:13+00:00 app[web.1]:     mod = import_module(mw_module)
2012-06-10T04:04:13+00:00 app[web ...

Licenses