Ankiレビュー数の増加

Ankiはフラッシュカードシステム。復習間隔をスケジューリングしてくれる。気になるのは復習するカードが膨大になるんじゃないかということ。そこで、レビュー数(復習+追加)がどうなるかプログラムでチェック。数式でモデリングできそうだけど、数学は頭が錆びついて断念。

  • 一日に10枚と20枚追加する2パターン
  • 正解を続ければ1日、2日、4日、8日...と復習間隔が伸びる
  • 誤答すれば、復習間隔はそのまま
  • 誤答率は、10%、30%、50%の3パターン

結果


レビュー数は始めの3ヶ月ぐらいは急に増えるが、半年ぐらいになると増加は緩やかになる。

確認用スクリプト

#!/usr/bin/perl
use strict;
use warnings;
use GD::Graph::lines;

my $end = shift // 500;

my @data = ( [ 0 .. $end ] );
my @dataset = ();
my $add_per_day;

# Add 10 per day
$add_per_day = 10;
$data[1] = [ simulate_review( $end, 0.1, $add_per_day ) ];
$data[2] = [ simulate_review( $end, 0.3, $add_per_day ) ];
$data[3] = [ simulate_review( $end, 0.5, $add_per_day ) ];
@dataset = (
    "Fail 0.1, Add $add_per_day",
    "Fail 0.3, Add $add_per_day",
    "Fail 0.5, Add $add_per_day",
);

draw_lines( 'anki_add10.jpg', \@data, \@dataset );

# Add 20 per day
$add_per_day = 20;
$data[1] = [ simulate_review( $end, 0.1, $add_per_day ) ];
$data[2] = [ simulate_review( $end, 0.3, $add_per_day ) ];
$data[3] = [ simulate_review( $end, 0.5, $add_per_day ) ];
@dataset = (
    "Fail 0.1, Add $add_per_day",
    "Fail 0.3, Add $add_per_day",
    "Fail 0.5, Add $add_per_day",
);

draw_lines( 'anki_add20.jpg', \@data, \@dataset );

sub simulate_review {
    my $end         = shift // 500;
    my $fail_rate   = shift // 0.3;
    my $add_per_day = shift // 20;

    my @words = ();
    my @data  = ();
    for my $today ( 1 .. $end ) {
        my $review = 0;
        for my $word (@words) {
            $word->{rest}--;
            if ( $word->{rest} <= 0 ) {
                $review++;
                if ( rand > $fail_rate ) {
                    $word->{interval} *= 2;
                }
                $word->{rest} = $word->{interval};
            }
        }
        $data[ $today - 1 ] = $review;

        # Add new word
        for ( 1 .. $add_per_day ) {
            push @words, { interval => 1, rest => 1 };
        }
    }
    return @data;
}

sub draw_lines {
    my $file        = shift;
    my $data_ref    = shift;
    my $dataset_ref = shift;

    my $graph = GD::Graph::lines->new( 400, 400 );
    $graph->set(
        title            => 'Number Of Reviews using ANKI',
        x_label          => 'Day',
        y_label          => 'Review',
        y_max_value      => 350,
        x_label_skip     => 100,
        x_label_position => 0.5,
        r_margin         => 10,
        dclrs            => [qw(black red green)],
        line_types       => [qw(1 1 1)],
    );
    $graph->set_legend(@$dataset_ref) or die "$!";

    my $image = $graph->plot($data_ref);

    open my $fh, '>', $file or die "$file:$!";
    binmode $fh;
    print {$fh} $image->jpeg();
    close $fh or die "$file:$!";
}

コマンドラインからWeb検索

コマンドを実行して、エラーが出たときとかWebで検索することが多い。コマンドラインから直接Web検索ができると便利なんじゃないかと思い、searchというシェル関数を作ることにした。

使い方

$ search "firefox chrome opera"
0 : bing.com
1 : google.co.jp
2 : goo dictionary(all)
3 : eijiro
4 : google translation
5 : excite translation
6 : wikipedia(jp)
7 : wikipedia(en)
select number:

