Perl製自作便利ツール紹介: 時間電卓

Perl製・掌編自作ツール紹介の第3回です。

以前の回はこちら。(古い順に)

今回は前回まで以上に「他の人はどうしてんだろ・・」的な案件なのですが、時間どうしを足す電卓、「時間電卓」のご紹介です。

この電卓では差分は計算せず、二つ以上の時間をひたすら足す時に使います。
(ちなみに、二つの時間の引き算は前回紹介した日時電卓の datetime_substract.pl で出来ます)

動機: CDブックと「Excel様」

そもそも、なぜそんなものが必要なのかと言うと、僕の場合はCDブックの編集・制作という仕事の都合上、たとえば15曲入りのCDを作ろう! などとなったときに、それがCDに収録できる最大許容時間(72分とか74分とかいろいろ言われていますが、それについては割愛)に収まるかどうかをつねに留意しておく必要がありまして、「はあ、この15曲、超いいラインナップだな〜」なんて思っても、「いやちょっと待て、これって合計何分だろ?」とふと我に返り、サクッと時間の足し算をしなければならないケースがよくあります。

まあ、そういう立場にある人はそう多くはないかもしれないんですが、とはいえ、他にまったく居ないということも無いはずで、そういう人は普段、どうやって計算してるのかなあ? とも思います。

と言いつつ、これはそれこそ、Excelだと結構簡単にできます。というか実際、僕にしても自分のこのスクリプトだけだとちょっと不安なので、超大事な状況下であったり、すでにExcelが起動していたりする時にはExcelも併用するのですが、Excelって案外「Excel様」的に、こちらの言うことをあまり聞いてくれない時があるというか、想定したとおりに動かない場合があり、とくにそれが「時間」を扱うときに顕著な印象があるため(僕の知識やスキルが足りないせい、とも言えますが)、こうやって裏側までちゃんと把握できる、原理がシンプルなツールを作る&使うメリットはあるかなとも思います。

でも単純に、それ以前の話として、一般的な電卓にこういう「時間を加減する機能」が入っていないのはどういうことだろう? とよく思います。ニーズないのか??

詳細・使い方

肝心のコードはこちらです。

#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use integer;
use Time::Piece;
use Time::Seconds;

my ($time_total, $time_calc, $ans_minute, $ans_hour, $ans_second);

my @list = <DATA>;
for my $calc_batch(@list) {
    if ($calc_batch =~ /^(\d\d*):(\d\d):(\d\d)$/) {
        $time_total += $1*60*60 + $2*60 + $3;
    } elsif ($calc_batch =~ /^(\d\d?):(\d\d)$/) {
        $time_total += $1*60 + $2;
    } else {
        $calc_batch = "Error!\n";
    }
}
$ans_hour = ($time_total / (60 * 60));
$ans_minute = (($time_total / 60) - ($ans_hour * 60) );
$ans_second = ($time_total) - ($ans_hour * 60 * 60) - ($ans_minute * 60);

say "total: $time_total sec";
say "ans: $ans_hour hr $ans_minute min $ans_second sec.";
say "---";
for my $view(@list) {
    print $view;
}

__DATA__

例のごとく、「__DATA__」の下に素材を入れていきます。以下の内容を入れて実行すると、

__DATA__
6:58:14
17:09:49
1:02
02:45

こんな風に出てきます。

total: 87110 sec
ans: 24 hr 11 min 50 sec.
---
6:58:14
17:09:49
1:02
02:45

このとき、6ケタなら「時:分:秒」と認識し、4ケタなら「分:秒」と認識します。

やっていることは単純明快で、一旦全部「秒」に置き換えて、すべてを足し終わってから「時・分・秒」に戻しているだけです。

でも最初はそんな方法にも気づかず、とりあえず「時間電卓作るで〜!」みたいになって、「ええと、まず秒と秒を足して、60を過ぎたら分に1個繰り上げて・・それを分同士の足した数値に足して、60を超えたら・・」とかやって結構大変な目に遭いました。

というか、さらに正直に言うとそこで一旦挫折して、何ヶ月も放置してからあらためてトライした際に「もしかして一旦秒に揃えればいいのでは・・」と気づいてから何とか現状のようになったのですが。

まあ、前回の日付電卓もそうですが、まだ自分の想定する使い方しかしていないので、バグというのか、普通に使えない部分もいろいろあるとは思いますし、それとは別にもっと洗練できるところもあるとは思うのですが、ひとまず現状、「Excelを開かずに複数の時間を一気に足す」ことはできるので、いいんじゃないかなと思っています。

付録: 数値電卓

当初の予定では上記で終わるつもりだったのですが、オマケ的な何かとして、「数値電卓」もご紹介します。

いや、そもそも電卓って数値を計算するものでしょ、という感じですが、これは数十個の数字を一気に足し算することを想定して作りました。それだけの数になると、電卓に打っていくのも面倒ですし、ミスタイプする可能性もありますから。
というかまあ、それなら今度は(それこそ)Excelでやれば一瞬なのですけど、ようは上のを作ったついでに試したかったというか・・

たとえば、こんな数字群があったとして、

95, 83, 47, 44, 43

それを一気に足したいな、という時に、以下のコードの「__DATA__」以下にそれを入れて実行すると(1行に数字1個)、

#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';

my $time_total;
my @list = <DATA>;
for my $calc_batch(@list) {
    if ($calc_batch =~ /^(\d+)$/) {
        $time_total += $1;
    } else {
        $time_total += 0;
    }
}

say "total: $time_total";
say "---";
for my $view(@list) {
    print $view;
}

__DATA__
95
83
47
44
43

こんな感じに出てきます。

total: 312
---
95
83
47
44
43

Congrats!!

付録: 曜日電卓

まだありました。こちらは以下のコードの「__DATA__」以下に日付を入れておくと、それに応じた曜日を出す、というものです。

具体的には、このコードを実行すると、

#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use Time::Piece;
use Time::Seconds;

my $switch = 'short';
#my $switch = 'long';

my ($stamp_local, $stamp_day);
my @week = <DATA>;
for (@week) {
    chomp $_;
    my $output = $_;
    $_ =~ s/\//-/g;
    $stamp_local = localtime->strptime($_, '%Y-%m-%d');
    if ($switch eq 'Sun') {
        $stamp_day = $stamp_local->wdayname;
    } elsif ($switch eq 'Sunday') {
        $stamp_day = $stamp_local->fullday;
    }
    say $output."\t".$stamp_day;
}

__DATA__
2015/2/4
2015/2/21
2015/2/26
2015/2/27

このような結果が出ます。

2015/2/4	Wed
2015/2/21	Sat
2015/2/26	Thu
2015/2/27	Fri

日付の後に、タブを挟んで曜日が出てくるという。

現状、曜日名が「Wed」や「Sat」になっていますが、以下の行をコメントアウトして、

