歩いたら休め

If the implementation is easy to explain, it may be a good idea.

【本】プログラマーのための『贈与論』

最近、面白い本をいくつか見つけて読んでいました。

特にモースの『贈与論』に関係あるところで。とはいえ、まだまとまった文章は書けるほど消化できていないので、簡単に紹介していくだけにします。

本書『贈与論』Essais sur le donは、フランスの文化人類学者マルセル・モース(1872~1950)の著作だ。1925年に出版された。

本書でモースは、ポリネシアメラネシアにおける贈与の体系や、ローマ法やゲルマン法といった古代法の分析をもとに、社会一般において贈与が果たし、また果たすべき役割について“道徳的”な観点から論じている。

贈与論 他二篇 (岩波文庫)

贈与論 他二篇 (岩波文庫)

プログラマーがだいすきな『伽藍とバザール』にも、「ハッカー文化は贈与の文化で、贈与による承認欲求ををイニシアティブにして品質の高いソフトウェアを開発できている」みたいな記述があります。以下、こちらの記事から引用します。

また,なぜ、そんな評価という無形のご褒美が効いたのか,訳者の山形浩生さんの 第6章 訳者あとがき には原著者のエリック・レイモンドさんがこう答えたとあります 

Raymondの答・・・・・・みんな暇だから。暇で、物質的にはある程度充足しているから。  これは大事なポイントだ。そして、そういう物質的に充足した社会では、従来の市場による稀少資源の配分システムが機能しない。  そのとき、別の原理が動き出す。贈与によって名声を得るという原理だ。これがハッカーたちにフリーソフトを書かせる動機なのだ!

そして,この文化により,バグを作ってしまった人をDisるのではなく,バグを直した人が賞賛される文化になり,品質(機能も含め)が高まったとありました.

贈与論再考 人間はなぜ他者に与えるのか

『贈与論』に関する最近の論文集みたいな本です。

特に「ポトラッチ追証できておらず、モースが生きた限られた時代にだけ行われたものらしい」ということは初めて知りました。

特に次の2つが印象に残ってます。小山さんの内容については、後で彼女の著書を紹介するのでそちらで…。

  • 毒と贈り物 / 近藤宏 著
  • 〈借り〉を回すシステム / 小川さやか 著

贈与論再考 人間はなぜ他者に与えるのか

贈与論再考 人間はなぜ他者に与えるのか

借りの哲学

『贈与論再考』に名前が出てきたので読みました。「贈与論などを下敷きにした道徳本」みたいな印象でした。

1542夜『借りの哲学』ナタリー・サルトゥー=ラジュ|松岡正剛の千夜千冊

この一文が印象に残っています。

私たちはちょうど反抗期をへて、自分ひとりでは生きていけないとわかった思春期の若者のようなものである。自分ひとりの力では生きていけず、かといって、これからの人生を《借り》をつくりっぱなしで生きていくこともできない。

借りの哲学 (atプラス叢書06)

借りの哲学 (atプラス叢書06)

その日暮らしの人類学

先程も紹介した小川さやかさんの本です。読売オンラインでは次のように紹介されています。

著者はタンザニアの市場で自ら古着の行商人として働いたりしながら、この種のインフォーマルな、「その日暮らし」の生存戦略を研究してきた。そして、日本人の仕事観が世界の全体の中ではきわめて異様なものであることを示す。世界の大部分では安定した雇用はむしろ稀なものであり、ほとんどの人が雇用されずに自分の工夫で小規模なビジネスを展開して人生を構築している。そのような仕事では未来はまったく不確実だが、まさにそれゆえ、急速な成長が可能であり、状況の激変にも対処でき、リスクの分散もしやすくて、かえって強さと安定性があるというのだ。不確実であることは希望がないことと同義ではないという。

「働き方」や仕事していく中での「仲間意識」など、考えさせられることが多々ある内容でした。(後から来た人には気前よくノウハウを教えてしまう、というのはプログラマーにも通じるところかもしれません。)

また、ケニアのモバイル送金サービスである「エム・ペサ」についての考察も、非常に面白かったです。

gaiax-socialmedialab.jp

M-PESAとは、簡単に言うと携帯電話で送金から出金・支払までなんでもできるモバイルマネーサービスです。ケニアでは公共料金や教育費などの支払いから、給料の受け取りまで今やM-PESAで賄われています。

にわかに信じがたい話ですが、M-PESAではなんとケニアのGDPの約5割を超える金額が動いています。