コマンドラインからsearchを調べたい文字列付きで実行すると番号が聞かれる。番号を選択するとブラウザを開いて検索する。

screenのコピーモードと併用すると、マウスを使わずに検索文字列を貼り付けられるから便利。

  • firefoxのみ
  • 日本語は上手く検索できんかも
  • debianでのみ動作を確認

ソース

function search() {
    encoded=$(perl -MURI::Escape -e 'print uri_escape(shift)' "$1")

    echo "0 : bing.com"
    echo "1 : google.co.jp"
    echo "2 : goo dictionary(all)"
    echo "3 : eijiro"
    echo "4 : google translation"
    echo "5 : excite translation"
    echo "6 : wikipedia(jp)"
    echo "7 : wikipedia(en)"
    echo -n "select number: "
    read number

    case "$number" in
        0)
            firefox -new-tab 'http://www.bing.com/search?q='$encoded &
            ;;
        1)
            firefox -new-tab 'http://www.google.co.jp/search?q='$encoded'&hl=ja&ie=UTF_8&lr=lang_ja' &
            ;;
        2)
            firefox -new-tab 'http://dictionary.goo.ne.jp/srch/all/'$encoded'/m0e/' &
            ;;
        3)
            firefox -new-tab 'http://eow.alc.co.jp/'$encoded'/UTF-8/' &
            ;;
        4)
            firefox -new-tab 'http://translate.google.com/translate_t?hl=ja&langpair=en%7Cja&text='$encoded &
            ;;
        5)
            firefox -new-tab 'http://www.excite.co.jp/world/english/?before='$encoded'&wb_lp=ENJA' &
            ;;
        6)
            firefox -new-tab 'http://ja.wikipedia.org/wiki/'$encoded &
            ;;
        7)
            firefox -new-tab 'http://en.wikipedia.org/wiki/'$encoded &
            ;;
        *)
            echo "Unknown number $number" >&2
            ;;
    esac > /dev/null
}

テストドキュメンテーションの自動化という夢想

テストのドキュメントを自動生成したい。ユニットテスト・フレームワーク一覧を探したけど、よさそうなのがない。希望としては

  • 単体テスト、総合テストでも使える
  • HTMLで出力する
  • 結果の一覧を確認できる
  • テストの手順を出力できる

こんな感じで

サマリ表示

