MacVimで簡単にウィンドウを切り替える

なぜ今まで気づかなかったのか……? たまたまキーを打ち間違えたら実現した。

f:id:note103:20170225164346g:plain

コマンドを押しつつ「 [ 」か「 ] 」を押すとどんどんウィンドウが切り替わる。
これ、今まで一番欲しかったやつや!!

Excelで複数のファイルを開いているとき、コントロール+TABを押すとどんどんウィンドウが切り替わるので、それのMacVim版が欲しい〜……でもそういう機能はなさそう〜って、ずっと思っていた。

で、今あらためてメニューを見直したら……

f:id:note103:20170225165029p:plain:w350

ちゃんと書いてありましたね……こういうの、結構チェックしている自覚だったけど全然見てなかった。

最近よく使っている自作ツール(2) delete.sh

前回に続き、掲題の件。
前回の内容は、以下。

note103.hateblo.jp

今回紹介するのは、以下。

github.com

と言っても、シェルスクリプト1本ですが。

このツールには前段があって、以前にこのブログでも紹介した「trash」というソフトウェアがあるのだけど、

note103.hateblo.jp

github.com

今回のツールはそれを自分なりにアレンジしたもの。

DEMO trash

先に、その元ネタになったtrashの方を簡単に紹介すると、使い方としてはこんな感じ。

f:id:note103:20170218145111g:plain

trashというコマンドの引数にファイル名を入れると、そのファイルを任意のフォルダへ移動してくれる。
ディレクトリを扱う場合はオプション「-r」を付ける)

その移動先が「仮のゴミ箱」みたいな役割を果たすので、いきなりrm -rfとかするより安全でいいよね、しかもコマンドラインからの簡単な操作で不要なデータを捨てられるのでいい感じだよね、みたいな話。

ただこれの場合、ちょっと面倒なのは、いちいち対象のファイル名を自分の手で打ち込まなければいけないところ。

上のデモのようなシンプルなファイル名なら指定しやすいけど、たとえばこんなファイル名がうごめくカレントディレクトリだったりすると、

2016-04-22-project1.txt
2016-05-14-project1.pdf
2016-05-24-project2.txt
2016-05-25-project3.md
2017-05-26-project4.txt
2017-06-26-project5.md

何回タブで補完しても他のファイル名と共通する文字列でいちいち詰まってしまって、目当てのファイルを指定しきるまでになかなか厳しい思いをすることになる。

そこで、こういうファイル群からプルダウン的に(ファイル名を打ち込まなくても)対象を選択できるようにしたいなあ、と思って、例のごとくpecoとchoをこれに結びつけたのが今回のスクリプト

DEMO delete.sh

f:id:note103:20170218145211g:plain

「d」を叩くとカレントディレクトリ内のファイルやディレクトリがバラララッと出てくるので、あとは画面を見ながら対象を選択。すると、それが任意のゴミ箱へ飛んでいく。

(「d.」を叩くと不可視ファイルも候補に含まれる。いずれも後述のエイリアスで設定する)

移動先のゴミ箱は初期設定だと「$HOME/.Trash」(Macのゴミ箱)になっているけど、.bash_profileからTMPTRASH変数に設定すれば自由に置き換えられる。

# ホームディレクトリ直下の tmp_trash/ をゴミ箱にする場合
export TMPTRASH=$HOME/tmp_trash

なお、前述のとおりchoとpecoを使っているので、それらも要インストール

前回紹介したchoco同様、オプションで-aを指定すると不可視ファイルも扱えるようになり、-pを指定すると選択ツールがchoからpecoになる。

よって、それらを組み合わせたエイリアスを設定するならこんな感じ。

alias d="sh /path/to/delete.sh"
alias d.="sh /path/to/delete.sh -a"
alias dj="sh /path/to/delete.sh -p"
alias dj.="sh /path/to/delete.sh -ap"

ちなみに、このエイリアス例にある「d」はdeleteのdだけど、「j」にはとくにそういう意味はない。

jは単に打ちやすいから使っているのと、僕の場合は「pecoを使う時のエイリアスはjにする」という暗黙のルールみたいのがあるのでそうしている。

なんにせよ、これらのツール&設定により、「このファイルちょっと作業の邪魔だな〜。ゴミ箱に移動しとこ」と思ったらポンと「d」を叩くだけでサクサク選択&ポイできる。

一方、このツールだと1回のアクションで捨てられるデータが1個だけなので、複数の対象を選択してポイできるようにしたいなあ、と思って作ったツールもあって、次回はそれを紹介したい。

最近よく使っている自作ツール(1) choco

プログラミングの学習にともない作った自分用のコマンドラインツールというものがあって、折りに触れこのブログでも記録&紹介しているのだけど、それでも以前に紹介した後に手元でどんどんアップデートしつつも外には出せていないものや、新たに作ったけど自分しか知らないツールというのもあって、少しずつでもそういうのをあらためて紹介していきたいと思ったのでそうする。

リストアップしてみたら結構な数になったので、何回かに分けるかもしれない。(いま書きながらどうするか考えている。書き終える頃にはどうなるか決まっているはず)

choco

まずはこれまでも何度か紹介している以下の最新版。

github.com

mattnさんによるchoと、lestrratさんによるpecoを使って、ディレクトリをスイスイ移動したり、移動した先で選択したファイルをオープンしたりする。

choで移動しているところ

f:id:note103:20170217202617g:plain

pecoで移動して最後に選択したファイルを開いているところ

f:id:note103:20170217202639g:plain

オープンするやつはmacOSのopenコマンドを使用しているので、他の環境でどうなるかはわからない。

たぶんコンピュータを開いて作業している日のうち、これを使わない日はないと思う。
我ながらすごく便利だし、俺グッジョブという感じ。

(いやもちろん、mattnさんやlestrratさんのおかげなわけですが)

名前

以前はこのツール、 "dirmove" という名前にしていたけど、それだとファイルやディレクトリ自体を移動させる意味が含まれてしまいそうなのと、移動先のファイルを開く、という目的も大きくなってきたので名前を変えたいと思い、choとpecoを使っているので合わせて "choco" にした。

これ自体は作業のメインに使うものではなく、単にちょこちょこ動きたいだけ、というグルー(のり)的な道具なので、意味を限定しすぎず、なおかつちょっと可愛い感じで良いネーミングではないかと自分では思っている。

懸案

メインのコードはPerlで書いているが、コマンドラインから居場所をどんどん移動して、なおかつ移動先に着地しなければならない都合上、bashrcにも少なからず記述が必要になる。

詳しくはREADME.mdを参照してほしいが、現時点ではこんな感じ。

# .bashrc

