しばらくぶりにubuntu ppaへパッケージを上げるときの手順

Ubuntu Preciseへのアップグレードをしたので、自分のppaのpythonライブラリのパッケージを更新した。launchpadへのgpg鍵の登録から行うことになり、そのメモ。

パッケージのPreciseへの対応

debian/controlのDependsでpreciseのパッケージに対応するパッケージ名に変える。preciseではPythonのバージョンはpythonが2.7でpython3が3.2で、2.6がpython2.6として独立してインストール可能である(3.1は消えた)。

すなわち"debuild -uc -us"でビルドできるようにしておく。

gpg鍵生成

gpg --gen-key

有効期限は1yでアルゴリズムや鍵長はデフォルトで良いが、名前とメールアドレスはdebian/changelogの名前とメールアドレスに合わせなくてはいけない。鍵生成をサーバで行う場合rng-toolsパッケージを入れておくといい。passphraseは必須。

gpg鍵登録

まず鍵送信

gpg --send-keys --keyserver keyserver.ubuntu.com 580B5697

最後の引数は生成した鍵のID。"gpg --list-keys"コマンドで鍵一覧が見える。この限りストのうちuidが付いているpubの鍵IDを送る。

次にlaunchpad上で鍵を登録する。ブラウザで"OpenPGP Keys"のアイコンをクリックし、下部の"Import and OpenPGP Key"のフォームにfingerprintを入れ、"Import Key"ボタンを押す。(鍵送信からlaunchpadが利用可能になるまで少し時間がかかるので、失敗したら数分待ってから行う)

fingerprintの出し方は、以下のようにコマンドで鍵IDを指定して行う。

gpg --fingerprint 580B5697

ここで出る指紋の4x10文字をスペース入りのままフォームへコピペする。

するとメールが送られてくる。このメールのうち

-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.10 (GNU/Linux)
...
-----END PGP MESSAGE-----

の部分をテキストファイルとして保存する。たとえばencrypt.txtというファイル名にする。

このファイルをgpgで復号する。

gpg encrypt.txt

復号したファイル内の一番下の行のURLへアクセスし、continueすればOpenPGP Keysに登録される。

この鍵でCode of Conductサイン

launchpad上で古いCoCをdeactivateすれば、CoC署名のインタフェースが出る。
UbuntuCodeofConduct-1.1.txtをダウンロードし、署名する。

gpg --clearsign UnbuntuCodeofConduct-1.1.txt

UnbuntuCodeofConduct-1.1.txt.ascが生成されるので、そのファイルを開き内容全部をlaunchpadのフォームへコピペし送れば完了。

ppaへアップロード

dch -v 1.0.5.5-0nmu1ppa1
debuild -S -sa
cd ..
dput ppa:bellbind/python-simplexquery_1.0.5.5-0nmu1ppa1_source.changes

上から順に、dchでppa用バージョン付をし、debuild -S -saで署名付きのchangesをつくる。dput出アップロードする。あとはlaunchpadでビルドが終わるのを待つ。

"大学生数学基本調査"を解いてみる

http://mathsoc.jp/comm/kyoiku/chousa2011/surveyslip0955.pdf

  • 1-1 (1)× (2)○ (3)×
  • 1-2 (1)○ (2)× (3)×
  • 2-1 (b)○ 理由: 1は奇数である。あらゆる奇数は偶数+1で表現できる。あらゆる偶数+偶数は偶数である。偶数+奇数は偶数+偶数+1となり、すなわち偶数+1であるため必ず奇数となる。
    • 1は奇数。任意の整数nにおいて、2n+1は奇数。任意の整数n,mにおいて、2つの偶数の和は、2n+2m=2(n+m)で偶数となる。任意の整数n,mにおいて、偶数と奇数の和は、2n+2m+1=2(n+m)+1で奇数となる。
  • 2-2 1. y軸に(0, -8)で交わる。 2. x軸とは(2, 0)と(4, 0)トで交わる。 3. (3, 1)で傾きが0になり、yの最大値をとる
    • y = -x^2+6x-8 = -(x-2)(x-4), dy/dx = -2x+6
  • 3.
    • 1. 定規で線分をb側に伸ばし、コンパスで2倍、3倍の点をつける:
    • 2. 2倍点をつかい、b点を通る垂線を引く:
    • 3. a点を中心に3倍点をとおる大円弧を書き、垂線と交わらせる:
    • 4. a点と垂線との各交点をつなぐ2線分を引く(2線分:線分ab=3:1):
    • 5. a点を中心にb点から小円弧を書く:
    • 6. 小円弧の上下の交点の間で線を引くと、aからabの1/3の位置で交わる垂線となる:
    • 7. 1/3点を中心にaを通る円弧を書くと、aから2/3の位置で交わる

