ホンモノのエンジニアになりたい

ITやビジネス、テクノロジーの話を中心とした雑記ブログです。

NginX+Gunicorn+Bottleでアプリケーションを公開する?

ローカル環境でPythonのBottleを使ってWEBアプリを書いて、いざ公開というときに実際のサーバ環境をどうするかで悩みました。

色々調べながら環境を作りましたが、非WEB屋の私には躓いたところも多く、悩み調べた内容、そして最終的に到達した理解の部分までこのウェブログに残しておきます。個人的な理解のため間違いもあるかもしれないですがご容赦ください。なおこのエントリでは各ミドルウェアの設定値については触れません。あくまで考え方や全体の構成についてのエントリになります。

  

1.本番でもBottleでrunするんでしょ?

WEBフレームワーク初心者の私にとっては、「BottleでrunってすればWEBサーバ動くじゃない、本番サーバでも80ポートでrunしてlistenしてればいいんでしょ?」と思っていました。

ただ調べていくとどうやらBottleのrunでrunさせるのは性能面や信頼性の観点で良くないらしい。確かにローカル仮想サーバでrunさせてる時には10回に1回くらいの割合でコネクションエラーが発生していました。

オープンソースプロジェクトとして時間をかけて進化してきたNginXやApacheと、フレームワークにちょこんと居座るビルトインサーバのどちらがWEBサーバとして優れているかといったらそりゃ前者って話なんでしょう。餅は餅屋の原理。

 

2.NginXからのSupervisorしたGunicornからのアプリケーション(Bottleなど)がトレンドなんだって

さて、どのお餅屋さんを使おうかしら、と調べていくとNginXをフロントに使ってSupervisorしたGunicornからアプリケーション(DjangoとかFlaskとかBottleとか)を稼働させるというのが最近のトレンドらしい。

  

トレンドってなんやねん!と思う気持ちもあるが、それは置いておこう。

ただ、ただただ素直に意味がわからない。

私が勉強不足なだけですが、正直何が何だか全く意味がわからなかった。NginXがWEBサーバというのは知っていましたし、アプリケーションは私の場合Bottleになるのでしょう。GunicornとSupervisorは初めて聞きました。

調べてみるとGunicornはPythonWSGIサーバというものらしい。WSGIサーバはWikipediaにこう書いてある。

Web Server Gateway Interface (WSGI; ウィズギー) は、プログラミング言語Pythonにおいて、WebサーバとWebアプリケーション(もしくはWebアプリケーションフレームワーク)を接続するための、標準化されたインタフェース定義である。

Web Server Gateway Interface - Wikipedia

 

なるほど合点!標準化されたインタフェース定義か!

って意味わからん!

 

Wikiのページの中にWSGIサーバという項があってこのように書いてある。

WSGIサーバ(WSGIアプリケーションコンテナ)は、WSGIアプリケーションを常駐させ、HTTPクライアントからリクエストを受け取るごとに、WSGIアプリケーションのcallableオブジェクトを呼び出す。これによって、クライアントからのリクエストがアプリケーションに転送される。

GunicornはWSGIサーバなので正にここに書いてあるお仕事をします。Bottleで書いたアプリケーションを常駐させて、クライアントからのリクエストが来ると適宜Bottleアプリへリクエストを渡していく。

 

ピンと来ない人もいるでしょうが、WSGI意味わからん勢は説明書読むより動かした方が理解が早いです。大抵のソフトウェアは動かした方が理解が早まると思うんですが、私は説明書を読みこむタイプなので、ガッツリ調べてしまいました。素直に動かせば何となくわかると思う。

 

私はGunicornを勉強しはじめた時に「WSGIは標準化されたインタフェース定義である」に対して「WSGIは定義?じゃあWSGIサーバは定義をServeしてくれんの?意味不なんだが!」と思ったが、そんな風に考えてはいけなかった。

だって例えば「WEBサーバ」はWEB自体をServeしてくれるわけではないし、もう少し具体的に「HTTPサーバ」と言ったとしても、Hyper-TextをTransferするProtocolをServeしてくれるわけじゃない。

あくまでも、Hyper-TextをTransferするProtocolに準拠した仕様のServiceをServeしてくれるものなわけです。WEBサーバやHTTPサーバという言葉を何となくそのまま受け入れているのであれば、同じようにWSGIサーバという言葉も受け入れなければ、それはWSGIさん差別です。HTTPサーバさんと同じようにフワっとした理解でWSGIサーバさんを受け入れられるか、オープンで優しい心を持つ者かどうか試される場と思って間違いない。

 

WEBサーバ・HTTPサーバという言葉と同水準でこのWSGIサーバのことを考えると、要はWSGIサーバというのは「Pythonにおいて、WebサーバとWebアプリを接続するための、標準化されたインタフェース定義に準拠した仕様のServiceをServeしてくれるサーバ」と解釈するのが正しいわけだ。

 

クソ面倒くさい説明を書きましたが、とにかくWEBサーバとWEBアプリを橋渡ししてくれるサーバという抽象的な理解に留めておいて問題はありません。それくらいの理解レベルで手を動かしていった方がトータルで早いです。「WSGIよくわからん...ワイ頭悪いのかも」なんて思い悩む必要は無いです。さーっとWikiを読んでざっくり理解して、設定して動かして、それから具体的な理解へ進めばよろしい。

 

さて、ここでGunicornが何となく理解できたものとすると、今回のNginX+Gunicorn+Bottleという全体構成について見通しがついた感じになると思う。大雑把に以下のような並びでリクエストを処理していくシステムになる。

 

Nginx <-> Gunicorn <-> Bottle

NginX・ ・・・フロントのWEBサーバとして動作

Gunicorn・・・NginXとBottleアプリを繋ぐ謎のインタフェース

Bottle ・ ・・・これはアプリケーション本体

 

ちなみに、ここまで登場しないSupervisorさんはGunicornさんのプロセスを管理する人になるため、全体の流れからは切り離して考えてOKです。あくまでWEBアプリケーションとしての処理はNginx <-> Gunicorn <-> Bottleの3人でワチャワチャやるものです。

 

3.インストールして繋げてみる

はてさて、ここから3人のお友達(Nginx、Gunicorn、Bottle)を連携させて求めるべき姿に仕上げていく。とりあえずBottleアプリは既にあるので、あとはNginXさんとGunicornさんを呼んでくることになる。

NginXとGunicornをインストールして、「いっせーのーせっ!」でくっ付けることもできますが、私はWEB周りはド素人だから1つずつ進めていくことにした。

これは私見100%ですが、非WEB屋さんや全くのド素人がいきなりガッチャンコでこの三人衆を繋げると、上手く接続できない時に原因の特定が難しくなるのでオススメしません。上手く接続出来たら出来たで、「何か知らんけど出来た」状態にしかならないのでエンジニアとしてどうなのよという話もあるし、運用中のトラブルなど発生しようもんなら手に負えなくなるので、やっぱり初心者は1つずつ接続を確認して誰がどういう仕事をしてくれているのか理解することが重要だと思う。

 

さて、それでは1つずつ繋げていくとして、どこを動かして繋げていけばいいか、私が辿った道を紹介します。

①Bottleの単独動作(本番サーバでrunして動作することを確認する)

②NginXの単独動作

③NginXをリバースプロキシとして動作させrunさせたBottleアプリへ接続

④GunicornからBottleアプリへの接続

⑤NginX→Gunicorn→Bottleの接続

 

①Bottleの単独動作(本番サーバでrunして動作することを確認する)

まずは開発環境で作成したBottleアプリケーションが単独動作することを確認する。これはOS設定やPython、パッケージ周りのインストールがミスってないかを確認するテストになる。ここの動作が担保されていないとNginX・Gunicornと繋いだところでうまくいかない時の原因追究が分かりづらくなるだけだから、先に単独で動かしてみる。サーバ上でlocalhost向けにcurlコマンドを打って期待するレスポンスが返って来ればそれでよろしい。

 

②NginXの単独動作

NginXを動かして外の世界からウェルカム画面やHello Worldあたりが出ることを確認しておく。ネットワークやFirewallといった外面の問題が無い事がここで担保される。

 

③NginXをリバースプロキシとして動作させrunさせたBottleアプリへ接続

BottleとNginXがそれぞれ動作したら、とりあえず繋げてみたくなるのが人情。別にこのプロセスは踏まなくてもよかったかもしれません。Bottleアプリを適当なポート(8080ポートとか)でrunさせる。NginXは80ポートでListenさせてリバースプロキシで8080ポートへリクエストを流す。NginXのリバースプロキシが動作することの確認になる。ここの確認は外の世界からブラウザアクセスするのがいいと思う。

 

④GunicornからBottleアプリへの接続

Gunicornをインストールして、GunicornからBottleアプリを起動する。Bottleアプリはrunの行をコメントアウトしておくと確実にGunicornで動作していることが確認できる。Gunicornは外から見るとwebサーバとして動作するので、curlコマンドかブラウザアクセスで確認できる。

 

⑤NginX→Gunicorn→Bottleの接続

GunicornとBottleの接続が取れているので、頭にNginXを噛ませる。NginXのリバースプロキシの向き先をGunicornに設定する。これで目的の形に。

 

ここで調べてもわからなかったことが1つ。NginXからGunicornへリクエストを流す際にIPアドレス+ポートで繋げるか、ソケット通信で繋げるか。色々見てみましたが、みんなどっちというわけでもなく、ある人はIPアドレス、ある人はソケット通信と割とばらばらのご様子でした。性能や拡張性とか保守性とか違いはあるんでしょうけど、いまいちどっちがどう優れているのかはわからなかったです。ソケットの方が速そうと思って私はソケットで繋げました。

 

