プログラム

チェスのPGN関係メモ

iPhoneのチェスプログラム tChess Pro が コメント付きPGN(チェスの棋譜) をきちんと解読できないようなので、コメントを削除するプログラムを書きたい。ちょっと検索したところ、Chess PGN関係のPerlモジュールがCPANにあるようだ。ということで、メモ。

http://search.cpan.org/~gmax/Chess-PGN-Parse-0.19/

Perlでエクセル・データを処理する

とある件で、マイクロソフト・エクセル(MS Excel)のデータを取り扱うことになった。というか、入力済みのデータがエクセルのフォーマットという次第。ホントはテキスト・データでくれれば嬉しいのだが、どうも、事務関係はどこもかしこもエクセルばかりのようだ。

幸いなことに、Windowsを起動しなくても、Ubuntu上のOpen Office SpreadSheetで開くことができて、さらに、これを CSV (Comma Separated Values) 形式のテキストファイルとして保存できる。こうなれば、あとは楽である。やっぱりテキストファイルが一番だよねえ。

CSV形式のオプションとして、セパレーターが選べる。コンマで区切るよりもタブで区切る方が、ある意味合理的なので、タブで区切って保存する。これって、Tab Separated Values だから、TSVと呼ぶべきだと思うが、これでもやっぱりCSVと称するのだろうか。

それはともかく、あとは1行ずつ読み込んで処理すればよい。UNIXの標準入力から読み、標準出力に書き出すことにした。実際には、リダイレクトすれば良い。こうすると、プログラムは極めて簡単。入出力を書かなくてよいから。

while (<STDIN>) {
  chomp; # 行末コードを削除
  @data = split /\t/, $_; # $_は1行分のデータ
  # 以下、この配列に対する作業を行う。
}

こんな感じ。UNIXの便利さ、Perlの柔軟さが実感できる。

ファイル全体を一つのスカラー変数に代入するには

PerlでTeXの文書をちょちょっと変換するプログラムを作ろうとしたのだが、思わぬところで頓挫。Perlで処理する普通の作業ってのは、行単位で読み込んで処理して出力して、とかいうのが多い。よくあるサンプルを真似して作っていたのだが、大域変数$_ に入っているのがファイル全体だと思い込んでいたら、実は一行分だったのが迷走の原因だった。

ファイル全体、つまりすべての行を一つの文字列変数に代入するには、読み込む前に区切り記号を表す大域変数 $/ を未定義の状態、つまり undef にする。たったこれだけの為に、難渋してしまった。ということで、備忘録としてメモ。

{
  local $/ = undef;
  $_ = readline INFILE;
}

とすれば、ファイルハンドラー INFILE から読み込んだすべてのデータが $_ に入る。

文字コードを判別してTeXにかけるPerlスクリプト

とある事情で、Ubuntu上ではUTF-8およびShift_JISの2種類のTeX文書を処理している。一々 platex -kanji=utf8 とか platex -kanji=sjis とか、したくないので、文字コードを判別してから組版し、ついでにPDFに変換して文書ビューアで表示させる Perl スクリプトを作ってみた。

ユーザーは自分だけなので、思いっきり手抜きだが、まずまず役立っている。

#! /usr/bin/perl -w
#
# [usage] myplatex hoge
#  hoge.tex の文字コードを判別して、platex -kanji=KANJICODE とコンパイル
#  引き続いて dvipdfmx で PDF を作り、文書ビューアー evince を起動する
#  とりあえず,普段使っている UTF-8 と Shift_JIS のみサポート

use strict;

my $basename;   # hoge
my $texfile;    # hoge.tex
my $dvifile;    # hoge.dvi
my $pdffile;    # hoge.pdf
my $kanjicode;  # UTF-8, Shift_JIS

$basename = $ARGV[0];
$texfile = $basename."\.tex";
$dvifile = $basename."\.dvi";
$pdffile = $basename."\.pdf";

open (INFILE, "<$texfile") || die "File Not Found\n";
close INFILE;

$kanjicode = `nkf -g $texfile`;
chomp($kanjicode);

if ($kanjicode eq "UTF-8") {
 system("platex -kanji=utf8 -interaction=nonstopmode $texfile");
} elsif ($kanjicode eq "Shift_JIS") {
 system("platex -kanji=sjis -interaction=nonstopmode $texfile");
} else {
 die "Not supported\n";
}