解答例

http://mathsoc.jp/comm/kyoiku/chousa2011/answer.pdf

そもそもコンパスで平行線ってどう引くんだっけ、って思った。

  • 線上で平行の点と重ならないような垂線を引く
  • 平行線の点からコンパスで垂線上に適当に2点つける
  • 二点からそれぞれ平行線の点を通る円弧をかく
  • 2円弧が交わる2点に直線を引くとそれが平行線

問3はその前に比べ面倒な問題だと思ったけど、FAQを見ると今の中学の教科書に同じ問題があるらしい

ECMAScript5で作ったSameGameの更新

ECMAScript5を使ってSameGameを書いてみた - ラシウラを少しアップデートしました。
エンジン共用でcanvasの他に、CSS3のUIをつくってみました。canvasのない3DSのブラウザでも動くようになったが、アニメーションも入れたので重いけど。

デモ:

SameGameルールエンジン:

SameGame UI:

ES5互換ライブラリ:

更新したこと

  • canvas2dのほかに、CSS3を使ったUIも用意した
  • OperaSafariのようなES5標準関数が足りない環境でも動くように、ダミー実装ライブラリをいれた
    • CSS3のtransitionで少しアニメーションするようにした(IE9以外)
  • boardのcellはcolor値じゃなく、{color: color値}のオブジェクトに変えた
  • 多値や複数パラメータを単一オブジェクトにして受け渡しするようにした
    • forEachをArrayと同じインタフェースにした
  • 最小チェーン数をルール側に移動し、GameOver判定をいれた
  • UIでスコアをつけた
  • 更新リスナをいれた
  • タブレット対応途中

現在のmingw/msysのインストール方法

以前のMSYSのインストールは、コア部分はバンドルインストーラでいれて、足りないものはアーカイブをダウンロードして展開する、という感じで、管理がおそろしくめんどくさかった記憶がありました。
しかし最近更新しようとしてみたら、mingw-getですべて完結するようになっていて、管理がとても簡単になっていた。

古いMinGWの完全削除

新しいmingwを入れる前に、MinGWとMSYS双方をアンインストールし、その後残ったc:\MinGWやc:\msysもディレクトリごと完全に消しておきます。

mingw-get-instでインストール

最新のming-get-inst-YYYYMMDD.exeをダウンロードします(今現在だと20110530)。

このexeを実行し、進めていけば、c:/MinGW以下にmingwが、c:/MinGW/msys/1.0にMSYSが入ります。
(自分はチェックで全部入れるようにしたが、あとで下記のmingw-getコマンドでも追加できる)

minttyからMSYSを使う

スタートメニューから"MinGW Shell"ショートカットを実行すれば、MSYS環境に入ります。このMSYS環境でもcygwinと同じようにターミナルエミュレータでminttyが使えます。

まずMSYS環境で以下を実行し、MSYS用mintty.exeをインストールします:

mingw-get update
mingw-get upgrade
mingw-get install msys-mintty

minttyを実行するには、

  • "MinGW shell"のショートカットの"プロパティ"を開き、"リンク先"に"--mintty"オプションを入れる
C:\MinGW\msys\1.0\msys.bat --mintty

ちなみにminttyコマンドを直接実行して開く場合は以下のようにすれば良いようです。

