いものやま。

雑多な知識の寄せ集め

「ロマ数本 発売記念イベント」に参加してみた。

数学にまつわる面白い話をプレゼンするイベントである「ロマンティック数学ナイト」。

そのオフィシャル本が発売され、発売記念イベントが開催されたので、参加してみた。

実は、このイベントの存在を知ったのがチケット販売締め切りの10/23(金)の朝で、ギリギリでの購入だった。 よく調べもせずに買ったので、どんなものかなとちょっと不安でもあったんだけど、予想を遥かに上回る面白さで、買ってよかった。

話題は多岐にわたり、どの話も面白かった。 これは数学的な面白さというよりかは、「自分はこの数学をこんなに愛してるんだ」というパッション迸ってるのが面白かった感じ。 数学が分からなくても(実際、自分も聞いててよく分かってないものが多い)、もっと話を聞いてみたいと思わせるものがあった。 こういうプレゼン能力、凄いよね。

それにしても、ゼータ関数って凄いのね。 複素関数論が自分はちょっとサッパリなので(ちゃんと勉強してればよかった・・・)、ほとんど理解できてないんだけど、凄さだけは伝わってきた。 これに魅入られる人が多いのは理解できる。

あと、最大公約数の話は、「比喩で用語を使うな」というのには全力で頷きながらも、ちょっと捉え方が違うんじゃないかなとも思ったり。

他にも、フ記法とかデカルトヒルベルトの話とか、さらには一般相対性理論の話とか、とても興味深い話が多かった。 これは本も買って読まないとな・・・

今日はここまで!

笑う数学

笑う数学

笑う数学 ルート4

笑う数学 ルート4

QK部 トランプゲーム部の結成と挑戦

QK部 トランプゲーム部の結成と挑戦

「CSS組版 Vivliostyle ユーザーと開発者の集い 2020秋」に参加してみた。

Vivliostyleの勉強会があったので、参加してみた。

3部構成になっていて、1部では開発者側からの最新トピックの紹介、2部ではユーザ側からの事例紹介、3部ではVivliostyleに限らないCSS組版の話題となっていた。

1部を聞いていて、試しに使ってみようかなとも思ったけど、2部、3部を聞くと、なかなか大変そうというのが正直なところ。 そこまで頑張るならもう諦めてWord使うかInDesignで普通に組版するか本気出して \TeXに手を出すかした方がいいのではとも思ってしまう。

これはVivliostyle自身の問題というよりかはブラウザ側の問題なんだけど、じゃあブラウザ使うのやめますとはできないのがツラいところ。 Re:VIEWを使ってて \TeXの問題が出てくるように、Vivliostyle使ってるとブラウザの問題が出てくる感じ。 総じて組版はツラみが多い・・・

とはいえ、 \TeXやSATySFiに比べれば筋はいいと思うので、今後に期待。

まぁ、自分に時間と余裕があれば、一からシステム作りたいんだけどね・・・ (ちょっと手をつけたりもしたんだけど、優先すべきものではないのでペンディング中)

今日はここまで!

『Rubyで作る奇妙なプログラミング言語 ヘンな言語のつくりかた』を読んでみた。

先週、『自作プログラミング言語の集い』という勉強会に参加してみた。

そこで紹介されてた『Rubyで作る奇妙なプログラミング言語 ヘンな言語のつくりかた』という本が面白そうだったので、買って読んでみた。

概要

内容はタイトルの通りで、Rubyを使って変わった仕様のプログラミング言語の処理系を作ってみようというもの。

言語処理系の本って、字句解析や構文解析の話から始まり、けっこう頑張って読む必要があるイメージが強い。

けど、この本はそういうのはすっ飛ばして、「こういうヘンな言語があるよ」という紹介から始まり、とりあえず動く処理系を作る感じになってた。 なので、すごく気楽にスラスラと読めた。