my $switch = 'short';

上記ではコメントアウトしてある以下を活かすと、曜日名がフルで出てきます。

my $switch = 'long';
動機: 「曜日電卓」編

ちなみに、なぜこのようなものを作ったのかと言うと、ぼくは日頃、「曜日」が記憶を呼び起こすトリガーとして有効であると思っているので、自分の記録を付けるときにはなるべく曜日を併記するようにしているのですが、とはいえ、いちいち毎回、日付を記述するごとに曜日を思い出したり、それを打ち込んだりするのも徒労感があるので、この辺をザバッとやってくれるスクリプトがほしいなあ、と思って作った次第でした。

で、こちらも Time::Piece と Time::Seconds モジュールを使っているので、曜日名を日本語にローカライズすることも可能ですね。
ちょっと時間がかかりそうですけど、練習としてはその機能を持たせるのもいい気がします。

・・と思い始めたら気になって眠れなそうだったので、サクッとやってみたら出来ました。これで良さそうです。(コード部分のみ)

#my $switch = 'Sun';
#my $switch = 'Sunday';
#my $switch = '日';
my $switch = '日曜日';

my ($stamp_local, $stamp_day);
my @week = <DATA>;
for (@week) {
    chomp $_;
    my $output = $_;
    $_ =~ s/\//-/g;
    $stamp_local = localtime->strptime($_, '%Y-%m-%d');
    if ($switch eq 'Sun') {
        $stamp_day = $stamp_local->wdayname;
    } elsif ($switch eq 'Sunday') {
        $stamp_day = $stamp_local->fullday;
    } elsif ($switch eq '日') {
        $stamp_day = $stamp_local->wdayname(qw{日 月 火 水 木 金 土});
    } elsif ($switch eq '日曜日') {
        $stamp_day = $stamp_local->wdayname(qw{日曜日 月曜日 火曜日 水曜日 木曜日 金曜日 土曜日});
    }
    say $output."\t".$stamp_day;
}

__DATA__

上記同様、冒頭の変数 $switch の宣言時に活かしたい書式のコメントアウトを外してもらえばそれで出力されます。

2015/2/4	水曜日
2015/2/21	土曜日
2015/2/26	木曜日
2015/2/27	金曜日

前回紹介した「CPANモジュールガイド」のp97を見たら1分かからず書けました。トミールさん、ありがとうございました!

on GitHub

最後に、ここ数回でご紹介したコードの公開リポジトリへのリンクを張っておきます。日付電卓と時間電卓は以下。
note103/calculators · GitHub

曜日電卓と、ちょっと前に紹介した overlap.pl は以下に置いてあります。
note103/toolbox · GitHub

以上です!

Perl製自作便利ツール紹介: 日付電卓

自分用に作った小っちゃいPerlツールの紹介シリーズです。

前回はこちら。

Perl製自作便利ツール紹介: 重複行抽出スクリプト - the code to rock

上記の「重複(&非重複)抽出ツール」は、主に日常用途を想定して作ったものですが、今回は逆に(というか)、仕事で使う必要に迫られて作ったものです。

具体的には、日にちや時間を加減する電卓です。

動機

電卓といえば計算機、計算機といえばコンピュータの起源とも言える何かですから、時間や日にちを計算するツールなんて絶対ネットのそこいら中にあるだろう、と想像されるわけですが、探してみると案外(数年前からその必要に迫られるごとに検索していますが)、めぼしいものが見つかりません。

そういうものがまったく無いわけではなくて、WebアプリでもiPhoneアプリでも、各所で作成&公開されている物があるのはあるのですが、いわばデファクト・スタンダードというのか、「このニーズにはとりあえずこれでしょ」と言える定番が無いというか。

たとえば、ソーシャルブックマークならはてブでしょ、とか(少なくとも日本では)、入門者のプログラミング系Q&AならStack Overflowでしょ、とか。料理レシピならCOOKPADでしょ、とか。検索なら・・もういいですか。

ようは、これだけニーズがありそうな分野であるにもかかわらず、どうして「鉄板」と言えるものがないのかなあ、というのは僕にとっていまだに大きな謎です。
(もしかしたら通常の電卓にデフォルトで仕込まれているそういう機能を僕が知らないだけ、とか・・?)

上述のWebアプリなどももちろん、以前に試せるかぎりは試したのですが、どうにもまどろっこしいというか・・。ネットに繋がっていないと使えなかったり、単純な目的に比して手間がかかったりして(入力や選択の対象が多いなど)、もっと少機能で軽快に動くものがほしい、というニーズが固まってきたため、もう他人様が作ってくれたものにどうこう言うのではなく、自分で自分の用途に一番最適化したそれを作ってみよう、という流れになったのでした。

あとはまあ、このぐらいの内容なら、今までに教わったことを元に出来ないワケがないだろう・・というか出来てみたい、いや出来てください、という欲求が高まったということでもあるのですが。

前置きが長くなりましたが、そういうモチベーションから作成したスクリプトを3本ご紹介します。

日付電卓

まずは「日付電卓」です。これが3本中の2本です。

なぜ2本もあるのかというと、一つは「1つの日付に1つの数値(日数)を加減する」もので、もう一つは「2つの日時の差を求める」というものだからです。

具体的には、前者がこちら。(date_num_calc.pl)

#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use Time::Piece;
use Time::Seconds;

my @list = <DATA>;
chomp @list;
for (@list) {
    $_ =~ s/\//-/g;
}
my $date = $list[0];
my $num = $list[1];

my $stamp_local = localtime->strptime("$date", '%Y-%m-%d');
my $add = $stamp_local + ONE_DAY * $num;
say $add->ymd." (add)";
my $substract = $stamp_local - ONE_DAY * $num;
say $substract->ymd." (substract)";

__DATA__

後者がこちらです。(datetime_substract.pl)

#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use Time::Piece;
use Time::Seconds;

my ($pday, $phour, $pminute, $psecond);
my ($day, $hour, $minute, $second) = (0, 0, 0, 0);

my @list = <DATA>;
chomp @list;
for (@list) {
    $_ =~ s/\//-/g;
    if ($_ =~ /^(\d\d?:.+)$/) {
        my $d = localtime->date;
        $_ = "$d $1";
    }
}

my $date1 = $list[0];
my $date2 = $list[1];
stamp($date1, $date2);

