本を読む

読書やコンピュータなどに関するメモ

続・どう書く?org:制限時間内のキー入力検査

 「どう書く?org:制限時間内のキー入力検査」の続き。

 「ゲームで極める シェルスクリプトスーパーテクニック」を読んで、bashのSECONDS変数を知った。なんだ、もっと簡単に書けるんじゃん。さっそく書き直してみる。

#!/bin/bash

function InputChecker(){
    local timeout=$1
    local str=$2

    echo -n "input($str) =>"
    read -n1 c
    t1=$SECONDS
    read s
    t=$(( $SECONDS - $t1 ))

    echo -n 'result => '
    if (( $t >= $timeout )) ; then
        echo 'TIME OUT'
    elif [ "$c$s" == "$str" ] ; then
        echo 'OK'
    else
        echo 'NG'
    fi
}

InputChecker $1 $2
InputChecker $1 $2
InputChecker $1 $2

 余談。いままで、どう書く?orgのネタをわざわざブログで書いてきたのは、斜め上な回答を狙っていたから。が、どう書く?orgをやってる西尾さんによると、多彩なレシピを集めるのが目的だとか。その志をくんで、しょぼくてもちゃんと投稿したほうがいいかなぁ。

追記2008-08-19:
とかえらそうなこと書いたわりに、いまごろどう書く?.orgに投稿

「ゲームで極める シェルスクリプトスーパーテクニック」

 シェルスクリプトで、テトリス風などのアクションゲームを作ろうという解説書。キャラクタベースのゲームであるところとか、シェルスクリプトそのものを教える気はあまりなさそうなところとかが、昭和ふう(ベーマガとかあのへんのノリ)ですばらしい。

 なにより、ゲーム自体よりも移植性にこだわっているのが異色だ。echoの挙動の違いとその吸収方法だけで15ページ費やしているし。そのほか、移植性を考えるとエスケープシーケンスをベタ打ちしたほうがいいとか、移植性高く乱数を得る方法とか、シェルスクリプトでのリアルタイム入力とか、2次元配列の実現方法とか、細かいテクニックばかり書いてあって、アレゲな人専用になっているのが楽しい。

ゲームで極める シェルスクリプトスーパーテクニック
山森 丈範
技術評論社 (2007/09/06)
売り上げランキング: 12754

「キリン」34巻

 バイク乗り(の一部)からカリスマ的人気を集めるマンガの最新刊。

 なんというか、ガルーダのカシラがどんどんすさんでいく姿が悲しい。

 キリン親父も登場(してたんだけど)。親子がそれぞれいう「バイクを楽しみなよ」というのが、Run the Hazard編の最初のほうで出てきた言葉と重なって、ちょっと考えさせる。

キリン 34 (34) (ヤングキングコミックス)
東本 昌平
少年画報社 (2007/10/26)

「極道めし」2巻

 刑務所で受刑囚たちが「思い出のメシ」を競い合うという、ある意味究極のグルメマンガの2巻がついに出た。内容はグルメの対極なんだけど。

 前の巻が圧倒的によかったのだけど、この巻もやっぱりいい。チープなメシにそれぞれの人生が重なり、思わずこちらもつばを飲んでしまう。で、優勝ネタもいいけど、なんといっても「最高のラーメン」は最高だった。

 ネタ命の作品なので、このままネタ切れせずに続いてほしいし、ネタ切れをひっぱらずにまとめてほしい。

極道めし 2 (2) (アクションコミックス)
土山 しげる
双葉社 (2007/10/27)

IPA最新情報をPlaggerでフィード化

 ひさしぶりにPlaggerいじり。

 IPA最新情報を自分用フィードにして読もうと思い立った。そこでWeb::Scraper(>= 0.22)+CustomFeed::Script。

変更:2007-10-26:
linkにas_stringを噛ませた。

追記:2007-10-27:

EnterFullTextナシで考えていたのですが、EntryFullTextするとPlagger::Date->parse_dwimしてくれるんですね。知らなかった。勉強になりました。

ipa-news.pl

#!/usr/bin/perl
use strict;
use warnings;
use URI;
use Web::Scraper 0.22;
use DateTime;
use DateTime::Format::W3CDTF;
use YAML;
use Encode;
use utf8;

my $uri = 'http://www.ipa.go.jp/about/news/index.html';

my $year = 1970;

sub parse_year {
    ($year) = $_[0] =~ /\[(\d+)年\]/;
    $year;
}

sub parse_date {
    my ($m, $d) = $_[0] =~ /(\d+)月(\d+)日/;
    my $date = DateTime->new(year => $year,
                             month => $m,
                             day => $d,
                             time_zone => 'Asia/Tokyo' );
    DateTime::Format::W3CDTF->format_datetime($date);
}

my $items = scraper {
    process '//title', 'title' => 'TEXT',
    process '//strong[text() =~ /最新情報.*\[.*年\]/]',
            'year' => ['TEXT', \&parse_year];
    process '//td[@nowrap]/..', 'entries[]' => scraper {
        process 'a', 'title' => 'TEXT';
        process 'a', 'link' => ['@href', sub { $_->as_string } ];
        process 'td[nowrap]', 'date' => ['TEXT', \&parse_date];
    };
    result 'title', 'entries';
};
my $result = $items->scrape(URI->new($uri));

my $out = {
    title => $result->{title},
    link => $uri,
    entry=> $result->{entries},
};
print encode('utf-8', Dump($out));

どう書く?org:文字列の反転(括弧の対応を保存)

 sedで。文字列にコントロールコードが入っていないこと前提。

#!/bin/sed -f
:paren
s/(\([^][(){}]*\))/\x01\1\x02/g;
t paren
s/{\([^][(){}]*\)}/\x03\1\x04/g;
t paren
s/\[\([^][(){}]*\)\]/\x05\1\x06/g;
t paren