とはいっても、ちゃんとインタプリタコンパイラトランスレータ)、中間言語VMをそれぞれ扱ってて、最後はちゃんと構文木も作っている。 なので、子供騙しというわけではなくて、ちゃんとした内容になっていた。 『RubyでつくるRuby』ですごくガッカリしたのとは正反対な感じ。

扱ってる言語

ちなみに、扱ってる言語は以下:

  • HQ9+
  • Brainf*ck
  • Whitespace

HQ9+はオモチャ言語なのでいいとして、Brainf*ckはインタプリタトランスレータRubyプログラムに変換する)、Whitespaceは中間言語方式の処理系を作る。

Brainf*ckやWhitespace、名前は有名だけど仕様を全然知らなかったので、その詳細を知れてよかった。

意外だったのがBrainf*ckで、とんでもなく分かりにくい言語なのかと思ってたら、全然そんなことなかった。 (手順を踏めば)好きなアドレスにアクセスできるメモリがあって、ちゃんと構造化もされてるとは。 見た目で驚かされるけど、アセンブラに比べたら全然高級な仕様だと思う。 Rubyへのトランスレータが簡単に作れるのも納得。

一方、Whitespaceはもっとアセンブラに近い感じ。 中間言語に変換してたけど、ほぼアセンブラなので簡単。 VMもスタックマシーンで実装簡単だし。

本のオリジナル言語

本ではさらにオリジナル言語を考案して実装するというのをやってる。

  • Starry
  • Bolic

Starryは見た目がAAの星空みたいに書ける言語。 アイディアの段階から実際にそんなふうに書けるのかを確かめながら実装を進めていく様子が楽しめた。

そしてBolicはユニコードの記号で書く言語。 これは構文解析して構文木を作るのまでやるので、少し本格的な感じだった。

その他

さらにオマケとしていくつかの言語が紹介されてる。

凄かったのはGrass。

これも言語としては知ってたけど、どういうふうになってるのかまでざっくりと説明されてた。 書きやすいかどうかは別として、関数型言語は奥が深い・・・


そんな感じで、とても面白い本だった。 商業誌だけど、ノリは同人誌っぽくて、読んでてとても楽しい本だった。

こういう本読むと、やっぱりプログラミング言語作りたいなぁってなるよね。 (Lucidから目を背けつつ・・・リソースが足りない)

今日はここまで!

日記ブログを書いてみた(&書くのをやめた)。

7月に再就職してから、なかなかアウトプットが出せていなかった(実際、このブログも止まってた)。

そこで、アウトプットを促すために日記ブログを書いてみた。

ただ、実際にやってみるとうまくいかなかったので、やめることにした。

そのふりかえり。

始めたきっかけ

日記ブログを始めようと思ったきっかけは以下:

最近、あまりアウトプットを出せていない。

これはなぜだろうと考えたときに、ある程度まとめたり整理しないとアウトプットとして出せないという心理が働いてるんじゃないかなと思った。 そのせいで、取り掛かる心理的ハードルが高くなってる。

なので、もっと気楽に「何をやったのか」を書くくらいでもいいんじゃないかなと思った。 それであれば、断片的な取り組みや整理されてない取り組みであっても書くことができる。 少しの時間でもいいから、とりあえず進められるところまでやってみようと思える。

さらに、「何をやったか」を書くようにすれば、何かしら成果を書けるようにするだろうから、それもモチベーションとして働くと思う。

じゃあ、これが実際に効果あったのか?という話。

やってみた結果

期待していることは、次の2つ:

  1. 気楽に記事を書けるようになる
  2. 記事を書くために勉強や行動をするモチベーションになる

まず、1つ目については「短くてもいい」「途中でもいい」「何もしなかったという報告でもいい」とすることで、たしかに気楽に書けた。 そういう意味ではよかったと思う。

ただ、そうやって書かれた記事に何か意味があったのか?というのをちょっと考える必要がある。 これは後述。

そして、2つ目については、ほとんど効果がなかった。 むしろ、自分を追い詰めてしまう感じでよくなかった。