WEBド素人の私がこの構成でWEBサービスを稼働させて面白いなと思ったのは、NginXは当然として、GunicornもBottleアプリもみんなやろうと思えばWEBサーバとして動作できるところです。それぞれ単独でも動かせるし、それぞれを連携させて動かすこともできる。これは想定通りに動いてくれない時に問題点を局所化出来るので、構築している時のトラブルシュートがすごく楽でした。

ただ一方でちゃんと理解しないと運用中のトラブルに対応出来ないだとか、実は間違った状態で稼働していたとかってことが起こりそうな気がします。あと理解に至るハードルが割と高い。WSGIも動かすまでは何してくれるものか分かりづらいし、構成上、中間にいるGunicornの存在は外から認識しづらいという面がある。NginXはフロントで動くので80ポートとコネクションが取れるかである程度外から挙動が見えるし、バックにいるBottleアプリは最終的なレスポンスによって動作が見える。Gunicornは動作が外から見えないのでハードルが高いです。それぞれのログを見れば動作状況はわかりますが、やっぱりド素人に対してはハードルが高く見える。

本当のITド素人がPython(やRails)アプリ作ってIaaS環境で公開することは多くないと思いますが、、、、あ、Herokuってもしかして、この辺のメンドイ所を楽にしてくれるのかしら

 

おわりに

このエントリはローカル環境で作っていたおもちゃアプリを公開しようと思い、環境面を調べていく中で、よくわかんねーなと思ったのがきっかけでした。「世の情報を集めて整理していってもイマイチ理解できない、それじゃ自分がまとめよう」と勢い込んで書き始めたのですが、長いだけで具体的な設定値も書けてないし、はたして意味があるのかもはやわかりません。

誰か一人でもいいから、このエントリが役に立ってくれるといいなと思い、筆を置きます。

 

【読書感想文】リーダブルコードを読んで、一流のプログラマーに憧れて

読書感想文です。

 

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

 

 

この本を読もうと思った理由

 

良いコードを書こう系の情報を集めていると自然に目に入ってくるほど、色々な所で評価されている本だからです。

 

私は普段SIerでサーバ屋さんやセキュリティ屋さんの顔をして仕事しているので、ぶっちゃけ仕事に直結する本ではないです。ただぼんやりと未来の事を想像すると、私が現役で働いている間にサーバ屋の仕事ってどんどん減っていくだろうなと思っているので、これからも技術者として生きていくならキチンとコードを読み書きできるスキルが必要になる。

 

特に書くってところはある程度の数をこなさないとダメで、しかも漫然と数をこなしてもこれまたダメで、武道の型のように清く正しく美しい基本を身に着けた上で書かないといけないと考えています。これまで三十余年生きてきて勉強もスポーツも仕事も大抵の事はそうでした。たぶんプログラミングも同じだと思います。

 

というわけで、清く正しく美しい型を求めて本書を手に取ってみたということになります。

 

インターネッツ上で「英語版PDFは公開されてる」という情報を見たので検索してみました。本家ではなくアーカイブサイトですけど、メモとして残しておく。

https://the-eye.eu/public/Books/IT%20Various/the_art_of_readable_code.pdf

 

 

全体の感想

読みやすい本

まず1つ目に書きたいことは、とても読みやすい本だったということ。

本書はオライリージャパンの出版ですが、とても読みやすかったです。オライリーは全般的に ”良い意味で” 堅いところがある印象ですが、読み物系やマジ初心者向け系は割と読みやすい本が多いです。この本も読み物系としてかなり読みやすいです。

「良い本とは聞くけど、ボク ”No オライリー” なんですよ」という方でも余裕で読めます。私はオライリーチャレンジに失敗して何冊か本棚のオブジェとしてしまいましたが、これは楽勝で読めました。

 

訳者まえがきに書いてあるんですが、「(コードの)読みやすさを扱った本の翻訳が読みにくいというのではシャレにならない」 とある通り、訳者がいい仕事をしてくれています。もちろん原著が素晴らしいのはそうなんだと思いますが翻訳のせいでダメになる本もいっぱいある中で、本書が読みやすいのは訳者の仕事のおかげなんだろうと読後に思いました。

内容自体もシンプルで読みやすいです。全体ボリュームは200ページ程度だし、1つの章は10ページくらい、1つの節は1~2ページです。ちょっとした空き時間や休憩時間にパラパラ眺めるのにいい感じです。

 

本書にはコードを綺麗にするために、「明確な単語を選ぶ」とか「大きな問題を分割する」などなどのテクニックが紹介されています。本書で紹介されている「読みやすい良いコードを書くテクニック」は本書の執筆にあたっても同じく使われているんだろうなと感じました。全体的に読みやすい良い設計がなされている本という印象です。

 

読み手を選ぶかもね

全体通しての2つ目の感想は、「読み手を選ぶかも」です。この本はサブタイトル「より良いコードを書くためのシンプルで実践的なテクニック」の通り、シンプルなテクニックについて書いてあります。

本書はそれなりにコードを書けるけど、効率性や美しさを追及する上級者には至らない中級者層をメインターゲットにしているんだと思います。上級者から見ると「新しいことは何も書いてなかった。自分にとって当たり前の内容ですけど。ははん。」と映る内容です(たぶん)。逆にプログラミング初心者には「CとかJSとかPythonとかいろんなプログラム言語でサンプルが書いてあるので無理。あたしRubyしか分からないし。」と思うでしょう。

基本的には何らかの言語で”アプリケーション”と呼べる代物を作ったことがあって、作れるけど綺麗でエレガントなコードを書きたいと思っている人が対象になるかと思います。

 

と思ったんですが踏み込んで考えるとちょっと違うかも。

読み手側の反応を考えると上に書いたように上級者は「ははん」だし、初級者は「むり」という反応を示すと思います。ただ書き手側の思いはまた別物だろうなと思います。上級者には知識の整理に使って欲しいし、知らないことがあったらコードの書き方をアップデートしていってもらいたい。初級者にはそれこそ早く知ってもらいたい内容という思いがあるのだと推察いたします。

 

というわけで結局プログラム書く人はレベルに依らず皆読んだ方がいい本ってことになる。うんたぶんそうだ。

 

内容が良い

3つ目は内容が良いって話です。プログラミングの基本的なお作法が纏められているので私のように独学でアプリケーション作っている人間にはとても有難い書籍でした。

一例を挙げると、変数のネーミングのところは特に刺さりました。tmpとかretvalという名前の変数を作ることがよろしくないというのは、一般論として聞いたことがあったし、実践して苦い思いもしたので理解していました。ただし本書によると、本当にその変数の役割が一時的なものである場合はtmpでいいと記載されていました。このようにtmpが本当にtmpであるならOKといった具合に名が体を表すことこそが重要だと。しかし何でも拘ればいいってもんでもなくて、スコープが狭い数行の中でしか生きられない変数であれば頭文字一文字でもOKだと書いてある。

「名前に拘ろう、tmpは良くない」というのは感覚的に理解できていたが、なぜだめなのか、どうしたらいいのか、一切合切ぜんぶダメなのか、と問われると本書を読む前だったら論理的に説明できなかったと思う。こういった内容が頭の中で整理できて、なぜダメなのかが理解できると応用を利かすことができるようになる(気がする)。

 

別の方のブログエントリで、「読みやすさと言っているけど、定量的な評価がなされていない」という意見も見かけました。確かにそうだなと思いました。こういった海外翻訳本だと綿密な調査をベースにしてこっちの方が良いとか悪いとかってことを論じる本が割にあるイメージですが、本書ではそこまでやった上で書かれているわけではありません。これについては本書内でも「最終的には個人の好みになってしまうこともある」と書かれているので、そういうことなんでしょう。本書では「一貫性のあるスタイルは、正しいスタイルよりも大切だ」ともあります。一貫して汚いコードではだめだけど、どっちの書き方でも一長一短あるよねということであれば、どちらが優れているかよりもその書き方で統一されているかのほうが大事であると。

 

メモっておきたいところ

個人的にクリップしておきたいと思ったところを簡単にまとめます。

2章 名前に情報を詰め込む

明確な単語を選ぶ

名前を付けるとき「取ってくる系だからとりあえずGET」と考えるのではなく、ネット経由ならDownloadにするとか、動作や状態を説明するよりよい単語を使う。

 

tmpやretvalなどの汎用的な名前を避ける

絶対禁止ではないけど、tmpが本当にテンポラリなのかちゃんと考えよう。変数の生存期間が長いと、あらためて読んだ時に「あれ?このtmpって何入ってるんだっけ?」となり読みやすいコードとは言えない。

 

スコープが小さければ短い名前でもいい

tmpの話とも似ているけど、数行程度でしか生きられない狭いスコープの中でだったら長ったらしい具体的な名前をつけなくても読みやすい。

 

3章 誤解されない名前

限界値を含めるときはminとmaxを使う

境界値を含む/含まないで発生する不具合をなくすために、min、maxという単語を使う。以上以下、未満の情報を名前に含める。

 

範囲を指定するときはfirstとlastを使う

start/stopで指定すると、stopが指すものが範囲に含まれるか曖昧になる。lastであればより明確に包含関係を表現できる。

 

ブール値の名前

ブール値の変数名は、より状態を明確にするために、is・has・can・shouldを先頭につけるのがいい。

 

4章 美しさ

一貫性と意味のある並び

一連のコードの中で、ある場所ではABCと並んでいるものは別の場所でも同じ並び順で書く。

 

個人的な好みと一貫性

最終的に個人の好みになってしまうこともあるが、「正しい」スタイルよりも「一貫性」のあるスタイルの方が大切だ。

 

5章 コメントすべきを知る

コメントするべきでは「ない」こと

コードからすぐに読み取れる内容はコメントに書かない。

 

ひどい名前はコメントをつけずに名前を変える

名前だけでは正確に内容を読み取れないところにコメントを書くのではなく、名前自体をわかりやすいものに変える。

 

6章 コメントは正確に簡潔に

あいまいな代名詞を避ける

「これ」「その」などの代名詞を使用することは避ける。

 