c:\MinGW\msys\1.0\bin\mintty.exe /bin/bash --login -i

MinGWと併用する場合、pythonrubyWindowsビルドの物を使う場合が多いと思いますが、xtermであるminttyではWindowspythonirbの対話モードが機能しません。なので、通常の"MinGW Shell"ショートカットのプロパティで"簡易編集モード"にチェックを入れておいて使うのが一番良いかもしれません。

簡易編集モードは、ドラッグ選択で(矩形)選択モードになり、右クリックでコピー&モード終了、左クリックでキャンセル&モード終了。通常モード時に右クリックでペーストになります。


その他msysパッケージのインストール

種類はそれほどないですが、追加のmsysパッケージは同様にmingw-get installでいれられます。たとえば、

mingw-get install msys-openssl
mingw-get install msys-openssh

mingw-getで入れられるパッケージの一覧は

mingw-get list | less

で見ることができます。

MSYSのSSL CERTSを更新する

cygwinでのcerts更新方法( http://d.hatena.ne.jp/bellbind/20110609/1307622037 )とほぼ一緒です。

cd /var/ssl/certs
wget -O - http://curl.haxx.se/ca/cacert.pem | awk 'split_after==1{n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1} {print > "cert" n ".pem"}'
c_rehash

これで、wgetでもhttpsサイトに普通にアクセスできるようになります。

bash環境の設定

~/.profile (c:\MinGW\msys\1.0\home\USERNAME\.profile)を作ります。
たとえばxyzzypythonにpathを通す場合:

# clean windows path
export PATH=/usr/local/bin:/mingw/bin:/bin

export PATH="$PATH":/c/Python27:/c/Python27/Scripts
export PATH="$PATH":/c/Ruby187/bin
export PATH="$PATH":/c/Program\ Files\ \(x86\)/MiKTeX\ 2.9/miktex/bin/

export JAVA_HOME=/c/Program\ Files/Java/jdk1.7.0
export PATH="$PATH":"$JAVA_HOME"/bin
export PATH="$PATH":/d/opt/apache-ant-1.8.2/bin
export PATH="$PATH":/d/opt/groovy-1.8.0/bin

function xyzzy {
  HOME="c:/Users/bellbind" /d/opt/xyzzy/xyzzy "$@" &
}

# fallback to cygwin commands
export PATH="$PATH":/c/cygwin/bin

function emacs {
  /c/cygwin/bin/emacs-nox "$@" ; clear
}

おまけ: MSYSシェル上でscala実行

antやgroovyと違いscala-2.9.0.1の時点でコマンドスクリプトはMSYSに対応してません。
そこでMSYS上でコマンドを動かすための簡単なpatchを作りました。

scalaのREPLはbash風の編集コマンドが使えるmintty上のほうが使いやすいと思います。
(scalagithubに移行らしい https://github.com/scala/scala/wiki/Github-Move )

cygiwnでrvmを使ってruby-1.9.2をビルド&インストールする

herokuのデフォルトのrubyが1.9.2になるとのことで、cygwinにもruby-1.9.2を入れておくことにしました。
直接ソースをビルドしてシステムに入れるのではなく、rvmを使ってHOME下にインストールしました。

以下は、その手順です。

事前準備1: cygwinパッケージのインストール

cygwin上に以下のパッケージが入ってなければ入れます。当然cygwin自体も最新版にしておきます。(上からssl certの更新で使うもの、さらにrvmで必要なもの、さらにrubyのビルドで必要なもの、です)

  • gcc4
  • mingw-win32api
  • make
  • openssl-devel
  • libgdbm-devel
  • zlib-devel
  • tcltk
  • bison
  • autoconf
  • m4
  • libffi4
  • libreadline7
  • libopenssl098
  • procps
  • quilt

(いらないものや足りないものがあるかも)

事前準備2: cygwinSSLルート証明書のアップデート

cygwin付属のルートSSL証明書は古いようで、gitやcurlwgetでrvmのサイトなどへhttps接続しようとすると失敗してしまいます。
そこでまず、cygwin上のcertを更新する必要があります。

git - SSL certificate rejected trying to access GitHub over HTTPS behind firewall - Stack Overflow の回答にあるやり方そのままでOKでした。
具体的には以下の3行を実行します:

cd /usr/ssl/certs 
curl http://curl.haxx.se/ca/cacert.pem | awk 'split_after==1{n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1} {print > "cert" n ".pem"}' 
c_rehash

rvmのインストールとruby-1.9.2-headのビルド

事前に古いrvmデータは削除しておきます

rm -rf ~/.rvm ~/.rvmrc

https://rvm.beginrescueend.com/に書いてある方法でrvmを入れます。

bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)

certが古いままならばここで何も表示されずに終わってしまいます。certが更新されていればgit経由でrvmをダウンロードしていきます。

次にrvmを使ってruby-1.9.2を入れます:

source $HOME/.rvm/scripts/rvm
rvm install 1.9.2-head -C "--enable-shared optflags='-O2 -march=native'"

certが古かったり、cygwinパッケージが足りなかったりするとダウンロードやビルドに失敗し赤い文字が画面上に出ます(失敗しなければ緑か白の文字だけ出ます)。

ruby-1.9.2のビルドの仕方はcygwinでrvm - akcnvの個人的備忘録 @ ウィキ - アットウィキのものを参考にしています。今の1.9.2-headではLIBRARY_PATHの設定は不要のようです。(ちなみに1.8.7-headのほうは、上記記事にある対策を取る必要がありました。)

あとビルド時間は結構かかります(5%クロックアップしたASUS UL20Aで1時間くらい)。

rvmのruby-1.9.2がきちんと入ったことを確認する

ビルド後、そのままコマンド

rvm use 1.9.2-head

を実行するとrubyコマンドやgemコマンドが、rvm上のruby-1.9.2のものを使うようになります。

以下のような結果になっていれば入っていることになります:

$ ruby -v
ruby 1.9.2p274 (2011-06-06 revision 31932) [i386-cygwin]

システムのrubyコマンドに戻す場合は、

rvm use system

です。

起動時にrvmコマンドを使えるようにする

以下の行を~/.bashrcや~/.bash_profile等に追加すれば、ターミナルを立ち上げた時点でrvmコマンドが使えるようになります。以下の行はrvmのインストーラーが自動で追加するようです。

[[ -s $HOME/.rvm/scripts/rvm ]] && source $HOME/.rvm/scripts/rvm

デフォルトのrubyをrvmのrubyにする

上記の.bash_profileに加え、以下を実行しておけば、次のターミナル起動からは最初からrubyコマンドやgemコマンドが、rvmのruby-1.9.2のものを使うようになります。

rvm use 1.9.2-head --default

rvm gemsetでgem環境を切り分けよう

rvmはrubyランタイムだけでなく、gemパッケージの環境を切り替えることができます。たとえば、webアプリプロジェクトごとに必要なgemパッケージだけを持った環境を作っておくことで、プロジェクトごとにgem環境を切り替えて使うことができます。

gem環境の管理はrvm useした状態に入ってる時にrvm gemsetコマンドを使って行います。

gem環境作成、たとえばminiblogプロジェクトのための"miniblog"環境を作る場合は

rvm use 1.9.2-head
rvm gemset create miniblog

を実行します。

次に作ったgem環境に切り替えます。

rvm gemset use miniblog

この状態であとはgemコマンドでgem installしていけば良いです。

rvm useコマンドで一緒にgem環境も切り替えることも可能です。

rvm use 1.9.2-head@miniblog

ちなみにデフォルトのgem環境は"global"です。

おまけ: cygwinでrvm install 1.8.7-headする方法

インストール方法

curl -O http://dl.dropbox.com/u/14499563/ruby-1.8.7-p348-cygwin/current-cygwin-has-own-setjmph.patch
rvm install 1.8.7-head -C "--enable-shared optflags='-O2 -march=native'" --patch ./current-cygwin-has-own-setjmph.patch
解説

普通にビルドして失敗するのは、cygwinがすでにsetjmp.hを持っているのに、ソースeval.cとgc.c中でifdef __CYGWIN__内でsetjmp/longjmpのプロトタイプ宣言をしているからです(しかも型が違う)。
そのためmakeを失敗させないためには、単純にこの宣言部分を削除するpatchをつくればいいことになります。

patchの作り方(ruby-1.8.7-p348の場合)

cd ~/.rvm/src/ruby-1.8.7-head/
ed eval.c <<EDIT
210,212d
wq
EDIT
ed gc.c <<EDIT
42,44d
wq
EDIT
git diff > ~/current-cygwin-has-own-setjmph.patch

このpatchはdropbox上においておきます。


https://rvm.beginrescueend.com/rubies/patching/によると、 ".rvm/patches/ruby/1.8.7/"にあるpatchは自動適用されているようで、そこに置くようにgithubでpull requestするのが良いようです。

naveを使ったnode.jsインストールと、最近のnpmの使い方

今風のnode.js環境の作り方です。naveによって複数バージョンのnode.jsを共存させます。
またnpmも以前とは少し使い方が変わってるので、その使い方をフォローしています。


簡単な用語説明:

  • node.js: イベント駆動アーキテクチャなサーバサイドJavaScript環境
  • nave: 複数node.jsバージョンを管理するシステム
  • npm: node.js用パッケージシステム

あらすじ

  • naveダウンロード
  • naveからnodejsインストール
  • インストールしたnodejsにnpmインストール
  • npmでグローバルモジュールインストール

確認した環境

必要なもの

事前に必要なものは、あらかじめパッケージをいれておきます:

  • naveやnpmで必要な物
  • nodejsビルドに必要な物
    • ubuntu natty: python-all、build-essential、pkg-config、libssl-dev、libz-dev
    • cygwin: gcc4-g++、make、openssl、openssl-devel、pkg-config、zlib-devel、python
      • /etc/resolv.conf がなければ以下の内容で作っておく
nameserver 8.8.8.8
nameserver 8.8.4.4

naveを使ったnodejsのインストール

naveをgitでダウンロードし、そこからnode.js最新版をインストールします。以下コマンド:

mkdir ~/.nave
cd ~/.nave
git clone git://github.com/isaacs/nave.git 
~/.nave/nave/nave.sh install latest

以下、nodejs最新版のダウンロードとビルドが走ります。完成後、

~/.nave/nave/nave.sh use latest

とすると、さらにシェルが起動してその中でnodeコマンドが使えるようになります。(Ctrl+Dで抜けれる)

$ node -v
v0.4.8

naveコマンドとして使えるよう、~/.bash_aliasesや~/.bash_profileなどに以下を追加しておくとよいです:

alias nave=$HOME/.nave/nave/nave.sh

このaliasで、nave.shはどこでもnaveコマンドとして使えます

$ nave use latest
Already installed: 0.4.8
using 0.4.8
$

npm インストール

nodeコマンドが使えるようになった状態で、以下を実行します:

curl http://npmjs.org/install.sh | sh

途中対話モードになり"Is this OK? enter 'yes' or 'no'"と聞いてくるので、"yes"と打ちます。

nodeコマンドが使える状態のとき、npmコマンドが使えるようになります。

$ npm -v
1.0.6

グローバルパッケージとしてインストール

コマンドを提供するパッケージは、グローバル(といっても、nodeコマンドのある場所)に入れる必要があります。
たとえば以下のパッケージは、コマンドライン用コマンドを提供しています:

  • vows: BDD(Behavior Driven Development)システム
  • docco: ソースコードからドキュメント生成するツール

グローバルに入れるには、npm install -gで入れます:

npm install -g vows 
npm install -g docco

nodeコマンドが使える状態のとき、vowsコマンドとdoccoコマンドが使えるようになります。

アインインストールは以下のようになります:

npm uninstall -g vows 
npm uninstall -g docco

おまけ: ローカルパッケージとしてダウンロード

オプション-gがないと、実行ディレクトリ下に"node_modules"ディレクトリを作り、そこにパッケージが入ります。

その位置でnodeコマンドを実行すれば、入れたモジュールをrequireで読み込めるようになっています。

例: underscore.js

$ ls
$ npm install underscore
underscore@1.1.6 ./node_modules/underscore
$ ls
node_modules
$ node
> var _ = require("underscore")
> _.map
[Function]
>

node_modulesはその直下のディレクトリ内からも有効になっています。

$ ls
node_modules
$ mkdir -p src/js
$ cd src/js
$ node
> var _ = require("underscore")
> _.map
[Function]
>

npmコマンドも上位ディレクトリのnode_modulesに対して機能します

$ npm install chaos
chaos@0.1.7 ../../node_modules/chaos

ECMAScript5を使ってSameGameを書いてみた

ECMAScript5の追加ArrayメソッドやObject.freeze/Object.createを使い、JavaScriptでSameGameを書いてみました。

意識した部分

  • ピュアECMAScript5仕様の機能のみでゲームロジックを書く(HTMLの機能を使うUIは完全分離する)
  • forループを使わず、forEachやmapを使う
  • Object.createを適切に使用する
  • ステップで盤面生成し副作用なしなので、すべてObject.freezeする。

for文を避けるため、Array(n).forEach(...)/map(...)は機能しない仕様(呼び出しても引数を実行しない)のようなので、range(n)関数を用意しています。Selected.pointsはArrayのindexOfを使うため、座標を"x,y"形式の文字列にして保持させています。

コード

ブコメを見るとどうも誤解されているようですが、1個のSelectedが可能なのはバグではないです。デモUIの初期値が全部消せる設定になっているのも、コードを最後まで走れる(isClearがtrueになるところまで)ようにするため。

1個のSelectedが成立する設計は意図的なものです(そもそも0個のSelectedだって可能だ)。Boardが上書きせず、別Boardを生み出す構造で設計であるのと同様、数判定を混ぜないのも工夫によるものです(ヒントはコヒージョン)。

追記: 設計をいくつか更新

  • Selected.forEachをArray.forEachのように第二引数にコールバックのthisオブジェクトを設定できるようにした。
  • Board.forEachを用意し、tableイテレートを抽象化し、実装でtableをパディングしないようにした
  • UI部分も汎用化し、canvas要素ごとに結合できるようにした
    • Viewオブジェクト定義でObject.createを使う
    • Viewオブジェクトは、状態を更新するがプロパティ構成の変更はないのでObject.sealする
    • イベントリスナー登録でFunction.bindを使う
  • コード全体に"use strict"をいれた
  • ES5では、オブジェクトリテラルの最後のプロパティのあとの","が使えるようになったのでいれておく
  • インスタンスはそのままだとconstructorプロパティはObjectを返すので、constructorプロパティを上書きしておく
  • Viewのパラメータを変えるUIをつけた。HTML5追加のinput要素のrangeとnumberを利用した。
  • モジュール変数はトップレベルでthis.MyModule = ...のスタイルでセットするようにした。このスタイルで作れば、nodejsのrequire(jsfilename)でも読み込めるようになる。

感想

  • ES5で拡張された関数によって、だいぶシンプルにコードが書ける。
  • Arrayがここまできたら組値としてのtupleかstructもほしい。ペア値で、===で同値比較したい。パターン展開出来ればなおよし。
  • Object.freeze()がメソッドでもなく字面上も長いので、値オブジェクトで必要部分をfreezeして回ると結構ごちゃごちゃする。
  • Object.createでの定義で、privateメソッドを使いたい場合は、PImpl風になるのかな?
  • Arrayのコールバックを渡すメソッドでは第二引数でthisを渡せる。forEach(cb.bind(this))とforEach(cb, this)どっちがいい?
  • さめがめは実装は数時間で作成できるので、設計演習にはちょうどいいかも。