東工大ポータル マトリックスコードのブックマークレット

AAA...JJJにA1, A2, A3, ..., J7のコードを入れる。
動かなかったら残念(IE8, Safari, Chromeで動作確認済み)。

使用は自己責任で。

javascript:(function(){var c='AAAAAAABBBBBBBCCCCCCCDDDDDDDEEEEEEEFFFFFFFGGGGGGGHHHHHHHIIIIIIIJJJJJJJ';var r=document.body.innerHTML.match(/\[\w,\d\]/g);for(var i=0;i<r.length;i++){document.getElementsByName('message'+(i+3))[0].value=c.charAt(7*(r[i].charCodeAt(1)-String("A").charCodeAt(0))+(r[i].charAt(3)-1));}})();

Gnuplotでときどきplotがやたら遅い理由

Gnuplotでグラフを出力するのにかなり時間がかかることがときどきある。plot sin(x)のようなものでも数分待たされる。
その理由がやっとわかった。

Gnuplotは、%TEMP%にfontconfigというフォルダを作成する(たとえばWindows 7のデフォルトではC:\Users\username\AppData\Local\Temp)。その中に(おそらくはフォント一覧の)データが残っていればそれを利用するためすぐ描画されるが、ない場合はこれを生成する時間が必要になる。この生成には、理由はわからないがとにかく時間がかかる。

したがって、Tempフォルダお掃除ソフトなどを使っている場合は、クリーンアップ後の初めてのplotはとても時間がかかる。これはバグやwhile (1)ではなく仕様なので、いずれ終わるのを待てばよい。我慢できないなら、このフォルダを削除しないように指定すればよい。

ワンライナー・ダイス

誰得。

正規表現で12d3を置換するだけ。

my $dice = "3d4";
$dice =~ s/(\d+)d(\d+)/my $s = $1; $s += int rand $2 for 1 .. $1; $s/ie;
print $dice;   # ex. 7

ただしfor (foreach)でこっそり$_を使っている。この置換の前後で$_を維持したいときは、s///;の右側にlocal $_を加えるか、変数を明示してループを組まなければならない。

関数として組むときは、ワンライナーを捨てる方が簡単にできる。

sub dice {
  my($k, $n) = shift =~ /(\d+)d(\d+)/;
  my $s = $k;
  $s += int rand $n for 1 .. $k;
  return $s;
}

File::Copy::Recursive

cp -r ...のようなことができるため重宝する。
しかし、現行バージョン(0.38)では@EXPORT_OKrcopy_globが入っていないため、この関数がちょっとだけ使いにくい。なぜだ。

頻繁に呼ぶときはとりあえずこうしてごまかそう。

use File::Copy::Recursive qw(...);
sub rcopy_glob { File::Copy::Resursive::rcopy_glob(@_); }
関連モジュール

MacBook Air 11インチ欲しい! ← 書くといいことがあるらしい

変数が定義されていないときはこの値とする

Maximaでこのようにする処理で結構はまった。perlでいうと、my $a ||= 1;に対応するものだ(厳密には違うが)。

if not member('a, values) then a : 1 $

どうも、こうすればよいようだ。valuesは現在定義されている変数のリストで、member()は第1引数が第2引数にあればtrueを返す関数である。
プライムはaにすでに中身があると先に展開されてしまうので、これを防ぐため。

複数のファイルを一度に作る

こういうのにとまどったためにプログラミングが嫌いになるのはよくない。ということで、研究室の同期に聞かれたことをパブリックに答える。

#include <stdio.h>

int main() {
	int i;
	char filename[20];
	FILE *fp;

	for (i = 0; i < 10; i++) {
		sprintf(filename, "test%03d.txt", i);
		fp = fopen(filename, "w");
		if (fp == NULL) { /* error handling */ }

		// do something
		// such as:
		fprintf(fp, "%d\n", i * i);

		fclose(fp);
	}
	return(0);
}

注釈

filename[]の宣言

sprintf()で予想される文字数から、この変数の大きさを検討する。このサイズが、sprintf()の結果 + 1 byte (NULL文字)よりも小さいと、バッファオーバーフローが起こってしまう。ただしあまり大きすぎるのはメモリの無駄で、また、OSによっては256 bytes以上をファイル名(パス)として受け付けないなどの制限があることに注意する。ここでは適当に20バイトを確保することにした。

ファイル名の決定
sprintf(filename, "test%03d.txt", i);

によって、ファイル名を決定する。このように書くとtest000.txt, test001.txt, ...のように連番で作られる。apple.txt, banana.txt, cherry.txt, ...のように数字と関係ないものにしたいときは、文字列の配列を別に定義して、それを添え字で参照する。なおバッファオーバーフローを危惧する場合は、sprintf()ではなくsnprintf()の使用を検討する。

個別ファイルの処理

fopen()でファイルを開く。なんらかの理由で開けなかったときは戻り値fpがNULLポインタなので、次のif文でエラーに対処する(ここでは略)。
その後は連番ファイルにいろいろ書き込んで、fclose()で閉じる。このコードではfpを再利用しているので、きちんと閉じないと恐ろしいことが起こるかもしれない。開けたら閉めるって大事だよ。

LiveUpdateが途中で打ち切られる問題

研究室のPC(プロキシ経由でインターネットに接続)に入っているSymantec Endpoint ProtectionでLiveUpdateをすると、よく3,500KBでダウンロードが中断してしまっていた。エラー内容は「LU1835: LiveUpdate サーバーに接続できません」だったが、どこをどう変更すればいいのやら。ウィルス定義を定期的に定義ファイルとセキュリティアップデート : セキュリティレスポンス|シマンテックから落としていたが、これはいかんせん面倒くさい。

などと夏ぐらいから悩んでいたが、改めて検索したところ、次のページが見つかった。

要約すると、次の通り。

  1. コントロールパネルからSymantec LiveUpdateを開く。
  2. HTTPタブを開く。
    1. 「LiveUpdateのHTTP設定をカスタマイズする」を選択する。
    2. 「HTTP接続の場合にプロキシサーバーを使う」にチェックを入れ、アドレスとポートを入力する。
  3. 更新キャッシュタブを開く。
    1. 最大キャッシュサイズを30MBにする。(注:いらないかも)
    2. 「キャッシュからすべてのファイルを削除」をクリックする。

コントロールパネルで見つからないときは、アイコン・クラシック表示で探す。プロキシサーバーのアドレスとポートは、「インターネットオプション」で入力するものと同じ。