入出力のコーナーケースに実例を使う

コメントに入出力の実例を書く時は、境界値を意識して読み手の理解を促す例を使う。

 

情報密度の高い言葉を使う

コメントは長々と正確に書くのではなく、密度の高い言葉で簡潔に書く。

 

第二部以降の覚えておきたいところ

  • 無関係の下位問題を抽出する
  • タスクを小さくして、一度に1つのことを
  • ネストを浅くする(読み手の精神的スタックにプッシュする量を減らす)

 

おわりに

こりゃ良い本ですわ。

私のように独学でコードを書いている人は、コードレビューなんて受ける機会が無いので、ダメな書き方なところがいっぱいあるんだろうなと思っていたんです。本職の人もそうかもしれないですが、自分で書いて一通り動作しているコードを修正するのを極端に面倒に思ったりもします。

 

この本の内容を生かして、未来の自分が理解しやすいコードを書いていこうという気持ちが出てきました。

プログラミング初心者の方は早い段階で綺麗な型を身に着けられるし、上級者にとっては言語化されてまとめられているものとして有用だろうしと、多くの人の役に立つ素晴らしい本だと思います。ネット上で高い評価を受けているのも納得です。

 

久しぶりに気に喰わない所の無い本でした。

 

以上

【読書感想文】「LEAN ENTERPRISE」を読んで

読書感想文です。今回読んだ本はずーっと気になってたこちら。

 

リーンエンタープライズ ―イノベーションを実現する創発的な組織づくり (THE LEAN SERIES)

リーンエンタープライズ ―イノベーションを実現する創発的な組織づくり (THE LEAN SERIES)

 

 

本のタイトルの通り、エンタープライズ(企業)にLEAN開発の手法を適用するための方法が書かれた一冊です。

 

この本を読もうと思った理由

オライリー(出版社)がシリーズ物として出版してるんだったら多分本物なんでしょ、と前から思っていました。で、こういうシリーズ物はきちんと出版された順に読んでいきたい派なんですが、ふと図書館でこの「LEAN ENTERPRISE」だけがちょこんと棚に載っているのを見つけてしまい、巡り合せを感じ借りてきてしまいました。

 

このリーンシリーズは2012年に日経BP社から「リーン・スタートアップ」が出版されたのが最初かと思います。

リーン・スタートアップ

リーン・スタートアップ

 

 

その後、オライリージャパンがシリーズ物として、6冊出版しています。「LEAN ENTERPRISE」はオライリージャパンが出版している内の一冊です。オライリーの出版は以下のリンクにまとめられています。
O'Reilly Japan - The Lean Series

  

私がリーン開発に興味を持ち始めたのは、2015年ごろだったと思います。本屋のオライリーコーナーでRunning LEANとLEAN Analytics、LEAN顧客開発が平積みで置かれていて、ポップに「今話題のLEAN開発!」といったコメントが書いてあって気になり始めたのが最初だっと思います。

それからもうかれこれ3年、さぼっていたわけではないですが、後回し後回しになってようやく巡り合ったのがこの2018年8月というわけです。

 

全体の感想

満点!まではいかないけど、すごく良い本でした。アウトプットしたいと思える本でしたね。

 

まず本書の軸になる考え方、リーンスタートアップについて振り返ってまとめてみます。ざーっくり言うと、こんな感じです。

  1. 事業のアイディア(仮説)を出す
  2. アイディアの効果を測定できるMVP(最小限の効果を持った試作品)を作る
  3. 新しモノ好きのアーリーアダプター層に使ってもらう
  4. 効果を測定し、アイディアを捨てたり方向性を変えたり、小刻みな軌道修正を繰り返す

 

スモールスタートで始めて、短期間でユーザの関心を調べたり、ユーザの声を反映させながら、ニーズに合致した製品へ仕上げていくという考え方です。

 

本書を読んでいてビビっと来たのは、MVP(最小限の効果を持った試作品)のところですね。私はSIerに勤めているので、MVPを作る状況にはなりませんが、考え方は非常に参考になりました。

 

スモールスタートは割と知られたやり方ですが、MVPは言われると当たり前なんですけど実際に作ったって話は聞いたことがありません。技術者側の立場で考えると、最小限の効果しか持たない試作品というのは作っていて悶々とするんでしょうか。技術者だけのチームであればスモールスタートで、「小さくても完璧なモノ」を作りたくなってしまうんじゃないでしょうかね。こんなサービス作りたい!という熱意が強いほど、完璧なサービスに仕上げたくなってしまう、熱が高いほどMVP作成という効率的な開発法から離れていってしまうというの面白い事象だと思いました。

 

こういったリーン開発の手法はこれからルールを作っていく新しい組織や、容易にルールの改定が可能な小規模組織で導入しやすいです。じゃあ大きな組織でリーン開発の手法は適用できないのか?この疑問に答え、実例を交えて紹介するのが本書です。

 

 

だいぶ逸れてしまいましたが、本書を読んだ上での全体視点での感想です。

  1. LEAN開発とは、という目次項目はない
  2. ちゃんとしてる本
  3. 結構難しい

 

1つ目は本書に「LEAN開発とは」という目次項目はありません。LEAN開発とか、LEANスタートアップについて真面目に知りたいなら先述の「リーンスタートアップ」あたりを読む必要があるのでしょう。本書では冒頭に書いてありますが、理屈・理論をこね回す書籍ではありません。エンタープライズ(大企業)向けにリーンを適用しようという本なので、あくまで応用のための本になります。

といっても、リーンスタートアップという仕組みの上澄み部分だけを知りたいと考えている人には良書です。電子レンジの仕組みを知らなくても誰でも使えるのと同じです。

リーンの考え方の中で、大企業に適用することの出来る部分を詳しく書いてあるので、本書だけを読んでも問題ないと思います。リーンの理屈や全体像を知りたい人は出版された順に読んでいくのがよさそうです。

 

 2つ目は「ちゃんとしてる本」です。何を言っているかと言うと、考え方の前提がきちんと提示されているという事を言っています。開発手法とかマネジメント手法というのは、他の科学分野と同じでいきなり新しい手法がぽんっと出てくるものではありません。「誰それが研究していた何とか論ではあれがこうだと言っている」と前提になった研究や書籍がくどいほど書いてある。数えたわけではないですが、全体の3割くらいのページに引用元が記されていて、巻末の参考文献は12ページもある。読みやすいライトな論文を読んでいるような感じです。

しかしちゃんとしているが故に一般書籍としては読みづらさがある。まぁ如何に今までしょうもない本を読んできたかの露呈となるので、これ以上は恥ずかしくて書けないですが、オライリーの読み物らしさはありましたね。人に薦められるかと言ったら、本気で「組織を変えたい」と思っている人以外には薦められないですね。

 

3つ目は「結構難しい」です。一つ一つのトピックは難しくないですし、それぞれ嚙み砕いて読者にわかるように”内容”が解説されています。問題は言葉です。私は割とこういう海外の開発手法の本は好んで読むのでそこまでではなかったですが、一般的なサラリーマンが手を出すと読み切れないかもしれません。ぐだぐだ書くよりも実例を出します。本書で説明なしに使われる言葉です。

デリバリー、イテレーションインサイト、エンゲージメント、バックログ、WIP、インテグレーション、バッチ、ハードニング、デプロイ、マイグレーション、コンバージョン、ロギング

この言葉の意味や指すところがわからないと本書を読むのが苦痛になると思います。

本書のタイトルをもう一度見てみると、こうなっています。

「リーンエンタープライズ イノベーションを実現する創発的な組織作り」

特にIT系を示唆する用語がタイトルに入っていないので、一般のサラリーマンが「イノベーティブな組織を作りたい!」と思って手に取ると痛い思いをすると思います(普通のサラリーマンがオライリーコーナーに行くことは殆ど無いとは思いますが)。前述の固さと相成ってギブアップしてしまうのではないだろうか。

 

最初に戻ります。満点!とまで言えなかったのは、全体的な固さとちょこちょこカタカナ英語の意味がわからなかったところからの読みづらさです。こんな固い本だとは思ってなかったので心の準備が出来てなかったというのもありますが。

ただ内容は非常に面白かった。読み進むたびに考えさせられる良書でした。

 

ビビッときたところ

この時点で長いエントリになってしまいましたが、これは書いておきたいと思うポイントだけ引用します。

 

社会学者ウェストラムの組織の分類

病的組織は不安と恐怖が蔓延しています。人々は情報をため込んだり、政治的な理由から隠したり、自分を良く見せようと改ざんしたりします。

官僚的組織は自分たちの部門を守ります。部門にいる人は自分たちの「縄張り」を維持し、自分たちのルールを主張し、何でも自分たちのやり方でやろうとします。

創発的組織はミッションに集中します。「どうすれば目標を達成できるのか?」の質問に答え、高いパフォーマンスとそのために必要な事が何よりも優先されます。

私が勤めているSIerでは病的組織1、官僚的組織8.9、創発的組織0.1、といったところです。創発的組織は見たことがないですが、それなりの規模の会社なので無いことは無いはずという意味で0ではないだろうと。私のいる部署は超がつくほどの官僚的組織です。事前に根回しして、毒にも薬にもならない指摘を頂戴しないと話が先に進まない。そんな文化なのに、やれ働き改革だ、やれイノベーションだという耳障りの良い言葉が飛び交う。まずは自分たちの部署がどういう組織なのかを理解する必要性があるのだと思いました。

 

「プロジェクト」では、顧客に届けられた価値ではなく、仕事が時間・予算通りに完了したかどうかで人々を判断します。したがって、生産性は成果(アウトカム)ではなく、結果(アウトプット)にもとづいて計測されます。

開発者たちは、実世界で大規模に使えるようにすることではなく、開発マシンでコードを書きあげることに対して報酬を得るようになります。こうして私たちは働き過ぎと高稼働に報酬を与えてしまう持続不可能な「英雄文化」を作り出すのです。

