わくわく技術ブログ

プログラミング・統計・機械学習

アジャイルサムライを読んだ感想

書籍 アジャイルサムライ を読みました。

www.ohmsha.co.jp

とても有名な本なので評価は検索すればたくさん出てきますが、例によって自分の感想を。

一言:「実践は大変」

とても平易なというか、砕けた口調で書かれた本です。中高生でも難なく読めるでしょう。 ただその中身を真面目に考えると、とてもとても「大変」なことを書いています。

今、意図的に「難しい」ではなく「大変」という言葉を使いました。「辛い」と書いてもいいかもしれません。

恐らく、著者が想定していない「難しい」ポイントは「各国の法律の違い」くらいでしょう。そういう意味で、日本のIT業界でこの本のようなことがどのくらいの企業で可能なのかは、ちょっと自分にはわかりません。 ただ、その壁を除いたとしても大変です。

顧客の参加

この本は自分なりに整理すると次の3つの部分に別れます。

  1. チームの在り方
  2. 計画と実績評価の方法
  3. 導入すべき開発技術

このうち開発技術については、ユニットテストを書くとか、CIの仕組みを導入しておくとか、開発者サイドでの効率化の話です。
一方それ以外の部分では、 顧客の関わり方 がキーポイントになります。 アジャイルその時本当に必要なもの を見つめて 機敏(Agile)に動く ということでしょうから当然といえば当然なわけですが、本当に何度も顧客という言葉が出てきます。

日本語だと「お客様」という丁寧な言い方をしますが、今ここで必要なのは、もっとクールで対等な表現なのでしょう。顧客でもまだ違う気がします。 少なくともお客様は神様ではなく チームのメンバーとして積極的に関わってもらわないと失敗します。崇めてお気持ちを察するだけでは機敏には動けません。

開発チームがそういう状況を作るという意味では開発方法論なのでしょうが、 顧客に当たる人こそ読むべき本 という印象でした。

そして、日本社会で今の所あまり一般的ではない状況を強いるという点で、本人たちの意識次第ではあるけど大変だと思います。

現実の直視

「進捗どうですか?」と聞かれたときには基本的には、「進んでたらいいな」という期待があるわけです。すると現実がどうであれ良い返事を返したくなってしまいます。 「元気?」と聞かれたらとりあえず元気だと答えるように。

一方筆者は、たとえ進捗が0でデモするべきものがなくても、顧客とのデモの日程は延期しないほうが良いと述べています。何も進んでいないことを顧客に説明するだけでなく、そういう場を設けることでチームの意識ができると。 難しくはないけど大変なことです。。

評価は実績で

現実をより正しく捉えるために、「80%完了」といった途中での実績評価は許していません。たしかに、残り20%と思っていたら大きな問題を抱えるかもしれません。 そして、 完了基準はテストまで完了していること というのも繰り返しでています。 厳格にやり通すのはなかなか辛いかもしれないなと。

責任

  • 顧客は 何を優先し何を諦めるか を自ら決めなくてはならない
  • 開発者は 顧客の要求変化 に応えなければならない

これらは一定の権限さえあれば経験も技術も不要でしょうが、決断力や覚悟が必要です。

積極的な顧客なら今もやっているのでしょうが、平凡なサラリーマン同士が集まったら惰性で動くのが見えます。

誰に読んでほしいか

途中に書きましたが、 顧客に読んでほしい と思いました。
最近でもアジャイル開発要員を○○人増員しますといったニュースが出ていました。でもこの本を読んだら、開発会社だけが頑張る問題ではないと強く感じました。

それから、 経営者 にも読んで欲しいです。
アジャイルを採用したら開発コストが下がるみたいな発想は、そもそも見る視点が違うのだと理解できるかと。

日本語版のいいところ

日本語版には訳注として 訳者の経験則 がチラホラ入っています。

例えばユーザーストーリーの見積もりについて、筆者は「1, 3, 5 で十分」と書いていますが、訳者は「1, 2, 3, 5, 8」を使っているそうです。筆者の経験だけでなく訳者の経験も入っているのは、翻訳本の良いところですね。

ここまで書きましたが..