このサービスによって「気軽に親からの仕送りや、仲間うちでのお金の無心ができることになった」ことで、友人関係にも少なからぬ影響を与えているようです。同様の決済サービスを考えている人は、一度彼女の本を読むといいかもしれません。

「その日暮らし」の人類学 もう一つの資本主義経済 (光文社新書)

「その日暮らし」の人類学 もう一つの資本主義経済 (光文社新書)

マーケット進化論 経済が解き明かす日本の歴史

日本の歴史を、経済の視点から解き明かそうという試んでいる本です。

d.hatena.ne.jp

もともとは『経済セミナー』に連載されたコラムが元になっており、きっちりとした経済史というよりは、それぞれの時代からトピックを抽出して、マーケットの発展を分析しようとしています。

250ページほどの本で律令制以来の日本の経済史を分析しているため、「広く、浅く」という面は否めないのですが、高校の歴史の教科書などと比べると、経済学に基づいた本質的な議論がなされていますし、各時代ごとにぶつ切りになるのではない、まとまった見通しが得られます。

マーケット進化論 経済が解き明かす日本の歴史

マーケット進化論 経済が解き明かす日本の歴史

【自動要約】海外のニュースを自動で要約して翻訳して、自動でまとめてくれるプログラムを書ければいいなあ

海外のニュースを簡単に通知できないか試そう(試したい)という記事です。 国内の業界ニュースは当然追っているにせよ、海外に面白い動きがあるのに、全然把握できていないことは多々あります。

とはいえ、私は英語が得意ではないため、自分の興味のあるニュースなのか、おおざっぱでも良いので要約して通知したいと考えています。

ということで、同僚が読んでいた不動産関連のニュースを要約→翻訳してみようと思います。 日本語の自動要約は難しいものの、簡単なAPIやライブラリである程度はできるんじゃないかと踏んでます。

www.zoopla.co.uk

最終行に、都合のいいことに全体の要約があります。

  • The number of people buying a home with a mortgage has bounced back to the level seen before the UK voted to leave the European Union.
  • A total of 40,851 mortgages were approved for house purchase in October, the highest level since May.
  • But the number of loans in the pipeline for homeowners remortgaging to a new deal dipped slightly compared with September and is broadly unchanged since August.

これをGoogle翻訳すると、すごくいい結果が返ってきます。

  • 住宅ローンを持つ住宅を購入する人々の数は、英国が欧州連合を離れることに投票する前の水準まで戻ってきた。
  • 10月の総住宅購入件数は40,851件で、5月以来の最高水準であった。
  • しかし、新規契約に移管する住宅所有者のパイプラインの融資件数は、9月に比べて若干減少したが、8月以降は変わらない。

自動要約には、取り急ぎ、sumyというPythonプログラムを使いました。

github.com

コマンドラインでURLを指定すると使えるようです。なんてお手軽!

とりあえず、3文でまとめてもらうことにしましょう。

sumy lex-rank --length=3 --url="http://www.zoopla.co.uk/discover/property-news/mortgaging-activity-bounces-back-says-bba/#DR1uX77tk3xgULQQ.97"
  • The mortgage figures support anecdotal evidence from estate agents that following a brief dip in confidence after the referendum, buyers are once again returning to the housing market.
  • But despite the increase, mortgages for people buying a house are still 10% lower than they were in October last year, possibly due to affordability constraints following recent strong house price gains.
  • The fact that buyers appear to be returning to the market is obviously good news for people trying to sell a property.

何も考えずにGoogle翻訳に突っ込んでみます。

  • 住宅ローン数値は、住民投票後に安心して短期間で暴落した後、買い手が住宅市場に再び戻ってくる不動産業者からの事例を裏付けている。
  • しかし、住宅価格の上昇にもかかわらず、家を購入する人々の住宅ローンは、最近の強い住宅価格の上昇に伴う手頃な価格の制約のため、昨年10月の住宅ローンよりも10%低い。
  • バイヤーが市場に戻っているように見えるという事実は、財産を売ろうとしている人にとっては明らかに良いニュースです。

要約…というにはちょっと微妙な気がします。

要約さえきちんとできれば、最近精度が大幅に向上したGoogle翻訳でなんとかなりそうです。

【R Advent Calendar】Rプログラマーのための関数型プログラミングの学び方

R Advent Calendar 2016の5日目です。よろしくお願いします。