会社や部署ごとに”俺たちのやり方”がありますが、結局下っ端は”俺たちのやり方”でやるべき作業をやることが仕事になっている。本来は予算制約の中で顧客が受け取る価値の最大化を図ることが求められるのに、いつの間にか俺たちのやり方を構成する作業をこなすことが仕事になってしまう。そしてその作業を如何に効率的に多くこなすかが評価の指標となっている。

100の価値を創る仕事に10時間をかけたら生産性は10です。今のうちの会社では(殆どの日本の会社もそうだと思うが)この仕事を9時間で済ますにはどうしたらいいかという話ばかりになっています。これって働き方改革だなんだという話が出る前からみんな頑張って取り組んでいたので、乾いた雑巾を絞る行為なんです。本物の改革を目指すならば、時間を削ることも大事ですが、結局のところは価値の量を増大させることに帰着します。当然そこには先行投資が必要になったり、仕事のやり方を変えたり、痛みが伴うことが多いですが、そうやって成果を求めていくことが重要なんだろうと思います。

 

(スタートアップ買収により)優秀な人材を獲得して病的あるいは官僚的文化に入れても、その文化が変わる事はありません。その人たちを壊してしまうだけです。

文化を意図的に変えるのは難しい事です。「文化は非常に安定的で、変革が困難」であり、「成功に至るまでの考え方、感じ方、世の中に対する認識など、グループが学び、蓄積したものを象徴するものが文化」だからです。

この部分を読んで頭をよぎったのは「組織の文化は金で買えない」ということ。買えるのはせいぜい文化を変革させるきっかけ程度のものです。

 

これらを達成してもらうまでは、問題の解決や機会の追求のために大規模な計画を開始するようなことはさせません。

・達成されるべき計測可能なビジネス成果を定義する

・成果に向かって計測可能な進捗を示せる、最少限のプロトタイプを構築する

・提案する解決策が顧客のために作られ、実際に価値を提供していることを実証する

ここはLEANの考え方が端的に書いてあるところだったので引用してみました。”計測可能”な進捗と成果を計る指標を定義し、最小限のプロトタイプを作って、価値を提供していることを実証する。

以前Yコンビネータ―の本を読んだ時も同じようなことが書いてありました。1週間の目標をたてて、測定すべき指標を追いかけて対策を立てていく。似たような考え方を持っている人の本を私が好んで読んでいるだけかもしれませんが、異なる本で同じことが書いてあると、やっぱりそうなのか、と思ってきますね。

 

従来の財務会計では、業績・キャッシュフロー・収益性比率を計測します。これらはイノベーションのために作られたものではないので、新しい製品や活動を抑制したり、殺したりする恐れがあります。

 これは本書を読んで一番ビビビッときたところです。

私が務めているSIerでは厳格に業績が管理されていますが、それはSI事業であっても新事業計画でも同じ方法で管理されています。SIerではSI事業がベースになっているので、業績管理もSI事業を前提に考えられています。予算や納期、品質、使う技術などを長ったらしい計画書にまとめ、計画通りに予算を使いながら納品して、計画以上の利益を上げるというものです。

ただ新事業計画なんて不確実性だらけなんだから通常のSI事業並みの精度で計画を作ることなんて無理なんです(ちなみにSI事業にしてもそんなに高い精度で計画作れないですが)。じゃあ不確実性に対する予算をまとめてプールしておけばいいじゃない、と思う人もいるでしょうけど、業績管理システムはそんな入力項目を用意してくれていない。私が勤めている会社では不確実性なんてものはそもそも存在しないことになっています。そんなものがプロジェクトにあるんだとしたら「なぜ見積もりをすることができたのか?」という話しになり社内でボッコボコにされる。プロジェクトには不確実性が存在することをみんなが認識しているのに、社内のルール上、業績管理システム上は存在しないことになっている。表面上は会社のルールに従い、実態は不確実性に対してみんながそれぞれ独自の対処をしているのが現実です。工程ごとに多めにバッファを積んだり、計画外の要員に内緒で作業をさせたりとかやり方は色々あるようですけど。

これってすごくアホらしいんですよ。不確実性を無いものとするってのは、ただの会社や管理職の保身から出る理屈であって、プロジェクトを管理して多くの利益を生み出したいというプロジェクト管理の基本的な考えからは遠く離れています。大抵の場合は何だかんだ上手く終われているやり方ではありますが、やはり新事業をやるうえでSI事業と同じような考え方ではうまくいかないのだと思います。

本書を読んで特に考えさせられたのはここで、明確に書いてあるわけではないですが「不確実性とお友達になる」というのがリーン開発の本質なんじゃないかと思いました。不確実性を溜め込めば溜め込むほど爆発した時の威力が高いので、ほどほどにガス抜きさせてやって大爆発させないようにうまく付き合っていくのが大事なのではと。

 

小さく分散した自律的なチームをたくさん作る事です。本当に分散した組織は、補完性原則に従います。つまり、基本的に決定というものは、その決定によって直接影響を受ける人たちが下すべきなのです。官僚組織の上位レベルは、下位レベルでは効果的に行えないタスクのみを実行すべきです。上位レベルは下位レベルを「補完」すべきということです。

この考え方は初めて知ったのでメモっておく意味で引用。

以前、読書感想文を書いた「SEの教科書」にあった「上流工程で作り込んだ問題をプログラマが対処する。原因を作り出したところには、具体的な苦痛は無い場合が多い」という話と似ているなと思いました。微妙に対象が違う話ではありますが、本書に書いてある内容はより積極的に上位下位のそれぞれの人たちが”すべき事”に注目している点が面白いと感じました。

 

予防的コントロールを間違ったレベルで実行すると、不必要に高いコストをもたらします。

・簡単に自動化できる単純なタスクなのに、他のチームに実行をお願いしなければいけない。

・リスクを理解できない人から承認をもらう必要があるが、その人が多忙なのでボトルネックになっている。

・完成してもすぐに時代遅れになる不正確なドキュメントを大量に作らなければいけない。

・大きなバッチをチームや委員会に渡した後、その処理や承認が終わるまで待たなければならない。

私はSIerで金融系システムを担当することが多いのですが、これ全部あてはまる。もちろんガッチガチの運用をしているので、不必要に高いコストと一言で片づけるのは乱暴でそれが必要になった背景もあるんですが、全項目に「そうだそうだ」と思う所がある。権限や責任を厳密に定義しすぎると遅くなる(コストがかかる)という話です。アウトプットしたいと思ったのは、権限や責任所在の厳密さと、スピードやコストはトレードオフであるということ。何かまずい事が起こった時に再発防止策が実行されますが、これによって責任所在が明確になり権限が絞られていく。これ自体が悪い事ではないですが、業務の全てにこの考え方を適用していくのは誤りだと思います。金融系でガチガチのチームにいると、この再発防止の考え方がスタンダードになってしまって、何でもかんでもこの考え方を適用していってしまう。何でそうなるかと言うと、責任範囲が厳密に決められれば他の事を考えなくていいので楽になるからです。こうなると段々と上で引用した病的組織、官僚的組織の色合いが濃くなっていき、創発的組織が持つ要素は失われていく。そしてこの考え方は”文化”としてそこで働く人の心に刻み込まれる。

なので金融系SIのようなガチガチな仕事をしている人は特にこの責任所在の明確化とスピード・コストのトレードオフの関係性は強く意識して、対象の仕事によって使い分けないといけないと思う。

 

改善には決して終わりがありません。

これは覚えておきたい良い言葉なので引用。改善に取り組んですぐに良い結果が出るばかりではないですが、当たり前のように続けていくことが重要なんだなと。

 

おわりに

ここまで書いてあらためて振り返ると、良い事がいっぱい書いてある本だったなという印象です。個人的には読みづらさも感じましたが、内容はとても良い。特に基本的な考え方の部分でMVP(最小限の効果を持った試作品)は覚えておきたい。少し不思議なのは、仕事の中で資料作りをする時は、時間をかけずに粗い骨子を作ってレビューを受けるんですが、新事業や新しい取り組みの話になるとその考え方がスパッと頭から無くなってしまうということ。会社の中で予算のルールがあるからという理由もあると思いますが、なぜだか試作品を作るという考えがスパッと消えてしまう。

後は文中にも書いた「不確実性とお友達になる」。不確実性は見えないものなので、蓋をして隠しておきたいと考えてしまいますが、うまく付き合ってコントロールしていくことが重要なんだと思いました。

 

このリーン開発はとても面白い手法だったので、今後少なくともエリック・リースのリーン・スタートアップは読んでみたいと思います。

 

おわり

 

MariaDBの設定テンプレファイルが見つからないの巻

MariaDBのコンフィグテンプレファイルが見当たらなかったのであれこれ調べた内容を書き残しておく。

 

長くなったので結論だけ先に。

  • MariaDB v10.3.2以降には、それまで設定例として含まれていたmy-small.cnfなどのテンプレファイルは無くなった。
  • 基本はデフォルト値で導入して明確に実現したい要件があればconfファイルに書き込む。


 

インストールした日:2018/07/15

データベース製品 :MariaDB 10.3.8  database server(現在時点で最新)

インストール方法 :レポジトリを追加してyum

OS:CentOS 7.4

稼働環境:Oracle Virtual Box

 

事象(困ったところ)

インターネッツの情報を参考にMariaDBをインストール、それから初期セットアップのためにcnfファイル(config)の設定テンプレをコピーしようとしたら、テンプレファイルが見つからなかった。以下のようなテンプレファイルが/usr/share/mysql/ ディレクトリ配下に存在することを期待していたが無かった。

my-small.cnf
my-medium.cnf
my-large.cnf
my-huge.cnf
  

もう少し詳しくやった事を書いておく

最初は公式の情報からレポジトリを追加してyumで本体をインストール

MariaDB - Setting up MariaDB Repositories - MariaDB