書籍には、 アジャイルに決まったルールがあるわけではない とも書かれています。
著者のアジャイル観がこの本には詰まっているわけですが、他の人のアジャイル観も知りたいところです。

導入した大企業とかの社員の声も聞いてみたいところですが、そういう知り合いがいないのが残念。

Coursera Machine Learningコースの受講感想

Coursera Machine Learningコース https://www.coursera.org/learn/machine-learning を修了しました。

世の中に感想はあふれていますが、人それぞれだと思うので自分の感想とどんな人にオススメするかをまとめました。

受講前の筆者の前提知識/能力

  • SI企業勤務プログラマー
  • 理系の大学院修士卒なので数式耐性はついている
  • 機械学習は完全素人ではなくて、「ゼロから作る Deep Learning」等の書籍を かる~く流し読み したりしている。ただし、 実装はしていない
  • 英語は集中して聞けばある程度は分かる。

受講のきっかけと前評判

Qiitaか何かの 機械学習を学ぶならコレ! みたいな記事で知る。

検索をしてみると、Coursera Machine Learningコースは色々な記事で「とても良い」との評判であることを知る。

今の自分のレベルに合っているかは分からなかったが、有名かつ評判の良いものなら時間のあるときにとりあえず受けてみようと思いたつ。

ついでに英語のリスニング練習になったらいいなとも。

感想

良かった点

次の2点がこのコースの良い点だと思う

  • 確実に 「自分で考えながら実装する」工程を踏める
    • 一人では「ふむふむなるほど~」といって数式を流し読むか、よくて写経。答えが広がっているのを写すより、講義資料などをコードに落とす方が時間がかかるが理解が進んだと感じる。
  • 本質でない実装は省ける
    • 機械学習で何を試すにも、データの用意や読み込み,結果の可視化が必要になる。これらは業務上必要ではあるが、ツールの使い方を調べれば良いだけでもある。それらが先に準備されていて、学習対象のアルゴリズムの実装に集中できるのは手間が省けて良い。
  • 講師の考える 「大事なポイント」がわかる
    • 書籍では紙面の都合で「第○章を参照」みたいになってしまうことも、動画の授業なので「○○でも触れたが、こういう時には××するのが大事だ!」みたいに繰り返し教えてくれる。
  • 機械学習技術者のための教養の範囲を抜けないようになっている
    • プログラミングの学習時には教養としてデータ構造やアルゴリズムの実装を学びます。それの機械学習版くらいの内容という感触。深煎りしないようにかなり気をつけた講義だった。

Machine Learningコースというよりは、Courseraの利点かもしれない。(他コースを受講したことがないので)

(自分にとって)いまいちだと思った点

無料のコースなので、不満を言いたいわけではないものの..

  • 日本語字幕があるとはいえ辛い
    • 動画の数式を見ながら日本語の字幕を追うのは思ったよりも難しい。字幕が映像と少しずれてくる事が多いので尚更。誤訳らしきところもあるので、英語だけで理解できる人とはやはり受講のしやすさはかなり違うと思う。
    • 「きれいな英語」との評判だが、受験のリスニング問題みたいなものを想像していたらさすがに違った。
  • かなりの時間を費やす
    • 「約55時間で修了」のコース。丁寧なぶんだけ、時間を多く使ってしまう。個人的にはもう一回り早くて良いと感じた。

その他

  • PythonでもRでもなくMatLab/Octaveなのがちょっと…」という声もあるが、その点は大きな問題ではないと思う。どちらかというと、PythonのNumPyやMatplotlibはMatLabを参考に作られてるんじゃないかと思う。(CやJavaしか触ったことないとエッってなると思う。)
  • 同じCoursera内の他の講義の紹介とかあっても良いのではと思った。似た名前の講座が多くて選びにくいので。
  • ちょっと古い講義なので、その分は勘案して見たほうが良いと思う。「ここまでの内容を理解していたら、シリコンバレーでフルタイムで働く多数の人間よりも効率良く問題に適用できる」とか途中で仰ってますがさすがに今はお世辞にしても違うのでは。
  • リスニング練習になったかは疑問。