最近、R界隈ではHadley Wickham氏が中心となって開発しているtidyverseと呼ばれるライブラリ群が流行っています。 彼がWelcome to the Tidyverseという記事の中で、次のような宣言を行っています。

Hadley Wickham, co-author (with Garrett Grolemund) of R for Data Science and RStudio's Chief Scientist, has focused much of his R package development on the un-sexy but critically important part of the data science process: data management. In the Tidy Tools Manifesto, he proposes four basic principles for any computer interface for handling data:

  1. Reuse existing data structures.
  2. Compose simple functions with the pipe.
  3. Embrace functional programming.
  4. Design for humans.

「データマネジメントってセクシーじゃないけどめっちゃ重要なプロセスだよね。Tidy Tools Manifestoでも言ってるけど、データを扱うときのインターフェイスって4つ重要な原則があるよね」みたいな感じだと思います。

その原則の1つがコレです。

Embrace functional programming.(関数型プログラミングの思想を受け入れよう)

といっても、関数型言語やそのプログラミング手法は、まだまだ一般的なものではありません。 また、(オブジェクト指向と同じく)言語ごとに「関数型」という言葉の意味が少しずつ違い、 どのように勉強すればいいのか分からない、どんなメリットがあるのかわからないという方も多いでしょう。

というわけで、Rのプログラマー関数型プログラミングを紹介しようという無謀な記事を書いてみます。 (最初に言っておきますが、私はデータ分析者ではないし、オブジェクト指向言語であるPythonRubyを使い慣れているWeb開発者です。)

といっても、私自身も関数型言語の経験が深いわけではなく、 例えば「Ladder of Functional Programming 〜関数型プログラミングのレベル分け〜」でいうとADVANCED BEGINNERのあたりのレベルです。 PythonRubyで関数/Procを用いたプログラミングは問題なくできるのですが、もっと抽象的な世界や「型」に関する知識がまだまだだと思っています。

つまり、「自分もまだまだだけど、今のコードから一歩進んで、よりよいプログラミングのために一緒に関数型プログラミングを学んでみませんか?」というお誘いです。とはいえ自分の経験不足のため、間違っている箇所や、「おれならもっと語れるぜ」という箇所もあると思うので、コメント等でツッコミいただけるとうれしいです。

Rは関数型言語なのか

結論から書くと、関数型言語の影響は強いものの、関数型言語ではないと私は思っています。

Rが関数型言語なのかについては、既にR Advent Calendar 2014R Advent Calendar 2014: Rでfunctional programming!?という記事に、話が出ていますが、

qiita.com

古典的な関数を自由に扱えるという点は満しそうです。下記のごとく無名関数はfunctionというclassを持つ一級オブジェクトで、関数定義は無名関数本体を代入しているだけです。(無名)関数を引数として使う高階関数(higher-order function)は、下記の例がRっぽいかは別としてlapplyやsapplyなどで一般的です。

(中略)

ということで、R言語関数型言語かどうかは定義によるという微妙な結論なようです。

私も全く同じ意見です。ただ、「無名関数やクロージャが使えるから関数型言語だ」と言ってしまうと、JavaScriptPythonなども関数型言語に入ってしまうような気がして個人的には違和感があります。

また、末尾再帰最適化やパターンマッチなど(関数型として)一般的な機能がRには存在しないため、 どうしても他の関数型言語と比べると見劣りしてしまう面もあります。 (じゃあ何言語なんだよ!と思うのですが、本当になんなんでしょう。RはRかな…)

といっても、関数型言語の定義を深く考えてもしょうがなく、 「データ分析者/Rのプログラマーとして、学んだ後にどのようなメリットがあるか」ということを考えたほうがいい気がします。

そして、実際に関数型プログラミングを学ぶメリットはあると思っています。

qiita.com

プログラミングはデータの変換をするものだ

関数型言語の一種と言われるElixirの入門書に「(関数型)プログラミングはデータの変換をするものだ」という説明がありました。

これは、dplyrtidyrでパイプ演算子(%>%)を用いたプログラミングに慣れている方には受け入れやすい説明だと思います。 これらのパッケージを使い慣れてくると、「データを変換する関数を作り」、「それをパイプ演算子でつなげる」という手順でRのプログラミングが行え、 それぞれの関数の役割(〇〇のデータを××に変換する)がはっきりした美しいプログラムが書けるようになっているはずです。

qiita.com