次に /usr/share/mysql にあるmy-large.cnfファイルをコピーして/etc/my.cnf.dディレクトリにserver.cnfの名前で保存する。が /usr/share/mysql ディレクトリにmy-large.cnfが見当たらなかった。

 

$ ls -l /usr/share/mysql/ | grep cnf
-rw-r--r--. 1 root root 3479 72 18:31 wsrep.cnf


インストールに失敗したのかしら?設定の考え方が変わったのかしら?と思い悩みながら、とりあえず今のコンフィグの状態を見てみる。

 

$ cat /etc/my.cnf
#
# This group is read both both by the client and the server
# use it for options that affect everything
#
[client-server]

#
# include all files from the config directory
#
!includedir /etc/my.cnf.d

 

これはインターネッツの情報通り/etc/my.cnf.d配下のファイルをインクルードしておられる。/etc/my.cnf.d配下を見てみると、こうなっている。

$ ls -l /etc/my.cnf.d
合計 12
-rw-r--r--. 1 root root 763 72 16:34 enable_encryption.preset
-rw-r--r--. 1 root root 232 72 16:34 mysql-clients.cnf
-rw-r--r--. 1 root root 1080 72 16:34 server.cnf

 

インストール後のデフォルト状態のserver.cnfを見てみるとこう。

$ head /etc/my.cnf.d/server.cnf
#
# These groups are read by MariaDB server.
# Use it for options that only the server (but not clients) should see
#
# See the examples of server my.cnf files in /usr/share/mysql/
#

 

#5: # See the examples of server my.cnf files in /usr/share/mysql/

/usr/share/mysql/ ディレクトリにあるサンプルを見ろ、と書いてある。

 

ネットで調べた初期設定手順では/usr/share/mysql/my-****.cnf をコピペしなはれと書いてあった。server.cnfには /usr/share/mysql ディレクトリを見てみろと書いてある。

 

でも/usr/share/mysqlディレクトリにはテンプレコンフィグファイルは見当たらない。

findコマンドで検索してもmy-****.cnfというファイルはシステム上に無い。

 

 

インストール時に変なパラメータを渡したわけでもなく、素直にインストールしたしエラーも無く完了していたはずなんだけどなぁ。

 

あるはずのファイルが無いってのはやっぱり何かがおかしい...でもMariaDB自体は普通に起動できている...configのテンプレファイルだけ欠落しているとは考えづらい。

 

ここで「まぁ動いてればいっか。ダメならダメで後から何か症状が出るっしょ」と考えられないのが、金融系SEとして調教された人間の考え方である。

 

調査

テンプレファイルが見当たらないというワードで調べたが、ぱっと見た感じ「同じ状態になってオラ困ったぞ」という情報も見当たらない。

やっぱりインストールの時に何かやらかしてたのかなぁと不安になったが、以下の情報を発見。

mariadb.com

上記リンクから引用します。

The following my.cnf example files were included with MariaDB until MariaDB 10.3.1. 

Google翻訳
次のmy.cnfサンプルファイルは、MariaDB 10.3.1までMariaDBに含まれていました。

 

今回インストールした最新版(v10.3.8)では含まれていないということか.....

 

さらに調べたらこんな情報も発見

https://git.launchpad.net/maria/commit/support-files?id=7fee164faf8fce7be4ebe322d2178efd3d075eae

  

このローンチパッドというサイトは公式からリンクされているページです。以下のMariaDB公式サイトの中段あたり「LaunchPadリポジトリ」から飛べます。GitHubとの住み分けがよくわからんけど、公式からリンクされているちゃんとしたソース管理システムです。

MariaDB はどこでダウンロードできるの? - MariaDB Knowledge Base

 

LaunchPadのページから引用

Remove dated my-{size}.cnf files

The dates on the these files shows they are very dated. Following the sentiments of MDEV-9882 the default values are quite decent so lets remove this old stuff.

Google翻訳
これらのファイルの日付は、日付が古いことを示しています。 MDEV-9882の感想に従えば、デフォルト値はまともですので、この古いものを取り除くことができます。

 

ここから更にもう1つ情報を発見。上記引用文中にあるMDEV-9882でググって出てきたページ。どういうサイトかはわからないけど、製品の不具合なんかを投稿するサイト?

[MDEV-9882] Lack of config defaults in 10.1.13 - JIRA

 

コンフィグデフォルトファイルが無くなった!と登録された内容に対して、Sergei Golubchikという人(ググったところMariaDBのChief Architectという立場らしい。要は中の人)のコメントにこう書いてあった。

 

This is intentional. We set generally useful defaults in the server. Configuration files are for the end user to modify the defaults, not for us to set them.  

Google翻訳
これは意図的です。一般的に有用なデフォルトをサーバーに設定します。設定ファイルはエンドユーザがデフォルトを変更するためのものであり、私たちが設定するものではありません。

 

つまりちゃんとしたデフォルト値を設定しているから、基本はデフォルトで使って大丈夫よと、で変えたいところは変えてくれよと、そういうことなのねきっと。設定の考え方が変わったと。

 

MariaDBのセットアップ手順を紹介しているサイトのいくつかは、テンプレのcnfファイルコピーをせずに、キャラクタセットだけUTF8に変更しているものがあったが、あれが正解なのかもしれない。

 

よっぽどメモリ使用量を制御したいといった要件がなければ、デフォルト+文字コードくらいで運用を開始してもいいのかも。まぁ厳しい要件で環境構築することになっても結局はメモリの動きなんかはある程度動かしながら挙動を見ていくことになるので、いずれにしても最初はあまり細かいことは考えなくていいのではないかと思われる。  

 

ちなみにではあるが、実は途中で調べるのが面倒になり、過去のバージョンであるv.10.2系をインストールしてコンフィグテンプレ(my-large.cnf)を抜き出し、最新のv10.3.8に投入するという少々乱暴なやり方でやってみていた。

 

でもやっぱしそれじゃいかん、気持ち悪いと思ってちゃんと調べ直したのですが、過去バージョンに含まれるコンフィグテンプレファイル(my-large.cnf)を投入しても別にエラーが出たり起動しなくなるといった事はありませんでした。

 

目に見えるエラーや警告は無かったので、あのテンプレはあのテンプレで特定のシチュエーションには使えるもののように思えます。もちろん廃止されているパラメータなんかもあるかもしれないので、それは調査しないと危険ですけど、とりあえず動かす分には動かせると。

 

おわり

【読書感想文】「Yコンビネーター シリコンバレー最強の~」を読んで

読書感想文です。今回読んだ本はこちら。

 

Yコンビネーター シリコンバレー最強のスタートアップ養成スクール

Yコンビネーター シリコンバレー最強のスタートアップ養成スクール

 

本文中でYCと記載しているところはYコンビネータ―の頭文字をとった略称です。

 

この本を読もうと思った理由

ハードカバーの本は嵩張るのであまり好きじゃないんですが、Yコンビネータ―というスタートアップスクールの話は何かで聞いたことがあって、面白そうだと思った記憶があったので読んでみました。

あと作者が外国人で、翻訳された本というのも選んだ理由の一つです。海外で出版された本で、クソみたいな本は翻訳されないですからね。たまに内容がクソで商業的に成功しただけの本もありますが、Amazonの評価も高かったのでまぁ大丈夫でしょと読んでみました。

 

全体の感想

書評家みたいなことは書きたくないですが、本書は劇薬です。取扱い注意です。

ITの力を信じていて、でも普段の仕事ではそれを実感できなくて、世界のテック企業と自分のいる場所に隔たりを感じ諦めてしまっている方は、本書を読むと熱気にほだされる可能性があるため注意してください。文章を通して強い熱気を感じ取れる良書ですが、熱すぎて火傷の危険性があります。

 

繰り返します。良書です。私は今まで何冊もIT系やビジネス系の書籍を読んで来ましたがトップクラスです。