そんなこんなで、技術書展9の原稿も佳境になり、ブログを書く余裕は時間的にも精神的にも全然なくなった。

「やれないことはやれない」と認めること

仕事をすると、体力と精神力を使うので、そのあとでさらにアウトプットをするのはかなりシンドイ。 そこを無茶してもダメだなと思った。 「やれないことはやれない」と認めた上で、じゃあ次にどうするのかを考えた方がいい。

ふりかえって、平日はインプットで、休日にアウトプットと割り切ってしまうのもいいのかなと思った。 もちろん、平日に何か書きたいことがあれば、それを抑制はしないけど。

常にアウトプットを意識続けるのはツラい。 書きたいものがあるから書くとした方がいい。

記事の価値と情報の集約

そして、書かれた記事の価値について。

「何もできなかった」と書かれた記事は、まぁ意味がない。 その数の多寡でアウトプットの量を測るということはできなくもないけど・・・それなら単に月別アーカイブの数を見ればいい。

それと、その他の短い記事。

考えてたのは、日記ブログの方には断片でもいいので書いておいて、あとでこちらのブログでまとめようということ。

ただ、それなら最初からこっちのブログに書けばいいじゃんとなった。

一つ言えるのは、あとでまとめようと思っても、絶対にまとめない。 実際、こっちのブログの更新は止まってたわけだし。

下手にブログを増やすと、情報が散らばってしまってよくないというのが分かった。 情報は集約した方がいい。 あとでまとめ直すにしても、別のブログに分けて書いておく必要は何もない。

なんでブログが書けなくなっていたのか

そして、最初から答えは自分の中にあったことに気づく。

ある程度まとめたり整理しないとアウトプットとして出せないという心理が働いてる

結局、これに尽きる。

元々、最後の「今日はここまで!」というのは、記事が長いと大変なのでいくつかに分割できるようにというのと、毎日記事を書き続けることを意識して書いてたもの。 記事が長いと書く方も大変だし読む方も大変なので。

それが、いつのまにか記事が肥大化するようになってた。 それでは書くのがしんどくなるのも当然・・・

書きたいことをさらっと書きたいままに書くというのが答えになりそう。 「やれないことはやれない」を認めるのもそうだけど、自分の心に耳を傾けて、それに従うというのが大切だと思った。

文ごとの改行に関して

ちょっと余談として、文ごとの改行をなくしてもいいのかなと思った(この記事は実際にそうしてる)。

ネットの文章の場合、本と同じように書いていくと文字が詰まって読みづらいので、文ごとに改行し、改段落では行を空けた方がいいというのがある (Markdownで書いてみた。(その2) - いものやま。でもちょっと言及)。 ただ、Markdownでこれをやろうとすると行末に半角スペースを2つ入れないといけなくて、これがけっこう面倒。

そこで、日記ブログでは気楽に書けるように文ごとの改行をやめてみた。

感想としては、ちょっと違和感はあるけど、そこまで変じゃないかなという感じ。 なので、今後はこのブログでも文ごとの改行をやめてみようと思う。

まとめ

  • 書きたいときに書きたいものを書くといい
    • やれないことを無理してやろうとしてもできない
    • 記事が長くなるなら分ける
  • 情報は一ヶ所に集約する
    • まとめ直したい/書き直したい記事があれば、もう一度書けばいい
  • 文ごとの改行をやめる

ということで、日記ブログは畳んで、こちらのブログをもっと気楽に更新していこうと思う。 とりあえずは日記ブログに書いた記事で残しておきたいものをこっちに移してくる感じかな。

今日はここまで!

プログラミングは名が命。

f:id:yamaimo0625:20191023151952j:plain

「プログラミングをするとき、何に気をつけるべきか?」という質問に対して、自分が思っているのは「命名を大切にする」こと。

プログラミングというのは、モヤモヤしている概念(操作なども含む)を抽出して明確にし、そこに名前をつけていくことだと思ってる。
なので、いい命名を行えるかどうかで、概念の切り出しがキレイかどうかーーすなわち、プログラムがキレイになるかどうかが決まってくる。