詳細表示

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=CP932"/>
    <title>Testing Summery</title>
    <link rel="stylesheet" href="style.css" type="text/css" />
  </head>
  <body id="top">
    <h1>1. Test Overview</h1>
    <table  border="1">
      <tr>
        <th>Project</th>
        <td>Test Project</td>
      </tr>
      <tr>
        <th>Sub Project</th>
        <td>Sub Test Project</td>
      </tr>
      <tr>
        <th>Module</th>
        <td>Module Name</td>
      </tr>
      <tr>
        <th>Sub Module</th>
        <td>Sub Module Name</td>
      </tr>
      <tr>
        <th>Test Date</th>
        <td>2012-03-04
        </td>
      </tr>
    </table>
    <br/>
    <h1>2. Test Result</h1>
    <h2>2.1. Functional Requirement</h2>
    <table  border="1">
      <tr>
        <th>1st Category</th>
        <th>2nd Category</th>
        <th>3rd Category</th>
        <th>ID</th>
        <th>Description</th>
        <th>Count</th>
        <th>Pass</th>
        <th>Result</th>
        <th>Comment</th>
      </tr>
      <tr>
        <td rowspan="5">Function A1</td>
        <td rowspan="2">Sub-Func A1</td>
        <td>Sub-Sub A1</td>
        <td>
          <a href="detail.html#a1-1-1">a1-1-1</a>
        </td>
        <td><br/></td>
        <td>0</td>
        <td>0</td>
        <td class="None">--</td>
        <td><br/></td>
      </tr>
      <tr>
        <td>Sub-Sub A2</td>
        <td>
          <a href="detail.html#a1-1-2">a1-1-2</a>
        </td>
        <td><br/></td>
        <td>0</td>
        <td>0</td>
        <td class="None">--</td>
        <td><br/></td>
      </tr>
      <tr>
        <td rowspan="3">Sub-Func A2</td>
        <td>Sub-Sub A1</td>
        <td>
          <a href="detail.html#a1-2-1">a1-2-1</a>
        </td>
        <td><br/></td>
        <td>0</td>
        <td>0</td>
        <td class="None">--</td>
        <td><br/></td>
      </tr>
      <tr>
        <td>Sub-Sub A2</td>
        <td>
          <a href="detail.html#a1-2-2">a1-2-2</a>
        </td>
        <td><br/></td>
        <td>0</td>
        <td>0</td>
        <td class="None">--</td>
        <td><br/></td>
      </tr>
      <tr>
        <td>Sub-Sub A3</td>
        <td>
          <a href="detail.html#a1-2-3">a1-2-3</a>
        </td>
        <td>Description XXX</td>
        <td>2</td>
        <td>1</td>
        <td class="NG">NG</td>
        <td>Comment1</td>
      </tr>
      <tr>
        <td rowspan="5">Function A2</td>
        <td rowspan="2">Sub-Func A1</td>
        <td>Sub-Sub A1</td>
        <td>
          <a href="detail.html#a2-1-1">a2-1-1</a>
        </td>
        <td>Description YYY</td>
        <td>3</td>
        <td>3</td>
        <td>OK</td>
        <td>Comment2</td>
      </tr>
      <tr>
        <td>Sub-Sub A2</td>
        <td>
          <a href="detail.html#a2-1-2">a2-1-2</a>
        </td>
        <td><br/></td>
        <td>0</td>
        <td>0</td>
        <td class="None">--</td>
        <td><br/></td>
      </tr>
      <tr>
        <td rowspan="3">Sub-Func A2</td>
        <td>Sub-Sub A1</td>
        <td>
          <a href="detail.html#a2-2-1">a2-2-1</a>
        </td>
        <td><br/></td>
        <td>0</td>
        <td>0</td>
        <td class="None">--</td>
        <td><br/></td>
      </tr>
      <tr>
        <td>Sub-Sub A2</td>
        <td>
          <a href="detail.html#a2-2-2">a2-2-2</a>
        </td>
        <td><br/></td>
        <td>0</td>
        <td>0</td>
        <td class="None">--</td>
        <td><br/></td>
      </tr>
      <tr>
        <td>Sub-Sub A3</td>
        <td>
          <a href="detail.html#a2-2-3">a2-2-3</a>
        </td>
        <td><br/></td>
        <td>0</td>
        <td>0</td>
        <td class="None">--</td>
        <td><br/></td>
      </tr>
    </table>
    <p>Pass/Total = 4/5 = 80.00%</p>
    <h2>2.2. Non-Functional Requirement</h2>
    <table  border="1">
      <tr>
        <th>1st Category</th>
        <th>2nd Category</th>
        <th>3rd Category</th>
        <th>ID</th>
        <th>Description</th>
        <th>Count</th>
        <th>Pass</th>
        <th>Result</th>
        <th>Comment</th>
      </tr>
      <tr>
        <td rowspan="5">Function B1</td>
        <td rowspan="2">Sub-Func B1</td>
        <td>Sub-Sub B1</td>
        <td>
          <a href="detail.html#b1-1-1">b1-1-1</a>
        </td>
        <td>Description ZZZ</td>
        <td>1</td>
        <td>1</td>
        <td>OK</td>
        <td>Comment3</td>
      </tr>
      <tr>
        <td>Sub-Sub B2</td>
        <td>
          <a href="detail.html#b1-1-2">b1-1-2</a>
        </td>
        <td><br/></td>
        <td>0</td>
        <td>0</td>
        <td class="None">--</td>
        <td><br/></td>
      </tr>
      <tr>
        <td rowspan="3">Sub-Func B2</td>
        <td>Sub-Sub B1</td>
        <td>
          <a href="detail.html#b1-2-1">b1-2-1</a>
        </td>
        <td><br/></td>
        <td>0</td>
        <td>0</td>
        <td class="None">--</td>
        <td><br/></td>
      </tr>
      <tr>
        <td>Sub-Sub B2</td>
        <td>
          <a href="detail.html#b1-2-2">b1-2-2</a>
        </td>
        <td><br/></td>
        <td>0</td>
        <td>0</td>
        <td class="None">--</td>
        <td><br/></td>
      </tr>
      <tr>
        <td>Sub-Sub B3</td>
        <td>
          <a href="detail.html#b1-2-3">b1-2-3</a>
        </td>
        <td><br/></td>
        <td>0</td>
        <td>0</td>
        <td class="None">--</td>
        <td><br/></td>
      </tr>
    </table>
    <p>Pass/Total = 1/1 = 100.00%</p>
    <h2>2.3. Performance Measurement</h2>
    <p>TBD</p>
    <a href="detail.html">Go to detailed</a>
    <a href="#top">Go to top</a>
  </body>