タイトルにある「Yコンビネータ―」はシリコンバレーにあるスタートアップ養成スクールです。ここでは熱意と能力とアイディアを持つ起業を目指した人間を集めてきて、投資をしつつ3ヶ月かけてスタートアップ企業として鍛え上げていくスタイルで運営されています。ドロップボックスやヘロク、エアビーアンドビーがここの出身です。あと有名どころの話としてハッカーニュースもYコンビネーターが運営しています。(https://news.ycombinator.com/

 

本書はそのスタートアップ企業を鍛える3か月間のドキュメンタリーになります。本書は最初の起業アイディアがうまくいかず参加者が悪戦苦闘している様子や、それに対するYコンビネータ―運営側からのアドバイスで構成されていますが、いずれも生々しいというか生きた言葉で綴られていてすごく惹きこまれます。パートナー(運営側のアドバイスする人)の方たちのシンプルでいて本質的なアドバイスは文章というフィルター越しに見てもとても熱いものを感じます。

 

本書内で「ポール・グレアムと話をするとみんな早くコーディングしたくなる」と書いてあるところがありました。話をしながら元のアイディアを磨いていくと、そこで話した内容を早く実現したいと思ってコードを書きたくなるという意味なんですが、私は本書を読んでいるだけで『何か作りたい』と思うようになるほどでした。

これは人の思考に影響を与えるほどの大きなエネルギーを持ったYコンビネータ―のパートナーがすげぇという事ももちろんありますが、そのエネルギーを文章越しでも感じられるように書いた著者も素晴らしいですし、更にそれを翻訳した人(Tech Crunchの翻訳チーム)も良い仕事をしています。

 

Amazonのレビューを見ると投資の世界の人たちが多く読んでいる本のようですが、これは何かを為したいと思っているエンジニアこそ読むべき本です。すごくエネルギーが湧いてきます。またスタートアップをやりたいと思っている人や実際にやっている人には本当に身になることがいっぱい書いてある本ですので、オススメできます。

 

次項に本書を読んで心に響いてきたところを引用しながら書いていきますが、「ここだけは!」という二点だけここに書きます。

YCの教義

コードを書いて顧客と話せ、早く出してやり直せ、数字で測れる週間目標を決めて集中しろ。

スタートアップ企業の大切なところとして「YCの教義」と紹介されていた言葉です。これはスタートアップだけではなく、日々の仕事や生活の中でパフォーマンスをあげなければならないあらゆる時に重要なことだと思います。基本的なやるべきことをやって、ユーザとコミュニケーションをとって、それを早く出して繰り返しやり直せと。そして計測可能な目標を定めて集中してやる。何だろう書いてあることはよく言われることなんですが、たぶん本書の読後にまだ熱気が残っていてそれにあてられてるのかもしれません。

 

もう一つ。

創業者があきらめない限りスタートアップは失敗しない

これも良い言葉。上に書いた教義と合わせて、諦めずにコードを書き続けてユーザと対話し続けろ、ってことですね。スタートアップの成功率というのは極めて低いです。そういう上手くいかないことが大半という性質を持つものは、うまくいくまでやり続けることが重要。ギブアップするまで失敗ではないというメッセージです。

 

私は本書はすごく良い本だと感じましたが、なにをもって良い本だと思ったのか考えてみました。

1つは上にも書いた文章越しに伝わってくる熱気、エネルギーです。ドキュメントだからか、参加企業の苦悶やYCパートナーのアドバイスが生々しく感じられます。この本を読んでいると本当にコーディングをしたくなる。目標が見えなくなって無気力になった時のカンフル剤としてずっと手元に置いておきたいと思える本です。

もう1つは、スタートアップの考え方を学べたことです。上で書いたYCの教義なんかもそうです。この教義だけを見ると割とどこかで言われているような内容なんですが、これがドキュメント形式の本書を通して見ると見え方が変わってくるんです。うまく表現できませんが、読めばわかるとしか書きようのない説得力があります。

あとは本書を読む前の私の考え方に近い部分があって、読んでいて心地よかったというのもあります。ひょっとするとこれが全てなのかもしれません。特にYCがハッカーを好むという点です。新しいものを作る時に、その人たちがその技術に精通していない、ようは自分たちでモノを作れないというのはダメという話です。本書を通してYC参加者はハッカーであることが望ましいと繰り返し書かれていて、この点は本当に読んでいて心地よかった。

 

良い本である理由をうまく挙げられていませんが、まぁ良い本ってのはだいたいそうなんですよ。良い事がいっぱい書いてあってダイジェストにまとめられないんです。よほど斬新で正しい内容が簡潔に書いてあれば、「AはBである。と書いてあった。目からウロコである」と感想を書けますが、良い本は「AはBだし、CはDだし、・・・・」と永遠と素晴らしい内容が続いて、しかも一冊の中でそれが複雑に絡み合いながら説得力を増していくので、どうにもまとめられないわけです。

本書の感想から少し逸れてしまいましたが、それでもこの素晴らしい本の内容は紹介したい。次項に「これキタ!」という箇所を引用して紹介します。部分的に抜き出すと、それだけではどうにも薄っぺらく見えてしまうところはありますが、私は書評家のような本を評価する言葉を持っていないのでこうするしかない。

 

「これキタァ!」と思ったところ

「これキタ!」ポイントを引用しながら紹介します。

 

スタートアップの本質は新しい会社だという点には無い。非常に急速に成長する新しいビジネスでなければいけない。スケールできるビジネスでなければいけないんだ。そうでなければ、それはスモールビジネスの開業であってスタートアップの企業ではない。

うまく言葉で言い表すことができなかったんですが、本書を読んで言語化できました。私が勤めるSIerで以前ソリューションサービスコンテストというものが社内で行われたんですが、その時にニッチなハードウェア技術を持っているチームが、「自分らの技術を使って社内スタートアップ企業を作りたい」と言っていて「なんか違うよなぁ」と思っていたんですが、これですね。急速に成長、スケールできるビジネスでないから、しっくり来なかったんですね。

 

スタートアップのアイディアを生み出すための3か条

1.創業者自身が使いたいサービスであること

2.創業者以外が作り上げるのが難しいサービスであること

3.巨大に成長する可能性を秘めていることに人が気づいていないこと

これはスタートアップだけの話ではないですね。SIerに勤めていると新事業の提案というタスクが突如与えられることがありますが、これは覚えておきたい。特に3番。

 

他の連中より真剣に考え抜いた点だけが優位性になる

これもスタートアップだけの話ではない。IT戦略やシステム提案の時に思い出したい言葉です。現実には企業勤めだと考え抜くための時間が与えられないケースが殆どですが、「この部分は考えるのが大変だから、考えた分だけ自社の優位点になる」という発想は忘れたくない。

 

最初にリリースしたプロダクトが赤面するほどひどい出来でないというのなら、そのリリースは遅すぎたのだ。

巧遅拙速のバランスの話ですね。私は巧遅の方に傾倒していて、意識しないとすぐに忘れてしまう。スタートアップでは拙速側に倒れている方が優れているようですが、完全に私に向いていない世界。。。改めて拙速の意識づけができました。

 

目標設定が効果があるのは、集中力が養われるからだ。スタートアップではやるべきことは毎日無数にある。しかし毎週成長目標を決めたら、その目標を達成するのにどうしても必要な仕事はどれか、適切な時間の使い方を必死で考え抜く必要がある。

”毎週の”成長目標というのは斬新に感じた。SIerや一般企業に勤めていると半年や1年単位の目標を作ることはよくある(大抵機能しない)が、週間目標というのは発想が無かった。もちろんスタートアップの話だから手持ち資金が底をつく前に成長しないといけないということであろうけども、SIerや一般企業の個人目標の話とは次元が違う速度が求められるということか。人の成長速度とビジネスの成長速度を比較してもしょうがないかもしれないですが、シリコンバレーのスタートアップでは1週間の単位で成長度合いを測るのに対して、日本の一般企業では26週(半年)ないし52週(1年)で測ると。しかも国内企業では多くのところで儀式化されているレベルですので達成への情熱も段違いに低いわけです。こういうところから地力の差が出てくるんだろうなぁと思いました。

 

成功するスタートアップはミートアップに行かない。アドバイザーたちと話すために走り回らない、ひたすらコードを書き、顧客と話す。

すごく納得したところです。スタートアップの本質はそれまでに無かった何かを作って市場に出すことです。”作って出す”というのが最も基本的で本質的なところですから、泥臭く時間を掛けてでもやるべきことという話です。たまに「何よりも人脈と繋がりが大切マン」と知り合うことがありますが、彼らは本当に薄っぺらい。あーなったら終わり。

 

流行語や使い古されたマーケティング用語は使うべきではない。「私たちはこの市場を破壊するつもりです」といった紋切型のフレーズは、グレアムにとっては素材写真のようなものだ。「ほかのスタートアップのプレゼンにも使えるようなスライドは使うな」と彼は言う。

これスタートアップだけの話じゃないですよね。この部分を読んで思ったのは、日本のSIerの会社紹介ですよ。あれは本当に酷いものだと思います。たぶん会社名だけ変えればそのまま使えますからね。オリジナリティーなんか欠片も無いくせに、面接では「なぜウチの会社なのかね?他社と比べてなぜウチ?」と聞いてきます。バカの極地です。

 

1ビットだけでもいいから世界を進歩させるようなプロダクト

これは言葉が気に入りました。どこかで使おうと思います。 1ビットしか世界が進歩しなくてもそれができる状態になったプロダクトはさっさとローンチしろ、というお話で使われていた言葉です。

 

うまくいかなかった点も多かったが、これはいつものことだ。うまくいかなかった点はこれから直していけばいい。どうせ私は死ぬまでうまくいかない点を直し続けることになるんだろうが。

カッコいいなと思った言葉。これもいつか使いたい言葉としてここに記録しておく。こういうことを言えるおっさんになりたい。 

 

ソフトウェアが世界を食う

今やソフトウェアはあらゆる産業のバックボーンとして普遍化している。いわばソフトウェアが世界を食ってしまおうとしているのだ。

抽象的でフレーズが気に入ったというのもありますが、正に世の中がこういう風に進んでいるなと私は思っています。他のエントリでも何回か書いていますがITシステムの中で真の価値を提供しているのはアプリケーションです。言い方は悪いですが、インフラはツールであってユーザに大きな価値は提供できない。世界を食ってしまうほどの巨大な何かはアプリケーション(ソフトウェア)だと思っています。インフラはインフラで面白いんですが。

 

本人が勉強熱心であれば、ウェブやモバイルの複雑なアプリケーションを驚くほど短時間で完成させることができる。ソフトウェア・スタートアップを起業してベンチャーキャピタルの門を叩くために、マイクロソフトやオラクルのような大企業で5年、10年と下積み生活をする必要はまったくない。

こういう言葉ですよ。前項で劇薬だとか書きましたが、生きた言葉で綴られたこういう本で、「大企業で下積み生活をする必要はない」とか書かれていると、「そんじゃ俺もやったろやないかい!」って思ってきちゃうんですよ。

 

おわりに

何回も書きましたが、良書です。本当に手元に置いておきたいと思える本です。自分で言うのもなんですが、私は割と悲観的、否定的に物事を考える癖があって大抵の本は見下した状態から入るんですが、今回は完全に覆されました。私は今までビジネス系の本は50か100かくらい読んでいると思うんですが、トップクラスです。

 

このエントリを上からここまで読んでくれた方は、狂信的とか信者かと思うかもしれません。私もこのエントリを書きながらプレビューを見たらそう思えました。ちょっと気持ち悪いくらいに。でもそれだけ良い本なんです。

内容的、分量的に誰にでも薦められる本ではありませんが、スタートアップの世界を覗いてみたい方や実際にスタートアップとして走り始めている方、SIerの中で疲弊して無気力化してしまった方は是非読んでおいた方がいい本です。

 

おわり

ベネッセ情報流出事件の地裁判決が出たニュースについて

先週、2014年に発覚したベネッセ社の情報流出事件の続報が報道されてました。最近読んだ本と関連のあるニュースだったので脳内整理も兼ねてだらだら書いていこうと思います。

 

私が読んだニュースがこれ。

www.nikkei.com

 

で、最近読んだ本のレビューがこれ。

 

ニュースの概要

ベネッセ社の個人情報流出事件で被害のあった180人が計1478万円の損害賠償を求めた訴訟を起こし、東京地裁判決が出た。「慰謝料が発生するほどの精神的苦痛があるとは認められない」として請求は棄却。原告側は控訴の方針。

  • 原告側の主張

「流出情報をもとに営業電話やDMを受けたり詐欺などの犯罪に利用されるリスクがあり重大な不安感がある」

  • ベネッセ側の反論

「勧誘行為があったとしても、日常的にありふれたものだ」

  • 判決

裁判長はベネッセ側に対策や監督を怠った注意義務違反を認定。一方で氏名住所などの情報が思想信条や性的指向などの情報に比べ、他者にみだりに開示されたくない私的領域の情報という性格は低いと判断した。また実害が生じていない事、お詫びの文書と500円相当の金券を配布した事を考慮して、原告側が求めた損害賠償を認めず。

  • 判決を受けた弁護士のコメント

「プライバシー侵害を認めながら損害が生じていないということは矛盾だ」

 

考察

損害賠償の金額

180人が1478万円の損害賠償を求めているので、一人当たりの平均は82,000円ほどですね。流出した内容をあらためてみてみると以下の通り。

 

  • 個人に関する情報

 保護者と子供の氏名・性別・生年月日・続柄・出産予定日

  • 連絡するための情報

 郵便番号・住所・電話番号・FAX・メールアドレス

 

 参考:事故の概要 | お客様本部について | ベネッセお客様本部

 

個人情報流出における賠償(和解)金額の相場はどれくらいかと調べてみたところ、みずほ中央法律事務所というところが一覧で整理して公開していたので引用。

  • 秘匿性=『低』レベル→500円〜1000円

  住所・氏名など

  • 秘匿性=『中』レベル→1万円

  クレジットカード情報、収入・職業に関する情報

  • 秘匿性=『高』レベル→3万円

  スリーサイズ、エステの施術コース

 【個人情報漏洩・流出の民事的責任(賠償金額)の実例と基準や相場】 | 企業法務 | 東京・埼玉の理系弁護士

 

住所や氏名、電話番号などの情報は直接犯罪に結びつきにくいという性格からか500~1,000円コースですね。

クレジットカードや収入、職業はお金に関連して直接的な損害に結びつきやすいため1万円コース。

センシティブ情報(機微情報:思想信条、性的指向、健康情報、DNA情報、その他好き嫌いに関する情報)は3万円コース。

 

今回のベネッセ社の事件では流出した情報の秘匿性が低いので500~1000円コース。過去の賠償例に沿った妥当なところじゃないのかというのが、傍観者としての私の意見です。

とはいえ、仮に自分が被害者になったと考えると500円じゃ安いというのは確かにそう思う気がします。

 

子供と大人で個人情報の価値は同じか

上にリンクを張った元記事では詳細が書いていないだけかもしれませんが、一人当たり8万円を求める原告の主張は弱いと思います。

 

原告側

「流出情報をもとに営業電話やDMを受けたり詐欺などの犯罪に利用されるリスクがあり重大な不安感がある」

ベネッセ側

「勧誘行為があったとしても、日常的にありふれたものだ」

 

過去の事例では、原告が主張するような不安感に対して「500円で勘弁してくれ」という趣旨でお詫び金が発生しているわけです。この事件が過去の事例とどう違うのかという点で争わないと500~1,000円コースに落ち着いてしまうのは明らかです。

 

例えば、子供の情報が中心だからリスクに晒される期間が長いとか、子供個人に焦点をあてて自分で個人情報をコントロールできない子供の情報を流出させたから今までよりも重い事件であるとか、そういった主張をすべきではないのかと。してるのかもしれませんが。

 

個人情報についての考え方として、自分の情報をコントロールする権利というのがあります。個人情報に変更があったらそれを訂正する権利があるというやつです。

この権利のことを考えると、自分の情報をコントロールする権利が認められているならば、自分の情報をコントロールする判断力の無い子供の情報というのは、大人の個人情報よりも重く見られるべき、社会的に守られるべき情報だと思えます。そう考えると情報を主体的に管理・制御することのできない子供の個人情報が漏えいしたんだから、もっとお詫び金出せよという主張もありだなと思います。

 

外部犯でも内部犯でも同じなのか?

この事件は内部犯によるものなので、外部から攻撃されて情報流出した他の事件と比べ、より管理責任が問われても仕方のないことだと思います。

外部から攻撃される穴となる脆弱性を全て完全に塞ぐというのは相当難しいです。既知の脆弱性になるべくタイムリーに対応していくのが精一杯というのが多くの企業の実情です。ここは突き詰めていくと際限なく金がかかるところなので、状況にもよりますが企業が被害者顔をして世間が納得する場合もあるにはある。

しかし今回の事件は金に困った内部の人間による犯行なので、これを止めるために現実的に出来ることは割とあったんじゃないかと思います。そもそもUSBでスマホを接続しても情報を抜けない仕組みを作るとか、統制のとれる体制で運用すべきだったとか、監視を強めるだとか、いろいろと言われていることですが現実的にやれることはあった。けどベネッセはそれを怠ったと。

 

感情的な話

冒頭にリンクを張っていますが、私が最近読んだ「あなたのデータ、お金に換えてもいいですか?」にこんな事が書いてありました。(いま手元に本が無いので記憶から引用)

不幸にも幼い子供が亡くなってしまったとして、生きてれば7歳になるという時には小学生向けのDMが届く。その後も中学校入学、高校入学、成人式、新社会人と色んなタイミングでDMや営業・勧誘の知らせが届くわけだが、親はそれを見るたびに子供を亡くした事実を思い出し涙を流す。

 

これは確かに辛い。そして情報流出が無ければ「(子供が亡くなったので)もう送らないで」と連絡するだけで傷をえぐるDMは送られなくなるはずだったわけです。しかし裏で色んなところで情報が売買されもう止めることは出来ない。まぁ引越して電話番号変えれば止められはしますが。

 

これは個人情報全体の議論からするとレアケースですが、本質的なところを考えると、子供の個人情報は大人の情報と比べて影響範囲が違う、異なる性質を持っているというお話なんだと思います。

 

日本語でググってみた感じだと、子供の個人情報について特別に規定した条約や法律は無さそうです。このあたりも裁判の結果に影響しているのかもしれないですね。

 

おわりに

今回は直近で読んだ本に関連するニュースがたまたま報じられたため、思う所を含め書いてみました。このエントリを書きながら興味深いなと思ったのは、子供の個人情報に関する取り決めが(たぶん)無く、大人と同じ枠組みで考えられるということでした。

とは言ってもまだ控訴するという話なので裁判がどうなるかわかりませんが、そのうちEUあたりで同じような事件が起こって莫大な賠償額の裁判が起こりそうな予感もしています。

”個人情報”はEUGDPRにしろ国内法にしろ曖昧さが残る部分があるので、ちゃんと考えないといけないなぁと思いました。

 

おわり

麻雀のアガリ判定アルゴリズムで苦戦したこと

ひょんな事から麻雀で使う清一色チンイツ)のツールを開発することになりました。