これを、「コードの臭い」というリファクタリングの一視点と絡めて、実際に見ていきたい。

「初心者がリファクタリングで目をつけるべき場所」

とらラボ主催のLT会で、きり丸さん(@nainaistar)による次のような発表があった:

「コードの臭い(Code Smells)」に注目してリファクタリングするといいよ、という話なんだけど、この話の多くは「いい命名をしましょう」の一言で片付いたりする。

ここで挙げられてるのは、以下:

  • Large Class(大きすぎるクラス)
  • Long Method(長すぎるメソッド)
  • Long Parameter(多すぎる引数)
  • Duplicate Code(重複したコード)
  • Magic Number(意味が読み取れない謎の値)
  • Comments(大量のコメント)
  • Arrow(深すぎるネスト)
  • Primitive Obsession(基本型に執着する)
  • Feature Envy(外部モジュールの内部データを使う)
  • Data Clumps(一緒に扱われるべきデータが個別に扱われてる)

それぞれを「命名」の観点で見てみる。

Large Class

大きすぎるクラスというのは、いくつもの責務を持っていることになる。
そうなると、あれもやってこれもやってとなるから、その名前は一言で言い表しづらいものになる。

なので、以下のような特徴が出てくる:

  • 「〜マネージャー」「〜コントローラ」etc.
  • 名前にそぐわないメソッドがある
  • 1モジュール=1クラスのstaticおじさんクラス

こういった場合、概念を切り出して名前をつけ、いくつかのクラスに分けてあげるといい。
「この概念はまとめて名前をつけられるな」とか「このデータだけ抜き出して名前をつけられるな」と考えるといい。

Long Method

長すぎるメソッドというのは、処理をダラダラと書いてしまってる。

そういう場合、大抵は

// ここでxxxする
...

// 次にxxxする
...

みたいに、空行を挟んでいくつかの処理の塊が続いてることが多いと思う。

そういったときは、それぞれの処理の塊をメソッドに切り出してやるといい。
「ここの処理の塊、何やってるの?」という質問に対して、「〜をやってるんだよ」という答えが出せるなら、その操作には名前がつけられるということになる。
なので、その名前でメソッドを用意する。
そうすると、メソッドは短くなるし、メソッド名で処理が説明されるのでコメントも不要になる。

ここで一つ気をつけたいのが、処理の重複を防ぐためにメソッドを用意するのではなく、処理の説明をするためにメソッドを用意するということ。
実装上の都合(=同じ処理を何度も書くのは嫌)から設計を考えるのではなく、概念を整理する観点(=この処理には名前をつけられる)から設計を考える。
あとでも言及するけど、これは結構重要。

Long Parameter

パラメータが多すぎるメソッドは、そもそもそのパラメータをまとめて名前をつけられることが多い。
あるいは、処理に必要な情報があまりに多いということは、責務が大きくなりすぎてる可能性もある。

前者であれば、そのまとめたものに名前をつけてクラスとして切り出すといい。
そうすればパラメータの数はグッと減る。

そして、後者の場合、部分的な処理を適切な名前をつけて別のクラスに移せば、その処理で必要になるデータは移した先のクラスが持ってればいいので、パラメータとしてデータを渡す必要がなくなる。

「パラメータをまとめたものに名前をつけられないか」「やってる処理に名前をつけて、その処理で使ってるデータに名前をつけられないか」と考えるといい。

Duplicate Code

重複したコードは、その処理に名前をつけられるはずなので、その名前でメソッドにすればいい。

ここで重要なのが、「処理が同じだから抜き出してメソッドにする」のではなく、「処理に名前がつけられるからメソッドにする」ということ。
前述の通り、実装ではなく概念が同じかに気をつけないといけない。

たとえば、スライドだと次のような変更をしてる:

// 変更前
private static int userId = 0;
private static int taskId = 0;