sub stamp {
    my ($date3, $date4) = @_;
    my $stamp_local = localtime->strptime("$date3", '%Y-%m-%d %T');
    my $stamp_local2 = localtime->strptime("$date4", '%Y-%m-%d %T');

    my $substract_day = ($stamp_local - $stamp_local2) / ONE_DAY;
    $day = sprintf("%d", $substract_day);
    my $substract_hour = (($stamp_local - $stamp_local2) - $day * ONE_DAY) / ONE_HOUR;
    $hour = sprintf("%d", $substract_hour);
    my $substract_minute = ($stamp_local - $stamp_local2 - ($day * ONE_DAY) - ($hour * ONE_HOUR)) / ONE_MINUTE;
    $minute = sprintf("%d", $substract_minute);
    my $substract_second = ($stamp_local - $stamp_local2 - ($day * ONE_DAY) - ($hour * ONE_HOUR) -  ($minute * ONE_MINUTE));
    $second = sprintf("%d", $substract_second);

    ($day, $hour, $minute, $second) = map {abs($_)} ($day, $hour, $minute, $second);
    plural($pday, $phour, $pminute, $psecond);

    my $result = "$day $pday $hour $phour $minute $pminute $second $psecond\n";
    say $result;
}

sub plural {
    ($pday, $phour, $pminute, $psecond) = @_;
    unless ($day == 1) { $pday = 'days'; } else { $pday = 'day'; }
    unless ($hour == 1) { $phour = 'hours'; } else { $phour = 'hour'; }
    unless ($minute == 1) { $pminute = 'minutes'; } else { $pminute = 'minute'; }
    unless ($second == 1) { $psecond = 'seconds'; } else { $psecond = 'second'; }
}
__DATA__

いずれも、ファイル下方の「__DATA__」の下に、1行につき一つ、対象となる日にちや数値を入れて実行する次第です。

たとえば、前者の「__DATA__」以下をこのようにすると、

__DATA__
2016-01-27
98

このように出力されます。

2016-05-04 (add)
2015-10-21 (substract)

「2016-01-27」に98日分足した日にちと、98日分引いた日にちが出てきます。

また、後者の方をこのようにしておくと、

__DATA__
2015-02-16 02:05:28
2015-01-19 00:18:34

このように差が出力されます。

28 days 1 hour 46 minutes 54 seconds

この際、時刻を入れずに設定すると自動的に0時0分0秒となり、また日付を入れずに設定すると実行した日を日付に入れるので、たとえば2015/2/16に以下のように実行したら、

__DATA__
2015-02-16
00:18:34

こんな感じになります。

0 days 0 hours 18 minutes 34 seconds

この際、差は絶対値で出しています。

最初は絶対値にしていなかったので、上記の例だと

0 days 0 hours -18 minutes -34 seconds

みたいになってしまい、見づらかったのでそのように直しました。

さらにちなみに、後者は初めは日数だけの差分を求めるようにしていたので、もっとシンプルな内容(行数が少ない)だったのですが、何となく時間も一緒に計算できるようにしたくなってしまったので、そうしたらえらい長くなりました。リファクタリング待ちですね。

謝辞

以前はこれらをDatetimeモジュールで作っていたのですが、それは少し前にコアモジュールから外れたという話を聞いたので、Time::Piece と Time::Seconds を使ったコードに頑張って置き換えました。

その際には、言わずと知れたこちらのモジュールガイド本と、

Perl CPANモジュールガイド

Perl CPANモジュールガイド

毎度お世話になっています木本裕紀さんのブログ、

その他、検索先の皆様に助けて頂きました。ありがとうございました。

用途

このスクリプトは、とくにスケジューリング作業のときによく使います。

前者の「日付 + 日数」電卓なら、「このタスクは20日はかかるなあ・・取り掛かれるのは多分2週間後の水曜ぐらいだから、その日から数えて終わるのは何月何日になるだろう?」なんて思った時に使います。
まあ、そういう対象が1個や2個ならばカレンダーを見ながら(もちろんエディタでcalendar.vimを見ながら)目視&暗算すれば良さそうなものですが、スケジューリングのときには何十という対象についてそういう算出をするので、こういうツールがあった方がラクだなと。

また、後者の「日時 - 日時」電卓であれば、「以前にやってA日からB日までかかった作業があるけど、結局その作業は何日間で終わったんだろう? また同じ作業をするから日数の見積もりの目安にしよう」なんていう時に、BからAを引いて欲しい数字を求めます。

というか、そういう時、他の方はどうやって乗り切っているのでしょうね・・? Excelですかね? まあ、たしかにExcelならできるでしょうけど、でも皆が皆Excelでそれを求めているとは(とくにプログラマーの人は)思えないのですが・・

長くなったので本日はここまでにします。続きは次回!

Perl製自作便利ツール紹介: 重複行抽出スクリプト

以前に書いた記事で、

この他にも自作ツールで使っているものがもう少しあって、それは超ちっちゃい、ちょっとした一つのことをやるためだけの、限られた目的をもったわずか数行のPerlスクリプトですが、地味にだいぶ役立ってもいるので(略)、次の機会ではそれを紹介したいと思っています。

と予告していたツールの一つを紹介します。

vimrcの重複問題

エディタはプログラミングのときもそれ以外のときも(仕事のテキストを編集したりメールを書いたり)使っているのはVimで、あ、ところで最近読んでいる青木峰郎さんの以下の本で、

青木さんは普段のプログラミングではVimを使って、メールや原稿書きの用途ではEmacs、その他時々IDEを使う、と書いていたので、ああ、そういうEmacsの使い方、いいなあ〜と思ったりしましたが、とりあえず僕は今全編Vimなので、そうなるとvimrcには始終付き合うことになります。

vimrc、慣れてる人は綺麗に掃除が行き届いている印象ですが、僕はあちこちで見かけたよさげな記述をただボンボン放り込んでいるだけという感じでもあり、そうなるとありがちなのが、同じ記述を複数回書いてしまう現象です。

それぞれの記述の本来的な意味などがきちんとわかってるわけでもないこと、また日常的にVimに触るとは言っても、実際の職業はプログラミングとは全然関係なかったりするので、なんだかんだでその雑で混沌としたまま、数百行にわたるそれを修正する間もなく、たとえば

set swapfile

set noswapfile

が100行ほどの間を空けてどちらも記述されていたり、あるいは

set hlsearch

が2個も3個も入ってたり、ということが普通にあります。

これを何とかしたいなあ・・とは前々から思ってはいて、それを解決するためにあちこち検索しながら書いたスクリプトがこちら、overlap.pl です。


この下方、__DATA__ 以下に対象のデータを入れて実行すると、重複している行が出てきます。

overlap:
orange
lemon

※ハッシュを使っているのでorangeとlemonの順番は時により変わります。

いわゆる車輪の再発明的なツールですが、すぐに使える他の適した道具を知らなかったので、grepやハッシュの勉強もかねて作ってみました。

あと、一度こういうのを書いて発信してみることにより、こういう場合には他の先輩方はどうしているのか、ということを知るきっかけにもなるかな、と思っています。

非重複行の抽出

ついでに、その真逆の「他のどの行とも重複していない行」も抽出できるようにしています。

具体的には、上記Gist内の7行目

my $switch = 'o';

コメントアウトして、次行の、今コメントアウトしてある

my $switch = 'u';