実際に手を動かしてアプリを作っていったら、これが結構大変だったので時間がかかったところの考え方だけでもインターネッツの世界に書き記しておこうと思います。

 

 

何が大変だったか

ガリ判定のアルゴリズムです。インターネッツで情報公開している先駆者の方の情報を参考にしましたが、なかなか判定し切れなかったです。

 

何を引いてきたかはとりあえず考えないで、以下の手牌のアガリ判定を考える。

f:id:kwnflog:20180612114946p:plain

麻雀経験者からすると清一色の手の割に簡単ですね。

f:id:kwnflog:20180612115610p:plain  f:id:kwnflog:20180612115620p:plain  f:id:kwnflog:20180612115631p:plain  f:id:kwnflog:20180612115631p:plain  f:id:kwnflog:20180612115640p:plain

頭の中でこう分解できれば和了

ただこの分解を実装しようとしたら意外に難しかった。

 

インターネッツで調べながらコードを書いてはチェケラしていったのですが、どうも全パターンは判定できない。ネッツで調べたところ大体以下の手順でした。

①頭候補を探し順に試行していく

刻子候補を探し面子確定させる

③残った手配を順子に分割できたらアガリ

 

①の頭の確定のところはたぶん正解だと思います。特殊形を除いて頭は必ず1つ必要なので先に確定させた方が試行回数が減少するはず。

で、次いで3枚以上ある牌で刻子を確定させ、残りの手牌は順子を構成するものとする。

 

順子だけの場合は端から判定して抜き出していけば、和了の時は問題なく全部抜き取れる。ただ刻子や頭と組み合わさった時が曲者なんですね。

 

上の例だと三萬と四萬が刻子候補ですが、何も考えずにこれらを面子確定させてしまうと、アガリ形とはならない。

f:id:kwnflog:20180612115620p:plain  f:id:kwnflog:20180612121356p:plain  f:id:kwnflog:20180612121550p:plain

 

じゃあ、とばかりに順子から面子確定させていくと、

f:id:kwnflog:20180612115610p:plain  f:id:kwnflog:20180612121814p:plain  f:id:kwnflog:20180612121814p:plain  f:id:kwnflog:20180612121848p:plain

 

やはりアガリ形をうまく判定できない。

 

大抵の清一色手牌だったり、清一色以外の手牌ではこういう事は発生しません。刻子と順子が同じ牌を使う場合のみに発生しうるレアケースですが、私が書いていたのは清一色で遊ぼう系アプリだったためこれは避けられない問題。

 

