IronPython Console をもっと便利に(TABによる補完とか)

IronPyhton の開発環境を構築しています。

お客様に .NET Framework 4.0 が必要な提案をしておりまして、しかも、コンパイルが必要な言語はイマイチ要件にあわない。初めは IronRuby でやろうかと思ったのですが、調べたところ日本語の扱いに不安がある。ここはそろそろ安定しているであろう IronPython かな?というわけ。

さて、本題。インタラクティブシェルを便利にする、ipy.exe おすすめの起動時オプションをご紹介。
どんなオプションがあるのかはこんな感じで確認できます。

C:\Users\murave>"C:\Program Files\IronPython 2.6 for .NET 4.0\ipy.exe" -?
Usage: ipy.exe Usage: ipy [options] [file.py|- [arguments]]

Options:
 -3                       Warn about Python 3.x incompatibilities
 -c cmd                   Program passed in as string (terminates option list)
 -D                       Enable application debugging
 -E                       Ignore environment variables
 -h                       Display usage
 -i                       Inspect interactively after running script
 -m module                run library module as a script
 -O                       generate optimized code
 -OO                      remove doc strings and apply -O optimizations
 -Q arg                   Division options: -Qold (default), -Qwarn, -Qwarnall,
-Qnew
 -s                       Don't add user site directory to sys.path
 -S                       Don't imply 'import site' on initialization
 -t                       Issue warnings about inconsistent tab usage
 -tt                      Issue errors for inconsistent tab usage
 -u                       Unbuffered stdout & stderr
 -v                       Verbose (trace import statements) (also PYTHONVERBOSE=
x)
 -V                       Print the version number and exit
 -W arg                   Warning control (arg is action:message:category:module
:lineno)
 -x                       Skip first line of the source
 -X:AutoIndent            Enable auto-indenting in the REPL loop
 -X:ColorfulConsole       Enable ColorfulConsole
 -X:CompilationThreshold  The number of iterations before the interpreter starts
 compiling
 -X:Debug                 Enable application debugging (preferred over -D)
 -X:EnableProfiler        Enables profiling support in the compiler
 -X:ExceptionDetail       Enable ExceptionDetail mode
 -X:Frames                Enable basic sys._getframe support
 -X:FullFrames            Enable sys._getframe with access to locals
 -X:GCStress              Specifies the GC stress level (the generation to colle
ct each statement)
 -X:LightweightScopes     Generate optimized scopes that can be garbage collecte
d
 -X:MaxRecursion          Set the maximum recursion level
 -X:MTA                   Run in multithreaded apartment
 -X:NoAdaptiveCompilation Disable adaptive compilation
 -X:PassExceptions        Do not catch exceptions that are unhandled by script c
ode
 -X:PrivateBinding        Enable binding to private members
 -X:Python30              Enable available Python 3.0 features
 -X:ShowClrExceptions     Display CLS Exception information
 -X:TabCompletion         Enable TabCompletion mode
 -X:Tracing               Enable support for tracing all methods even before sys
.settrace is called

Environment variables:
 IRONPYTHONPATH    Path to search for module
 IRONPYTHONSTARTUP Startup module

お勧めは、TABキーでのキーワードの補完が有効になる「-X:TabCompletion」、自動でインデントしてくれる「-X:AutoIndent」、コンソールがカラーになる「 -X:ColorfulConsole」あたり。昔はTabCompletion と AutoIndent は設定すると問題もあったのですが(TabCompletion では日本語が文字化けするとか)なおっているようです。

これらのオプション、3年前に買った『オープンソース×Windowsスクリプティング IronPythonの世界』(荒井 省三)という本で知ったのですが、いまだにこの本ぐらいしか参考書がないみたい。

私は、スタートメニューの IronPython Console のショートカットをコピーしてリンク先に上記のオプションを追加したショートカットを作ってます。便利ですよ。

切れちゃってますが、リンク先の内容は「”C:\Program Files\IronPython 2.6 for .NET 4.0\ipy.exe” -X:TabCompletion -X:AutoIndent -X:ColorfulConsole」です。ipy.exe の Path については調整してくださいね。

Facebooktwitterlinkedintumblrmail

お中元