を生かせばOKです。

実行すると、この例の場合には apple だけが出てきます。

ただ、ところで、この非重複に関わる変数名を現時点では「unique」としていますが、普通はこの状況で unique と聞いたら、重複している行であっても一つは出しておく方が直感的な気もするので(つまり例にある果物名が全部一つずつ出てくる)、現状の意図ならばもう少し適した変数名を付けた方が良さそうとも思います。

alone とか solitude とか・・そういう仲間のいない感じ・・
いや、落ちこんできそうなので、この検討はまたにしましょう。

このスクリプトはささやかなものですが、時々使っています。
数ヶ月に1〜2度という感じでしょうか。

似たような規模のものがまだあるので、シリーズ的にもう少し続きます。

自作英単語学習ツール: "Carvo2" の最近の様子

今年最初のエントリーです。

Perl入学式で学んだPerlの基礎知識を使って、自分に役立つツールをいくつか作っています。

昨年末の Advent Calendar でも、最後にひとつ紹介しました。

今日はそうした自作解題シリーズの第2回ということで、「Carvo2」を紹介します。
note103/Carvo2 · GitHub

来歴 / 新機能

と、言いながら、Carvoはすでに何度かこのブログでも扱っていまして、古い順にこんな感じで。

  1. 英単語学習ツール "Carvo" - 機能拡張&モジュール化してGitHubに公開しました - the code to rock
  2. 英単語学習ツール "Carvo" に得点加算機能を付けました - the code to rock
  3. Carvo2の作成 / Perl入学式 in YAPC::Asia2014 - the code to rock

ということなので、このツールだけで実はもう4回目の登場です。

にもかかわらず(というか)、また紹介したいと思った一番の理由は、「読み上げ機能」を付けたことにあります。

上の記事群では、どれもGIF動画でその様子を紹介していることからもわかるように、このツールはこれまで「無音」で使っていたのですが、やはり英単語の暗記ツールというなら「読み上げ」の機能がほしいなあ、とは前々から思っていました。

そんな時、増井俊之さんの『Perl書法』をパラパラと頭から眺めていたら、その方法がさらっと書かれていまして。

Perl書法 (ASCII SOFTWARE SCIENCE Language)

Perl書法 (ASCII SOFTWARE SCIENCE Language)

といっても、実に単純なことで、たとえば Hello World! と出力したいときに、

print "Hello World!\n";

と書くのと一緒に、

print `say Hello World!`;

と書いているだけ、みたいなことなのですが。

具体的なコードで言うと、たとえば Carvo.pm の268 - 270行あたりでそのように書いています。(2015/01/10時点)
https://github.com/note103/Carvo2/blob/master/lib/Carvo.pm#L268

Macでは、「say」とした後に読ませたい語句を入れると、それをMacが読み上げてくれるので、その機能に動いてもらっている感じです。

動画作成

さて、そのように新機能を実装し、自分が楽しむところまでは良かったのですが、英語を読み上げている本ツールの様子を、ネットの向こうの人たちにどう知らせるか? というのはちょっとした問題でした。

そこで、いろいろ探してみたところ、「Soundflower」というのが良さそうだったので、それとQuicktimeを組み合わせて撮ってみました。

Soundflowerの使い方や撮影方法については、以下が参考になりました。ありがとうございました。

マシンや環境によっては上手く動かなかったり、録音した音量がやけに小さかったりという問題があるようで、部分的にそれに陥りましたが、検索を重ねてなんとかなりました。(詳細は割愛)

動画

ということで、実際にツールを使っている様子はこちらです。(2分半ほど)


carvo: 2015-01-10-01-06 - YouTube

喋っているのは、Macで僕が読み上げ担当者として設定しているVickiという女性(たぶん)です。
男性の声だとAlexという人が良いですね。

ちなみに、Macで読み上げをさせる方法や、その種類(選択肢)については以下の記事がシンプル&必要十分でわかりやすいです。

疲れたときなど、これを片端から試して気持ちを落ち着けたりします。

使い方: 読み上げ関連

最初は、デフォルトでは読み上げないように設計していたのですが(いきなり音が出たら驚くユーザーもいるかと考えて)、自分では毎回必ず読ませるので、自分のためにデフォルトは「オン」にしました。

これも具体的なコードで言うと、Carvo.pm の11行目でそのように設定しています。
https://github.com/note103/Carvo2/blob/master/lib/Carvo.pm#L11

デフォルトでオフにしたい場合は、変数に代入する文字列を現状の on から off にしておく、という感じです。

our $voice_sw = 'off';

動画のデモには含めませんでしたが、「v」というコマンドを入れると、途中でもオン・オフを切り替えたり、声の種類を変更したりできるようになっています。(上記の Alex の声に切り替えたり)

また、Carvo2では単語(見出し語)以外に「例文」も出力できるようにしていますが、この例文まで読ませると、けっこう待ち時間が長くなって、だるくなってしまいがちだったので、デフォルトでは例文の読み上げはスキップして、読ませたい時にはそちらのモードを選択できる、という風にしました。
動画でいうと、1:20あたりで「lo」(long)と入力しており、これが例文を読ませるモードへの切り替えコマンドです。

元に戻したいとき(例文を読ませないようにする)には、「sh」(short)と入力します。

使い方: 間違えた単語のリスト化機能

以前に紹介した「Worg」同様、自分で毎日使っているので、日々「もっとこうした方が良くなる」ということが出てきます。

最近のそうした「自分リクエスト&自分対応」で付け加えたのが、「回答ミスした単語を覚えておいて、それだけをリピートできる」という機能です。

上の動画でいうと、1:40ぐらいで「f」(fail)というコマンドを入力していますが、それです。
これまた全くどこにも説明がないので(今はじめて書いた)、そのうちきちんとします。

ちなみに、元に戻るには「b」(back)でOKです。
このとき、fail list モードに入る前の状況を覚えておいて、その続きからスタートできるようにしたので、自分がんばったな、という感じです。

とはいえ、この fail list モードや上記の「lo/sh」スイッチ、また「v」による音声切り替えやオン/オフなどの諸機能については、用法はおろか、存在じたいに関する説明すらツール上に無いため(READMEにも)、そのうちきちんとドキュメントを書きます。

その他

「Carvo」の読み方について書いていませんでしたが、「カルボ」でも「カーヴォ」でも何でも大丈夫です。

ぼくは20代の終わりから30代の初めにかけて、近所の個人経営のイタリアンレストランでアルバイトをしていましたが、そこの名物のひとつであったカルボナーラの厨房での略称が「カルボ」だったので、その影響があるかもしれません。

単語練習用のカードはJSONファイルで作っていますが、GitHubに上げている物にはそれぞれ30語程度ずつしか入れていません。
例文もあるので、「試すには少なすぎる」というほどでもないとは思いますが、実際にはやっぱり、数百語あったほうが面白いかな、とも思います。