誰にオススメするか

次のような人が受けるととても効率が良いと思う。

  • 英語だけでもなんとなく話が分かる
  • 少なくとも高校理系の数学知識がある、できれば大学1年次レベルの知識がある
  • 機械学習は概念的なことは何となく理解しているけど、どういう数学が裏あるのか知らない

逆に、これらにあまり当てはまらない人には必ずしも勧めない。英語も数学も分からないので見るのは苦痛だろうし、機械学習のことを数式レベルである程度理解していたら、日本語の書籍を見て実装をしたほうが時間効率としては良い。

自分は時間があったから最後まで受けたし、受けてみないと向き不向きも分からないわけだが、人生における時間の割り振り方というのは難しいので、これがベストな解になる人はそこまで多くないのではないかと思う。(とはいえ、大きく後悔する人も少ないと思う。)

プログラミングコンテスト中に浮動小数点数で悩んだ話

※ 2019/02/11 に https://wkwkhautbois.wordpress.com/ に投稿した内容の再掲です。

久しぶりの投稿です。 CodeIQやPaizaは今まで何度か挑戦したことがありました。先日、「みんなのプロコン2019」 なるコンテストがAtCoderで開かれるということを知り、アカウントを作り初めてAtCoderに挑戦しました。

AtCoderのアカウント自体を作ったばかりで使い方が分からずバタバタしたり、「え、Python3.4なの?(ちょっと古くない?)」とか焦ったりしながら挑戦する中で、掛け算 , 割り算浮動小数 でハマったのでまとめます。

ハマったこと

C問題「 When I hit my pocket… 」を解いていたときのこと。 入力例3の入力を試すも、微妙に計算結果が合わない。

このときの使用言語はPython3。 出力の際に、最後に

print('%d' % x)

のようにしていた。最初は

print(x)

としていたが、浮動小数点の書式で出力されてしまったので上記のようにしていた。 思えばこのときすぐに気づくべきだった。。

すると、小さい数字では上手くいくのに大きな数字になると微妙に値がずれる現象が発生した。 具体的には、 48518828981938099 が出力されてほしいのに、 48518828981938096 が出力された。 おかしいなと思い、試しにExcelで計算をしてみた。すると、Pythonのときとも違う値が出てきた。

そこで、浮動小数点演算になっている可能性に気づいた。 しかし、偶数のときと奇数のときで場合分けをしていて、整数以外でてこないはず…どこで?

整数演算の結果の型

Pythonは除算の演算子の意味が、Python2とPython3で異なることが、破壊的変更なので結構有名。

Python2: 3 / 2 → 1
Python3: 3 / 2 → 1.5 、3 // 2 → 1

それから、Python3では全ての整数がint型で、Python2のlong型相当になっている。

ここまで知っていたが、一つ知らなかったことがあった。 6÷2のように、 割り切れる演算 のときの結果はどうなるのか? つまり、次のようなときにどういう結果になるか?

if a % 2 == 0:
    b = a / 2
else:    
    b = (a - 1) / 2

このとき、bは常に浮動小数点数(float)になる。 実行コストを考えてみれば当たり前で、いちいち割り切れるかどうか判断してintとfloatを分けるはずもなく。 ただ、浮動小数点数であっても結果が整数(に極めて近い小数)だったら問題になることは今までなくて気にしたことがなかった。

というわけで、除算の演算子を”/”から”//”に変えて一段落。

あれ、Excelは?

Excelでの結果がPython浮動小数点数演算になっていたときと違った。 どうやらExcelでは内部的に全て浮動小数点数で扱っているようで、大きな数の乗算で誤差がでてくる。

セルに直接

=348728501 * 139130667

と入力してみたり、各セルに入力して

=A1 * B1

みたいにしてみたりしたが、どうも計算誤差が出てしまう。

上の計算は、正しくは 48,518,828,946,040,167 なのだが、Excelでは 48,518,828,946,040,200 になる。 33大きい 。表示形式を「通貨」にしてもダメだった。お金の計算はもう少し慎重にしてほしい。

Javascript:整数型の存在しない言語