system("dvipdfmx $dvifile");
system("evince $pdffile");

Perlでガウス記号

やってみると、Perlの数学関係はまったく充実していないことが判明 😳 。やっぱり PARI/GP のように数学に特化したものにする方が良いかも。そうは言っても、所詮は四則演算だけで済むので、必要な関数を自前で作ることにした。

まず整除ができない。13を5で割ると商が2で余りが3という計算。余りならば % という剰余演算子があり、13%5=3 となるらしいが、負の数に対しては Perl の実装によって結果が変わる可能性があると書いてあった。何と言語仕様で決めてないのかあ。まあ、文字列がメインターゲットってことですよね、やっぱり。

整数部分を与える関数 int(x) というのはあるが、xがマイナスのときはガウス記号とは違って int(-3.2)=-3 のようになるらしい。ああ、これも使い物にならない。

そこで、整数部分(ガウス記号)を与える関数を準備。ついでなので、切り捨て(ガウス記号)と切り上げの両方を作ってみよう。日本ではあまり普及してない呼び名だが、floor (フロアー、床)、ceiling (シーリング、天井)と言われるもの。動作は次のようになる。

 floor(3.14)=3、floor(3)=3、floor(-3.14)=-4

 ceiling(3.14)=4、ceiling(3)=3、ceiling(-3.14)=-3

効率は考えずに、とりあえず動くことだけを考えて作成。

# floor function
# &floor(3.14)=3, &floor(3)=3, &floor(-3.14)=-4
sub floor {
  my $x=$_[0];
  my $n=int($x);
  if ( $x==$n ) {
     $n;
  } elsif ( $x>0 ) {
     $n;
  } else {
     $x= -$x;
     $n=int($x);
     $n+=1;
     -$n;
  }
}

# ceiling function
# &ceiling(3.14)=4, &ceiling(3)=3, &ceiling(-3.14)=-3
sub ceiling {
  my $x=$_[0];
  my $n=int($x);
  if ( $x==$n ) {
    $n;
  } elsif ( $x > 0 ) {
    $n+=1;
    $n;
  } else {
    $x = -$x;
    $n = int($x);
    -$n;
  }
}

Perlで構造体

Perlの言語仕様にはやはり構造体は含まれていないようだ。しかし、追加モジュールというのがいろいろとあり、そこで実現されている。構造体を定義したければ、Class::Struct というモジュールを取り込む必要があるらしい。次のページはCに馴染みがある者に、てっとり早くPerlの要点を教えてくれて便利。

C言語を知る人へのPerl の基礎知識

C言語の

struct quadratic_form {
  int  left;
  int  center;
  int  right;
};
quadratic_form  some_qf;
some_qf.center = -3;

に対応させるには、次のように書けば良いのかな?

use Class::Struct

struct quadratic_form => {
    left   => '$',
    center => '$',
    right  => '$'
};
 
my $some_qf = new quadratic_form();
$some_qf->center(-3);

初めてのPerl

ランダル・L. シュワルツ,トム フェニックス
Amazonランキング:34323位
Amazonおすすめ度:


2次形式の変換作業を計算機にさせようと :mrgreen: Perlの入門書を本棚から引っ張り出してきた。良く知っている PASCAL とか C で書いてもいいのだが、まあ、所詮は整数の四則演算だから言語はどれでも大差ないから、復習も兼ねて。というか、以前、TeXの数式部分を画像に変換するプログラムを書いてから大分経つので、すっかり忘れてしまって、全くの初心者に戻っているのだけど(苦笑)。

Perl特有の習慣に未だ馴染めない所もあるが、まずまず理解しやすい本。実際に動作するサンプル・プログラムが付いているともっと良いと思うが。差し当たって、2次形式のデータ型を定義するにはどうするかとあちこち見るのだが、構造体ってのはないんですかね。


パスカルのレコード型、Cの構造体に対応するものが見つからないが、ハッシュで表現しろということなのだろうか。2次形式
\[ f(x,y)=ax^2+bxy+cy^2 \]
を (a,b,c) と略記して、これを一つのデータ型にしたいのであるが・・・。

パスカルなら、例えば、