</html>

detail.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=CP932"/>
    <title>Test Detailed Results</title>
    <link rel="stylesheet" href="style.css" type="text/css" />
  </head>
  <body id="top">
    <h1 id="a1-2-3">1. Test ID a1-2-3</h1>
    <h2>1.1. Test Case Infomation</h2>
    <table  border="1">
      <tr>
        <th>ID</th>
        <td>a1-2-3</td>
      </tr>
      <tr>
        <th>Classify</th>
        <td>Function A1/Sub-Func A2/Sub-Sub A3</td>
      </tr>
      <tr>
        <th>Description</th>
        <td>Description XXX</td>
      </tr>
      <tr>
        <th>Condition</th>
        <td>Cond</td>
      </tr>
      <tr>
        <th>Valid</th>
        <td>Valid</td>
      </tr>
      <tr>
        <th>Note</th>
        <td>Note</td>
      </tr>
    </table>
    <br/>
    <h2>1.2. Test Pattern</h2>
    <table  border="1">
      <tr>
        <th>No.</th>
        <th>Pattern</th>
        <th>Note</th>
      </tr>
      <tr>
        <td>1</td>
        <td>Pattern1</td>
        <td>Note1</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Pattern2</td>
        <td>Note2</td>
      </tr>
    </table>
    <br/>
    <h2>1.3. Test Steps</h2>
    <table  border="1">
      <tr>
        <th>Step</th>
        <th>Process</th>
        <th>Expect</th>
        <th>Result</th>
        <th>Note</th>
      </tr>
      <tr>
        <td>1</td>
        <td>Process 1</td>
        <td>Expect 1</td>
        <td>OK</td>
        <td><br/></td>
      </tr>
      <tr>
        <td>2</td>
        <td>Process 2</td>
        <td>Expect 2</td>
        <td class="NG">NG</td>
        <td><br/></td>
      </tr>
    </table>
    <br/>
    <h1 id="a2-1-1">2. Test ID a2-1-1</h1>
    <h2>2.1. Test Case Infomation</h2>
    <table  border="1">
      <tr>
        <th>ID</th>
        <td>a2-1-1</td>
      </tr>
      <tr>
        <th>Classify</th>
        <td>Function A2/Sub-Func A1/Sub-Sub A1</td>
      </tr>
      <tr>
        <th>Description</th>
        <td>Description YYY</td>
      </tr>
      <tr>
        <th>Condition</th>
        <td>Cond</td>
      </tr>
      <tr>
        <th>Valid</th>
        <td>Valid</td>
      </tr>
      <tr>
        <th>Note</th>
        <td>Note</td>
      </tr>
    </table>
    <br/>
    <h2>2.2. Test Pattern</h2>
    <table  border="1">
      <tr>
        <th>No.</th>
        <th>Pattern</th>
        <th>Note</th>
      </tr>
      <tr>
        <td>1</td>
        <td>Pattern1</td>
        <td>Note1</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Pattern2</td>
        <td>Note2</td>
      </tr>
    </table>
    <br/>
    <h2>2.3. Test Steps</h2>
    <table  border="1">
      <tr>
        <th>Step</th>
        <th>Process</th>
        <th>Expect</th>
        <th>Result</th>
        <th>Note</th>
      </tr>
      <tr>
        <td>1</td>
        <td>Process 1</td>
        <td>Expect 1</td>
        <td>OK</td>
        <td><br/></td>
      </tr>
      <tr>
        <td>2</td>
        <td>Process 2</td>
        <td>Expect 2</td>
        <td>OK</td>
        <td><br/></td>
      </tr>
      <tr>
        <td>3</td>
        <td>Process 3</td>
        <td>Expect 3</td>
        <td>OK</td>
        <td><br/></td>
      </tr>
    </table>
    <br/>
    <h1 id="b1-1-1">3. Test ID b1-1-1</h1>
    <h2>3.1. Test Case Infomation</h2>
    <table  border="1">
      <tr>
        <th>ID</th>
        <td>b1-1-1</td>
      </tr>
      <tr>
        <th>Classify</th>
        <td>Function B1/Sub-Func B1/Sub-Sub B1</td>
      </tr>
      <tr>
        <th>Description</th>
        <td>Description ZZZ</td>
      </tr>
      <tr>
        <th>Condition</th>
        <td>Cond</td>
      </tr>
      <tr>
        <th>Valid</th>
        <td>Valid</td>
      </tr>
      <tr>
        <th>Note</th>
        <td>Note</td>
      </tr>
    </table>
    <br/>
    <h2>3.2. Test Pattern</h2>
    <table  border="1">
      <tr>
        <th>No.</th>
        <th>Pattern</th>
        <th>Note</th>
      </tr>
      <tr>
        <td>1</td>
        <td>Pattern1</td>
        <td>Note1</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Pattern2</td>
        <td>Note2</td>
      </tr>
    </table>
    <br/>
    <h2>3.3. Test Steps</h2>
    <table  border="1">
      <tr>
        <th>Step</th>
        <th>Process</th>
        <th>Expect</th>
        <th>Result</th>
        <th>Note</th>
      </tr>
      <tr>
        <td>1</td>
        <td>Process 1</td>
        <td>Expect 1</td>
        <td>OK</td>
        <td><br/></td>
      </tr>
    </table>
    <br/>
    <a href="index.html">Go to index</a>
    <a href="#top">Go to top</a>
  </body>