ぼくが手元で使っているカードは3種類あって、それぞれ100〜300個ぐらいの単語が入っており、週に数回、参考書を見たり、普段拾っておいた単語を調べたりながら、少しずつ数を足しています。

よって、もし手元でこれを使いたいという人がいたら、各自でカード内の単語を増やした方がいいのかもしれないですが、一方、それはそれで結構ホネというか、やや徒労感があるので、できれば今後のTodoとして、出題カードの作成については、もっと効率的でプログラマブルな(自分で一語一語足していくのではない)方法を探したいとも思っています。

暗記カードを自作することはもちろん、それ自体で勉強になるでしょうし、ちょっと遊ぶためぐらいなら、そのシステムでもいいかもしれませんが、本当に勉強に繋げたい、と思ったらやっぱり問題はきちんとしたものの方がいい気もしますし。

※ちなみに、自分の暗記カードをそのまま公開していないのは、転載元の参考書に配慮してのことです。

次回予告

前回、自作ツールの Worg を紹介した時には、

僕が作ったものの中でも1, 2を争う「自分でよく使っているツール」です。

と書きましたが、最近は Worg 以上にこの Carvo2 を(少なくとも1日1度は)使っているので、現状では「最も自分で使っている自作ツール」と言えます。

この他にも自作ツールで使っているものがもう少しあって、それは超ちっちゃい、ちょっとした一つのことをやるためだけの、限られた目的をもったわずか数行のPerlスクリプトですが、地味にだいぶ役立ってもいるので(実際に必要になるのは年に数回だけど、たまたまここ何日かの仕事で使ったという)、次の機会ではそれを紹介したいと思っています。

Perlで日々の行動や考えを記録する: "Worg" のご紹介

こちらは Perl入学式 Advent Calendar 2014 の10日目の記事です。

昨日は @__papix__ さんの「Perl入学式の歴史 〜その2 2012年〜」でした。
とてもドラマチックで、人間同士の一つ一つのつながりが「Perl入学式」を作ってきたのだなあ、と思いました。

僕の方は、このAdvent Calendarでこれまでに2本、やや抽象的で概念的な話を書いてきましたので、

今回はもう少し具体的に、ではプログラミングを学んで何を作ったのか? ということについて書いてみたいと思います。

イントロダクション 〜 Markdown環境について

前回までの記事にも書きましたように、僕の本業はCDブックの編集者です。
したがって、普段の仕事でプログラミングをする機会はありません。

しかしながら、プログラミング学習を通して得た知識や経験によって、生活や業務の上で便利になったことはたくさんあります。

たとえば、VimMarkdown、Gitやターミナルなどは毎日のように使いますし、とくにVimMarkdownがない生活にはもう二度と戻れないでしょう。

この記事もまた、MacVimというエディタに、Markdown形式でドラフトを書いています。

f:id:note103:20171007035219p:plain

僕のMarkdown環境については、以下の記事にも少し書きましたので、ご興味がおありの方はぜひどうぞ。

そしてもちろん、こうした環境面のことだけでなく、Perl入学式で学んだことを用いて実際に作成したツールもいくつかあります。
今回は、その中の一つである「Worg」(ワーグ)を紹介したいと思います。

Worg

「Worg」という名称は、「Work」+「Log」から来ています。
読み方は、上記の「ワーグ」でも、「ウォーグ」でも「ワルグ」でも構いませんが、ここでは便宜的に「ワーグ」と呼ぶことにします。

このツールは、その語源が示す通り、業務の記録作業を補助するために作りました。
GitHubでも公開しています。
GitHub - note103/Worg: Works and logs

そして、このツールの元には、今年の3月に開催された「Perl入学式 in東京 第2期修了式」のLTで初披露したツール「chat2spreadsheet」があります。

リンクの後者にもありますが、僕がそのときに発表したスライドを掲示しておきます。「chat2spreadsheet」に関する話はp31から始まります。

作業の流れ

今回紹介する「Worg」では、原型となった「chat2spreadsheet」から大小の書き換えがなされ、とくに、元々は1本のPerlスクリプト(c2s.pl)だけで済ませていた各種の処理を、一つの実行ファイル(worg.pl)と複数のモジュールに分けたことなどは、我ながら頑張りましたね、という感じではあります。

一方、その実行ファイルやモジュール内で実際にやっていることは、前のバージョンでやっていたこととほとんど変わらず、基本的にはif文とfor文とwhile文と正規表現をひたすら繰り返しているのみです。

そしてまた、以下のような作業全体の流れも共通しています。

1. 自分の行動や考えの記録を非公開のチャットルームや手元のエディタにどんどん投げ込んでいく。
2. それが一定量溜まったらテキストをコピーして、Perlスクリプトを通して記録用の統一書式に変換する。
3. 変換後のデータを閲覧用の場所に貼り付ける。

この2番目で使用する「Perlスクリプト」が、今回のツールです。

原型である「chat2spreadsheet」の方では、変換後のデータをExcelに貼り付ける前提にしていたので、テキストはタブと改行で区切っていました。
Excelは良くも悪くもいろいろな言われ方をしますが、やはりデータを整理することにはとても向いていると思います。

しかしながら、この場合の悩みは「せっかく整理した情報を読み返す(再利用する)ことが難しい」ということでした。
ExcelはPC以外の場ではあまり柔軟に使用できず、情報を入れることには適していても、取り出すことには向いていないようでした。

その点、やはり扱いやすいのはテキストファイルです。何しろ動作が軽快で、テキストファイルで運用できれば、データを修正する負担もだいぶ軽減されます。

また、閲覧に際しては、理想としてはブログの形態に落とし込んで、それをブラウザから見られるようにしたいと思っていました。

そこで試しに、ローカル環境にWordPressを構築して数ヶ月間更新してみたのですが、この方法の場合、確かに閲覧性は良くなるものの、情報を入れる更新作業が非常に大変で、これならまだExcelでやる方が良いと考え、継続することは断念しました。

そして、そのような時に出会ったのが、我らが @songmu さんの手によるブログツール「Riji」でした。

Riji

Riji のことは、2013年のYAPC::Asia衝撃のLTで存在は知っていましたが、


LT 2013年代のBlogツールRijiの紹介 - Songmu - YouTube

自分でも使えそうだな、と思ったのは「Perl入学式」の公式サイトで運用している様子を間近で見たからです。
Perl入学式 プログラミング初心者のためのPerl入門講座

僕は去年の3月に前述のLTをして、Perl入学式を(ひとまず)卒業し、4月からサポーターとして、運営サイドのお手伝いに回りましたが、その大きなメリットは、プログラマーの皆さん(先輩サポーター)が普段どのような話をしていて、どのような活動しているのかということについて、それまで以上に長い時間触れられるようになったことです。