type 
  quadratic_form = record
    left : integer;
    middle : integer;
    right : integer;
  end;

C は、えっと・・・うろ覚えだが、

struct quadratic_form {
  int  left;
  int  middle;
  int  right
};

みたいに定義すれば、quadratic_form 型というのが定義できる。

これをハッシュでやるとどうなるのかな? 個別の2次形式、例えば some_quadratic_form=(2,3,4) を表すには

%some_quadratic_form = (
  "left" => 2, 
  "middle" => 3,
  "right" => 4
);

などとするのだろうが、こういうものを包括的に一つの型として登録することはできないのだろうか。それとも、そういうことはしないという風土なのか。なんでもそうだけど、初心者はこんな簡単そうなところで悩むからつらいよねえ。

UbuntuでTeXをソースからコンパイル

いったい、そんなことが自分にできるのか全く自信なかったが、まあ、失うものはないし〜 :mrgreen: ということで、やってみた。Ubuntu 8.04 (Hardy Heron)にtetex3ベースのptetex3 (by 土村氏)をインストールするのが目標。

ptetex — teTeX 用日本語パッチ集

上記の土村氏のサイトからソース一式をダウンロードし、説明書の通りにした、と言えば簡単そうであるが、実はけっこう苦労した。最初にpatchがないよ、とエラーを吐かれたときにはどうなることやらと思った(笑)。 patchのような基本的ツールすら入ってないのか〜。次に、gccが実行可能ファイルを生成できないっす、というエラー。これに苦労した。依存関係を調べて、Debianでのtetex3に必要なライブラリーなどを検索。でも、大抵は入っていたような。おまじないで、gcc3.3のbasicではない方をインストールしたり、gcc3.4まで入れたりした。そんなこんなで、gcc関係のエラーは何とか突破。次にc++がないとか言われるので、g++(GNU c++コンパイラー)を入れる。最後に、lexとyaccがないと言われるので、GNU版のflexとbison (いずれも lexとyaccの拡張版である構文解析ツール)を入れる。以上で、何とかmakeに成功。ああ、疲れた〜。

あとは、make install で /var/tmp 以下に生成されたものを /usr/loca/teTeX 以下にコピーし、/usr/local/teTeX/bin にパスを通して終了。

楕円コンパスをJAVAで実現した楽しいページ

ふと思い出して、楕円コンパスって今でも売っているのかなあと、検索していたら、こんなのを見つけた。

■楕円の作図(楕円コンパスの原理)

自分には作れないのがちょっと悔しいけど、JAVAのプログラムが組めると、こういうものをネットにアップできるんだなあ。JAVA Applet を読み込むのに少し時間がかかるけど、一度読み込んでしまえば、あとの動きは軽快。こうやって、アニメーションというか、実際に動きが見えると楽しい。


楕円になることの証明は難しくない。上のページの記号で、$P(x,y)$, $AP=a$, $BP=b$, $AP$と$x$軸のなす角を$\theta$とする。すると、$x=a\cos\theta$, $y=b\sin\theta$ となるから、たしかに$P$の軌跡は楕円である。

ブクログ(BookLog)始めてみました

偶然こんなサービスを見つけたので,とりあえず登録してみた。

ブクログ | sukarabeの本棚

Book Log というらしい。バーチャルな書棚が作れる。蔵書の管理もこれでどうぞということだが,登録するだけで恐ろしく時間が掛かりそう(笑)。まあ,無人島に持って行くならどれにするかな〜くらいのつもりで選んでみよう。まだ数冊だけど。自分の書棚というからには,少しはコメント付けたいところだが,これが悩ましい。読み切ったものばかりじゃないしね。

Amazon.jpと連携していて表紙の画像が表示されて楽しいのだが,画像がないもの(主に出版年度が古い物かな?)もある。漢文名作選(大修館書店)の第1シリーズはなかった。残念だ。それに,そもそもAmazon.jpで扱ってないものもある。洋書関係はAmazon.comのデータを持ってこれると良いのになあ。

笑ったのは,最新のJavaScriptを使った画期的なインターフェースっていう能書き。あはは。JavaScriptは最新のテクノロジーじゃないと思うが,まあGoogle Mapで一躍注目された非同期通信の技術ってことで。Flickr!もこれだしね。