Home > Archives > 2005年02月

2005年02月

C#のお勉強をかねた「最萌カウンタ」

C#を勉強するために何かアプリケーションを作ろうと思い第2回東方最萌トーナメント の集計ソフトの GUI 版を作成してたんだけど,ようやく納得の行く動作のものが出来上がった.

もう,リストアイテムのソートがアルファベット順しかできないだの,アイテムが選択されているのに選択されていないだの,エラーをはいて止まるところをエラーを吐かずに止まったり,コントロールの扱い方がちぐはぐだったりとむちゃくちゃ作成に時間がかかった.最大の原因は MSDN のドキュメントが読みにくいことだろうけど... さらには簡単に使える汎用のレイアウトマネージャがないし... まあ,GUIは GUIのデザイナで作るものなのだろうけど.

そんなこんなで結構な時間が過ぎてしまったのだけど(先週のゆゆ様の試合に間に合わなかった...).デリゲートを使ったイベント処理やら各種プロパティの扱い方など,C#でのプログラミングというものを少しは理解できた.でもまあ,なんとなく Java ほどの完成度ではないなぁというのが素直な感想だろうか?もう少しコントロールを共通に扱えるようにしてほしいなぁ,とか.

とりあえず,ここに出来上がったものをおいとこう.いつの間にやら 3500 行とか行ってるし... saimoe-csharp.zip

C#でGUI

なんとなく C# をいじってみようと思い,先日は CUI で作った 第2回東方最萌トーナメント 途中経過集計プログラムの GUI バージョンを作り始めた.が,しかし,C# でのプログラム作成は初めてのため結構時間がかかってしまっている.というのも,ほとんど Java と同じのりで作れてはいるのだけどリファレンスが MSDN なので読みにくくて... よく目を通す JavaDoc ないし Doxygen の形式に慣れきってしまっているためMSDN では検索効率がかなり悪い.けどまあ,あとはでかい機能としてはグラフ描画だけなのでもう少しで出来上がりそう.

ちなみに,かなりの時間を費やして結局失敗に終わったのはListView のフィールドにラジオボタンとかチェックボックスとか置こうとしたことで,これをやるには WinProc 関数を書き換えるとこまでやらないとできないらしい.ひとつの手としてコントロールを直接上に配置してしまえば見かけ上はうまくいきそうになるが,スクロールとの兼ね合いやカラムの幅の変更などに対応させるのがかなり困難との結論に達した.まあ,DataGrid を使えばいろいろできるのだけれど.

最萌トーナメントの集計スクリプト

AWK の勉強のためとの建前で 第2回東方最萌トーナメント の集計スクリプトを書いてみた.スレッドの番号を入れると wget でページを落としてきて解析して gnuplot でグラフを描いてくれる.あほだ...

ファイルを置いといてみる.

Continue reading

AWK - match と substr

AWK 使いはじめて一時間ほどはまっていたのが,直前の正規表現でマッチした部分の取り出し方だった.ruby やら perl やらではそれらは簡単にできるのだが(特別な変数に入る),awk はそこまではできないらしい.結局 awk で正規表現でマッチした部分を取り出すには,match と substr あたりを使う必要があるとの結論に達した.

例えば, hh:mm 見たいな時間の表示を取り出すには

	pos=match($0, /[0-9][0-9]:[0-9][0-9]/) 
	if(!pos) next
	timestr = substr($0, pos, RLENGTH) 

などのようにする.

match で正規表現をマッチさせて,返り値でその開始位置を取得し(RSTART変数にも入る),長さが RLENGTH に入っているのでその分を substr で取り出すという手順になる.マッチに失敗したときは 0 が帰るらしい.コード中ではマッチしなかった場合に next を呼ぶようにしている.

AWK - はじめ

awk のプログラム(スクリプト)は

pattern { action }
pattern { action }
....

という構造にjなっている.pattern は /regex/ などのような正規表現や,BEGIN, END のような全ての最初と最後を意味するものがある.

入力はレコードセパレータ(RSという変数に入っている)によってレコードに分割され,全ての pattern に対してマッチが取られ,マッチしたときにはその pattern の action が実行される.デフォルトではフィールドセパレータは改行コードなので,一行が一レコードになってる.

例えば,外部から TARGET という変数に何か値を渡してあげて,"Start of TARGET" から "End of TARGET"までのレコードを出力するようなのは以下のとおり.

BEGIN {
	FLAG=0
	STARTPat="Start of "TARGET
	ENDPat="End of "TARGET
}
//{
	if($0 == ENDPat){
		FLAG = 0
	}
	if(FLAG) print
	if($0 == STARTPat){
		FLAG = 1
	}
}

BEGIN で最初に変数を初期化しておいて,その後ろの //{...} で全てのレコードに対してマッチして処理をしている.これをファイル(split.awk)に保存して

awk -f split.awk -v TARGET=1st < in.dat

とかやると, in.dat の中の "Start of 1st" から "End of 1st"までの行が取り出せる.

ちなみにレコードはフィールドセパレータ(FSという変数)で分割されて,各フィールドは $i (i=1,2,...,NF) で取り出せる.$0 はレコード全体.出力は print で,引数を省略すると print $0 の意味になる.

詳しくはマニュアル参照.

Home > Archives > 2005年02月

Search
Feeds

Page Top