Rijiの運用方法を知ることができたのも、そのメリットの一つで、もっとすごく大変だと思っていたけど、サポーターの人たちが実際に使っているところを見てみると、「このぐらいなら僕の知識やスキルでもできそうだな」と一気に興味が深まり、以下のチュートリアルを少し集中的に読んだところ、数日のうちに自分でも使えるようになっていました。
Riji tutorial

RijiはMarkdown形式のテキストファイルと、Gitさえあれば簡単に自分のブログを作ることができるツールです。
WordPressのようなデータベースの設定も不要ですし、テキストファイルとMarkdown形式が好きで、Git操作への憧れを持つ僕にはこれ以上ない選択肢でした。

たこれにより、「chat2spreadsheet」の方ではExcel用のタブ区切りの書式を採用していましたが、「Worg」の方では、Markdown形式へのテキスト変換を行うことになりました。

ひたすら自分のログを取る

コンセプトの話に戻ると、僕のライフワーク的な指向の一つに、日々の記録をひたすら取る、ということがあります。
僕はこれを、断続的ながら、2005年頃から継続しています。

ただ問題は、その記録方式がつねにバラバラだったことで、初めの頃はmixi日記に書いていたのが、やがてiPhoneアプリのローカルなメモ帳アプリに書き始めたり、あるいはチャットやメールに投げ込んでみたりと、置き場所も書式もめちゃくちゃで、これでは後から見返したり、今後の作業に役立てたりという「再利用」ができないため、そのことが長年の悩みでもありました。

そして、その課題を解決するために、つまり溜めこんだ記録を再利用しやすくなるように、データを一元化するための道具として作ったのがこれらのツールでした。

動作の流れ

コードの大半は、上記のとおり、Perlのごく基礎的な構文とサブルーチンから出来ています。

このスクリプトが行っている主な作業は、既存のチャットサービス(HipChatやSlackなど)や、手元のテキストファイルにどんどん投げ込んだ文章を、ループと正規表現から成る変換コードに通し、もし事前に登録していたキーワードにマッチした場合は、その語句を抽出し、変換後のテキストの行頭に持ってくる、というものです。

具体例として、たとえば、以下のような一文があったとします。

山本さんにメールした

このうち、事前に「山本」「メール」という語句がキーワードとして登録され、さらにそれぞれが「yamamoto」「mail」という語句(タグ)に抽出されるよう設定していたら、変換後のデータは以下のようになります。

[yamamoto,mail]山本さんにメールした

たこの際、文中のキーワードに#を付けておくと、それが元の文章からカットされて抽出されます。
以下の内容であれば、

山本さんに #mail 完了

このようになります。

[yamamoto,mail]山本さんに  完了

上記はスクリプトの主要な働きを示すために簡素化して説明しましたが、実際には、1行のテキストに日時の情報も入るようにしているため、このように変換されます。

変換前
- ドラフト完了 #mail 2014-12-02 16:39
- メール送信 2014-12-02 19:40
変換後
* 2014-12-02 16:39 [mail]ドラフト完了  2014-12-02
* 2014-12-02 19:40 [mail]メール送信 2014-12-02

本当はもう少し煩雑な制約があったり、未整理なところも多いので、あまり胸を張って見せられるものでもないのですが、エッセンスとしては、そのような感じです。

ちなみに、この「1行の中に必要な情報をすべて入れる」という点は、僕にとってはけっこう重要です。
というのも、僕はVimを使う都合上、行単位でデータを移動することが多いので(Shift+vやddといった操作を多用します)、複数の行がセットで意味を成すような構造になっていると、自由度が低くなり、使いづらくなってしまうのです。

DEMO

このツールは上記のとおり、すでにGitHub公開していますが、僕が普段使っているものは、仕事に関わるキーワードを多数登録しているため、GitHub上のコードでは一部をアレンジしています。
ただ、機能面では普段使っているものとまったく同じですので、以下では本ツールのDEMOとして、昨夜眠い目をこすりながら作成した画像+動画GIFを並べて、公開している内容でどのようなことができるか示しておきたいと思います。

1. まず、チャットからコピーしたものでも、直接エディタに書いたものでも良いので、素材となるテキストを用意します。ここでは決められた書式に沿って、4行文の内容を直接エディタに記述しました。

f:id:note103:20171007035454p:plain

2. 次に、"Worg" で元テキストを変換します。変換後の出力テキストをカットするところまでを動画にしました。

gyazo.com

ここでやっていることは、まずWorgディレクトリの中で実行ファイルを起動し、

perl worg.pl

いくつかの変換形式の中から、今回の書式に該当する「d」を入力します。(詳細は割愛)

すると、dataディレクトリ内のout.mdに変換後のテキストが出力されるので、これをターミナルのVimで開いて、

vi data/out.md

-->> <<-- で囲まれた、変換後のテキストをカットしています。


3. 次に、上でカットしたテキストを、Riji のリポジトリ内「article/entry/」に用意した記事ファイル(.md)にペーストします。

f:id:note103:20171007035606p:plain

1, 2行目にタグと日付を設定しています。
その後の「#demo」がタイトルになる予定です。
その他、Rijiの書式についてはチュートリアルの以下のページが詳しいです。
http://songmu.github.io/p5-Riji/blog/entry/006_header.html


4. その後、ターミナルでRiji を実行している動画がこちらです。

gyazo.com

最初に入力した「cdr」は、 .bash_profileに登録してあるエイリアスで、Rijiで作ったローカル・ブログのリポジトリに入るためのショートカットです。
ちなみに、ローカル・ブログのタイトルは「new notes」なので、リポジトリ名もその流れで「new_notes」としています。

その後、「ga」「gu」と入力していますが、これらもそれぞれ、

$ git add -A
$ git commit -m "Update"

エイリアスです。

さらにその後の「rjp」もまた、 .bash_profile に登録したエイリアスで、これは

$ riji publish

と同じです。

ということで、ここまでの作業で、ローカル・ブログにテキストがUPされました。


5. 仕上がりは、このような感じです。

f:id:note103:20171007035721p:plain

このブログは外部からは見えませんが、同じ無線LANの中に居れば、同URLで見ることができるようにしています。(マシンから離れてもiPhoneなどから見られるように)

また、Rijiのデフォルトのテンプレートはもう少しすっきりしたものでしたが、少し前に一念発起して、bootstrapを使ってデザインやフォントをsolarized(light)風のものに変えました。
solarizedは今のところ、僕の感覚と相性が良くて、この半年ぐらいはエディタやターミナルでも使用しています。(上の画像がどれも同じような色味なのはそれが理由です)

実はこのブログ・デザインの変更作業がかなり大変、かつとても良い経験になったので、また時間があればまとめたいところです。

Special Thanks: 参考文献紹介

以上で、今日の本題はおしまいです。
ここからはAftershow的に、このツールを作るにあたってお世話になった資料群をご紹介します。