というのも、ElixirはR(+tidyverse)と同じくパイプ(ライン)演算子(|>)を導入している言語で、 最近のRが目指しているものに似たプログラミングスタイルを取る言語だからです。 さらに言うと、パイプライン演算子自体、F#という関数型言語の機能が発祥らしく、そちらではもっと昔からパイプを使ったプログラミングが行われていたようです。

(また、Elixirは大規模分散処理や対障害性のあるアプリケーション等、統計解析ツールであるRとは全く違う分野で使われている言語であることも面白いです。)

関数型について学ぶと、抽象度の高い概念が出てきて面食らうと思いますが、 基本的には「データの変換をより楽に、関数をもっと汎用的に使うために考えられた機能」だと考えると勉強しやすいと思います。

プログラミングElixir

プログラミングElixir

パイプ演算子を使えば、Rで必要な関数型言語の知識は(そこまで)深くない

[増補改訂]関数プログラミング実践入門』にある関数型言語の説明を引用ます。 この本は実質的にHaskellの入門書みたいな感じなので、若干そちらの思想に寄っちゃってます。

一方、関数プログラミングでは、「プログラムとは『関数』である」という見方をします。 そして、大きなプログラムは小さなプログラムの組み合わせから成ります。 大きなプログラムは大きな関数、小さなプログラムは小さな関数であるとすると、プログラムの組み合わせとは関数合成(function composion)ということになります。

(詳しく説明すると長くなるので端折りますが)Haskell等の多くの関数型言語では、あらかじめ関数合成した関数を作り、合成した関数を変数に適用します。 一方で、RやElixirでは、「パイプ演算子で変数を関数に渡し、その戻り値を次の関数に渡す」というコードになります。

abrahamcow.hatenablog.com

例えば、Elixirの入門書の最初のコード例で出ている例なのですが、 なんとなく|>がパイプ演算子Task.asyncで並行処理にmapしていることがわかると思います。

(Rのpurrrでのリストの操作に四苦八苦している方も多いですが、実はElixirでは10ページ目に出てくるような内容です。)

defmodule Parallel do
  def map(collection, function) do
    collection
    |> Enum.map(&Task.async(fn -> function.(&1) end))
    |> Enum.map(&Task.await/1)
  end
end

このプログラムでは、Parallel というモジュールに pmap という関数を定義しています。 pmap は、与えられたコレクションに対して map(Ruby での Enumerable#map と同じようなものと考えて下さい)を行なうのですが、 各要素の処理を、要素数の分だけプロセスを生成し、各プロセスで並行に実行する、というものです。 ちょっと見ても、よくわからないような気がしますが、大丈夫、本書を読めば、わかるようになります。

関数合成では「関数を返す関数」というちょっと難しい概念が必要なのですが、 パイプ演算子のある言語では単に「戻り値を次の関数に渡す」というデータの変換でプログラムを記述・理解することができます。

実際、関数合成や引数の部分適用を使うようなプログラミングスタイルを、Hadleyは『R言語徹底解説』の12章で紹介しているものの「Rでは自然ではない」と言っています。

この種のプログラミングはタシットプログラミング(tacit programming)やポイントフリープログラミング(point-free programming)と呼ばれる. (中略)このスタイルはHaskellでは一般的であり,ForceやFactorのようなスタック志向のプログラミング言語において典型的である. これはRにおいては自然でもエレガントでもないスタイルになってしまうが,試してみるのも悪くないだろう.

この本では特にパイプを使ったプログラミングスタイルには触れられていませんが、 おそらく、『R言語徹底解説』の原著が2014年で、パイプ演算子magrittrライブラリも2013年末から開発が始まったようなので、執筆より後に広く使うようになったのでしょう。

ちょっと話がズレてきちゃいましたね。

何を学べばいいのか → とりあえず高階関数を使いこなせるようになろう

最初にも触れた『Ladder of Functional Programming 〜関数型プログラミングのレベル分け〜』でいうと、 「NOVICEはマスターして、ADVANCED BEGINNERの一部は理解している」状態くらいあれば、Rのプログラマーとして困ることは無くなると思います。

(というか、むしろRのプログラマーが普段やっているような、統計解析のほうが難しい理論を使っていると思います!)

qiita.com

特に、型に関する項目は必ずしも必要なく、ひとまずは高階関数汎関数)に関する項目があれば充分です。 つまり、PythonRubyなどの、一般的なスクリプト言語で必要なレベルと大差ありません。

  • 二階関数(map, filter, fold)をイミュータブルなデータ構造に対して使える
    • Rの組み込み関数ではMap, Filter, Reduce、purrrではmap, keep, reduce
  • 二階関数にラムダを渡すことができる
  • 関数を引数にしたり関数を返したりする関数を書ける
  • 非純粋なコードから純粋なコードを見つけ出し切り分けることができる