少し前の話になりますが、社長の奥様から会社宛にお中元をいただきました。(いつもありがとうございます)

いつも真っ先に私が好きなモノを選ぶので、他の方には申し訳ないんですが(笑)、まあこれも開封した人の特権ということで…。

マカロンは初めて食べました!チョコ味。可愛いし美味しかったです。
プリンも大好きなので、こうやって県外のプリンを食べる機会を持てて幸せです。感謝です。

甘いものは好きですが、同時に好き嫌いも激しいので、最近周りの方が気を使って選んでくださるのが申し訳ないやら恥ずかしいやらで……スミマセン。笑

Facebooktwitterlinkedintumblrmail

UTF-8なCakePHP+EUC-JPなMySQL4.0

CakePHPは非常に良くできたPHPフレームワークです。
DBの種類等も設定ファイルに少し書いてやるだけで動いてくれます。

文字コードもそうで下記設定ファイルに書くだけです。
MySQLでEUC-JPを扱う場合も下記のようにするだけです。

/app/config/database.php
 'mysql',
        'persistent' => false,
        'host' => 'localhost',
        'port'=>3306,
        'database' => 'dbname',
        'login' => 'dbuser',
        'password' => 'dbpassword',
        'prefix' => '',
        'encoding' => 'ujis',
    );

}
?>

MySQLの場合はここで設定したencodingを使って、「SET NAMES ujis;」を自動的に発行してくれています。ここで問題が発生したのですが、MySQL4.0系にはSET NAMES構文がないので文字化けしてしまいます。CakePHP側もEUC-JPにしてしまえばいいのですが、今回はUTF-8である必要があり、DBとの入出力の際に、UTF-8⇔EUC-JPと変換することにしました。CakePHPはデータ操作の際に呼ばれるコールバック関数がありますので、そこで変換してやればOKです。

基本的に全ての生成されたModelはAppModelクラスを継承していますので、このクラスで変換してやります。

/app/config/app_model.php
data配列をEUC-JPに変換する処理

        return true;
    }
}
?>

もっと根っこのところで変換かけても良いのでしょうが、今回はCakePHPのライブラリには手を加えたくなかったので、こうしました。子クラスで上記関数をオーバーライドしている場合は親の関数を呼ぶのをお忘れなく。こうしたほうが良いというのがあればツッコミお待ちしてます。

Facebooktwitterlinkedintumblrmail

複数テーブルをまたいで重複しないIDを自動的に振る(PostgreSQL)


CREATE TABLE test(id serial, hoge text, primary key(id));
CREATE TABLE test2(id int default nextval(pg_get_serial_sequence('test'::text,'id'::text)::regclass), hoge text);

INSERT INTO test(hoge) VALUES('hoge');
INSERT INTO test2(hoge) VALUES('hoge');
INSERT INTO test(hoge) VALUES('hoge');

PostgreSQL8.1.9で確認。

testのidには1,3が、test2のidには2が入ります。
立っているclassは親でも使えと言う感じです。
デフォルト値にはcurrvalも使えますが、setvalで初期値を忘れずに。

普通に使う機会が無さそうなものばかりで。

Facebooktwitterlinkedintumblrmail

文字コードの話(EUC-JP)

大体知ってるという人も多いと思うので、概略だけ。

EUC-JPは拡張としてマイクロソフトが規定したCP51932と 日本ベンダ協議会が規定したeucJP-msが有ります。何が違うかと言うと
前者はJIS X 0212が無い、NEC選定IBM拡張文字が有る、ユーザ定義文字が入らない
後者はJIS X 0212が有る、NEC選定IBM拡張文字が無い、ユーザ定義文字が入る
と言う事のようです。
因みにブラウザではIEはCP51932のみ対応で、FirefoxやOperaは両方対応しているようです(表示に関して)。
で、またややこしい話ですが、これらの3ブラウザ全て送信時はCP51932らしいんですが
FirefoxだけはJIS X 0212をエンティティ化(数値文字列化って言うのかな)しないで送るので、Firefoxで送信した文字だけはFirefox以外で見ると文字化けする事があるという。
追記:今もそうなのか時間があれば調べたいと思います。