最初はもちろん、Perl入学式です。

1. 講義資料 - Perl入学式 | Perl Entrance

通年全6回の講義うち、第1回の環境構築と最終回のWAF(Web Application Framework)講座はあまり関係ありませんが、第2回から第5回までの資料は、制作にあたって何度も読み返しました。

2つめは、『雅なPerl入門』。

2. C85にて「雅なPerl入門第2版」を頒布します - Subvoice

最初は2013年のYAPC::Asiaで購入した初版を読み倒していましたが、その後に同年の冬コミで発売された第2版(大増補版)をPerl入学式の校長であるpapixさんに買ってきて頂いて、そちらも読み倒させて頂きました。

よく使う関数や正規表現演算子の種類や使い方など、本書で何度も確認していますが、通常の技術書に比べてページ数が少ないため、物理的に軽くて、そういった常備用の参考書としても非常に良いものです。

そして、その『雅なPerl入門』の著者さんも参考にされたという、結城浩さんの本がこちら。

3. 新版Perl言語プログラミングレッスン 入門編

本当に隅々まで読者への気づかいが伝わる丁寧な内容で、僕は以前の記事で「初心者のための本を作る人は初心者ではないがゆえに初心者の気持ちがわからない」などと書きましたが、本書は数少ない例外です。
なお、同書は「入門編」とあるぐらいで、Perlのリファレンスやオブジェクト指向プログラミングについては触れられていませんので、購入される方はご注意ください。

最後はこちら、木本裕紀さんの『業務に役立つPerl』。

4. もっと自在にサーバを使い倒す 業務に役立つPerl (Software Design plus)

入門書の要素もありながら、構成内容は多彩かつ独特で、様々な用途に使っています。
おそらく本書で書かれている内容は、書籍だけでなく、木本さんが運営されているブログと合わせて読むことで、何倍にも有用さが増すと思います。
ブログの方は、過去記事も含めて濃厚な内容がすべて無料で読めますので、こちらもお勧めです。
PerlならサンプルコードPerl入門

その他、入門者向けに限らず、Perl関連の推薦図書は以下の記事(の最後の方)でも紹介しています。興味を持たれた方はぜひどうぞ。

まとめ

今回紹介したWorg は、僕が作ったものの中でも1, 2を争う「自分でよく使っているツール」です。
これと並んで使っているものがあと2〜3個ありますが、それはまた機会があればご紹介したいと思います。

以上で、Perl入学式 Advent Calendar 2014 10日目の記事はおしまいです。

明日の担当は @toku_bass さんです。@toku_bassさんは僕が初めてPerl入学式に参加したときのサポーターのお一人でした。1年以上を経て、このように並んでPerlについて書けるというのは、ささやかながら嬉しいものですね。

ではひき続き、Perl入学式 Advent Calendar 2014 をお楽しみください!

英単語学習ツール "Carvo" に得点加算機能を付けました

以前にこのブログでも紹介しました自作のPerl製英単語学習ツール "Carvo"ですが、

英単語学習ツール "Carvo" - 機能拡張&モジュール化してGitHubに公開しました - the code to rock

その時点でやりたいことはだいぶ反映してあったのですが、続けてみるとどうも、ゲーム性というか、やり続けたい、という気持ちを喚起/誘発する要素に欠けるな・・ほっておいても自然にやりたくなるような、射幸心を煽るまでは行かなくても、それに似た何かがほしいなあ〜、とは思っていて、とりあえず得点を加算できるようにしてみました。

note103/Carvo · GitHub

「とりあえず〜できるようにしてみました」とかサラッと言ってみましたが、上手く加算できてるのを見たときには飛び上がりそうなほど嬉しかったですね。

とはいえ、じつはそれもすでに10日ぐらい前の話で、というのも結局こういうのって仕事の合間とか寝る前みたいなときにしか手を入れられない&ようやく出来ても紹介するためのキャプチャ撮ったりブログ書いたりする時間もあまりとれない、とかなのでなかなか紹介できずにいたのですが、えいやって感じでREADMEの更新&新たなDEMO(得点加算バージョン)も作ってみました。

f:id:note103:20140629101633g:plain
Carvo/README.md at master · note103/Carvo · GitHub

あまり分かりやすくはないですが、正答すると「hit」、誤答は「error」、その両方の合計を「try」という感じに加算して適宜出力しています。

このツールでは途中で4つのモードを選択&切り替えできるのですが(「英→日」「日→英」「ショートバージョン」「ラージバージョン」の組み合わせ)、そのモード切り替えではリセットされず(得点保持)、最後にプログラム終了すると、総計スコアを出力して、そこでリセットされます。
プログラム終了しても記録に残るといいんですが、そこからはもうデータベースの登場になるんでしょうか。

あと、最初は「hit」のみ加算していくつもりだったのですが、モチベーション的にはじつは誤答の加算も重要というか、その正答を得るためにどれだけの試行、トライを重ねたか、という点を記録に残したかったので、「hit/error/try(hit+error)」を出すことにしました。

ちなみに「error」(誤答)は「非正答」ではなくて、何かを入力してそれが間違っていた場合に加算されます。つまり何も入力せずに解答を見た場合にはノーカウント。これは別にそういう思想に基づいているのではなく、その方が作りやすかったのでそうしただけですが。

それから出力時に、

You tried 3 times. 2 hits and 1 error.

みたいなメッセージを出すようにしていますが、この「time(s)/hit(s)/error(s)」という単語の単数形/複数形を変えるのにも地味にif文を使ったりして、最初はそこで条件分岐せずに済む方法ないかな・・としばらく考えましたが(面倒なので)、ちょっと浮かばなかったので何とか頑張ってそのようにしました。

ソースコード的にはこんな感じで・・

sub plural {
    ($times, $hits, $errors) = @_;
    unless ($times == 1) {
        $times = 'times';
    } else {
        $times = 'time';
    }
    unless ($point == 1) {
        $hits = 'hits';
    } else {
        $hits = 'hit';
    }
    unless ($miss == 1) {
        $errors = 'errors';
    } else {
        $errors = 'error';
    }
}

今思い出しましたが、それ用の関数を別に立てて都度それを呼んでるんですね。おつかれさまです。

その辺のソースコード全体はこちらです。(上記の関数は現時点では一番下の方にあります)
https://github.com/note103/Carvo/blob/master/lib/Carvo.pm

得点加算の他にも地味にいくつか、気になっていた変なところや不便だったところに手を入れています。

たとえば、登録語の最後まで行ったとき、今までは「もう終わったよ!最初に戻って!」みたいなメッセージを出すようにしていたのですが(それですら単なるエラーじゃなくて独自メッセージ出すようにできただけで最初は満足していましたが)、それも自動的に(登録語のリミットを過ぎたら)最初に戻るようにしたり、他にもメッセージの整合性が合わないところを調整したり、とかそんな感じですね。