Javascriptでは数値は全て浮動小数点数で扱われるということを思い出した。 それで問題になったことはあまり聞いたことがないが、どうなるかNode.js 8で上記の計算を試してみると、 48,518,828,946,040,170 になった。こんどは 3だけ大きい 。 Node.jsで競技プログラミングに参加するのは避ける方が懸命のようだ。あるいは、対処法がある??

なお、整数演算が安全にできる範囲は定数で取得することができて、 手元の環境でも確認したが Number.MAX_SAFE_INTEGER は9,007,199,254,740,991 だった。なるほど確かにそれを超えていた。

[参考] qiita.com

Pythonのfloatでの演算

Python3で小数に変換してから掛け合わせて、整数として表示すると、 48,518,828,946,040,168 になる。これまたNode.jsともExcelともちょっと違って 差は1 。ここで差がなかったら、プログラミングコンテスト中に気づくこともなかったかもしれないから逆にラッキーか。 各言語(ツール)の結果の差は、浮動小数点数の内部表現の違いからくるのだろうか?CPUが浮動小数点数演算の回路を持っているからそれに依存するのが速いのだと思っていたけど、違うのだろうか?

学んだこと

スクリプト言語では動的に型付けされることもあって、あまり強くは型について意識していませんでした。それが便利なわけですがど、数値演算なら誤差に、文字列なら不用意な変換やら何やらに悩むことがあり、気をつける必要があると改めて学びました。

あと、5000兆円を手に入れたときにはExcelJavascriptを利用したアプリで資産管理しないようが良さそうです。気をつけましょう。

スーパーフライデー?

フライが安くなる日 というのはなんとなく見えている
それ以外で思うことをなんとなくツラツラと書く。

IT企業の普段の業務

って多くの場合、(他社の)業務の効率化だと思うんですよね。
IT企業というのは主語が大きいけど、売上高を基準としていわゆるWeb系のベンチャー企業を除けば、
「貴社の業務を効率化」とか「その仕事引き受けます」みたいな文言は付いていることが多いような。

勤務時間を減らす策

作業効率を上げて早く帰りましょうとは言うものの、
思いつく範囲で、効果の示せる効率化なんてすでにやっていますよね。
やらない理由もないですよね。

「テストが手動で効率が悪い」「エクセル方眼紙が…」「PCスペックが…」みたいな話はあるかもしれないけど、
それが変わらないというのは、管理者レベルの人たちがそれを変えることによって「効率化できる」と思ってないからだと思うんですよね。
だから、首相とかが何を言おうとも、そういう方向の変化は起きない気がする。

じゃあどうするのか

業務時間を短くする圧力だけは高まっていく。

コンサルに頼るのが一番の解決策なのかなーとぼんやり思っている。
コンサルという職種は口が上手いだけな人も多そうで好きではなかったのだが(というか今もあれだが)、
外からそれらしき事を経営層に吹き込むことができるという点では素晴らしい。
同じことを説明するのにも、社内の下っ端からの意見より、高い金の対価として外部からもらった意見の方が信じる気になりやすいだろう。

本当は

こんな諦め気味な書き込みをしてしまう時点でダメとか言われそうな気がする。
でも、上の話に戻ってしまうけど、効率化しようとして効率化できるなら、すでにやってると思う。
違うのかな。

仕事の活用方法

大学時代の友人と飲み…ではなくて焼肉に行ってきた。(・ω・)オイシカッタ

とりとめもない話をしたのだけど、そのときの話題のひとつが、
「仕事ってプライベートに何か活かせたりするの?」
だった。

業界も職種も全然違う人なので、単純に興味で聞いたんだと思うけど、自分にとっては新鮮な発想だった。

仕事とプライベートを「切り離す」という話はよく聞く。その方が効率が上がるからという理由を話す人もいれば、業務外でPCに触りたくないみたいな人もいる。

逆に、家でもコーディングしてます、それが趣味ですからという人もいる。
自分はどちらかというとこちらか。ただ、資格勉強したりとかもするし、その時のモチベーションの1つは「業務で活かせる」だ。