function dirmove {
    local result="$1"
    local basename=""
    local dirname=""

    if [ -e "$result" ]; then
        basename=${result##*/}
        if [ -f "$result" ]; then
            dirname="${result%%$basename}"
        elif [ -d "$result" ]; then
            dirname="$result"
        fi
    fi
    cd "$dirname"
}

function choco {
    local command="${@:$#}"
    local result=$(perl ~/path/to/choco/choco.pl "$@")

    if  [ $# = 0 ] ; then
        command=echo
    elif [[ "$command" =~ - ]] ; then
        if [[ "$command" =~ p ]] || [[ "$command" =~ a ]]; then
            command=echo
        fi
    fi

    if  [ -e "$result" ]; then
        dirmove "$result"
    fi
    $command $result
}

alias s=choco
alias s.="choco -a"  # 不可視ファイルを対象に含める
alias j="choco -p open"  # pecoを使う
alias j.="choco -ap open"  # pecoを使って不可視ファイルも対象に含める

zshだとどうなるか、とかはわからない。

上では関数を二つ書いていて、chocoというメインの関数の他にdirmoveという関数を分けて作っているのだけど、これは後日紹介予定の別ツールでもそのdirmove関数を使うから。
逆に言うと、chocoしか使わないならこれらを一つの関数に合わせてしまってもよい。

いずれにせよ、けっこう行数があるので、シェルスクリプトのファイルに切り出した方が良いのではないかと思って何度か試したのだけど、前述のとおりディレクトリを移動するためにはbashrcへの記述が必須のようで*1、仕方なくbashrcにいろいろ書くことになってしまっている。

最後にエイリアスをいくつか設定しているが、ようはデフォルトだとchoを使うようになっていて、オプションとして -p を指定するとpecoを使うようになり、また -a を指定すると不可視ファイルが対象に含まれ、さらに引数の最後にopenコマンドを入れると最終的に選択したファイルがオープンされる、という感じ。

次回予告

似たようなツールを少なくとももう一つ紹介するつもりだったが、結構長くなったのでここまで。

ブログ記事1本あたりの負担を軽減してコンスタントにパブリッシュできるようにしたいところだけど、どうなるか……。

*1:たとえば「start/path/to/end」というディレクトリ構造で、「startから移動してendのディレクトリに出たい」というときに、それらの関数をbashrcではなくシェルスクリプトなどに書くと、操作中はあちこちに移動できるのだけど、操作を終えるとstartに戻ってしまう。

21世紀の文字起こし(2)

以前に書いた記事からだいぶ間が空いてしまったけど、
note103.hateblo.jp

今回はその続編というか、スピンオフ的な経過報告。

ちなみに、一つ前の記事でも本件の環境設定に関することを書いているので、よろしければどうぞ。
note103.hateblo.jp

今回の課題

前回の記事の主眼というのは、

  1. 録音した音声ファイルを聴きながら、Googleドキュメントの音声入力にシャドウイング*1で言葉を吹き込んでいくと、普通に文字起こしをするよりずっとラクにテキスト化できるじゃん!
  2. ……とか思ってたら、さらにSoundflowerというのを使えば自分でしゃべらなくても音声ファイルからダイレクトで文字起こしできるじゃん!!

みたいな話だったと思うのだけど*2、その後にいろいろな音声データでトライしてみたところ、綺麗に拾える場合と、誤認識が多くてカオスな状態になる場合とでバラバラというか、綺麗に拾える条件・法則がちょっとわかりづらかったので、今回は以下の観点から、その辺を整理してみたい。

  1. 再録音の有効性
    1. 再録音(元音声を聴きながらシャドウイングで新たな録音すること)は必要か?
    2. もし元の録音データのままでも使えるとすれば、どの程度の録音状態なら許容範囲か?
    3. 悪音質のデータを再録音したら、どの程度仕上がりが改善されるのか?
    4. 再録音した音声ファイルから音声入力をするのと、直接マイクに向かってしゃべりながら音声入力をするのとでは、どちらの方が精度が高いか?
  2. 音声入力時の再生速度の最適化
    1. 音声ファイルをGoogleドキュメントで音声入力させる際、再生速度は仕上がりテキストに影響を与えるか? もし与えるなら、最も綺麗にテキスト化されるスピードは?
    2. Googleドキュメントは最大で何分程度読み込み続けるのか?

1. 再録音の有効性

1-1. 再録音(元音声を聴きながらシャドウイングで新たな録音すること)は必要か?

結論から言うと、そこそこ綺麗に録音されているデータなら、再録音せずともある程度は正確に拾えるし、環境が整っているところで録音された音声ならば、なお良好な結果を得られると思う。

また、前回の記事でも示したように、英語の音声であれば日本語以上に綺麗にテキスト化されやすいようなので、たとえば英語のPodcastをテキスト化したい、といった場合にも再録音は不要かもしれない。

逆に、講演や会議、あるいは周りの音が一緒に入ってしまう場所でのインタビューなど、録音以外のことがメインになっている環境で録った音の場合、そのまま使うことはあまりお勧めできない。

実際には、そういったデータからでもテキスト化は成されるが、本来の内容との乖離が激しくなる可能性が高く、最初のテキスト化のコストを軽減できたとしても、そこから修正するコストが通常以上に高くなってしまい、かえって非効率になりかねない。

よって、そういった悪コンディションのデータを使う場合には、再録音、または後に示すように、直接しゃべり直しながら音声入力してしまった方が、トータルのコストを下げられるとは思う。

1-2. もし元の録音データのままでも使えるとすれば、どの程度の録音状態なら許容範囲か?

2種類のサンプルを用意してみた。

一つは、昨年のちょうど今頃にプログラミングの勉強会で発表をしたときの録音*3から、1分間だけ切り取ったもの。
2016-01-15_kichijojipm_sample by note103 | Free Listening on SoundCloud

もう一つは、自分のメインブログで時々公開している日記調のモノローグというか、Podcast風に淡々としゃべっている音声から、同じく1分間切り取ったもの。
2016-12-29_sample by note103 | Free Listening on SoundCloud

前者は広めの会議室のようなところで、自分の発表時にスライドを操作するPCの脇にICレコーダーを置いて録音している。
聴講席から他人の発表を録音するよりはクリアだが、それでもあまり良い音質とは言えない。

後者はAudacityというフリーのソフトウェアを使用して、ヘッドセットマイクから直接録音している。

http://www.audacityteam.org/

よって、文字起こしを行うための録音としては良質な部類に入ると思う。

そして今回は、それぞれの音声を用いて音声入力をさせているところを、リアルタイムで動画に撮ってみた。
元の音声と仕上がりのテキストだけを提示するより、直感的に違いがわかるかもしれないと思ったので。

ちなみに、この動画撮影に際しては、音声ファイルの再生にExpressScribe*4、その音声を機械に聴かせるためにSoundflower、音声入力にはGoogleドキュメント(ブラウザはGoogle Chrome)、動画の録画にはQuickTime Playerを使用している。

以下では、まず動画だけ2パターン並べて示し、その後に仕上がりテキストを掲示する。
動画内で流れている音声は、そのときにGoogleドキュメントが聴いているのと同じものである。

動画比較
  • 勉強会発表(会議室・ICレコーダーで)
    • 20秒を過ぎてからは変化しなくなるのでそっ閉じ推奨。

youtu.be

  • モノローグ(ヘッドセットマイクで)
    • 上より少し音量が大きいので注意。

youtu.be

テキスト比較
  • 勉強会発表(会議室・ICレコーダーで)

ちょっと待って勇気出してんですけどそれはただ死んだけど
(27文字)

  • モノローグ(ヘッドセットマイクで)

後ね今回でスト掲示板に二つにページしかないんですがさっき言った400局から31局を経て最後の22曲になったって話があるんですけど31よりもちょっと多い70曲ぐらいですかねちょっと今正確に合わせていましたけど迷わ準決勝戦ぐらいの決勝戦が31から22に搾られる家庭だとした場合70キロから30局になる31分解中途半端ですけどね言いながら思いましたけどまたまた勝ったんですけどその70から31になるまでは準決勝みたいな感じが自分では下手ですねそのね70ぐらいまでをあの掲載してますので今回は
(242文字)

ということで、比べるまでもないほど前者はまったく拾えていない。
「メッセージはここで途切れている」みたいになっている。

後者の方はそれに比べるとだいぶ良い。というか、かなり違う。
それでふと気になったので、音声の波形も見てみた。

波形比較

上述のAudacityで、双方前半30秒分を切り出してみる。

なお、勉強会発表の方はICレコーダーのステレオ録音、モノローグはヘッドセットの1マイクなので、見比べやすいように前者はLだけを切り取った。

もしかすると音質以前の問題として、「ステレオはテキスト化されづらい。モノラルだとテキスト化されやすい」などの違いがあるのかな? とも思ったので、別途でICレコーダーのステレオ録音でモノローグを録ってみたが(マイクの近くで発声する)、これは綺麗にテキスト化されたので、ステレオとモノラルの違いはこの際とくに考慮しなくて良いと思う。

ではあらためて、波形の比較。

  • 勉強会発表(会議室・ICレコーダーで)

f:id:note103:20170104105409p:plain

  • モノローグ(ヘッドセットマイクで)

f:id:note103:20170104105425p:plain

別の話をしているので、山の場所が異なるのは当然のこととしても、それ以上に何より起伏の差がかなり違う。
だからどう、ということまでは言えないのだけど、まあ、「起伏の差が激しいとテキスト化されづらく、おとなしいとされやすい」ということなのかな、ぐらいの印象は持った。

で、このような結果を見ると、今度は以下のようなことが気になってくる。

1-3. 悪音質のデータを再録音したら、どの程度仕上がりが改善されるのか?

ということで、次はそれについて検証したい。

まずは先ほど惨憺たる結果をはじき出した、勉強会での発表内容を再録音する。

方法としては、ヘッドセットのヘッドホンからスロー再生で発表を聴きながら、同じヘッドセットのマイクからその内容を吹き込み直す。

ツールとしては、上記同様にヘッドホンへの出力にはExpressScribeを使用し、マイクからの録音にはAudacityを使う。

これが上でも何度か言っている「シャドウイング」というもので、とはいえ今回は元音声でぼくがかなり早口でしゃべってしまっているので、スロー再生を前提にセッティングしているが、シャドウイング自体は「音を聴きながら同じ言葉を発声する」ことができればよいので、このような環境がなければ「iPhoneからイヤホンで音を聴きながら口元で別のレコーダーに録音する」とかでも実現自体は可能である。

で、そのように再録音したものをGoogleドキュメントに読み込ませると、このようになる。

  • 勉強会発表音声(再録音版)

youtu.be

  • 仕上がりテキスト(再録音版)

でもう1個はまあよくあるこれもちょっとミスマッチがちかなっていう気がしているんですけどまあとりあえず4エラーお嫁様と出てるじゃんみたいなそれは正しいんだけどで後はまぁ確かにね英語はちょっとなじまないだろうけどとか言うんだけど英語が問題じゃないたぶんそれは多分エラーを読む人はそもそも何を読んでいるのかって言うと自分の頭で仮設がある程度できていてここでこけるって言うことはこれかこれかこれかそれかそれ以外かっていうのがあるわけですよねですそれと出てきたエラーをその前提と比べていると思うんですよだけど初心者っていうのはそれがもとの仮説がないから出てきたやつをもう最初から読んでいくしかないとだからたぶん日本語で出ても初心者にはわからないと思う日本語で言われても引数がどうだとかサブルーチンが不正な呼び出しをされていますとかしかもそれはちょっと違ったりとかするんで
(380文字)

ということで、元音声では30文字にも満たなかったのが嘘のように、大量かつ高い精度でテキスト化されている。*5

これだけ違いが出ると、ここでもまた波形を見たくなってくる。
で、取ってみた。

波形比較

まずは先ほどの、全然拾えなかったやつ。

  • 勉強会発表(会議室・ICレコーダーで)

f:id:note103:20170104105409p:plain

次に、再録音したらだいぶ拾えるようになったやつ。

  • 勉強会発表(再録音版)

f:id:note103:20170104105955p:plain

だいぶスリムになっている。
ついでに、先ほど綺麗に拾えたモノローグ音声も並べてみよう。

  • モノローグ(ヘッドセットマイクで)

f:id:note103:20170104105425p:plain

はい。まあ、とくにこれを分析できる知識はないのだけど、とはいえやはり、波形が激しいやつだと拾いづらいのかな、という感じはする。

ところで、先ほどの元音声と、再録音版とを聴き比べると、そのスピードが違うことが気になってくる。

どういうことかと言うと、再録音版がゆっくりしているのは、上記のようにシャドウイングする際の都合によるわけだけど、もしかすると元音声の方も再生速度を落としたらけっこう拾えるのでは? みたいな疑問が湧いたということ。

なので、念のために元音声の速度を落とした場合も試してみた。

  • 勉強会発表音声(元音声・再生速度70%)

youtu.be

まったく反応ナシ……(なので途中で止めた)。

1-4. 再録音した音声ファイルから音声入力をするのと、直接マイクに向かってしゃべりながら音声入力をするのとでは、どちらの方が精度が高いか?

上記の検証により、音質の悪い音声ファイルでも、シャドウイングで再録音すれば音声入力によるテキスト化が可能になることがわかった。

しかしここで新たに気になるのが、一度別ファイルに再録音するのではなく、直接シャドウイングしながら音声入力ツールに吹き込んだらどうなるのか? ということだ。

というのも、別ファイルに再録音した場合、その後にGoogleドキュメントに読み込ませるときにもほぼ同じ時間をかけて読み込ませなければならないので、少なくとも元データの2回分(スロー再生で再録音するならばそれ以上)の時間がかかる。

翻って、再録音の工程を省いて直接音声入力してしまえば、その時間が半分で済む。

ということで、同じ勉強会の元音声を聴きながら、直接音声入力してみたのが以下。

  • 勉強会発表音声(直接音声入力版)*6

youtu.be

  • 仕上がりテキスト(直接音声入力版)

もう1個はまあよくあるこれもちょっとミスマッチがちかなっていう気がしているんですけどまあとりあえずエラー読めよと出てるじゃんみたいなそれは正しいんだけどで後はまぁ確かにね英語はちょっとなじまないだろうけどとか言うんだけど英語は問題じゃないたぶんそれは多分エラーを読む人がじゃあそもそも何を読んでいるのかって言うと自分の頭でも仮説がある程度できていてここでこけるって言うことはこれかこれかこれかそれかそれ以外かっていうのがあるわけですよねでそれと出てきたエラーをその前提と比べていると思うんですよねだけど初心者っていうのはそれがもとの仮説がないから出てきたやつをもう最初から読んでいくしかないとだからたぶん日本語で出ても初心者は分からない日本語で言われても引数がどうだとかサブルーチンが不正な呼び出しをされてますとかでしかもそれがちょっと違ったりとかまーするんで
(380文字)

ふむ。若干ながら、上の再録音版より精度が上がっているように見える。
拾った語数もほぼ同じ。

つまり、少なくともこの直接入力の方法が再録音版より劣るということはなさそうなので、もし最初からこの方法を採れるなら、その方が効率は良いかもしれない。

また、先に再録音だけを行う場合というのは、地味に「この発声でちゃんとテキスト化されるのか?」という不安が生じたり、かつ実際にその再録音したものを読み込ませてみたら上手くテキスト化されなかった、なんていうことも何度かあったりしたので、そのように結果が出るまで不安を抱えてしまうぐらいなら、最初から直接入力でフィードバックを確認しながらやったほうが精神的にラク、というメリットもあるかもしれない。

一方、これはあくまで個人的な実感だけど、この直接入力というのはなかなか疲れる。
上記のように、基本的には目の前で起こされていく状況を確認しながら進めることになるので、そうなると「音を聴きながら発声する」という作業に加え、「目視で仕上がりを確認する」という作業をマルチタスク的に抱えることになり、そのぶん肉体的な負担が増すのかもしれない。

また、直接音声入力をする際には、Googleドキュメントで文書を作成しながら録音を行える環境を整えなければならないので(マイクのセッティングなどはもちろん、他人の迷惑にならない場所へ移動するなど)、そうした「ちょうどよい環境」を作るコストが低くない。

その点、先に再録音を行ってから、別の機会に音声入力をするのであれば、トータルの作業時間は多くなるとしても、それぞれの特化的な作業に集中できるので、並行して一気にすべてを進めることに比べて負荷が低く、継続的な作業を見込める面もあると思う。

よって、この「再録音」と「直接入力」の選択に関しては、上記のようなメリット/デメリットを踏まえつつ、作業者それぞれの目的や、環境に応じて適した方法を選ぶのが良いように思える。

2. 音声入力時の再生速度の最適化

2-1. 音声ファイルをGoogleドキュメントで音声入力させる際、再生速度は仕上がりテキストに影響を与えるか? もし与えるなら、最も綺麗にテキスト化されるスピードは?

これについては、上記の再録音版データを「150%(速い)」「標準速度」「50%(遅い)」の3種類で読み込ませてみた。
(「標準速度」は前出のもの)

先に動画を3点並べ、その後に仕上がりテキストを並べて掲示する。

動画比較
  • 再生速度150%

youtu.be

  • 再生速度100%(再掲)

youtu.be

  • 再生速度50%

youtu.be

テキスト比較
  • 再生速度150%

もう1個はまあよくあるこれもちょっとミスマッチがちかなっていう気がしているんですけどまあとりあえず予定はお嫁様と寝てるじゃんみたいなそれは正しいんだけどで後はまぁ確かにね英語はちょっとなじまないだろうけどとか言うんだけど英語が問題じゃないもんたぶんそれは多分エラーを読む人がそもそも何を読んでいるのかって言うと自分の頭で稼ぐがある程度できていてここでこけるって言うことがこれかこれかこれかこれかそれ以外かっていうのがあるわけですよねでそれと出てきたエラーをその前提と比べていると思うんですよだけど初心者っていうのはそれがもとの仮説がないから出てきたやつをもう退職から読んでいくしかないとだからたぶん日本語でても初心者にはわからないと思う日本語で言われても引数がどうだとかサブルーチン学生の呼び出しをされていますがしかもそれはちょっと違ったりとかするんで
(376文字)

  • 再生速度100%(再掲)

でもう1個はまあよくあるこれもちょっとミスマッチがちかなっていう気がしているんですけどまあとりあえず4エラーお嫁様と出てるじゃんみたいなそれは正しいんだけどで後はまぁ確かにね英語はちょっとなじまないだろうけどとか言うんだけど英語が問題じゃないたぶんそれは多分エラーを読む人はそもそも何を読んでいるのかって言うと自分の頭で仮設がある程度できていてここでこけるって言うことはこれかこれかこれかそれかそれ以外かっていうのがあるわけですよねですそれと出てきたエラーをその前提と比べていると思うんですよだけど初心者っていうのはそれがもとの仮説がないから出てきたやつをもう最初から読んでいくしかないとだからたぶん日本語で出ても初心者にはわからないと思う日本語で言われても引数がどうだとかサブルーチンが不正な呼び出しをされていますとかしかもそれはちょっと違ったりとかするんで
(380文字)

  • 再生速度50%

でもう1個はまあよくあるこれもちょっとミスマッチがちかなっていう気がしているんですけどまあとりあえずよヘラを読めよと出てるじゃんみたいなそれは正しいんだけどで後はまぁ確かにね英語はちょっと馴染まないだろうけどとか言うんだけど英語が問題じゃないたぶんそれは多分エラーを読む人はそもそも何を読んでいるのかって言うと自分の頭でか説がある程度できていてここでこけるっていうことはこれかこれかこれかそれかそれ以外かっていうのがあるわけですよねですそれと出てきたエラーをその前提と比べていると思うんですよだけど初心者っていうのはそれがもとの仮説がないから出てきたやつをもう最初から読んでいくしかないとだからたぶん日本語で出ても送信者には分からないと思う日本語で言われても引数がどうだとかサブルーチンが不正な呼び出しをされていますとかしかもそれはちょっと違ったりとかするんで
(380文字)

ということで、目視でこれらの違いを判別するのはけっこう大変なのだけど、ざっと読み取れるのは以下のようなこと。

  • 拾える文字数はほぼ変わらない。
  • 再生速度が速くても遅くても、それぞれ100%の場合に比べて誤認識が増えている。
    • 150%: 「仮説」→「稼ぐ」、「最初」→「退職」
    • 50%: 「エラー」→「ヘラ」、「初心者」→「送信者」

じつは事前の仮説としては、「スピードが遅いほど綺麗に起こされるのでは」と思っていたのだけど、実際には遅くすれば綺麗になるということはなく、むしろ読み込ませるのに余計時間がかかる分、デメリットの方が多いと思えた。

逆に、再生速度を速くしてもこのぐらいの誤認識で済むのであれば、それによって読み込む時間を短縮できるメリットを取った方が良いと考えることもできるが、とはいえこの段階でミスが多くなると、その後に行うテキスト編集(修正)の段階で手間や集中力といった負荷が増えるので、やはり誤認識は少なければ少ないほどよいとも思える。

よって、その辺りも含めて総合的に考えれば、標準速度(再生速度100%)にするのが無難かなと思うが、よくよく考えてみれば、再生速度が速すぎても遅すぎても、本来の人間がしゃべる言葉から離れていくことになるわけで、ようは「最も一般的な人間のしゃべり方に近い速度」を設定するのが良いということかもしれない。

また、そもそも人がしゃべる速度というのも人によって様々なわけで、ゆっくりしゃべっている音声ならやや速めに、逆に早口な人なら速度を落とすように、といった調整を行った方が綺麗に検知することもあるかもしれない。

2-2. Googleドキュメントは最大で何分程度読み込み続けるのか?

ところで、上記の動画群を見て気づいた人もいるかもしれないのだけど、前回の記事でぼくはこのようなことを書いていて、

4. 音声ファイルが終わるまで再読み込みなどのケア
前述のように、入力は音声ファイルが止まるまで続くわけではなく、途中で止まる。いわばフリーズしたような状態になる。
調子が良ければ1分以上入力され続けることもあるが、平均的には40秒程度かもしれない。
(略)
よって2秒程度入力が止まったら、もうフリーズしたとみなして再起動する。
具体的には、マイクボタンを押して一度入力機能をストップし、もう一度押して再開させる。すると、また入力が始まる。

しかし上の動画においては、そのような再起動は不要だった。

もしかすると、Googleの音声入力機能が向上したということだろうか?
よくわからないが、とりあえず現時点ではどの程度、再起動せずに動き続けるのか気になったので、これも試してみた。

といっても、そのためにわざわざ長尺の再録音をするのも面倒なので、上で元音声のままでもそこそこの精度でテキスト化された、モノローグ音声のフル尺版(約11分半)を読み込ませてみた。

結果はこのような感じ。*7

youtu.be

なんと音声ファイルが終わるまでの11分半、すべて再起動なしで読み込んでしまった。

じつはブラウザの拡張機能でiMacrosというツールを使うと、一定時間ごとに任意の処理をさせることができて、それを設定すれば数分ごとに音声の読み込みを再起動させることができるので、いずれその方法も紹介しようと思っていたのだけど、これならもはや不要かもしれない。

経験上、この音声入力機能は音を読み込めない時間がしばらく続くとストップしてしまうようなので、切れ目なく読み込める程度に音質が良いファイルなら、再起動の必要性が低くなったということなのかもしれないが。

まとめ

例によって長くなってしまったけど、最初に掲げた課題については触れ終えたので、ひとまずここまでのまとめ。

  1. 再録音の有効性
    1. Q1: 再録音(元音声を聴きながらシャドウイングで新たな録音すること)は必要か?
      • A1: 録音状態が良ければ不要な場合もある。ただし誤認識が多ければそのぶん後の作業に負債を抱え込むことになるので、後のことまで考えて判断すべし。録音状態が悪ければ再録音一択。
    2. Q2: もし元の録音データのままでも使えるとすれば、どの程度の録音状態なら許容範囲か?
      • A2: 講演会場や会議室など広い空間におけるICレコーダー等での録音は、そのままでは使えない可能性が高い。一方、マイクと発声源が近い録音ならば良好な結果を得られる可能性が高い。
    3. Q3: 悪音質のデータを再録音したら、どの程度仕上がりが改善されるのか?
      • A3: まったくテキスト化されなかったものが、かなりテキスト化されるようになる。
    4. Q4: 再録音した音声ファイルから音声入力をするのと、直接マイクに向かってしゃべりながら音声入力をするのとでは、どちらの方が精度が高いか?
      • A4: 直接しゃべりながら音声入力を行った方が、精度が高くなると思われる。この場合、再録音の工程をスキップできるので、作業時間の短縮というメリットもある。ただし、工程を分ければ環境を準備しやすくなったり、作業負荷を軽減できたりするメリットもあるので、状況に応じて判断すべし。
  2. 音声入力時の再生速度の最適化
    1. Q5: 音声ファイルをGoogleドキュメントで音声入力させる際、再生速度は仕上がりテキストに影響を与えるか? もし与えるなら、最も綺麗にテキスト化されるスピードは?
      • A5: 1分のサンプルデータで確認したかぎり、再生速度による大きな違いはないが、その中では標準速度の仕上がりが一番良いように見える。ただし、元音声の発話速度によって、チューニングの余地があるかもしれない。要検証。
    2. Q6: Googleドキュメントは最大で何分程度読み込み続けるのか?
      • A6: 以前に試した際は40秒〜1分程度ごとの再起動が必要だと感じたが、今回試したところでは10分以上にわたるノンストップの入力が実現した。ただし、音質が良好であるという条件が必要かもしれず、その他にも長時間入力を実現させるための条件があるかもしれない。要検証。

免責事項

今回行った各種の実験は、限られたサンプルと機会を通じて、それぞれ1〜2度ずつ試してみたものに過ぎないので、普遍的な正解ではまったくない。

再現性の高い結論を出すためには、より厳密に条件を揃えた上で、同じ実験をくり返し行うべきだが、さすがにそこまではできないし、そもそもこのツール自体どんどんアップデートされていくだろうし、あるいは突然使えなくなってしまう可能性だってある。

あくまで一人のユーザーが、個人的・自主的にいろいろ遊んでみた結果として見てもらえたらありがたい。

次回予告

前回の最後で、textlintの導入について予告したのだけど、それ以前の音声入力関連の情報をまとめるだけで力尽きてしまった。
textlintの使用を含む、「テキスト整形」に関わる作業については、次回以降にあらためてまとめてみたい。
(いつになるかは無保証だが……)

*1:耳から入った音声を追いかけるように発声すること。語学の学習などでよく行われるらしい。

*2:もう半年前の記事で自分でも忘れかけていたので、この部分を書きながら少しずつ思い出した。

*3:元資料などはここで読める。→ 吉祥寺.pm6に参加しました(トーク音声公開&スライド作成方法) - the code to rock

*4:音声の再生はiTunesなど他の汎用音楽ソフトでも可能だが、ここでは細かいショートカットキーの設定が便利なのでExpressScribeを使った。

*5:不思議なことに、というか、皮肉なことに、というか、この再録音版は、人間の耳で聞くと、元の音声よりぎこちない調子で、けっして聞き心地が良いとは言えないのだけど、機械にとってはこちらの方が聞きやすいようである。これが人間にとって聞きづらく感じられる理由は、この音声がシャドウイングという、「発声し直すこと」を目的に録音されているからであって、言い換えれば、「人間に話の内容を理解してもらうこと」を目的にはしていないからだと考えられる。つまり、想定リスナーは「人間ではない何か」である。そのような音声が人間からは親しみを持たれづらく、しかし機械からは理解(というか解釈)されやすい、という状況が面白い。

*6:メインの発話の後ろで薄く聞こえている声があるが、これはヘッドホンから漏れている元音声。シャドウイングは耳から入る音に集中して、自分の発声はあまり聞こえないようにした方がやりやすい、という話を時々聞くけど、まさにそんな感じがしたのでヘッドホンの音量を大きめにしていた。

*7:実験の目的上、仕上がりテキストは不要なので動画のみ掲示するが、通読できる程度まで整形したテキストはここで読める。→ 音声入力を用いた文字起こしでブログ(3) 〜schola16巻のつくり方〜 - 103

AudacityとSoundflowerをセットするまで

昨年11月に長期プロジェクトがひと段落して、軽いマシンがほしかったので(重量的な意味で)、MacBookを購入した。

以前のマシンから環境をそのまま引き継ぐか、少し迷ったが、把握していない不要データごと引っ越すのもいやだな、と思ってイチからいろいろ入れていくことにした。

心配していたのはMicrosoft Office系、それからAdobe系の移行だったが、いずれも気が抜けるほどすんなりライセンスが通った。

それでほぼ環境は整ったと思っていたが、その長期プロジェクトの切り替えにともない、若干ながら&一時的ながら、自分の時間が増えたので、以前にやや中途半端なまま止まってしまった、音声入力を使った文字起こしのトライを再開しはじめたところ、
note103.hateblo.jp

音声ファイルをエディットするために使うAudacityと、Googleドキュメントの音声入力ツールに音を読み込ませるためのSoundflowerが入っていないことに気づいた。

で、これらは今までの経験上、何気に導入コストが高いというか、面倒という印象があったので(とくにSoundflower)、びくびくしながらコトを進めたが、存外これもすんなり完了し、しかしそれでも後から思い出すのはやはり面倒そうだなと思ったので、ここにメモしておくことにした。

contents:

Audacity

まずAudacityの導入から。
公式サイトは以下。

Audacity®

そのトップページからソフトをダウンロードして、

f:id:note103:20170101132854p:plain

それをダブルクリックしたら、あとは案内に従ってインストールすればOK。

え、それだけ? という感じだけど、そう、普通に使うだけならそれで充分。

なのだけど、面倒なのはエディット後のファイルをmp3に書き出すときで、wavやaiffならそのまま書き出せるけど(たしか)、mp3に書き出そうとすると、Lameというのが足りないよ、と言われる。

具体的には、以下のリンクを示されて、とりあえずちょっとこれ見とけ、みたいなアラートが出る。

http://manual.audacityteam.org/man/faq_installation_and_plug_ins.html#lame

なので、そのリンク先にあるMacの項目の、最初にあるリンクをクリックして、

f:id:note103:20170101132803p:plain

http://lame.buanzo.org/#lameosxdl

飛んだ先で一番それっぽい、「For Audacity 1.3.3 or later on Mac OS X 10.4 and greater (Intel or PPC),and Audacity 1.2.5 on OS X 10.4 and later (Intel)」というところからdmgファイルをダウンロード&インストール。

f:id:note103:20170101132835p:plain

これでmp3に書き出せるようになる。

しかし以前はもっと大変だった気がするんだけどなあ〜……だいぶラクになっているような。

なお、Audacityについては以下の記事でも少し触れている。

note103.hateblo.jp

Soundflower

次、Soundflower。

Soundflowerについても、以前に書いた以下の記事でちらちら紹介している。

とくに後者、というか冒頭でも示した文字起こしの記事は比較的最近なので、基本的にはそのくり返しになるのだけど、以下のGitHub上のリリースページから、

Releases · mattingalls/Soundflower · GitHub

現時点の最新版(2.02b)をダウンロード&インストールした。

Soundflowerの場合はとくにOSのバージョンや導入時期などによって、ソフトはもちろん、配布場所や開発者も違ったりする印象があるので、この機会にきちんとメモしておきたかった。

そういえば、つい最近どこかで見たブログ記事でも、「元のソフトは新しいOSでは動かないから」といって上記のfork版を紹介していたなあ、と思ったらはてなの開発者ブログだった。
developer.hatenastaff.com

なお、上の文字起こし記事でも触れているように、マシン内で音声ファイルを再生&録音させる際には、サウンド設定を入出力ともに「Soundflower(2h)」にする必要があるので、注意。

マシンの環境設定>サウンドからでも設定できるが、Optionを押しながらメニューバーのスピーカーマークを押せば簡単に選択できる。

さらに、それを再びマシンから普通に鳴らしたい場合には同様の方法で「出力」の方を「内蔵スピーカー」などに戻す必要があるので、再注意。

と思いつつ、今回このメモをまとめるために念のためあちこち検索してみたところ、以下のまとめがわかりやすく*1
rnkv.hatenadiary.jp

その中で紹介されていた「LadioCast」というツールがその辺をより便利にしてくれそうだった。

http://blog.kawauso.com/ladiocast

上に書いた設定でSoundflowerで録音すると、その間はマシン内で流している音を聴けないのだけど、これを使うと自分でもモニターを聴けるみたい。
今度録音するときから試してみたい。

また、そのLadioCastを使って録音する手順などについて、以下のQiitaの記事がスクリーンショット付きかつコンパクトな説明でわかりやすそうだった。(まだ精読していないけど)

qiita.com

そして作業へ

ということで、準備系のそれらについては以上。

本来の目的である文字起こしなどについては、また別の記事にまとめたい。

なお、当然のことながら上記の情報は本日(2017-01-01)時点のものにすぎないので、時間が経過すればするほどあくまで参考までに、という感じでお考えください。

*1:なんと昨日の更新だったみたい。シンクロニシティ……。

Vimで今見ているバッファを「現在日時+好きなファイル名」で保存する


結論

.vimrcに以下を入れて、

function! s:newfile(title)
  execute ":f /path/to/".strftime('%Y-%m-%d-%H-%M-%S').a:title.".txt"
endfunction
nnoremap <Leader>nf :<C-u>call <SID>newfile("_")<Left><Left>

マッピングに設定したコマンド(上の例ではLeaderキー*1を叩いてからnf)を打つと、コマンドラインに入力欄が出るので、そこに好きな語句を記入してエンターすると「現在日時_記入した語句」がファイル名になって保存される。

実演

f:id:note103:20161230104425g:plain

注)ここでは関数定義部分の「/path/to/」を「~/Dropbox/sample/」にしている。

経緯

半年ほど前に書いた以下の記事で、

note103.hateblo.jp

今見ているバッファを現在時刻のファイル名で保存する

というTIPを紹介したのだけど、そのときの方法は以下だった。

:w 版

function! s:wsave()
  execute ":w /path/to/".strftime('%Y-%m-%d-%H-%M-%S').".txt"
endfunction
nnoremap <silent> <Leader><Leader>w :<C-u>call <SID>wsave()<CR>

:f 版

function! s:fsave()
  execute ":f /path/to/".strftime('%Y-%m-%d-%H-%M-%S').".txt"
endfunction
nnoremap <silent> <Leader><Leader>f :<C-u>call <SID>fsave()<CR>

前者はコマンドラインモードにおける「:w」、つまり今見ているバッファはそのまま残しつつ、現在日時を刻印したファイル名で別名保存するもの。
後者は「:f」の形式、つまり今見ているバッファがそのファイル名になる、というもの。

これらの良いところは、ファイル名をわざわざ考えなくても、すぐに一意の(他と重複しない)ファイル名を付けて保存できること。
秒単位で刻印するので、カブることはほとんどない。

デメリットとしては、そのファイルを後から探そうというときに、日時だけのファイル名からでは内容を推測できないので、けっこう面倒なことになる。

よってこれらを使うのは、基本的に「後から見返すことはほとんどないと思うけど、念のため保存しておく」というときだけで、後で読み返す可能性が高いファイルに関しては、その内容を示すキーワードをファイル名に付加できるようにしたいと思っていた。

ただ、そうは思うものの僕の知識ではなかなか良い方法を思いつくことができなくて、しばらくは以下のようなマッピングでしのいでいた。

nnoremap <Leader><Leader>ww :w /path/to/.txt<Left><Left><Left><Left>
nnoremap <Leader><Leader>ff :f /path/to/.txt<Left><Left><Left><Left>
cnoremap <expr> ,df strftime('%Y-%m-%d-%H-%M')

この場合、Leaderを2回叩いてからffを叩くと、コマンドラインに「:f 保存したいディレクトリのフルパス/.txt」という文字列が出てきて、すでに「.txt」の一つ前の位置にカーソルが合っているので、そこに好きなファイル名を入れてすぐに保存できるようになっている。

前回のTIPS記事で示した「簡便に日時を出すマッピング」をコマンドラインモードでも使えるようにしているので(コードの3行目)、まず「,df」と打って日時を入れてから、何らかのキーワードを記入するという流れ。

実演

f:id:note103:20161229193602g:plain

これはこれで必要十分というか、まあ、これでもいいか……という感じになるのだけど、やはり理想は「手で記入するのはキーワードだけ」という状態であって、たとえ「,df」の3文字だけであっても、わざわざ現在日時を自分では打ちたくないというか、そこは人間が打たなくても最初から入っておいてほしい、という気持ちが強かった。

それであらためて粘って見つけたというか、考えたのが冒頭に示した現在の方法。
コード自体はガチャガチャしてちょっと恥ずかしいが、それでもこれなら現在日時は最初から入っていて、カーソルもすでに入力位置にあるので、ほんとに「キーワードだけ打ってエンターすれば確定」という感じになっている。

なお、「ファイル名とかわざわざ考えたくない。ただ一意のファイル名で即保存しておきたいだけ」という場合には、アンダーバーだけ消して(あるいはそれもそのままで)エンターすればこれでも希望は叶うが、それすら面倒という場合には(時々ある)、素直に前回紹介したマッピングを使っている。

ついでに言うと、この一連の方法では格納先のディレクトリがつねに一定なので、後から探すときにもけっこうラクというか便利。

余談

ちなみに以前は、このようなファイル保存&取り出しの用途では、@mattnさんオススメのmemolist.vimを使っていたのだけど、

mattn.kaoriya.net

今はこの手作り感満載な方法のほうが身の丈に合っているように思われ、これだけになっている。

さらにちなみに、memolistで実現できたはずの(使ってはいなかったが)grep機能というか、保存したファイル群からパターンを横断検索する機能としては、agというのを別途で使っていて、これも重宝している。

残る課題

ということで、とりあえず理想形に至ったかのように見える本件ですが、まだこれでも不満はあって、コマンドライン

:call <SNR>14_newfile("_")

なんて文字列が出てくるのはあまり美しくないというか、せめて

newfile("_")

で待機してくれるとか、あるいは対話型っぽく

Input a new filename >>

なんてふうに入力待ち状態になってほしい〜……とも思うので、その辺はもう少し模索を続けるかもしれない。

こういう小さな改善というか、便利さの追求というか、ストレス解消(発散ではなく解消)のための道行きというのは、本人がそれを意識的に望まなければなかなか進まないものなので、今後も自分の中の微弱な不満の声に敏感になって、拾い上げていきたいと思っている。

*1:デフォルトだとたしかバックスラッシュ。

プログラミング入門を支える技術

  • こちらはPerl入学式アドベントカレンダーの21日目の記事です。
  • 昨日は@karkador73さんの「Perl入学式に参加して、いろいろ刺激を受けた件」でした。
    • ぼくは普段 in東京のメンバーとしかつながりがないので、すごく新鮮な話でした。
    • @karkador73さんがPerl入学式に参加したきっかけは@sago35tkさんからの誘いということですが、その@sago35tkさんも比較的最近からの参加なので、そうやって新しいメンバーがどんどん新たなつながりを作っていく、というのはPerl入学式の稀有な特長だと思います。

  • さて、本日の記事では、ぼくが普段プログラミングに触れながら考えていることのうち、あまり他では聞かないというか、むしろ通常言われるセオリーみたいなものとは逆な気もするけど、人によっては役立つかもしれない視点というか、方針について、いくつか書いてみたいと思います。
  • 先に簡単に自己紹介をしておくと、ぼくは普段はフリーの編集者として過ごしていて、今はおもに坂本龍一さんの音楽全集「schola(スコラ)」の制作に携わっています。
    • じつはたまたま本日12/21(水)、1年ぶりとなるシリーズ最新刊が発売されました!!
    • いやー、偶然だなあ。(ハハ)
    • 公式ページのどこかにぼくの名前もあります。(→公式ページ

commmons: schola vol.16 Ryuichi Sakamoto Selections: Japanese Pop Music

commmons: schola vol.16 Ryuichi Sakamoto Selections: Japanese Pop Music

  • それ以外だと、去年の夏頃に山口県YCAMという文化施設のWebサイトのリニューアル・プロジェクトに参加したりしました。(→参考記事
  • そんな中、プログラミングは趣味として、2013年の春頃に始めました。そして同年夏からPerl入学式に生徒として通い始めて、翌年から生徒出身のサポーターとして活動に加わっています。
  • だから、というわけでもないですが、この記事で想定している「プログラミング入門者(初心者)」は、とくにITの仕事をしているわけでも、それを志しているわけでもない、「一般人だけど趣味で始めてみた」というような人です。
  • よって、IT企業の新人さんや、そうした進路を検討している情報系の学生さんなどはちょっとズレますが、部分的には参考にしてもらえるところもあるかもしれません。
  • また、上記のような初心者に「教える立場」の人にも、参考になる要素があるかもしれません。

Contents

1. 明確な目標はなくてもいい

  • 少なからぬ書籍やネットの記事において、「まずは学習を始める前に、プログラミングでどんなものを作りたいか、具体的にイメージしてみよう!」なんてことが言われます。
  • その心はと言うと、「目標が曖昧だと何をやればいいかわからなくて、無為に時間が過ぎるから」とか、「ゴールがはっきりしていれば必要な学習内容に集中できるから」ということのようですが、そこまで聞いても、ぼくにはこれは奇妙な方針だと思えます。
  • もしあなたの目の前に、初めて見る精巧な機械をポンと置かれて、「使い方は後で教えるから、まずはこれで何を作りたいか具体的にイメージしてみよう!」と言われたらどう思うでしょうか?
  • プログラミングの初心者とは、プログラミングに関する知識がない(または少ない)人ですから、まだそれを教わっていない段階で、「それを使って何ができるのか」を想像させるというのは矛盾があります。
  • しかし現実には、そうした要求をする「教える人」が少なくないように見えます。なんでだろう? と以前は不思議に思っていましたが、これはおそらく、「教える側にとって都合がいいから」ではないか、と今は思っています。
  • たしかに生徒さんの方から、「ぼくは掲示板を作りたい! Twitterアカウントでログインできて、画像も投稿できるようにしたい!」などと具体的なリクエストを言ってくれれば、「なるほど、じゃあそのためにはこの言語を覚えて、この知識を身につけて……」という具合に、何を教えたらいいのか、自然と決めやすくなるかもしれません。
  • 一方、「いや〜……とくに何を作りたいとかはないんだけど、とにかくプログラミングをやりたいというか……」などとぼんやり言われてしまうと、教える側としては、提示できる選択肢が無限に広がってしまい、「もう少し具体的に注文してよ!」という感じになってしまうのかもしれません。
  • しかし上記のとおり、初心者が知っている「プログラミングで実現できること」なんていうのは、「ない」か、あってもせいぜい数種類しかないはずで、しかもそのなけなしの選択肢ですら、本人が「本当にやりたいこと」かといえば、怪しいものだと思います。
  • ぼく自身のことを振り返ってみると、最初に「プログラミングをやりたい」と思ったときに頭にあったのは、「黒い画面になんか打ち込みたい」とか、「英数字でカッコよく構成されたあれ(ソースコード)を書きたい」みたいなものでしかなかった気がします。
  • それは「先に作りたいものをイメージしよう」と助言してくれる人が期待する答えからは程遠いものかもしれませんが、それでもぼくが一番求めていたのは、そんな曖昧で、とらえどころのない憧れのようなものだったと思います。
  • 「作りたいもの」なんてなくても、プログラミングの学習はできます。後述のとおり、すぐに(最短ルートで)求めるものに出会うことはできないかもしれませんが、続けていれば必ず、どんな曖昧な憧れであっても、近づいていくことができます。
    • 少なくとも、ぼく自身は入門から3年半が経った今、かつて思い描いていた上記のようなことは普通にできるようになりました。
    • 一応責任をもって、「作りたいものがなくてもプログラミングの学習をスタートする方法」を示しておくと、「入門書を読みながらサンプルコードを動かしていく」という方法があります。Rubyなら「たのしいRuby」、Perlなら「かんたんPerl」か結城浩さんの入門書、Pythonなら、未読ですが「独習Python入門」あたりが良さそうです*1
    • もし希望する言語がないのであれば、上記のようなプログラミング入門書の中で、一番表紙の雰囲気が好きなものにするといいと思います。
    • 動画サイトの「ドットインストール」も良い選択肢だと思います。無料ユーザーにもたくさんのコースが開かれているので、明確な目的がない入門者でも自分の好みに近いレッスンを選びやすいですし、動画1本につき3分なので、ちょっと試して合わなければすぐ次を試したり、スキマ時間に気軽に始めたりすることもできます。
  • 念のために付け加えておくと、初めから「プログラミング自体は目的ではなく、自分のやりたいことを実現するための手段である」と、明確に目標を意識化できている人は上記の限りではありません。
  • また、すでに初心者的な段階を終えて、「プログラミングでどんなことができるのか」ということをある程度想像できる人であれば、「先にゴールを定めてから学習に取り組む」という方法も有効かもしれないと思います。

2. エラーは無理に読まなくていい

  • プログラミングの入門初期には、「本やネットに書いてあるとおりに実行しているはずなのに、想定どおりの挙動をしない」ということが多々あります。
  • そのようなときに、入門者はコンソールに出てくるエラーをろくに読みもせず、自分で書いた(あるいはコピペした)コードをじっくりまったり読み返しては、何度も同じエラーを出し続ける、ということがよくあります。
  • そしてこのとき、教える側の人は、「エラーメッセージをちゃんと読んで!」と言います。これはまったく正しいアドバイスで、その点に文句はないのですが、そのアドバイスが果たして有効に働くのかと言えば、あまり有効ではないとも思います。
  • 初心者にとって、コンソールに出てくるエラーというのは、もはや文字ですらない帯状の模様です。
  • その中のどれが英語で、どれが数字か、という見分けさえすぐにはつきません。
  • もし初心者と熟練者が、同じエラーメッセージを同時に覗き込んでいたとしても、両者が見ているのは別物です。おそらく熟練者は、行番号や主要なキーワードを真っ先に見つけているはずですが、初心者はそのメッセージにおける「どの単語がどの単語より重要なのか」という優先順をつけることができません。
  • また、普段からプログラミングをしている人は、エラーメッセージが出てきた時点で、「またコイツか……」とばかりに「以前にそれを見たときのこと」を思い出したり、仮にそれが初めて見るエラーメッセージだったとしても、かつて経験したエラーをもとに原因の「仮説」を立てたりしているはずですが、初心者にはそうした過去の蓄積が少なく、経験していたとしてもすぐに忘れてしまっているので、結局毎回メッセージの行頭から、見慣れない文言を一つひとつ読み解いていかなくてはいけません。
  • またそれと似た話で、「初心者はエラーメッセージが英語だから読みたがらない」ともよく言われますが、ぼくは「英語」はあまり関係ないと思っています。
  • もし「Undefined subroutine ..」の代わりに、「指定されたサブルーティンが定義されていません」などと丁寧な日本語のメッセージが出てきたとしても、経験の浅い初心者には英語と同様の難解さがもたらされるでしょうし、逆にその日本語を理解できるなら、英語であっても理解できるはずです。
  • つまり、問題は英語の能力や、本人のやる気の有無にあるのではなく、初心者は「なぜエラーが出たのか?」という文脈を想像できないがゆえに、エラーメッセージを「目に入れる」ことはできても、その意味するところを「読み取る」ことができないのだと思います。
  • そうした前提を踏まえつつ、ぼくが思うのは、「エラーメッセージなんて、慣れれば自然に見るようになる」ということです。
  • エラーメッセージは、プログラマーが離れたいけど離れられない悪友のような存在であると同時に、忌憚なく、しつこくミスを指摘し続けてくれる親友でもあるので、やがて自分が何をやっているのか理解しながらコードを書けるようになれば、進んでその声に耳を傾けるようになるはずです。
  • 逆に言えば、苦しい思いをしてまでエラーを読んで、プログラミングに忌避感を抱いてしまうぐらいなら、気が済むまで何度でも、それを見慣れて頭に染み込むまで、同じエラーを吐き出させ続ければよいと思います。
  • ここでも一応付け加えておくと、これは「初心者にエラーを読めとか言うな」という話ではありません。むしろ読むように言うべきですが、ただ、もしあまり積極的にエラーを読まない初心者がいたとしても、それは怠慢や指導者への反抗心によるものとは限らなくて、上記のような理由があるからかもしれないよ、ということです。そして、教える側がそのように思えれば、無用な軋轢を避けやすくなるのではないか、みたいな話です。

3. 先生が間違っているかもしれない

  • このアドベントカレンダーの本体である「Perl入学式」は、プログラミングの初心者(またはPerlの初心者)に、無料でプログラミング言語Perlを教える有志による講座ですが、講義に使用する資料(教科書)もすべてメンバーがイチから作成しています。(→今年の資料
  • ぼくもその作成者の一人ですが、メンバーの中に職業としてプログラミングの講師をしている人は一人もおらず、みな自分の仕事の合間に時間を持ち寄って取り組んでいるので、残念ながら(というか)、資料中の不備や間違いも絶えません。
  • 一方、講義を受講する生徒さんにとって、ぼくたちスタッフはいわば「先生」ですから、基本的には「間違っていない」ことが前提になります。
  • よって、資料の中に誤記や、意味の通らない説明、問題文などがあっても、生徒さんによっては「わからない自分のほうが悪い」と思ってしまい、実際には教える側のミスなのに、それに気づかないまま少なからぬ時間を過ごしてしまう、ということも起こりがちです。
  • そしてこのようなことは、じつはプロが作った入門書や技術書でも起こることで、たとえば本の途中から、それまでに一度も説明していない用語や概念を使って話を進めてしまい、それ以降は読者を置いてけぼりにしてしまうような本もよくあります。
  • 商業出版物でもそんなことが起きてしまう理由には、そうした技術書が必ずしも「執筆のプロ」によって書かれているわけではない、ということがあるのではないかと思います。
  • 小説家や評論家、あるいは各種のメディアに寄稿する本職のライターなどは、みな執筆のプロですが、プログラミングなどを扱う技術書では、執筆で生計を立てているわけではない、それぞれの専門的な分野で活躍する人が文章を書く、ということが多々あり、それは言い換えると、「執筆のプロではない人が執筆している」という状況です。
  • 言うまでもなく、そうした状況が悪いわけではなく、そうでなければ生まれなかった名著も数え切れずあるはずですし、むしろそのような「執筆のプロではない人が書いた良書」を生み出すために、「編集者」と言われる人々が読者と執筆者の間に入り、わかりづらい表現や各種のミスを修正して回るわけですが、とはいえ編集者にできることにも限りがありますから、やはり書き手が執筆のプロであるかどうか、という点はどうしても影響してくるところだろうと思います。
    • ちなみに、個人的に思う「執筆のプロ」とそうでない人の一番の違いは、「読者の視点で自分の文章を読めるかどうか」という点にあると思います。それは「読者に対する想像力」とも言えるもので、たとえるなら、幼稚園の先生が何人もの園児たちを引率して外を歩くとき、園児がちゃんと自分についてきているか、つねに振り返って確認しながら先頭を歩く姿に似ています。
    • ぼく自身はこのような、「読者がちゃんとついてきているかどうか」を想像しながら文章を書ける人が「執筆のプロ」だと思っています。
  • 話を戻すと、書店で売られている本だからといって、必ずしも安心して身を委ねられるわけではない、ということです。もし入門書などを読み進めているときに、よくわからない説明などに出会ったら、「自分が悪いはず」と思いすぎず、「この著者の表現がわかりづらいのではないか?」と疑ってみることも必要だと思います。

4. 最短ルートはないけど遠回りもない

  • よく経験者からの助言で、「自分はAの勉強より先にBの勉強をしていたから、効率がよかった」とか、「私は間違ってAの勉強から始めてしまったけど、時間の無駄だった。Bからやればよかった」といったふうに「学習の最短ルート」を示すような話を聞くことがありますが、ぼくはこういう話はちょっと怪しいと思っています。
    • 上記の「A」「B」には、「HTML」や「JavaScript」、「C言語」や「データベース」といったプログラミングの学習対象を適当に入れてみてください。
  • というのも、これがもし資格試験のように、過去の出題データをもとにして、その後の傾向をある程度予測できる分野であれば、効率的な学習の最短ルートを分析したり、体系化したりすることも可能かもしれませんが、一度しかないその人の人生から導き出される「別の方法をとっていれば云々」というタラレバの話は、実際にはとくに検証されたわけでもない、根拠のない思い込みに過ぎない可能性があるからです。
  • もし、「Aが駄目だったからBを試したらうまくいった」という人がいたとしても、それはもしかすると、「先にAを試したことが助けになって、その後のBがうまくいった」のかもしれませんし、いずれにせよ、その人が時間を遡って、他のすべての条件を同一に揃えて、別の方法を検証することは原理的に不可能です。
  • さらに言えば、100人の学習者がいれば、100通りのスタート地点があり、100通りのゴールがあるはずです。仮に、誰かにとって最短ルートの方法が見つかったとしても、それが他の人にも同様に作用するかと言えば、そのような保証はどこにもありません。
  • つまり、学習において、事前にわかる最短ルートなんて存在しないということです。
  • と同時に、最短ルートがないということは、遠回りもない、ということです。それが無駄な努力だったなんて、証明できる人はいません。
  • 学習というのは、続けるかぎり能力が向上するものだとぼくは思います。その「能力」の定義は時間の経過とともに変化するかもしれませんが、途中でやめてしまわないかぎり、その成果は生まれ続けるはずです。
  • というか、途中でやめてしまってすら、無駄になるとは言えないでしょう。どうもプログラミングを学ぶことは、あたかも無条件に良いことであるかのように語られがちですが、「やってみたらあまり興味を持てなかった」という人がいてもそれはそれで自然なことですし、そういう場合には、もっとその人に向いたことに自分の人生を費やすべきかもしれないですから。

5. 自分に合った方法は自分で作るしかない

  • 事前に考えていたトピックは上記の4点でしたが、最後にひとつ思い出したので、それを書いて終わりにします。
  • ここまでに書いてきたことも含めて、基本的に他人が示してくれる方法というのは、ユニクロで売っている既製服のようなものです。
  • ユニクロは、あなたの体型に合わせて服を作っているわけではありません。人間の体型を数種類の「大体のかたち」に分けてそれを作り、お客さんはその中から「自分の体型に近い服」を買っています。
  • 他人が示してくれた学習の方法は、世界に一人しかいないあなたのための方法ではありませんから、うまく機能しないこともあるでしょう。
    • むしろ、機能しないことばかりかもしれません。
  • これは学習に限らないと思いますが、自分のパフォーマンスを最大限に発揮するには、既存の方法を参考にしながらも、最終的には、自分だけにフィットした、オーダーメイドの方法を作る必要があるのだと思います。
  • その方法は、他の人にはフィットしないかもしれませんし、もしかするとほんの数ヶ月後のあなたにすらもう合わないかもしれませんが、「今までいろいろ試したけど、どうしても長続きしなかった」という場合には、この考え方が役立つかもしれません。

  • 本日の記事は以上です。
  • 明日のアドベントカレンダーは、吉祥寺.pmの主宰でもある@magnolia_k_さんです。
  • 今年のPerl入学式 Advent Calendarは、例年に増して多彩な人たちが参加していて面白いので、ぜひお楽しみください。

qiita.com

*1:その後に買って読んだら面白かったです。関連記事 → 変数は「箱」か?(3) - the code to rock