Rに必要な関数型プログラミングをどうやって勉強するかですが、おそらく『R言語徹底解説』の汎関数(高階関数)の章の内容を学ぶのがベストです。 ただし、R独自の仕様のために、必要以上に難しく見えて行き詰まるかもしれません。

R言語徹底解説

R言語徹底解説

例えばたくさんのapply系の関数が存在し、リストとベクトルを返すものや、オプションが付いているものがあったりすることに面食らいます。 例えば、tidyverse関数型プログラミングを支援するpurrrパッケージがあるのですが、その中で特に重要な関数はmap, keep, reduceの3つだけで、Rの場合は戻り値の型(リスト、ベクトル、データフレーム…)によっていろいろなバリエーションがあるために難しく見えるだけです。

その場合、一般的な関数型言語をある程度勉強して、その後にRに戻ってくるといいでしょう。

Rを使いこなすために(≒tidyverseのライブラリを使うために)必要なレベルはそこまで高くないため、一般的に関数型言語といわれているものを1つ触れば充分だと思います。 本屋に行って肌に合いそうな本を探すのがいいと思います。

…と言って投げっぱなすのもアレなので、私が最近読んでいる本のリンクを貼っておきます。 『関数プログラミング実践入門』というタイトルですが、実質Haskellの入門書です。

Rに近いところでいうと、Rの影響元でもあるLisp (Scheme)がいいかもしれません。

postd.cc

さいごに

関数型プログラミングといいつつ、ほとんどパイプ演算子高階関数の話しかしていない記事になってしまいました。