あとはもう、ひたすらやっていけばよいだけ! という感じなのですが、こうなると今度はまた新たな欲望が出てくるもので、ランダムモードに入ったら後はずっとランダムに出てくるとか(今は基本、語順に出てくる)、リバースモードにしたら逆順に出てくるとかしたいし、あるいは僕の場合はやっぱり英語の勉強とかしたい&できそうなときって基本、モバイル環境時だったりするので、同じようなレッスン(単語が出てきてそれの日本語訳or英語訳を回答する)をモバイルでサクサクできるようにしたいなあ〜、といったあたりが現時点での次のハードルです。

とはいえ、モバイル対応のためには、とりあえずWebアプリ化してそれをローカルのサーバーに上げて同ネットワークからアクセスできるようにして・・とかなのかなあ・・? あるいは自分用のiOSアプリを作るとか・・? どっちの方がより現実的かと言ったら、とりあえず前者でしょうかね・・わからないですが。

英語の勉強よりも英語の勉強ツールの作成、のための勉強の方が楽しい! というありがちなパターンになりつつありますが、まあそれはそれ、楽しみとしてやっていますから楽しいならどっちにせよ正解でしょう。

ちなみに、GitHub上のサンプルデータ(単語ソース)ですが、当初は10〜20語ぐらいだったのですが、あまりにこれじゃ少ないかと思って、ショートモード(単語少ない版)は50語、ラージモード(単語多い版)は200語、というふうにしてみました。
以前のよりは少しは楽しめるかもしれないです。

ちなみに自分の手元の単語データはショートで200語、ラージ版で1000語近くありますが、案外感覚的には、このサンプルの方でもあまり変わらない感じかもしれません。登録語の多少よりも、単に毎日やるかどうか、とかの方が重要な違いなのかも。

以上です。

極私的ログ管理ツール "Worg" のご紹介

たぶん自分以外の誰にも、少なくとも現段階ではとくに使われる理由も必要もナイとは思うのですが、自分的にはけっこうエポックメイキングな感じになってきたのでお知らせしておきます。

note103/Worg · GitHub

Worgというネーミングは「Work」と「log」から来ています。
テーマ曲はこれです。

Isley Brothers「Work to do」。夢のような名曲です。

上記GitHubではREADMEもほぼナイに等しいので、あらためてざっくり&だらだら説明しますと、これは毎日の「自分が何をしているか、何を終わらせたか」というテキストログを定型でアーカイヴィング&再閲覧しやすいように統一的に整形するためのツールです。

じつはこれの前身というのがすでに公開されていて、

note103/chat2spreadsheet · GitHub

そっちのREADMEはけっこう一生懸命作ってあるので、まずそちらをご覧頂くと早いかもしれないのですが、あとはこんな紹介記事もありまして、

#Perl入学式 第2期最終回&修了式に行ってきた&LT発表した - 103

これは今年の3月末に、Perl入学式の第2期最終回&修了式というのがあった際にその修了式のLTで発表した内容ですが、さらにその記事中でも触れている同ツールの紹介スライドはこれになります。(ツール紹介以外の話題も多いですが)

ここで取り上げている「chat2spreadsheet」(以下「c2s」)というやつ。これはHipChatにモバイル&PCからサクサク入れておいたログを、Excelで管理しやすくするための整形ツール、みたいなもので、Perl入学式で学んだfor文やif文を駆使して作ったのでそうした場で発表させてもらったのですが、もう少し具体的に、どういうことをするのかというと(だからまあそのスライドとかREADMEを見てもらえばいいんですが)、たとえば

今日はAという仕事のBという作業をした。 2014/06/28 22:57

とか書いて、そのログをこのツールに通したときに、その中の日付や時刻、それから、上記の例ならばAとかBといった語句をキーワードとしてソースコードに登録しておくと、いわばフィルタ的に、文中からその要素を抽出して格納しておいてくれる、みたいなことをやっています。

で、その「c2s」をグレードアップしたのが今回ご紹介している「Worg」なのですが、(今思いましたが読み方、考えてなかったですね・・「ワーグ」とかですかね。「ウォーグ」でもいいですが)、「c2s」の場合は入力したテキストがExcel複数列(カラム)に分かれて格納されるように整形されるのですが、「Worg」の場合はExcelではなくテキストファイルに出力されることになっていまして、上記の例文だと以下のようになります。

# 2014/06/28
* 22:57 [A,B]今日はAという仕事のBという作業をした。

まあ、厳密にはちょっと違うんですけど、大まかにはそんなコンセプトだということで。
で、しかしそれだと何が「グレードアップ」なのか、という気もするのでもう少し詳しく書き出してみると、「c2s」から「Worg」への転換にあたって変わった部分はこんな感じです。

  • 機能追加 / 変更
    • HipChatだけでなくPC上で使ってる作業ログからも同じ形式に整形できるようにした。
    • 前身ではExcelへの出力を前提としていたが、テキストファイルへの出力に変えた。
  • 不備解消
    • 同じタグも遠慮なく重複して抽出していたが、重複しないようにした。
    • 特定の語句を別の語句としてタグ化できるようにした。
  • 技術的改善
    • 一時はHipChatからの整形用コードと作業ログからのそれとで共通部分が多くあるにもかかわらず、それぞれに(ほぼ)同じ内容を載せていたけど、共通部分を別のモジュールに移して共有できるようにした。
    • HipChatからの整形用コードと作業ログからのそれはどちらも同じタグの登録リストを使っていたけど、それも共有できていなかったので共有できるようにした。

みたいな感じでしょうか。

本当は上記「c2s」のREADMEみたいなキャプチャ群とか、DEMO動画などあると分かりやすいんだと思いますが、あまりにも普段使っているソースが極私的(プライベート&マジ仕事に関わるもの)すぎてそれは公開しづらく、となると公開用のサンプルソースを作る必要があるんだけどそんな時間もなかなかないのでかなり抽象的な話にしかなっていないですが、そういえば以前、というか去年にこういうブログ記事を書いたんですけど、

私のメモ術 - 103

これともちょっと繋がるところがあって、その続編(最新版)も書きたいと思っていたので、その辺と繋げて続きを書けたら書きます。

あとはまあ、この辺の作業フローって全般的にVimの利用とか、あと以下のような内容ともそれなりに密接に繋がっていたりもするので、

MarkdownのプレビューをVimで見る2つの方法 - the code to rock

本当はそれらも含めて総合的に紹介してみたいんですが(あとgitか・・gitもめちゃ日常に侵食してるな)、うまく時節があったらそのときに・・

※そういえば最近 peco を入れてみました。Docker熱がやや冷めてきたので(あまりにもわからないので)今はVagrantの復習とpecoをいじってみている感じでもあります。この辺も日常に関わるツールという点で自分にとっては本文の内容と少し共通しています。