</html>

style.css

th {
    background-color : PaleGreen;
    text-align       : left;
}

td.NG {
    background-color : Red;
    font-weight      : bold;
}

td.None { background-color : Yellow; }

h1 {
    border-top       : 4px solid Blue;
    border-bottom    : 1px solid Blue;
    background-color : SkyBlue;
    color            : Blue;
}

h2 {
    border-top  : 1px solid Black;
    color       : Black;
    font-weight : bold;
}

table.elを使ったHTMLテーブル生成

以下のようなテキストをHTMLテーブル化する。

,単位,最小,最大,平均
CPU使用率,%,10,90,50
ディスク使用率,Gb,100,200,150
メモリ使用率,Mb,200,500,250

罫線によるテーブル化

CSVのテキストをリージョンで選択し、M-x table-capture を実行。ミニバッファで入力が求められるので、例えば以下のように入力する。

  • Column delimiter regexp: , (デリミタ。今回はカンマ一文字)
  • Row delimiter regexp: Ctrl-q,Ctrl-j (改行)
  • Justify: center (他にright, left)
  • Minimum cell width: 15 (適当)

そうすると以下のような表ができる。

+---------------+---------------+---------------+---------------+---------------+
|               |     単位      |     最小      |     最大      |     平均      |
+---------------+---------------+---------------+---------------+---------------+
|   CPU使用率   |       %       |      10       |      90       |      50       |
+---------------+---------------+---------------+---------------+---------------+
|ディスク使用率 |      Gb       |      100      |      200      |      150      |
+---------------+---------------+---------------+---------------+---------------+
| メモリ使用率  |      Mb       |      200      |      500      |      250      |
+---------------+---------------+---------------+---------------+---------------+