とりあえず、私がいいたいことは次の4つです。

  • パイプ演算子を使うと、「データの変換」としてRのプログラムを記述できる
  • パイプ演算子R言語独自の特殊な機能ではない(ElixirやF#では昔から使われている)ので心配せずにガンガン使おう
  • Rのプログラマーに必要な関数型言語の知識のレベルは、ひとまずそんなに高くないし、高階関数をきちんと理解すればOK
  • purrr最高!一番好きなRのパッケージです

また、ここまで書いて気づいたのですが、ここまでRのコード例が一行も出ていません。 実際にパイプ演算子を使ったRの分析コード例が見たい場合は、こちらの記事を読みましょう!(投げっぱなし)

uribo.hatenablog.com

明日のR Advent Calendarは@yutannihilationさんのtidyverseについての記事です。 purrrの記事いつも読ませていただいてます。 楽しみにしています。

【Python】はてなブログのOAuth認証でブログを自動投稿するスクリプトを書いた

不動産関連のニュースを自動でスクレイピングで集めていたのですが、 Python2から3に移行する際にOAuth認証に移行しようとして、ずっと面倒でサボっていました。

Rubyでは、既にgemの形で実装している方がいました。記事の内容も素晴らしかったし、コードも読みやすく、勉強させていただきました。

blog.kymmt.com

ちなみにACCESS TOKENやACCESS TOKEN SECRETの取得時にスクリプトを利用させてもらいました。ありがとうございます??

get_access_tokenコマンドで、「承認を求める操作」のスコープを全部ONにしなければACCESS TOKENを発行できない仕様だったので、 時間のあるときにスコープも指定して認証できるようにするプルリク送ろうと思います。

さて、Pythonでは以下のようなコードになりました。

ひたすら面倒だと噂のOAuth認証requests-oauthlibライブラリと、 最初の取得は先のRubyスクリプトで終わらせてしまったため、あまり勉強にはならなかったかも…。

また、自分も余裕があるときにPythonのライブラリにしたいですね。

はてなブログAtomPub - Hatena Developer Center

多分「スクレイピングした結果をデータベースに入れて、Webサイトを作る」というのがエンジニアのあるべき姿だと思うのですが、 私には今のところそこまでの根気はありません…。

【Python】PyPIに『pychatwork』を公開しました

以前練習で作ったライブラリを、仕事でも後輩のタスクで使うようになった(らしい)ので、PyPIに公開してインストールできるようにしました。

pypi.python.org

登録手順など、こちらのページを本当に助けられました。ありがとうございます。

qiita.com

テストコードやSphinxドキュメント生成もやってみたかったのですが、ちょっと面倒になってしまってやってませんw

コードやひどい面が多いと思いますので、お気づきの点があればプルリク or ご指摘お願いしますm( )m

【Python】データサイエンティストのためのPython開発記事紹介

後輩が数値計算を使う、簡単なバッチ処理Pythonで書き始めました。

一応私もPythonの知識ならそれなりにあるのでいろいろ教えられることは(まだ)あります。 そのための予行練習としていろいろまとめておきます。

正直、自分よりもっと数値計算やプログラミングに関する知識と経験豊富なエンジニアがいれば、 彼ももっといろいろなことができるようになっているんじゃないかと思ってしまい、申し訳なさを感じています。

Pythonの言語のイディオムを覚えよう

まずは、道具であるプログラミング言語を使いこなせるようになりましょう。 おすすめは『Pythonチュートリアル第3版』です。

Pythonチュートリアル 第3版

Pythonチュートリアル 第3版

WEBでも内容が公開されています。

Python チュートリアル — Python 3.5.2 ドキュメント

内容は割と被りますが、『Dive into Python3』も素晴らしい資料です。こちらのほうが若干内容が高度です。

Dive Into Python 3 日本語版

numpyのベクトル演算を使いこなそう

既にRのベクトル演算を使いこなしているので基本的には問題ないと思いますが、 一部のコードでpandasのデータフレームをイテレーターとして回していたり、 もっと効率の良い&読みやすいコードが書けるんじゃないかと思っています。

(レビューする際、ロジックの細かいところまで見れていなくてゴメンナサイ…)

Pythonの数値計算ライブラリ NumPy入門 « Rest Term

関数型言語をひとつ勉強して、mapfilterreduceが使いこなせるようになれば、 ベクトルや行列演算も自然に使いこなせるようになるでしょう…が、けっこう負担が大きいかも…。

パッケージ化しよう

Rの記事ですが、パッケージ化するメリットはこちらの記事にまとめられています。

Rのコードをパッケージの形で管理すると、次のような利点があります。

  1. 他の人へのコードの共有が簡単になる(コマンド1つでインストールされる!)
  2. 実行結果が、環境に依存せず再現する(reproducible)ことが担保しやすくなる
  3. 規約に従うことで、本質的な実装に集中しやすくなる

Rのパッケージは上記 1, 2 の利点を実現するために、「テンプレートやさまざまな規約(convention)」を採用しています。一見きゅうくつに思えるかもしれませんが、こうした実装上の決め事に従うことにより、開発者はファイルの適切な配置に迷う必要がなくなり、本質的な処理の実装に集中しやすくなるのです。

ところが、歴史的な経緯(?)によって標準的なパッケージ管理・開発の方法のやり方の方法の情報が錯綜していて、正直自分にもどういうやり方がいいのかよくわからないです。

(完全に余談ですが、最近Elixirで遊んでいて、hex new xxxというコマンドでプロジェクトの標準的なディレクトリ構成が作られ、そのままスムーズにパッケージ開発できることを知って驚きました。Pythonでもこういう仕組みが欲しいですね。)

ひとまず、以前WACODE(わこうど)夏期講習チュートリアルで使われていたリポジトリを参考にすると良いでしょう。

github.com

qiita.com

単体テストSphinxドキュメントを書こう

パッケージ化する中で、単体テストとドキュメントを書いておくと、運用や引き継ぎが楽になると思います。 また、これらはWEB APIバッチ処理を書く際にも使えます。

Pythonには標準で添付されているunittestライブラリで単体テストが書けます。

adtech-blog.united.jp

テストにもいろいろなレイヤーがあるので、「機械学習のロジックの精度の検証までできるの?」と思うかもしれませんが、それは無理です。 交差検定とか、実データ流してテストするとか、そっちの知見が必要です。

unittestはすごく雑にいうと、値のif文での条件の網羅のし忘れ等のポカミスを防げます。 また、「どんな入力が想定されているのか」という仕様書のような役割もしてくれます。

もちろん、人が書くものなので、どんな入力データ(例えば境界値)を入れればいいかといった、基本的なソフトウェアテストの知識は必要です。

知識ゼロから学ぶソフトウェアテスト 【改訂版】

知識ゼロから学ぶソフトウェアテスト 【改訂版】

「そんなのJupyter notebookで試しているから大丈夫だよ」と思うかもしれませんが、だんだんコードが大きくなるに従ってつらくなるはずです。 また、今後運用していく中で、言語やライブラリのバージョンを上げた際に、異常を見つけるのにも役立ちます。

また、ドキュメント生成にはSphinxというツールを使うのが一般的です。

qiita.com

sphinx-users.jp

実行速度の早い言語も習得しよう

なんとなく感じていると思いますが、Pythonはそれほど早い言語ではありません。

コアの計算ロジック部分だけCやC++で書くという選択肢もあると思います。今からやるならJuliaもいいかもしれません。

…が、このあたりは私の経験不足のせいでアドバイスできるほどの知識は持っていません。

開発側の知識も持っておこう

もはやPython関係ないですが、今作っているような最適化のアルゴリズムを、 巨大なサービスに埋め込むのは大変な苦労がかかることは想像できると思います。

そんなとき、簡単にWeb APIや小さいプログラムに分けて、簡単に差し替えできるように作るべきです。 また、おそらく分析結果のロジックを、簡単にデプロイできるようなサービスやソフトウェアも増えてくると思います。 (既にいいものがあるかもしれません。) 「マイクロサービス」とか「サーバーレス」とかその辺のワードのニュースを追っておくと良いかもしれません。

そういうものが出てきた際に困らないように、ニュースを追っておきましょう。 多分、フロントエンドより、バックエンドやミドルウェアの知識が必要になると思います。

全て自分ひとりでできるようになる必要はないと思います。どちらかというと開発者側とのコミュニケーションのために知っておいたほうがいいです。

【Python】pip installで突如UnicodeDecodeErrorが出始めたので対処した

Github上にアップした自作のPythonモジュールをインストールしようとしたところ、UnicodeDecodeErrorが出てしまいました。

$ pip install --upgrade git+https://github.com/takeshi0406/twlist_to_urllist
Exception:
Traceback (most recent call last):
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/commands/install.py", line 272, in run
    with self._build_session(options) as session:
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/basecommand.py", line 72, in _build_session
    insecure_hosts=options.trusted_hosts,
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/download.py", line 329, in __init__
    self.headers["User-Agent"] = user_agent()
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/download.py", line 93, in user_agent
    from pip._vendor import distro
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/_vendor/distro.py", line 1051, in <module>
    _distro = LinuxDistribution()
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/_vendor/distro.py", line 594, in __init__
    if include_lsb else {}
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/_vendor/distro.py", line 922, in _lsb_release_info
    stdout, stderr = stdout.decode('ascii'), stderr.decode('ascii')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 22: ordinal not in range(128)
Traceback (most recent call last):
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/bin/pip", line 11, in <module>
    sys.exit(main())
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/__init__.py", line 233, in main
    return command.main(cmd_args)
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/basecommand.py", line 251, in main
    timeout=min(5, options.timeout)) as session:
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/basecommand.py", line 72, in _build_session
    insecure_hosts=options.trusted_hosts,
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/download.py", line 329, in __init__
    self.headers["User-Agent"] = user_agent()
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/download.py", line 93, in user_agent
    from pip._vendor import distro
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/_vendor/distro.py", line 1051, in <module>
    _distro = LinuxDistribution()
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/_vendor/distro.py", line 594, in __init__
    if include_lsb else {}
  File "/home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/pip/_vendor/distro.py", line 922, in _lsb_release_info
    stdout, stderr = stdout.decode('ascii'), stderr.decode('ascii')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 22: ordinal not in range(128)

「Anacondaを使っているせいでは?」「サーバーの文字コードの設定がおかしいのでは?」とも疑ったのですが、以前は同じサーバーで動作していたし、そもそも通常のPythonでも同様の現象が置きており、pip自体のバグのようでした。

エラー文に従い、site-packages/pip/_vendor/distro.pyの922行目を

        stdout, stderr = stdout.decode('ascii'), stderr.decode('ascii') 

から

        stdout, stderr = stdout.decode('utf-8'), stderr.decode('utf-8') 

に書き換えたところ、動作するようになりました。(標準出力や標準エラー出力を処理している箇所のようでした。)

どうやら、pipのバージョンを上げた際に動作しなくなっていたようです。

$ pip --version
pip 9.0.0 from /home/takeshi/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages (python 3.5)

11月8日追記

issueとして報告しようと確認したところ、既にpip9.0.1のバージョンでこの問題は解決されていました。

github.com