public static int takeUserId() { return userId++; }
public static int takeTaskId() { return taskId++; }

// 変更後
private static int id = 0;

public static int takeId() { return id++; }

これはダメな変更の例。
なぜかというと、「処理が同じだから」という理由で共通化してしまっているから。
でも、元のメソッド名が示す通り、「ユーザIDを取得する」という操作と「タスクIDを取得する」という操作は、実装は同じかもしれないけど、操作の意味が違う。
意味が違う(けど実装は同じ)処理をひとまとめにしてはダメ。
これをやってしまうと、概念ではなく実装に依存することになるので、途端に変更が難しくなる。

これに類似したミスというのはよくあって、代表的なのは処理が同じだから親クラスを作って、親クラスに実装を持っていくというもの。
結果、親クラスでした変更が思わぬ問題を引き起こしたり、あるいは変更が困難になったり。

特定の処理を使いまわしたいなら、その処理を行うクラスを用意して、そのクラスに処理を委譲するようにした方がいい。
「〜の処理をするクラス」と、ここでも概念を抜き出して命名を行っている。
Rubyの場合、Mix-inが強力なので、これはModuleとしてincludeすれば実現できる)

Magic Number

これはもうそのまんまで、数字をそのまま使うんじゃなくて、名前をつけて意味が分かるようにしましょうね、ということ。

コメントではなくメソッド名で処理を説明するというのもこれと同じ。
名前をつければ、コメントを書かなくてもその名前で説明できる。

Comments

コメントが多すぎるコードというのは、つまり概念としてまとめられるコードがあるのに、それをメソッドとしてまとめてないということ。
まとめてなくてパッと見だと何をしてるか分からないから、コメントが必要になってる。

もう再三言ってるけど、コメントを書くくらいなら、適切な名前をつければいい。

ただし、「こういう方法もあるはずなのに、なんであえてこんな処理をしてるのか」という説明が必要な場合もある。
そういった場合はメソッド名だけでは説明できないので、コメントをつけた方がいい。
(大抵、何らかの問題と結びついてるはずなので、issueへのリンクを貼っておくといい)

Arrow

入れ子が深くなってる場合、いろいろ原因はあるけど、まずは処理に名前をつけて切り出せる部分がないかを探してみるといい。
切り出せればそれだけで入れ子が浅くなる。

また、スライドのようにif文がズンズン深くなってるときは、その条件判断に名前をつけて切り出すといい。
たとえば、if (args_is_valid(...)) { ... }とするとか。

ちなみに、早期returnは個人的にはOKだと思ってるけど、コーディング規約で許されない場合もあるので注意。

Primitive Obsession

基本型に固執しているというのも、やっぱり適切に命名してないということ。
概念として切り出せるのだから、それに名前をつければいい。
名前をつければ、コンパイラの型チェックの恩恵を受けられるし、何を扱ってるのかも分かりやすくなる。

Feature Envy

外部モジュールの内部データを使おうとしてるということは、つまりそのデータを使って何かやりたい操作があるということ。
なら、その操作は名前がつけられるはずだし、それはその外部モジュールの機能として(=メソッドとして)提供できることになる。

ただ、データオブジェクトの場合はちょっと微妙で、たとえば設定値を保持してるConfigクラスがあったとして、その設定値を使う処理をConfigクラスが持つべきかというと、かなり微妙。
この場合、Configクラスは値を保持するという責務だけをやるべきで、保持してる値を他のクラスが目的に合わせて使う方が、責務が明確になる。

Data Clumps

一緒に扱われるべきデータが個別に扱われているというのは、つまりそのまとまりに名前がつけられてないということ。
名前をつけてクラスにすれば、一緒に扱われるようになる。


こんな感じで、大抵のことは「いい命名をしましょう」の一言で片付く。
なので、命名は本当に大切。

これは以前書いた言葉にするということ。 - いものやま。にも通じたり。
言葉にすることで曖昧だったものが明確になるように、命名することで曖昧だった概念も明確になる。

今日はここまで!