HTMLによるテーブル化

罫線でできたセルにフォーカスがあると、モードラインがTableとなる(罫線上ではなくセルにフォーカスがあること)。ここで、Ctrl-^を実行すると、ミニバッファで出力するファイルが聞かれるので適当に入力すると以下のようなHTMLができる。nbspがあるので必要なければ削除する。

<!-- This HTML table template is generated by emacs 22.2.1 -->
<table border="1">
  <caption>Table</caption>
  <tr>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;単位&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;最小&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;最大&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;平均&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
  </tr>
  <tr>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;CPU使用率&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;90&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;50&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
  </tr>
  <tr>
    <td align="center" valign="top">
      ディスク使用率&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;150&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
  </tr>
  <tr>
    <td align="center" valign="top">
      &nbsp;メモリ使用率&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;500&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;250&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
  </tr>
</table>

メモ

  • 前は日本語が入っているとテーブルがくずれてしまったような気がした。Emacsバージョンが古いと表示がくずれるかも。
  • table.elが役に立つのはHTML化することより、メール、テキスト、ソースファイルにテーブルを簡単に書けること
  • 特に、RFCで書かれているようなパケット構造やバイナリデータの構造を書くとき便利
  • 他の人も編集するファイルでテーブルを多用すると、Emacsを使っていない人から編集しづらいと苦情がくることがある
;; ---------------------------------------------------------
;; テーブルモード
;; ---------------------------------------------------------
;; [元ネタ]
;; http://www.emacswiki.org/emacs/TableMode
;; http://murakan.cocolog-nifty.com/blog/2009/01/emacs-tips-27c2.html
;; http://wassr.jp/user/dummy/statuses/B50uQibW2u
;;
;; [使い方]
;; M-x table-insert
;;  テーブルを挿入する。ミニバッファにカラム数なとが問われる
;;  Number of columns (default 3): (横方向のセル数)
;;  Number of rows (default 3):    (縦方向のセル数)
;;  Cell width(s) (default 5):     (セルの横幅)
;;  Cell height(s) (default 1):    (セルの高さ)
;;
;; M-x table-unrecognize-table
;;  カーソル位置のテーブルの編集モードを抜ける
;;
;; M-x table-recognize-table
;;  カーソル位置のテーブルの編集モードに入る
;;
;; C->, C-c C-c > (table-widen-cell)
;;  カーソル位置のセルを横拡張
;; C-<, C-c C-c < (table-shorten-cell)
;;  カーソル位置のセルを横収縮
;; C-:, C-c C-c : (table-justify)
;;  セル中の文字列の位置を操作 (left/center/right)
;;
;; 縦と横方向の分割と結合
;; M-x table-split-cell
;;  セルの分割 (vertically, horizontally)
;; C--, C-c C-c - (table-split-cell-vertically)
;;  セルの横分割
;; C-|, C-c C-c | (table-split-cell-horizontally)
;;  セルの縦分割
;; C-*, C-c C-c * (table-span-cell)
;;  セルの結合。(left/right/below/above)
;;
;; C-^ (table-generate-source)
;;  HTML, LaTeX, CALS (DocBook DTD) に変換
;;
;; M-x table-capture
;;  リージョンをテーブル化
;; M-x table-releas
;;  カーソル位置にあるテーブルモードのテーブルの罫線を削除

自分が英語をリスニングできない理由

英語リスニングのお医者さん [改訂新版]を読んだ。

中学で習うような英単語を使った英文でさえ聞きとれないことに自分は馬鹿なんじゃないかと思っていたが、聞き取れない理由がなんとなくわかった。

聞き取れない理由は