「仕事をプライベートに活かす」という話は聞かない。結果的にそうなっている時もよくあるのだろうが、そういう表現は聞かない。
業務内容が趣味と一緒ですというのと、大きな違いがあるわけではないけど、発想がちょっと新鮮だった。
改めて自分の業務を振り返ってみると、ちょっと違う世界になるかもしれない。

こういう、ちょっとした気づきのもとをもらうことが多い。

手を動かしてみて学ぶ (日経ソフトウェアの特集記事を通して)

事の発端

先日、日経ソフトウェアの2016年11月号を買ってきました。

主な目的としては、付録のWPFについての冊子。なかなか情報無いのでね。前に連載してたのは知っていたけど、日経ソフトウェアはあまり買わないので。
(Software Design, WEB-DB Press, 日経ソフトウェア の順に買う頻度が減る感じかな。どれも興味のある刊しか買ってない。)

ただ、特集1の後半、PHPのLaravelなるフレームワークを使った開発例が載っててちょっぴり興味を覚えました。 というのも、Webの話題(特にセキュリティまわり)では何かとPHPに触れられるのに、自分自身はPHPを全く触れたことがなかったため。
加えて、Laravelというフレームワークは聞いたことが無かったというのもあり。(自分が知らなかっただけで、かなり有名らしいですね。)

そんなわけで、普段は流し読みだけのところ、実際にコードを打ち込みながら勉強してみました。
そんな時のあれこれのメモというか日記。

(特集記事も商品なので、極力ソースコードが出てこないようにしてます。読みにくいですがあしからず。)

作業

Ubuntuのバージョンは最新ではないのかとか、やや疑問に思いつつ、基本的に記事に従う形で進めることに。

なんか遅いしエラーでたけど...??

Composer(PHPのライブラリ管理ツール、これも今回知った)で、Laravelを使うアプリのプロジェクトを作成。

composer create-project (略)

と打つ。
待つ。
待つ。
……なにか間違ったかな(・_・)?

そう、妙に遅い。

そして、やっと動いたと思ったら、次のようなメッセージが。

Failed to decode response: zlib_decode(): data error

…? デグレードしてやり直して今度は成功しました的なメッセージも出たけど、なんのことやら。
そんなエラーに関して、当然ながら特集記事には書いてない。

こういう記事もあるので、みんな経験しているのだろうか。
Composerが超遅い件

またエラーだけど? @git

記事では、開発フローの体験ということでgitを使って(形だけだが)コードを管理している。
というわけで、記事に書いてある通りのタイミングで、書いてある通りにgit commitしようとする。

…あれ?またエラーでた。

これはgitを知っていたのですぐに気づいた。
git addしていないのだ。

この記事を書いた人は、実際にはコマンドを打っていないのだなと認識した。
そんなものなのだろう。

サーバーにアクセスできない @環境準備での失敗

gitにcommitもしたし、まずはサーバーにアクセス。
ブラウザにURLを打ち込みEnterを押す!

…アクセスできない。

これはすぐには理由が分からず。