GCPのText-to-Speechでストレッチ音声を作ってみた。

f:id:yamaimo0625:20200618193136j:plain

きっかけ

一日中パソコンに向かってることが多いので、とにかく首と肩のコリが酷い。
おそらくそれが原因で頭痛がすることも。

さらに最近は外出も自粛してるので、腰や脚の方にもけっこうコリが出ていた。

一応、整体には通っているものの、対処療法という感は拭えないので、やはりストレッチを行って根本的に改善していかないとなぁ、と。

そんな中、Twitterでなかなか良さそうな本が流れてきたので、試しに買ってみた。

猫背の改善から始まり、首・肩・背中のコリ、腰・足のコリをほぐすストレッチが、イラストで伸ばす筋肉の説明と共に合計27個紹介されている。
実際にやってみると、たしかにぐおぉという感じで伸びを感じる・・・
これは効きそう。

問題点

ということで、毎日お風呂上がりにでもやっていこうかなと思ったんだけど、ここでちょっと問題点が。

  1. 覚えられない
  2. カウントがツラい
  3. 味気ない

まず、覚えられない
27個も紹介されてると、それぞれの動きを覚えるのも大変だし、どのストレッチをまだやってないのか覚えておくのも大変。
本を開いて順番にめくっていけば問題ないとも言えるけど、1つやるたびにページをめくるのはとても手間。

次に、カウントがツラい
1つのストレッチにつき、20秒×3セットやることが推奨されてるんだけど、20秒を自分で数えるのは大変。
タイマーを使うという手もあるかもしれないけど、1つやるたびにボタンを押したりするのは面倒。

最後に、味気ない
こう、無音の中でじっと筋肉を伸ばすのは、なんというか、ね。
せっかくだからリラックスできる音楽とか聴きながらストレッチしたいところ。

解決策

これらの問題点をどうしようかと考えて思いついたのが、音声ガイド
手順を音声で教えてくれて、カウントもお任せし、ついでにいい感じのBGMとかも一緒に流せば万事解決!

となると、問題となるのは音声データをどう作るかだけど、自分で吹き込むのはアレなので、Text-to-Speechを使って作ることにした。

macOSには標準で音声読み上げ機能がついてるんだけど、試しに使ってみたところ、かなり微妙。。。
代わりにGCPのText-to-Speechを試してみたら、なかなかいい感じだったので、GCPのText-to-Speechを使ってみることにした。

GCP Text-to-Speech

GCPのText-to-Speechは100万文字/月までは無料で使えるので、今回の用途なら無料でOK。
よく使われる言語(Rubyも含まれる)向けのライブラリも用意されてるので、簡単に使えた。

使い方はクイックスタート: クライアント ライブラリの使用  |  Cloud Text-to-Speech のドキュメントに書いてある通りに進めればOK(手抜き)。

読み上げるテキストとそれを保存するファイル名は、あとでファイル(YAML形式)で渡す形にしたかったので、次のようなRubyプログラム(text_recorder.rb)を書いてみた:

require "google/cloud/text_to_speech"
require 'yaml'

USAGE = <<~END_OF_USAGE
  Syntax:
    ruby text_recorder.rb <target>.yml

  Format of <target>.yml:
    - file: <output1>
      text: <text1 to speech>
    - file: <output2>
      text: <text2 to speech>
    ...
END_OF_USAGE

if ARGV.empty?
  puts USAGE
  exit 1
end

entries = YAML.load_file(ARGV[0])
if entries.empty?
  puts USAGE
  exit 1
end
total = entries.size

client = Google::Cloud::TextToSpeech.text_to_speech
voice = { language_code: "ja-JP", name: "ja-JP-Wavenet-B" }
audio_config = { audio_encoding: "MP3" }