英語は母音の音がとても強いため、(日本人にとって)子音が欠落して聞こえる

ということが理解できていないことだった。


以下、素人の考え。

「computer game」(1)を例に考えると、日本人は「コンピューターゲーム」と発音する(2)。

(1) computer       game
(2) コンピューター ゲーム

まず、英文の母音を日本語的に抽出してみると(3)のようになる。(3)を口に出してみるとわかるが、英語のイントネーションに自然と近くなることがわかる。

(1) computer       game
(2) コンピューター ゲーム
(3)  オ  ウ  ア     エイ

母音が強いため、母音と子音がわかれて聞こえる。また子音の音が弱くなる。これを抽象的に書くと(4)のようになる。cやmは小さく発音する。

(1) computer       game
(2) コンピューター ゲーム
(3)  オ  ウ  ア     エイ
(4) cオm pyウ tア  gエイm

「t」の発音が「r」になりやすいことを考慮すると最終的に(5)のように聞こえる

(1) computer       game
(2) コンピューター ゲーム
(3)  オ  ウ  ア     エイ
(4) cオm pyウ tア  gエイm
(5) cオm pyウ rア  gエイm


単語同士もくっつき、sold outも「ソウダウ」のように聞こえる

(1) sold  out
(2) ソールド アウト
(3)  オウ アウ
(4) sオウdアウt


今後は以下の心構えで英語を聞くことにしよう。

  • 母音を聞くことに集中する
  • 母音の前後に子音の弱い音の情報がくっついている聞こえる


まともな解析が知りたい人は、amazonで売れ筋を調べて町の本屋とかで本を買って下さい。

英語リスニングのお医者さん [改訂新版]

英語リスニングのお医者さん [改訂新版]

screen の backtick をいつか使う(mkfifo使用)

screen の backtick をいつか使う - l1o0の日記 でファイルの変更を読み取るのに、周期的にファイルを監視していたが、kazuhoのメモ置き場 を参考に、mkfifoを使えば簡単にプロセス間通信を実現できることがわかった。

mkfifo

mkfifoを使えばファイルをI/Fとして簡単にプロセス間通信を実現できる。例えば、以下のスクリプトを実行すると、

mkfifo.sh

#!/bin/sh

fifo_file="/tmp/tmp$$.fifo"
rm -f $fifo_file
trap "rm -f $fifo_file; exit 1" 1 2 3 15
mkfifo -m 666 $fifo_file

grep -i "init" $fifo_file | grep -v "grep" > result.txt &
ps aux > $fifo_file

rm -f $fifo_file
$ sh mkfifo.sh
$ cat result.txt 
root         1  0.0  0.0   2112   740 ?        Ss   02:38   0:01 init [5]  

となる。バックグランド(つまり別プロセス)で動いているgrepと、fifoファイルを通して通信できていることがわかる。

ファイルのリダイレクト以外でも、オプションでファイル出力するタイプのコマンドでも同じことができる。

mkfifo_f.sh

#!/bin/sh

fifo_file="/tmp/tmp$$.fifo"
rm -f $fifo_file
trap "rm -f $fifo_file; exit 1" 1 2 3 15
mkfifo -m 666 $fifo_file

grep -i "open" $fifo_file > result.txt &
strace -o $fifo_file ls