解決法ー刻子を組み合わせで考える

この手の場合どう考えればいいかというと、刻子候補のうち三萬のみを刻子として確定させ、残りを順子の組み合わせと考え面子確定させていくが正解です。アルゴリズム的な話にすると、

 

①牌種ごとに枚数をカウントする

②2枚以上ある牌種を頭候補として、各候補に対して以下を繰り返し

③頭を仮確定させ手牌から抜く

④3枚以上ある牌種を刻子候補として、その組み合わせを求める

刻子組み合わせ候補に対して以下を繰り返し

⑥対象の刻子を面子仮確定させ手牌から抜く

⑦残った手牌の端から順子を抜く

⑧全ての牌を抜き取れれば和了

 

もう少し具体的にみていきませう。

頭はアガリ形の中に必ず1組存在するため、順番に2枚以上ある牌を試せば問題はないかと思います。 ここでは上記手牌で八萬を頭候補とした場合を考えます。(もちろん3,4,5,6萬を頭候補としてアガリ判定を行い、全て失敗し八萬に到達した状況です)

この状況。

f:id:kwnflog:20180612131633p:plain  f:id:kwnflog:20180612115640p:plain

ここで上記④の刻子の組み合わせを求めます。

刻子自体は三萬と四萬がありますが、その組み合わせなので、

刻子無し)(三萬)(四萬)(三萬&四萬)の4パターンが存在することになります。

 

仮に刻子候補が3つあればそれぞれを刻子とするか否かの二択が3つなので、2の3乗の8パターン、刻子が4つであれば2の4乗の16パターンを考えることになります。刻子が4つであれば四暗刻なので別に四暗刻判定を入れてもいいかもしれません。

 

ではまず八萬を頭、刻子無しと考えて残りを順子分解してみましょう。

 f:id:kwnflog:20180612115610p:plain  f:id:kwnflog:20180612121814p:plain  f:id:kwnflog:20180612121814p:plain  f:id:kwnflog:20180612132420p:plain  f:id:kwnflog:20180612115640p:plain

ノー和了

 

次は三萬のみ刻子として考えた場合、こうなって、

f:id:kwnflog:20180612132758p:plain  f:id:kwnflog:20180612115620p:plain   f:id:kwnflog:20180612115640p:plain

こう。

f:id:kwnflog:20180612115610p:plain  f:id:kwnflog:20180612115631p:plain  f:id:kwnflog:20180612115631p:plain  f:id:kwnflog:20180612115620p:plain  f:id:kwnflog:20180612115640p:plain

和了

 

最後まで見てみましょう。次は四萬のみ刻子とする場合。

f:id:kwnflog:20180612133103p:plain  f:id:kwnflog:20180612121356p:plain  f:id:kwnflog:20180612115640p:plain

ノー和了

 

三萬と四萬を刻子とする場合、

f:id:kwnflog:20180612133226p:plain  f:id:kwnflog:20180612115620p:plain  f:id:kwnflog:20180612121356p:plain  f:id:kwnflog:20180612115640p:plain

これもノー和了

 

結局のところアガリと判定することができたのは、三萬のみを刻子と考えて残りを順子と見做した1パターンだけでした。

一盃口に頭がくっついた11223344であったり、それを含んだ更に複雑な形だと複数のアガリ形が存在し、アガリ役や点数に影響が出るため途中でアガリ形が求められても最後まで処理を継続する必要があると思います。

例えば、11223344456789 という形であれば頭を一萬とするか、四萬とするかで一気通貫がつくかが変わってしまうためです。

 

 

他の先駆者の方が公開している内容を見ると、頭を最初に抜き出すのは殆どの方が一致しています。

その後のアプローチに結構やり方の違いがあって、頭→刻子→順子と抜き出す人だったり頭→順子→刻子で抜き出す人がいます。

 

私がたどり着いた結論は以下。

抜き出す順番ではなく、抜き出す刻子の組み合わせが重要

刻子として抜き出せるけど、抜き出さないケースを考慮する

 

ここでは刻子の組み合わせに注目していますが、反対に順子の抜き出しの組み合わせを考えても同じようにアガリ判定ができるはずです。

ただ、

  • 刻子のほうができにくいので、数が少なく組み合わせを考えるのに適している
  • 順子は抜き出した面子によって、その後抜き出せなくなるケースが存在する

という理由で刻子の組み合わせを考える方が効率が良いと考えています。

 

例えば手牌中に以下のような形があったとして、

f:id:kwnflog:20180612140217p:plain

ここから取り出し得る順子は以下の4パターンがあります。

f:id:kwnflog:20180612140337p:plain f:id:kwnflog:20180612115610p:plain f:id:kwnflog:20180612121814p:plain f:id:kwnflog:20180612115631p:plain

ただし123を抜き出した場合は、234と345は取れなくなります。234か345で面子を作ると他の面子を作ることはできないです。

このように抜き出した面子によって、その後抜き出せる面子が変わってしまうため、事前チェックが必要となりコードとして冗長になってしまいます。

刻子であればどのように刻子面子を確定させようと、他の刻子面子には影響が出ません。

 

 

おまけ.組み合わせを考えないと判定できない牌姿一覧

清一色のアガリ形から「抜き出せるけど抜き出さない」をしないとアガリ判定ができない手牌を並べます。

この手牌は単純に刻子を全部抜き出すとか順子を全部抜き出すといった方法ではアガリ判定ができないのでテストに使えると思います。というか複雑な形が多いのでこの手牌を頭の中で瞬時に分解できれば清一色上級者と言えるかもしれません。

 

'23333444556688', '22333456667788', '22344445556677', '11123334445577', '22223333444556', '11222345556677', '22333344555667', '11333445566678', '11122223334455', '22555566677788', '23333444555566', '22566667778899', '22444567778899', '22444455666778', '12222333445599', '22223344455688', '11123334445555', '33344555566678', '44455667778999', '11112233344566', '11444556667778', '11225566778899', '44445555666778', '12222333445588', '22234555667777', '33345666778888', '11122334445666', '22223334445588', '33345666777788', '11122334445677', '22233345556677', '11223344667799', '11123444555566', '44455567778899', '33444455666778', '22234445556666', '11222334455567', '44456667778888', '11123344455688', '11222334445556', '11444566777889', '11123334445588', '11333344555667', '22234555666677', '11122333444566', '44566667778899', '55666677788899', '33334455566799', '11555667778889', '11333455566677', '22223344455699', '33344445556677', '33555566777889', '22233445556799', '11122333444588', '11122223344456', '22223334445599', '34444555666677', '44445566677899', '55556666777889', '22444556677789', '11122333444599', '11112223334499', '11334455667799', '33345566677899', '11123344455666', '33334445556699', '33444566777889', '11122233444556', '11666677788899', '33344555666788', '22233334445556', '11123334445566', '11566667778899', '11224466778899', '11224455667799', '22444556667778', '12222333444455', '22234445556677', '33444455566677', '22333344455566', '11123334445599', '33444556677789', '11122333444577', '11112223334466', '11122223334445', '22234455566667', '22223334445577', '11223355668899', '11444455666778', '11123444556688', '44555667778889', '11122334445699', '11333456667788', '11112223334488', '55566667778889', '11233334445566', '11334455668899', '33345556667799', '22233344555667', '34444555667799', '11223344557799', '11224455667788', '22333445556667', '22234445556688', '22234444555667', '11224455668899', '22234555667799', '11112233344599', '33344445556667', '44445566677888', '11112223334477', '55556677788999', '11112233344588', '11112222333445', '22234455566799', '11123444556699', '33555667778889', '22333445566678', '33566667778899', '12222333445577', '22444566777889', '22233444455567', '44455666677789', '22555677788899', '44455556677789', '44555566777889', '22233445556788', '11224455778899', '44455566777889', '33444567778899', '11444566677788', '44456667778899', '22335566778899', '33334444555667', '11223344668899', '22234455566777', '44456777888899', '33344556667899', '44455556667778', '11223344557788', '33666677788899', '11112233344555', '55567778889999', '11444455566677', '11455556667788', '33345556667788', '33344456667788', '22233444555699', '44555566677788', '11222233444556', '11122333344456', '11344445556677', '11222344555667', '44445556667799', '33555677788899', '22233444555677', '11123344455699', '11333445556667', '44456677788889', '22333455666778', '33455556667788', '11123344455556', '11334466778899', '33555566677788', '11444556677789', '44456677788999', '11122234445566', '22555667778889', '22455556667788', '33444556667778', '22233445556777', '33344445566678', '11555566677788', '33344555666799', '22555566777889', '33345566677778', '33345556667777', '33334455566788', '22233334455567', '22234445556699', '33334445556688', '11333344455566', '44455556667788', '33345566677888', '11123333444556', '33344556667888', '11222344455566', '33345555666778', '22234455566788', '22333455566677', '44455666777899', '23333444556699', '11333455666778', '11223344558899', '11444567778899', '11335566778899', '33334455566777', '45555666777788', '44456666777889', '11123344455677', '33444566677788', '11123444556666', '22444455566677', '22223344455666', '22233444555688', '11222233344455', '44456777889999', '44555677788899', '22444566677788', '22666677788899', '22233334445566', '44666677788899', '11122334445688', '22334455668899', '33344455666778', '56666777888899', '11555566777889', '55566667778899', '11112233344577', '22223344455677', '11555677788899'

 

おわりに

この問題は考えていて結構おもしろい問題でした。どう分解するアルゴリズムなら漏れなくアガリ形を捉えられるか、いい感じの難易度とコーディングの自由さがあって楽しめました。

 

色々やっているうちに結局のところアガリ判定はインデックス法(全アガリパターンの配列とマッチングする方法)を使うことにしましたが、その他の機能で部分的に生きてくるモジュールになるので書ききりました。たぶんシャンテン数を計算する機能で使うはず。

 

おわり