entries.each_with_index do |entry, i|
  input = {text: entry['text']}
  output = entry['file']
  output += '.mp3' unless output.end_with?('.mp3')

  current = i + 1
  STDOUT.print("[#{current}/#{total}] #{output} ... ")
  STDOUT.flush

  response = client.synthesize_speech(input: input, voice: voice, audio_config: audio_config)
  File.open(output, "wb") do |file|
    file.write response.audio_content
  end

  STDOUT.puts('Done.')
end

そして、次のような入力ファイル(stretch.yml)を用意する:

- file: 僧帽筋
  text: |-
      首の後ろを伸ばします。
      両指を組み、頭の後ろに回して、脇を絞めます。
      首を真下に向け、頭を下に押して伸ばします。
- file: 胸鎖乳突筋(右)
  text: |-
      首の横を伸ばします。
      首を左に傾け、右手の甲を腰の裏に回します。
      あごを少し上に向け、左手で頭を掴み、そのまま斜め後ろに引いて伸ばします。
(以下省略)

あとはコマンドラインで以下を実行:

$ ruby text_recorder.rb stretch.yml

これで「僧帽筋.mp3」や「胸鎖乳突筋(右).mp3」などが作られ、指定された文章が読み上げられた音声データが出来る。
あとは動画編集ソフトとかを使ってちょちょいと音声データをつなぎ合わせれば、完成!

出来上がった音声データ

せっかくなのでYouTubeにアップしてみた。
(好きなBGMを合わせた方がいいと思うので、BGMなしになっている)

なお、本では27個のストレッチが紹介されてるけど、動画では18個に減らしてる。
これは、27個全部やったら1時間近くになるから・・・(左右があるので、実質50個強のストレッチをやることになる)
同様の理由で、20秒×3セットではなく、15秒×3セットにしている。

それと、菱形筋と腰方形筋のストレッチはアレンジしてある。
前者は床に座って行う手順だったんだけど、床に座るのは面倒だったので、椅子に座ったままできるように変えている。
また、後者は手を体の前に落とすイラストになっているんだけど、体の横に落とすようにした方がよく伸びたので、変えている。

あと、ストレッチの並び順も、椅子に座って行えるもの→立って行うものと変えてる。
本に書かれた順番でやるよりもずっとやりやすくなってるはず。

ちなみに、自分はBGMとして以下の音楽をつけてみた:

最初はドビュッシーピアノ曲をつけようと思ったんだけど、クラシック音楽は聴き入ると自然と体が動いてしまうので、雰囲気を出すだけのBGMの方がいいのかも。

今日はここまで!

なぜ仕様変更は納期直前にやってくるのか。

f:id:yamaimo0625:20200614154529j:plain

ITちびまる子ちゃん

Twitterで「#ITちびまる子ちゃん」というタグが流行ってて、これがなかなか面白い。

こんな時事ネタもw

いろいろ眺めてたんだけど、目についたのが次のツイート:

まさにあるあるネタw

「水の上を歩くことと、仕様書からソフトウェアを開発することは簡単だ。どちらも凍結してさえいれば」というジョークが示す通り、ソフトウェア開発が大変なのは仕様が固まってないからとも言える。

仕様変更のタイミングの謎

さて、これを単なるあるあるネタで済ましてしまうのもいいんだけど、あるあるネタということは、みんな同じ悩みを持っているということ。
なので、ちょっと冷静に考えてみたい。

なんで仕様変更は納期直前にやってくるんだろう?

ここでポイントになるのは、「納期直前に」というところ。
これがせめてもっと早い時期にやってきたのなら、まだ対処のしようもあったかもしれない。
けど、現実はそうではないので、凄惨なデスマーチへと進むことになったりする。

はてさて、なんで納期直前にこんなことになるのか。

プログラマならここで、原因を突き止めるために「差分は何なのか」を考えるはず。
何か差分があるからこそ、違いは生まれてくる。

では、納期直前とそうでないときとの差分は何なのか?

動くソフトウェア

そう、差分を考えると、それは「動くソフトウェアがあるかどうか」