s/\x01/)/g;
s/\x02/(/g;
s/\x03/}/g;
s/\x04/{/g;
s/\x05/]/g;
s/\x06/[/g;

s/$/\n/
:reverse
s/^\(.\)\(.*\n\)\(.*\)$/\2\1\3/
t reverse
s/\n//

 実行例。

$ cat sample.txt 
文字列(もじれつ)の反転(はんてん)
対応[の{とれている(さまざまな)括弧}の(例)]です。
これ(は(対応のとれていない)括弧がある例です。
これ(も{対応の)とれていない}括弧の例です
$ sed -f reverseString2.sed < sample.txt 
(んてんは)転反の(つれじも)列字文
。すで[(例)の{弧括(なまざまさ)るいてれと}の]応対
。すで例るあが弧括(いないてれとの応対)は(れこ
すで例の弧括}いないてれと)の応対{も(れこ

追記2008-08-19:
いまさらながら、どう書く?.orgに投稿しました

Ubuntu 7.10をインストール

 Ubuntu Linux 7.10(Gutsy Gibbon)の日本語ローカライズド版が出た。なにはともあれ、常用しているThinkPad X60sのデータをバックアップし、Desktop CDからクリーンインストールした。

 まず、わりとどうでもいいファーストインプレッション。

  • GNOMEツールバーに検索バーを表示するやつがデフォルトで入っている
  • ホームディレクトリに、「テンプレート」「デスクトップ」「ドキュメント」「ビデオ」「音楽」「画像」「公開」というディレクトリができてる
  • compiz(Compiz Fusion?)がデフォルトで入っているっぽい
  • gnome-terminal上のvimで「set ambiwidth=double」が効くようになった
  • sudoのパスワードプロンプトが「[sudo] password for (ユーザー名):」になった

 以下、セットアップ作業のメモ。

  • あいかわらず/etc/hostsに127.0.1.1の設定が入っているので、127.0.0.1に
  • CtrlとCapsLockを入れ替え
    • 「システム」-「設定」-「キーボード」から、レイアウトのオプションで「Ctrl Key Position: Swap Ctrl and CapsLock」
    • /etc/console-tools/remapで「s/keycode 58 = Caps_Lock/keycode 58 = Control/;」の行をコメントから出す
  • 「システム」-「設定」-「外見」で、壁紙をナシに
  • CIM開始キーからCtrl+SpaceとShift+Spaceを削除
    • 「フロントエンド」- 「全体設定」
  • /etc/default/acpi-supportで「ENABLE_LAPTOP_MODE=false」をコメントアウト
  • GNOMEパネルにTomboyメモを追加
  • Synapticで「CD-ROM/DVDからインストール」のチェックを外す
  • Xのフォントがいまいちきれいじゃない
    • とりあえず「システム」-「設定」-「外見」で、フォントのヒンティングをナシに
  • i810switchは、今回もX60sに対応してない
  • アプリをSynapticから追加
    • manpages-ja
    • build-essentioal
    • devscripts
    • dpatch
    • dh-make-perl
    • linux-imageとlinux-sourceのメタパッケージ
    • firefox-greasemonkey
    • flashplugin-nonfree
    • zsh
      • chsh -s /bin/zsh
    • Emacs関連
      • Emacs22用とEmacs21用のパッケージが混在していてちょっと混乱
    • vim関連
      • .vimrcにset ambiwidth=double
    • Perl関連
    • Ruby関連
    • Python関連
  • その他、俺パッケージをインストール

どう書く?org:続・ファイル内の重複行削除

 これは手抜きしてPerl+SQLite3で。

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

my $dbfile = '/tmp/fileuniq.sqlite3';
my $table = 'fileuniq';

unlink $dbfile if (-e $dbfile);
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile",
                       undef, undef, { AutoCommit => 0 } )
                or die $DBI::errstr;

$dbh->do("CREATE TABLE $table (lineno integer, line TEXT)");

open my $fh, '<', $ARGV[0] or die 'File not found';
my $count = 0;
while(<$fh>){
    my $sth = $dbh->prepare("DELETE FROM $table WHERE line = ?");
    $sth->execute($_);
    $sth->finish;

    $sth = $dbh->prepare("INSERT INTO $table VALUES (?, ?)");
    $sth->execute($count++, $_);
    $sth->finish;
}
close $fh;
$dbh->commit;

my $sth = $dbh->prepare("SELECT line FROM $table ORDER BY lineno");
$sth->execute;
while(my @row = $sth->fetchrow_array) {
    print $row[0];
}
$sth->finish;

$dbh->disconnect;
unlink $dbfile;

どう書く?org:ファイル内の重複行削除(後優先)

 sedで。

#!/bin/sed -nf
H
x
s/\n\([^\n]*\)\n\1$/\n\1/
s/\n\([^\n]*\)\n\(.*\)\n\1$/\n\2\n\1/
x
${
    g
    s/^\n//
    p
}

 実行例。

$ cat sample.txt 
tako
ika
tako
tako
surume
tako
surume
$ sed -nf fileuniq.sed sample.txt 
ika
tako
surume

追記2008-08-19:
出来はともかく、どう書く?.orgに投稿してみました

WWW::Mixi::Scraperに勝手に外部から追加機能を注入してみる

 ふと、mixiのリニューアルで一番困っているのは専用ブラウザー系の人ではないかと思った。ためしにbackup_mixiを見てみたところ、まだ対応していないようだ。

 PerlのWWW::Mixi::Scraperモジュールだったらさっくり書けるんじゃないかと思って、使いかたを調べてみた。すると、WWW::Mixi::Scraperでは、日記一覧で次のページへのリンクを取得する方法が用意されていないらしい。

それ用のプラグインを作る?
WWW::Mixi::Scraperではプラグインのモジュール名とCGIのコマンド名が一対一で対応していて、同じコマンドに複数のプラグインを割り当てられないらしい
ListDiaryプラグインを改造?
いまの仕様はエントリのリストを返すようになっているので、その仕様を変更するとほかに影響が大
コピペして新しいスクリプトにする?
メンテが面倒そう

 というわけで、不精して、ListDiaryプラグインのsrcape()を動的に上書きして追加機能を注入する方法を考えてみた。Rubyで既成クラスを動的に変更するような感じのやりかた。

 WWW::Mixi::Scraperのプラグインは、Module::Pluggable::Fastを使って動的に読み込まれている。それを次のようにしてみた。

  • ListDiaryのscrape()を再定義するコードをテキストで用意
  • ListDiaryをuseでコンパイル時に読み込む
  • 元のscrape()のコードリファレンスを変数に保存
  • 再定義するコードをeval()で実行

 どう見ても場当たりですry

 ちなみに、これを試したらbackup_mixiはどうでもよくなって終了。

#!/usr/bin/perl
use strict;
use warnings;
use WWW::Mixi::Scraper;

use WWW::Mixi::Scraper::Plugin::ListDiary;
my $scrape_list_diary = \&WWW::Mixi::Scraper::Plugin::ListDiary::scrape;

eval <<'__OVERRIDE__';
package WWW::Mixi::Scraper::Plugin::ListDiary;
no warnings 'redefine';

sub scrape_nextpage {
    my ($self, $html) = @_;

    my $scraper = scraper {
        process 'div.pageList03>ul>li>a',
            'subject' => 'TEXT',
            'link' => '@href';
        result qw( subject link );
    };

    return $self->post_process($scraper->scrape(\$html));
}

sub scrape {
    my ($self, $html) = @_;

    my $list = $scrape_list_diary->($self, $html);
    my $nextpage = $self->scrape_nextpage($html);

    return {
        list => $list,
        nextpage => $nextpage,
    };
}

1;
__OVERRIDE__

my $mixi = WWW::Mixi::Scraper->new(
    email => 'sample@exaple.jp', password => 'xxxxxxxx',
);

my $diary_list = $mixi->list_diary->parse;

use YAML;
print Dump($diary_list);

「本能はどこまで本能か」

 動物の生得的な行動と後天的な行動の境目が、実はあいまいだということを解説するポピュラーサイエンス解説書。タイトルにあるように、先天的と思われがちな事柄が、実は後天的な部分も大きいという事実を説明していて、面白い。

 といっても、行動を後天的な事柄だけで説明するというのでもなく、物理的な構造や、生得的な要素、後天的な要素が分かちがたく組み合わさっているという立場をとっているようだ。そんなわけで、ID論にも否定的な立場をとっている。

 先天的と思われがちだがそうでないとうのは、たとえばこんな事柄。

  • 性別
  • 両眼視の脳機能
  • 鳥が後ろ足で頭を掻く動作
  • 鳥の雛が卵の殻を割る行動
  • のどが乾いたときに水を飲む行動
本能はどこまで本能か―ヒトと動物の行動の起源
マーク・S. ブランバーグ Mark S. Blumberg 塩原 通緒
早川書房 (2006/11)
売り上げランキング: 39028

「考具」

 評判がいい本なので、遅ればせながら読んでみた。企画で仕事している人間として、「そうそう」とうなずく部分も多いんだけど、それ以上に参考になる部分も多い。

 以下、うなずいた部分と参考になった部分を合わせてメモ。

  • アイデアはわがままに、企画はおもいやりで
    • アイデアは実現性を置いておいて奔放に広げる
    • 企画はアイデアをもとに絞ってまとめる作業
  • アイデアは組み合わせ
    • オズボーンのチェックリスト
      • 転用したら?
      • 応用したら?
      • 変更したら?
      • 拡大したら?
      • 縮小したら?
      • 代用したら?
      • 置換したら?
      • 逆転したら?
      • 結合したら?
  • カラーバス
    • 「今日はこの色に注目」といった縛りを決めることで、見たものをランダムに意識する
  • 七色いんこ
    • 身体を動かして他人を演じることで、はじめて見えるもの
  • アイデアスケッチ
    • 他人を意識せず、くだらないアイデアでもどんどん書いていく
    • 裏紙などを使って、とにかく遠慮しない
    • ひとつのアイデアを考えているときに、ふとひらめく別のアイデアも大切に
  • マンダラート、マインドマップ、連想ゲーム
    • 1つのお題からどんどん発想を広げる
  • 企画はタイトル重要
    • 具体的に置き換える
    • ビジュアルで考える
  • アイデアマラソン
    • アイデアを貯め続ける
  • 課題に対する問いかけのバリエーションを考える
    • ずらし方
考具―考えるための道具、持っていますか?
加藤 昌治
阪急コミュニケーションズ (2003/03)
売り上げランキング: 553

「クロサギ」15巻

 前巻の最後で振っていたネタでクライマックス…かと思いきや、そこは引き延ばし。ちょっと拍子抜け。

 今回は、レンタル+質屋のサギと、NPO法人詐欺という、よく知られたネタ。

「アンプラグドコンピュータサイエンス」

 小学生向けにコンピュータサイエンス、というかアルゴリズムを実習させるための本。それも、題名どおり、コンピュータを使わずにカードやミカンを使って。

 これは面白い。大人でも楽しめる。Linux/BSD関係で有名なハッカーの鵜飼文敏さん(Google)も講演で推薦しているぐらいだ(というかそれで知った:出典明記&属人論法)。コンピュータ版子供の科学かも。

 テーマは、2進数に始まり、探索アルゴリズムやソートアルゴリズム、ロック、有限状態オートマトンなど、けっこう高度な内容まで扱っている。しかもそれを、身の回りの道具で実験できるところが楽しい。

 O(1)で済むところをついO(n)でやってしまうようなダメな大人の私には、リアルに勉強になった。

コンピュータを使わない情報教育アンプラグドコンピュータサイエンス
Tim Bell/Ian H.Witten/Mike Fellows Matt Powell 兼宗 進
イーテキスト研究所 (2007/09/01)
売り上げランキング: 2726

「21世紀少年」下巻

 浦沢直樹氏による「20世紀少年」~「21世紀少年」の話もこれで完結。このエンドで、まぁよかったんじゃないでしょうか。

 とりあえずユキジの言葉。

「もしも もしもって 言ってたら キリがないわ。」

 …いやまったく、そう思う。

21世紀少年 下 (2) (ビッグコミックス)
浦沢 直樹
小学館 (2007/09/28)

どう書く?org:制限時間内のキー入力検査

 出力例のあたりがよく理解できてないのだけど、こんな感じだろうか。すべてbash内蔵コマンドで。

 1文字目をreadしたあと、残りの文字をreadで読んで、その時間を計測している。面倒だったのは、readにtimeをかませて結果を変数に入れる方法。

#!/bin/bash

function InputChecker(){
    local timeout=$1
    local str=$2

    echo -n "input($str) =>"
    read -n1 c
    TIMEFORMAT='%R' r=$((time read s; echo $s) 2>&1)
    t=${r%%.*}
    s="$(echo $r)"  # newline -> whitespace
    s=${s#* }

    echo -n 'result => '
    if (( $t >= $timeout )) ; then
        echo 'TIME OUT'
    elif [ "$c$s" == "$str" ] ; then
        echo 'OK'
    else
        echo 'NG'
    fi
}

InputChecker 5 'ABCDEF'
InputChecker 5 'ABCDEF'
InputChecker 5 'ABCDEF'

 | HOME | 

Categories

Recent Entries

Recent Comments

Recent Trackbacks

Appendix

emasaka

emasaka

フリーター。
連絡先はこのへん

Monthly


FC2Ad