結論としては、PHPのビルトインWebサーバーでは、デフォルトではlocalhost指定でないと動かないということ。 自身のIPアドレスを指定するのと、localhost指定するのと、127.0.0.1指定するのと同値だと思っていたよ…(´・ω・`)これは自分の勉強不足。

気づくのに遅れた理由の一つが、環境が記事とちょっと違ったこと。
記事ではBash on Windowsを薦めていたのだが、なんとなく嫌だったのでVirtualBoxUbuntuを用意することに。
(それでも良いと書いてあったし。)

ただ、今思えば、おそらく記事で意図していたのはDesktop用のUbuntuUbuntu内のブラウザから、localhost指定でアクセスする前提だったのかと。

自分はUbuntu Serverを用意してSSHでアクセスしてて、VirtualBoxのNAT機能でアクセスしようとしていたので。 ちょっとした(自分にとっての)はまりポイントでした。

正直、これがPHPの用意している機能なのかLaravelの用意している機能なのかも分からないまま検索することに。
こちらも先人のおかげで解決しました。
Laravelのartisanでサーバを立ち上げた時にプライベートIPでアクセスできない問題と、その対処法 - Front-end beginner's luck

Postできない…?

やっとアクセスできるようになったものの、 まだすぐには記事通りに進まず。

POSTしようとすると、MethodNotAllowedHttpExceptionが投げられる。
なぜ。

理由はなんてことなく、以下2点。 - HTML上で<form method="POST"&gtとしなければならないところを、&ltform mehtod="POST"&gtとミスタイプしていた。 - IlluminateをIllumminateとミスタイプしていた。

特に1点目、この場合、GETでリクエストが飛ぶんですね。
POSTに対する処理は書いていたけど、GETに対する処理を書いていなかったから、エラーになっていたと。

PHP初めてだしLaraval+Bladeとかいうのも初めてだし、単純なことにもなかなか気づかず。
試しにGETで書いてみたり、最終的にはFiddlerで飛んでるリクエストを覗いたりして解決に。

IDEとか使わず、カスタマイズを何もしていないvim(そもそもvimを普段使わない)で書いたのが敗因でした。

思ったこと

雑誌の特集記事とか、だいたい眺めて終わりにしているんですが、
意外とハマりポイントあるんですね。

IDE使えば解決できることだったり、 元記事の誤植だったり、 いやそんなもの初めから気づけよ的な話だったりするかもしれませんが、 本題とは別のところでもハマりポイント=学びポイントはありますね。

手を動かせとはよく言う話ですが、たしかに必要だなと思いました。
(実際には時間との兼ね合いなんですけどね。)

その他

artisanの読み方がわからず

Javaのenumとswitchとコンパイル結果

目的

Oracleの配布しているJDKと、Eclipseで使われるJDKで、コンパイル後のファイル数が違うケースに気づいたのでメモ。
switch文でenumを使う時のコンパイル結果についてです。

本題

Javaenumが、ただの定数ではなくて特殊なクラスとして扱われるのは有名なことかと思います。EffectiveJava(読みかけ 汗)にも書いてありました。
クラスなので、コンパイルすればenum定義は一つの.classファイルになります。クラス内で定義したら、staticな内部クラスとして、やっぱり別の.classになります。

ところで、そんなenumの利点として、switch文の条件にできるという点があります。
では、このようなコードはコンパイルするとどういったファイル名になるでしょうか?

Person.java

public class Person {
    public void work(Day day) {
        switch (day) {
        case SAT:
            System.out.println("寝て過ごす");
            break;
        case SUN:
            System.out.println("遊びに出かける");
            break;
        default:
            System.out.println("働く");
            break;
        }
    }
}

Day.java

public enum Day {
    MON, TUE, WED, THU, FRI, SAT, SUN
}

Eclipseコンパイル結果は予想通り

自分は、当然Person.classとDay.classの2つになると思ってました。
そして、Eclipseを使うとその通りになります。(バージョンは4.2と4.5で確認)

Oracle JDKでは違った

でも、OracleJDK(1.7)のjavacを使ったら、
* Day.class * Person.class * Person$1.class の3つになりました。なぜだ(・д・)

javap Person$1.class とすると、

Compiled from "Person.java"
class Person$1 {
  static final int[] $SwitchMap$Day;
  static {};
}

だそうな???

検索すると次のような記事に当たります

enum 定数の switch 文の実装 - happynowの日記

Java列挙型メモ(Hishidama's Java enum Memo)

enumの値が変わったり増減したりしても、enumを使う側はコンパイルし直さなくても済むというのがenumの特徴です。そういった挙動を既存の文法だけで再表現するための実装として、Oracleのjavacでは内部的に勝手にクラスを作っていたんですね。そしてEclipseコンパイラでは別の実装になっていると。

感想

Javaではクラスごとに.classファイルが作られることになっています。
しかも無名のクラスは$1のような通し番号のついたクラスになったりします。

実装依存なのだとしても、コンパイル後のファイル数まで違ってしまうのはなんとも気持ち悪いというか。
たとえば1つの.javaファイルから100個の.classが作られることも許されているのかなみたいな。
コンパイル後のことなんて気にするなと言われれば、まぁそうなんですが...('_')ナンダカナー

全然別の話題ですが

またオーボエはじめました。