またSQLサーバではPostgreSQLとMySQLはeucJP-msですので、同じEUC-JPでも微妙に違う文字が送られて来る事を意識しないといけないんですね。

PHPでは5.2.1以降でしかeucJP-msは対応していませんので、中間処理もこれより前のバージョンでは手で修正が必要になるようです。

あとは他の文字コードからの変換で微妙に違う字体になったりする事もあるらしいです。

まぁ、SJISもEUC-JPも色々と問題があるんですが、UTF-8も問題が無いわけではないんですね。
その辺はサロゲートペアで調べれば出ると思います。対応アプリとかメモ帳でバックスペースとか。

間違いに関して、突っ込みお待ちしております。

Facebooktwitterlinkedintumblrmail

PostgreSQLメモ

多分使わないメモ。

・カラム名column_nameのあるテーブルを探す。
 select t.relname,c.attname,format_type(c.atttypid, c.atttypmod) from pg_attribute as c
 inner join pg_stat_user_tables as t on(c.attrelid = t.relid)
 where attname = 'column_name';

・テーブルとインデックスのサイズを確認する(ブロックサイズ*ブロック数)。
 SELECT tablename,pg_relation_size(tablename::text) from pg_tables where tableowner != 'postgres';

 SELECT indexname,pg_relation_size(indexname::text) as indexsize from pg_indexes where schemaname != 'pg_catalog';

・今ロックされているテーブルを調べる。
 SELECT relname from pg_stat_all_tables where relid in(select relation from pg_locks) and schemaname != 'pg_catalog';

Facebooktwitterlinkedintumblrmail

Munin で PostgreSQL を監視する

PostgreSQL 大好きっ子なので PostgreSQL を監視するプラグインを追加するんだぜー。

PostgreSQL 監視用のプラグインはパッケージを導入した際にいくつか入ってます。

$ ls -l /usr/share/munin/plugins/postgres*
-rwxr-xr-x 1 root root 5377 2009-10-18 19:53 /usr/share/munin/plugins/postgres_block_read_
-rwxr-xr-x 1 root root 7777 2009-10-18 19:53 /usr/share/munin/plugins/postgres_commits_
-rwxr-xr-x 1 root root 2159 2009-10-18 19:53 /usr/share/munin/plugins/postgres_locks
-rwxr-xr-x 1 root root 6118 2009-10-18 19:53 /usr/share/munin/plugins/postgres_queries_
-rwxr-xr-x 1 root root 7243 2009-10-18 19:53 /usr/share/munin/plugins/postgres_space_

もちろん /usr/share/munin/plugins/ には、PostgreSQL 用だけじゃなくていろんなプラグインが入ってます。いっぱい、いっぱい。

PostgreSQL のコネクション数の監視をするプラグインは残念ながらここにはないので
http://munin-monitoring.org/wiki/plugin-pg__connections
から取ってきました。

こいつも /usr/share/munin/plugins/ に置いて、実行できるようにしておきましょう。

$ sudo chmod +x /usr/share/munin/plugins/pg__connections 

プラグインの設定方法はプラグインのファイルを開いて読むと書いてありますので、そのようにしていきます。

Munin のプラグインは /etc/munin/plugins/ ディレクトリにあるかどうかで管理されています。まずは、取ってきた pg__connections のシンボリックリンクを作成。

$ sudo ln -s /usr/share/munin/plugins/pg__connections /etc/munin/plugins/pg_5432_connections

プラグインのファイルの Usage には pg__connections ってな名前をつけるように書いてありますが、ポート番号にしてみました。このプラグインについてはこの文字列が動作に影響を及ぼすことはなさそうなので何でもいいと思います。

用意されているプラグインからも監視したい対象のプラグインをセットアップ。

$ sudo ln -s /usr/share/munin/plugins/postgres_block_read_ /etc/munin/plugins/postgres_block_read_5432
$ sudo ln -s /usr/share/munin/plugins/postgres_space_ /etc/munin/plugins/postgres_space_5432

この2つにしました。

シンボリックリンクの最後にデータベース名を付けるように書いてありましたがこれらについてもポート番号の5432にしてみました。これらのプラグインでは付けた文字列がグラフのタイトルで使用されるのでちゃんと考えて付けましょう。