要件定義や設計のときは、当然動くソフトウェアはない。
実装中も、ソフトウェアはまだユーザが使える状態ではない。
システムテストに入って、ようやく動くソフトウェアに触れることが出来るようになって、不具合なのかどうかもあやしい挙動が見つかったり、お客さんが実際に触ってみて感触を確かめることが出来るようになる。

で、そうやって動くソフトウェアに触れるようになって初めて「想定してなかったこと」が見つかったり、「使い勝手がいまいちだね」ということが分かったりする。

すると、システムテストも終盤で、いよいよリリースだねという納期直前になって、「ここは想定してなかったけどこういう動きにして」とか「ここは使い勝手がいまいちだから仕様を変えて」という仕様変更が襲いかかってくることになる。。。

よくよく考えれば、動くソフトウェアがなければ仕様変更なんか基本的にはないし、あったとしてもまだ作ってないんだから手間は変わらない。
動くソフトウェアが実際にあるからこそ、仕様変更は生まれてくる。
そして、動くソフトウェアが出来上がるのがシステムテストに入ってからなら、仕様変更が納期直前になるのは必然とも言える。

どうすべきなのか

しかし、そう考えると、仕様変更が納期直前になるのは必然であり、避けようがないようにも思える。
何か対策はないのか?

まず考えられる対策は、「上流工程をよりしっかりやる」こと。
「凍結してさえいれば」という通り、もうどう考えても抜け漏れのない完璧な仕様を作れさえすれば、たしかに仕様変更もなく楽に開発ができる。

けど、じゃあ上流工程をしっかりやろうとしてないプロジェクトがあったかというと、そんなことはないわけで。
どのプロジェクトも上流工程をしっかりとやろうとしてきたはず。
それでも現実には抜け漏れがあったりするんだから、正直これは理想論でしかない。
凍結してりゃ、そりゃ水の上も歩けるかもしれないけど、現にどんなに頑張っても凍結しないんだから、「凍結してさえいれば」なんて真にならない命題には何の意味もない。

じゃあ、どうすればいいかというと、もうこれは「動くソフトウェア」を早く作るしない。
もちろん、全部入りのソフトウェアを早く作るなんていうのは無理だから、一部の機能に限定したソフトウェアを作ることになる。
そして、実際に触れてみれば、想定してなかったことや、実際の使い勝手が見えてくる。
それを踏まえてプロジェクトの早い段階で仕様変更を受容するようにすれば、余裕をもって対応できるようになる。

まぁ、とどのつまり、アジャイル開発になるわけだけど。

面白いのは、これはソフトウェアだからできる対処法だということで、たとえば家を作るときにこんな芸当はできない。
リビングだけまず作って、次にダイニングを作って、みたいなことは不可能で、まずはちゃんと全体を設計して、土台を作って、骨組みを作って、壁を作って、と順番に作っていくしかない。
けど、ソフトウェア開発はそんな制約に縛られる必要性はない。

プロジェクトのすべての成果物を同期させることには累積効果があるので、先へ進むほど変更のコストが飛躍的に上昇します。
(中略)
少し調べてみると、その曲線が土木工学に端を発することがわかります。
(中略)
しかし、これらのルールがソフトウェア開発に当てはまるのは、私たちがそうさせたからにほかなりません。
ソフトウェアは、ソフトと呼ばれるだけあって、柔軟にできています。
ソフトウェアは容易に変更できるはずなので、正しい手法とよい道具さえあれば、非常に融通の利くものとなります。
ですから、土木工学のたとえを用いてソフトウェアを鉄筋とコンクリートになぞらえると、自分で自分の首を絞めることになります。
(『The RSpec Book』より引用)

この指摘は非常に面白くて、つまりソフトは他にも柔軟な開発方法があるだろうに、わざわざ後になるほど変更のコストが高くなる建築と同じように作れば、そりゃ後工程の変更コストがバカ高くなるのは当然よね、と。

なので、やっぱりいにしえの開発手法に縛られているのではなく、より柔軟な開発手法にシフトしていかないといけないんだろうなぁ。

今日はここまで!