rm -f $fifo_file
$ sh mkfifo_f.sh
$ cat result.txt 
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib/libselinux.so.1", O_RDONLY)  = 3
open("/lib/i686/cmov/librt.so.1", O_RDONLY) = 3
open("/lib/libacl.so.1", O_RDONLY)      = 3
open("/lib/i686/cmov/libc.so.6", O_RDONLY) = 3
open("/lib/i686/cmov/libdl.so.2", O_RDONLY) = 3
open("/lib/i686/cmov/libpthread.so.0", O_RDONLY) = 3
open("/lib/libattr.so.1", O_RDONLY)     = 3
open("/proc/filesystems", O_RDONLY|O_LARGEFILE) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3
open(".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3

strace の -o オプションでファイルの出力先としてfifo ファイルを指定して、別プロセスで動いている grep にコマンド出力を渡している。

backtickスクリプトの変更

ということで、screen の backtick をいつか使う - l1o0の日記で使っていたperlスクリプトを以下のようにした。

#!/usr/bin/perl
use strict;
use warnings;
use IO::File;
use Path::Class qw(file);
use POSIX qw(mkfifo);

my $fifo = file( $ENV{HOME}, 'tmp', 'backtick.fifo' );
unlink $fifo;
if ( !mkfifo( $fifo, 0666 ) ) {
    die "$!";
}

while (1) {
    open my $fh, '<', $fifo or die "$fifo, $!";
    while ( my $line = <$fh> ) {
        $line =~ s/\x0D?\x0A?$//;
        print $line, $/;
        (*STDOUT)->flush;
    }
    close $fh or die "$fifo, $!";
}

ディレクトリをブックーマーク

zsh で移動するディレクトリをブックマークできたら便利なんじゃないかと思い、探したがあまり見つからない。ということでbd (bookamrk directory) という簡単なコマンドを自作。

ディレクトリをブックマークに登録

$ bd /tmp /usr /usr ../../etc/apache2
push new dir /tmp
push new dir /usr
push new dir /usr
push new dir /etc/apache2
0 /tmp
1 /usr
2 /etc/apache2

移動ディレクトリをブックマークから選択

bd コマンドを引数なしで実行すると、select number:と出てくるので、番号を指定するとそのディレクトリに移動する。

$ bd
0 /tmp
1 /usr
2 /etc/apache2
select number: 2
$ pwd
/etc/apache2

ブックマークからディレクトリ削除

bd コマンドを引数なしで実行して、select number:と出てきたときに 「d 番号」とするとそのディレクトリをブックマークから削除。

$ bd
0 /tmp
1 /usr
2 /etc/apache2
select number: d 1
Delete /usr from bookmark
0 /tmp
1 /etc/apache2

ソース

以下のソースをファイルに保存してsourceすれば bd コマンドが使えるようになる。zleを使えば、ブックマークを登録順にソートだとか、階層化して折り畳み表示とかできそうだけどzleは修行不足のため断念。

BOOKMARK_FILE=${BOOKMARK_FILE:-"$HOME/.zsh.bmk"}

function _bd_dump ()  {
    count=0
    while [ $# -gt 0 ]
    do
        echo "$count $1"
        shift
        count=`expr $count + 1`
    done
}

function _bd_select_dir () {
    typeset -a -U bookmarks
    bookmarks=("$@")
    _bd_dump $bookmarks
    echo -n "select number: "
    read cmd1 cmd2

    case "$cmd1" in
        d|D)
            number=`expr $cmd2 + 1`
            echo "Delete $bookmarks[$number] from bookmark"
            bookmarks[$number]=()
            typeset bookmarks > $BOOKMARK_FILE
            _bd_dump $bookmarks
            ;;
        [0-9])
            number=`expr $cmd1 + 1`
            cd $bookmarks[$number]
            ;;
        *)
            echo "Unknown command $arg1"
            ;;
    esac
}

function bd () {
    bookmarks=()
    typeset -a -U bookmarks
    if [ -f "$BOOKMARK_FILE" ]
    then
        source "$BOOKMARK_FILE"
    fi

    if [ "$#" -eq 0 ]
    then
        # Select or remove dir
        _bd_select_dir $bookmarks
    else
        # Set dir(s)
        while [ $# -gt 0 ]
        do
            if [ -d "$1" ]
            then
                if [ $#bookmarks -gt 10 ]
                then
                    echo "bookmarks full in $bookmarks"
                fi
                new_dir=`realpath $1`
                echo "push new dir $new_dir"
                bookmarks+=($new_dir)
            else
                echo "$1 is not directory"
            fi
            shift
        done
        typeset bookmarks > $BOOKMARK_FILE
        _bd_dump $bookmarks
    fi
}