ちなみに postgres_block_read_5432 だとグラフのタイトルが「:: Postgres data reads from 5432」となります。postgres_space_5432 の方は「:: Postgres database 5432」となって、データベースの容量に関するグラフのタイトルとしてはイマイチな感じになっちゃいました。

PostgreSQLのプラグインについては設定ファイルに記述がないので設定を追記する必要があります。

$ sudo vi /etc/munin/plugin-conf.d/munin-node

私の実験環境での設定ですが、次のように追記しました。

[postgres_*]
env.PGHOST 127.0.0.1
env.PGPORT 5432
env.PGDATABASE postgres
env.PGUSER postgres
env.PGPASSWORD trust

[pg_5432_connections]
env.dbhost 127.0.0.1
env.dbport 5432
env.dbname postgres
env.dbuser postgres
env.dbpass trust

[postgres_*] は postgres_ が頭に付いているプラグインの設定、すなわち、用意されているプラグインの設定です。
[pg_5432_connections] はパラメータ名なども異なりますし別途書く必要があります。

実験環境の PostgreSQL の 接続設定は 127.0.0.1 からは trust にしています。よって、データベースの接続にパスワードは不要なのですが、何か書いていないとエラーなったので仮に trust としています。

PostgreSQL 側でやらなければならない設定として「postgresql.conf の stats_start_collector = true として統計情報収集器を有効にせよ」的なことも書いてありますが、PostgreSQL 8.3 以降、この設定は削除され、UDP ソケットの作成に成功したら必ず統計情報収集器が起動するようになったようです(http://www.sraoss.co.jp/technology/postgresql/8.3/ 参照)。

あとは Munin-Node を再起動すればOK、と言いたいところですが、実はこれでは動かない場合があります。 libdbd-pg-perl が入っていない場合です。プラグインが PostgreSQL にアクセスするのに使っているのです。
Ubuntu に Munin をインストールする時には入りませんでしたので、libdbd-pg-perl が入っていない場合には別途インストールする必要があります。

$ sudo aptitude install libdbd-pg-perl

こんどこそ、準備OK。Munin-Node を再起動します。

$ sudo /etc/init.d/munin-node restart
 * Stopping Munin-Node
   ...done.
 * Starting Munin-Node
   ...done.

再起動完了。

$ tail -n 20 /var/log/munin/munin-node.log

ってな感じで、 Munin-Node のログを見てエラーが出てないか確認すると良いでしょう。データがないせいで正常動作をしていてもエラーが出ていたりする場合もあります。内容で判断するしかないですね。

しばらく待つと、こんな感じに PostgreSQL のリソースのグラフが追加されたページが生成されます。

Facebooktwitterlinkedintumblrmail

画面いっぱいのUITextViewがキーボードに隠れないようにする

iPadで画面いっぱいにUITextViewを配置すると、入力状態になった際にキーボードが出てきて入力カーソルが隠れてしまいます。これには「キーボードが表示・非表示になるタイミングで、UITextViewの高さを変えてあげる」ことで 対処可能です。UICatalogのサンプルが少し古く、3.2ではDeprecatedになっているUIKeyboardBoundsUserInfoKeyを使っていたため、UIKeyboardFrameEndUserInfoKeyを使うようにしてみました。恐らくiPhoneでも同じようにできるはずです。

@interface CustomViewController : UIViewController  {
    UITextView *_textView; //対象となるテキストビュー。UIViewControllerのサブビューとして追加する。
}
@property (nonatomic, retain) IBOutlet UITextView *_textView;
@end


@implementation CustomeViewController

- (void)viewDidLoad {
    [super viewDidLoad];    
    //親ビューの高さが変更された時に追従するようにする
    _textView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    //キーボード表示・非表示の通知の開始
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];

    //キーボード表示・非表示の通知を終了
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

//キーボードが表示された場合
- (void)keyboardWillShow:(NSNotification *)aNotification {
    //キーボードのCGRectを取得
    CGRect keyboardRect = [[[aNotification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    keyboardRect = [[self.view superview] convertRect:keyboardRect fromView:nil];
    
    //キーボードのanimationDurationを取得
    NSTimeInterval animationDuration = [[[aNotification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

    //メインビューの高さをキーボードの高さ分マイナスしたframe
    CGRect frame = self.view.frame;
    frame.size.height -= keyboardRect.size.height;

    //キーボードアニメーションと同じ間隔でメインビューの高さをアニメーションしつつ変更する。
    //これでUITextViewも追従して高さが変わる。
    [UIView beginAnimations:@"ResizeForKeyboard" context:nil];
    [UIView setAnimationDuration:animationDuration];
    self.view.frame = frame;
    [UIView commitAnimations];
}

//キーボードが非表示にされた場合(keyboardWillShowと同じことを高さを+してやっているだけ)
- (void)keyboardWillHide:(NSNotification *)aNotification {
    CGRect keyboardRect = [[[aNotification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    keyboardRect = [[self.view superview] convertRect:keyboardRect fromView:nil];

    NSTimeInterval animationDuration = [[[aNotification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

    CGRect frame = self.view.frame;
    frame.size.height += keyboardRect.size.height;

    [UIView beginAnimations:@"ResizeForKeyboard" context:nil];
    [UIView setAnimationDuration:animationDuration];
    self.view.frame = frame;
    [UIView commitAnimations];
}

@end
Facebooktwitterlinkedintumblrmail

メモ:Linux::Inotify2 でディレクトリを監視して処理

Linuxサーバー上のディレクトリにファイルが作成されたら処理するってのをやりたくて、調べてたら cpan の Linux::Inotify2 が良さそうだったので試してみました。

モジュールをインストール(cpanminusを使用)。イベントループに AnyEvent を使うといいらしいので、そちらも。

$ cpanm Linux::Inotify2
$ cpanm AnyEvent

指定ディレクトリにファイルを投入したら別ディレクトリに mv するスクリプトを作成。

#!/usr/bin/env perl
use strict;
use warnings;

use Linux::Inotify2;
use AnyEvent;

my $watch_dir = $ENV{HOME} . '/inotify/queue';
my $processed_dir = $ENV{HOME} . '/inotify/processed';
my $inotify = Linux::Inotify2->new or die $!;

$inotify->watch(
    $watch_dir,
    IN_CLOSE_WRITE | IN_MOVED_TO,
    sub {
        my $e    = shift;
        my $name = $e->fullname;
        print "test!:${name}\n";
        system( 'mv', $name, "${processed_dir}/" );
    }
);

my $cv = AnyEvent->condvar;
my $inotify_w = AnyEvent->io(
    fh   => $inotify->fileno,
    poll => 'r',
    cb   => sub { $inotify->poll }
);
$cv->recv;

起動して queue ディレクトリにファイルを置いたら processed ディレクトリに移動するのを確認できました。

Facebooktwitterlinkedintumblrmail

Gitで短すぎるコミットログを禁止する

コミットコメントを意地でも書かせたい

http://d.hatena.ne.jp/kanu-orz/20100531/1275279046

上記を見て感化されたので、Gitで短すぎるコミットログのコミットを禁止するhookを書きました。

#!/usr/bin/env ruby

#place this file in .git/hooks/commit-msg

MIN_LENGTH = 10

log = File.readlines(ARGV[0]).grep(/^[^#].+/)
length = log.to_s.split(//u).size - 1

if length < MIN_LENGTH
  system('say Way way wait')
  puts <<-EOS

##################################################################
このコミットは許しません!

1行目   [変更した理由、目的を簡潔に]
2行目以降 [必要ならば詳細を]

最低でも何故変更したのかのを、
未来の自分と保守担当者に向かって書きましょう。

コミットログは未来の自分へのメッセージです。
今は不要に思っても、未来にはきっと役に立ちます。

#{length}文字しかありません。
有効なメッセージを#{MIN_LENGTH}文字以上
##################################################################
  EOS
  exit 1
end

せっかくMacなのでsayコマンド使ってAlexさんにしゃべらせてます。
ちなみにコミットログはcommit-msgスクリプトの第一引数に.git/COMMIT_EDITMSGというファイル名が渡ってきますので、それを覗いてやれば参照できます。

Facebooktwitterlinkedintumblrmail