FSharpでWebスクレイピング

wikia.comの艦これのデータを取得してみました。昨日のソースコードだとCSVに形式にできましたが、カラムのずれがありました。wikia.comのHTMLでは日本語名と英語名を分けて書かずに改行を使って書いていたり、イギリス艦はカタカナ表記がないので、泥臭く調整する必要があります。

001

 

SQLite3に取り込んでみる。

CSVファイルが正しいかどうかはデータベースで取り込んでみるのが手っ取り早いのでsqlite3にインポートしてみます。

sqlite3のコンソールを初めて使ったのですが入門情報が豊富なので問題ありませんでした。sqlite3のzipを回答したらsqlite3.exeがあるので、powershellから適当なファイル名(kancolle.db)でデータベースのコンソールに入ります。あとはデフォルトの区切り文字が(|)なので、.separator , でカンマに変更して、つくったcsvファイルを流し込みます。

002
DBBrowser for SQLiteで確認できた!

まとめ

インターネットのHTMLファイルから、データを取得してCSVファイルを作成し、データベースに格納するところまでできました。wikiなどのデータは手入力も多いため規則性がない場合は泥臭いところをしなければいけない場合も多いです。

関数型言語を道具として使う

今回は、PythonやBashで出来ることをF#でやってみました。文法を勉強しているときは全く感じなかったのですが、実際に実用的なアプリを作ってみると、C#の.NETのコードをそのままぶち込めたりして、思った以上にUnityやC#で学んだ知識をそのまま使っていけるのが分かりました。逆に.NETのAPIで、F#のインタフェースを用意していないのに驚きました。

F# Interactiveを使う開発は、Bash/Sed/Awkなどでやる泥臭いテキスト作業やコンソールでの開発と同じスタイルで、C#やJavaと同等の開発スタイルを想像していたのでこれも大きな発見でした。

次回はせっかくなので、作ったCSVまたはSqliteのデータをPHPかJavaでインターネット上に公開しようと思います。

 

FSharpでWebスクレイピング

最近、関数型プログラミング言語のF#を使っていますが、せっかくなのでWebスクレイピングをしてみました。F#Dataは、HTML CSS Selectorsも実装中なので、これが使えれば簡単にデータが取得できそうです。今回は、HTMLParserを使ってみました。

今回の目標は、艦隊コレクションのデータをテーブルとして作成して、複数のカラムでソートできるようなWebアプリを作ってみようと思います。本当はバックエンドをF#にしたいのですが、予算などの関係でPHPかJavaScriptのみです。データはひとまずkancolle.wikia.comからF#でデータを取得してみます。

とりあえずできたソースコード

Visual Studio 2015のNuGetでFSharp.Dataをインストールして、参照設定を右クリックして[Generate References for F# Interactive]をクリックすると、Scripts/load-project-debug.fsxファイルが作成され、これを#loadディレクティブでロードすれば、プロジェクトの参照設定をすべて読み込むことができます。

 

今回、コンソールでWebスクレイピングによりHTMLを取得して、CSVに加工するツールを作成してみました。実装はすこし関数型を意識するため、副作用のあるコードは MySideEffectsモジュールに詰め込むようにしました。

大半のアプリは、副作用だらけ

副作用のあるコードは MySideEffectsモジュールに詰め込むように意識して、はじめて分かったのですが、私たちが普段使ったり開発するソフトウェアは思った以上に副作用が多いです。ゲームや携帯アプリ、Webアプリなどはユーザー操作やデータ入出力が大半なので、副作用のかたまりです。

今回のプログラムを書き、F#Dataのソースコードを少しみたりしていて感じたのですが、F#は.NETのAPIがC#と同様使えるので、関数型プログラミング言語としてはHaskellなどにくらべてかなり緩いのかもしれません。プログやメディアの記事では、関数型言語といえば、参照透過性!副作用!モナド!とよく言われますが、.NETAPIとパイプライン演算子使いやすいし、F# InteractiveにAlt+Enterで流し込める手軽さがあるので、もう少し気楽に関数型言語を使ってもいいのかもしれません。

F#でfsファイルを使うときにF# InteractiveにDLLライブラリーをロードさせる方法

参照設定しているライブラリーをF# Interactiveにロードする方法

ソリューションエクスプローラーからプロジェクトを展開して、その中の[参照設定]でコンテキストメニューを右クリックで表示して、[参照をF# Interactiveに送信]で可能です。

a03
参照設定のライブラリーすべてをロード

FParsecライブラリーは、FParsecCS、FParsecの順番にロードする必要があります。このような場合は、ライブラリーを一つずつ選択して[F# Interactiveに送信]で可能です。

a04
ライブラリーを個別にロード

F#の実行形式

F#は、fsxファイルというスクリプト形式と、fsファイルというC#やJavaなどのコンパイル形式があります。fsファイルの場合はC#と同じように、プロジェクトに参照設定を追加して、緑の▶実行ボタンを押したら、参照設定のライブラリーを読み込みます。

ただし、F# Interactiveは、fsi.exeをVisual Studio Community 2015で呼び出しているだけのためプロジェクトの参照設定を自動でロードしてくれたりしません。なので、以下のソースコードのように他のライブラリー(ここではFParsec)をNuGetで参照に追加した場合、Visual Studioの緑の▶実行ボタンではどうするけれど、F# Interactiveではエラーが出てしまいます。

上記をエディター上でCtrl+Aで全選択して、Alt+Enterで、F#Interactiveに流し込むと以下のエラーが出てしまいます。

一番最初に紹介した[参照をF# Interactiveに送信]以外にも、[ツール]->[オプション]でオプションダイアログを表示して、F# Interactive オプションで、-rオプションによる指定も可能のようです。

001

 

もっと楽にfsxファイルでライブラリー管理をしたい

今回[参照をF# Interactiveに送信]を見つけたのですが、それ以外にもコンテキストメニューに[Generate References for F# Interactive]を見つけました。これを実行すると、Scriptsフォルダーに自動生成してくれるので要調査です。

 

関数型プログラミング言語F#で赤黒木アルゴリズムに挑戦

gihyo.jpの[入門]関数プログラミング―質の高いコードをすばやく直感的に書ける!第4章 木構造とハッシュ―平衡二分探索木「赤黒木」で知る豊かなデータ型 をF#でやってみました。

この赤黒木は、複雑なため上記の記事では検索と登録のみの実装でした。赤黒木を実装して分かったのですが、問題のパターンが確立していてコードに落とせる場合は、関数型言語の代数的データ型とmatch式と相性がすごく良いことが分かりました。

このソースコードではinsert関数でデータを登録後に、balance関数でデータが平衡になるようにします。木を平衡にする方法は4つのパターンが確立されていて、「このパターンだったらこれに変換」というになっています。このようなパターン化されたものは、関数型プログラミング言語の判別共用体型でデータ構造を用意し、match式状態を網羅して実装していくと非常に効率よく実装できるようです。

正直balance関数は写経しただけですが、問題をデータ構造とmatch式にうまく合わせる感覚が分かりました。もしかするとライフゲームは生存や死にセルの規則性があるので、相性が良いのではないかと思います。

 

 

 

F#で二分探索木を作る

平衡(へいこう)二分探索木を作る前に、F#で二分探索木を作ってみました。二分木と二分探索木という言葉があって、二分木はデータ構造のことです。F#だとかなり簡素で以下のようになります。

二分探索木は、アルゴリズムのことで、自分の値と、これから木に追加する値を確認して、小さい場合は左側の子供として配置して、大きい場合は右側の子供として配置します。

ソースコード

F#だと{}だけの行がないためかなり短いコードになりました。match式の書き方を変えたりしてさらに短くできますが見やすさのためこのままにしました。

次回は、平衡二分探索木の赤黒木に挑戦してみます。

最長重複文字列問題をF#でとく

gihyo.jpの [入門]関数プログラミング―質の高いコードをすばやく直感的に書ける! 第3章 リストと文字列―最長重複文字列問題で知るリストプログラミングをF#でやってみました。

ソースコードを載せる前にいろいろ感じたことを書いてみます。

問題がすごくよかった

この最長重複文字列問題は、関数型プログラミングに慣れていない人にとって非常によい問題でした。最初に概要と小さく関数を作っていくフロー図の説明をしてもらい、実際に丁寧な説明を見ながら一つ一つの関数を小さく作っていき、最後に合成関数で束ねました。

関数型言語をはじめると練習問題でsum関数を書いてみたりフィボナッチ数列を書きますが、このぐらいの問題だとグローバル変数やインスタンス変数の影響を受けない関数のメリットは分かりますが、小さな関数をどのぐらいの粒度で作るのかと、それを合成するメリットがぼんやりとしかみえませんでした。

この問題をやると、「たしかにこのぐらいの粒度で引数にしか影響を受けない関数を作っていけば、すぐ他の部品として使える」と感覚が掴めてきました。

開発スタイルの違い

私はあまりスクリプト言語の経験がなく、JavaやC#のような言語で統合開発環境上でデバッガーでブレイクポイントを立てる開発スタイルに慣れています。正直デバッガーを使わないのに抵抗がありました。

Visual StudioでF#でプログラミングをする場合は、型を書かないのに型推論で、コード編集中にエラーが出てくれるので、これは本当にJavaやC#をやっている人に合ってます。手軽にALT+Enterキーで試せるので、小さな関数を書いて、すぐテストコードを複数書いてというのを早いサイクルで繰り返すことができました。JavaScriptで開発するときは、Chromeで開発ツールを立ち上げてそこでいろいろ試したりもしますが、その場合もC#同様デバッガーを使うので、F#はそれ以上に手軽さを感じました。

私の場合は、仮想端末上で、Bashでちょっとコードを書いているとき、例えばfindやawkやsedを少しづつコード書いてそれをすぐ試すという時や、SQLをいろいろ試しているときと同じ感覚でした。

ソースコード

以下は綺麗に整えたソースコードです。F#のList.zipは要素数が一緒でなければならないため、ziph’という関数を用意しました。コードはstackoverflowなどを参考にしました。ところどころ引数の定義時にstringやchar listの型指定をしているので、綺麗にすることが今後の課題ですが、動いているので良しとします。

作業中のソースコード

実際にプログラミングをしているときは、ファイルは手書きのメモ帳のような感覚で、書いては消してを繰り返して、すぐ下にテストを書いてました。

 

 

F#でMapを書いたりしてみました。

[入門]関数プログラミング―質の高いコードをすばやく直感的に書ける!第2章 関数プログラミングのパラダイム―命令プログラミングと何が違うのか 」Gihyo.jpのHaskellの入門記事ですが、Haskellを勉強するのは時間がかかりそうなので、F#で第2章を実装してみました。

 

Haskellでは文字charのリストは文字列なので操作がしやすそうでした。F#だと別のようです。

 

Windows10にStack+ATOMのHaskellの環境構築

Gihyo.jp – [入門]関数プログラミング―質の高いコードをすばやく直感的に書ける! の第4章、第5章が気になったのでWindows10にHaskellの環境を構築してみました。Qiitaのhttp://qiita.com/igrep/items/da1d8df6d40eb001a561を見ながらインストールしたのですが、いろいろ調べるとhttps://haskell-lang.org/get-started をみるのがよさそうです。

Stackとは

Haskellは、JavaScriptのnode.jsやnpmのようなプロジェクト構築をするstackというのが最近でているようです。公式でインストーラーがあるのでそれでインストールできます。

STACK_ROOTについて

2016年11月現在、stackのインストーラーでは、STACK_ROOT=C:\srを環境変数に設定するかどうかのラジオボタンがありました。なのでインストーラーを起動する前にSTACK_ROOT環境変数は設定する必要はないのかもしれません。

stack.exeやghc-mod.exeをインストールした時の場所

私はいつここにPATHを指定したかわかりませんが、ここにstack.exeが配置されて、PowerShellからstackコマンドが使えるようになりました。

プロジェクトの開始

stack buildをやるとコンパイラーがないのでstack setupをしてくださいを言われるので実行して、問題なくビルドと実行ができました。10分は待たされないと思いますが、コンパイラーのダウンロードなりでそこそこ時間を取られます。

ファイルの変更監視(watch)

–file-watchオプションで変更監視ができました。これはhttps://haskell-lang.org/get-startedを見てわかったのですが、やはり私を含めて初心者はコンパイラーで実行するほうが良いので、一度上記URLでコンパイラー実行する方法を見ておいたほうが良いです。

以下にstackをインストールしたときのコマンドの書き方が載ってました。

https://haskell-lang.org/tutorial/stack-script

HelloWorld.hs

コンパイル

省略した書き方

これでHelloWorld.exeができました。

スクリプトとして実行する場合は、runghcに書き換えれば行けそうです。

ghc-mod,hlint,stylish-haskellのインストール

よくわかってませんが、Qiitaで書いてあったエディターのATOMで使いそうなツールをいくつかインストールしました。これらは%HOMEPATH%\AppData\Roaming\local\binに配置されるため、powershellから問題なく起動できるようです。

おそらく、ATOMの拡張機能でPATHを通すときに必要になると思われます。

ATOMのパッケージ

ATOMのパッケージはいつでもアンインストールできるので、atom-haskellが製作者になっている上位のパッケージをインストールしました。

  • language-haskell
  • haskell-ghc-mod
  • ide-haskell
  • autocomplete-haskell
  • ide-haskell-cabal
  • ide-haskell-repl
  • ide-haskell-hasktags

まとめ

Haskellをやるかどうかはわかりませんが、勢いでWindows10で環境構築してみました。

ベン図を書こう

関数型プログラミング言語のF#を勉強していく過程で、関数型言語はプログラミングよりも数学の集合や写像を勉強したほうが良いことが分かってきました。

もう少し具体的に言うと、数学のテストが解けるようになるのではなく、プログラミングで普段使っている、集合、Set、disjoint union、Discriminated Union、直積、直和、関数、function、マップ、タプル、などを、数学の記号、数学の読み方、XY座標、ベン図でも理解できるようにしておかないといけないと感じました。

といっても数学の勉強をしはじめると眠くなるだけなので、Python3のmatplotlibでベン図を作ってみようと思います。本当はF#でやってみたいのですがやりかたが分かりません。

Windows10で手軽なPython3環境構築

Windows10でPython3の環境を簡単に構築するには、以下だけです。

  1. Python3を公式サイトからインストール
  2. Visual Studio Code テキストエディタをインストール

Visual Studio Codeは、hello.pyなどのファイルを作ってpythonを書いていこうとすると、それを検知して、Python拡張機能インストールする?pep8インストールする?といい感じにやってくれます。なので、autopep8,pep8,pylintなどがボタン押しているだけで構築できます。

matplotlibのインストール

依存関係で、numpyなど必要なライブラリーもインストールしてくれます。

またsympyという数式処理ライブラリーもあるようです。これも必要ならpipで簡単にインストールできました。

 

追記

Windows10(64bit)+Python3.5(32bit)だと、pip install scipyでSciPyがインストールできませんでした。以下URLを参考にして、pip uninstall numpyをして、.whlファイルをダウンロードして、numpy+mklとSciPyをインストールしました。ダウンロードするファイルはたくさんありますが、cp35とかcp36と書かれているのは、CPythonつまり普通のPythonの事です。よってPython3.5(32bit)を使っている場合は、cp35-cp35m-win32.whlという末尾のファイルをダウンロードしてインストールします。

http://qiita.com/r-ngtm/items/15caf43648acbccd37d2

 

とりあえず、サインカーブ

matplotlibを使うとWindows10のPython3で簡単にベン図が書けるようなので試してみます。

001
できた!

ベン図を書いてみます

pip install matplotlib-venn

とりあえず動作テストをしてみます。

figure_1
ベン図だ!!!

 

関数型言語F#をやっているときに学んだ数学

関数型プログラミングのF#を学んでいくときに、少しずつラムダ計算と集合・写像・関係などを調べていろんなことが分かってきました。数学の教科書で問題を解こうとすると苦痛で続かないので、mathjaxを書いたり、プログラミングで解いたりして、すこしづつ数学もやっていこうと思います。

集合(set、セット)

集合は、ド・モルガンの法則やベン図で覚えている人も多いはずです。何かしらの集まりを表します。英字で表す場合は、集合を大文字で表し、要素(element、エレメント)は小文字で表します。

数学の記号は、そのままGoogle検索で、「数学 記号 読み方」で見つかります。

集合Aに要素xは属する(belong to)

$$ x \in A $$

集合Bに要素1,2,3,4,5は属する

$$ B = \{1,2,3,4,5\} $$

表記はいろいろあって以下のように条件を書く場合もあります。

$$ C =\{ n | n = 2k, k=1,2,…,10\}$$

$$ C =\{ 2,4,6,8,10,12,14,16,18,20\}$$

上記2つは同じ意味です。

部分集合

集合Aの要素が、集合Aの要素でもある場合、AはBの部分集合である。

記号で書くと、

$$ A \subseteq B $$

べき集合(Power Set)

集合Aのすべての部分集合からなる集合をAのべき集合といい、以下のような表し方をします。

$$ 2^A $$

A={a,b}なら、P(A) = { Φ, {a},{b},{a,b}}

直積集合(direct product)

$$ A \times B = \{ (a,b) \mid a \subseteq A \land b \subseteq B \}$$

Wikipediaの図が分かりやすい。直積は、direct product、デカルト積(Cartesian product)ともいう。

集合X = 1,2,3で集合Y = 5,6,7だったら、総当たりで以下のようになります。

X x Y = {(1,5),(1,6),(1,7), (2,5),(2,6),(2,7), (3,5),(3,6),(3,7)}

プログラミングだと2重のforループです。また(x,y)のような書き方を対(つい)、タプル、ペアと呼びます。

内包表記(comprehension)

数学の集合では、条件を書く方法がいろいろあります。プログラミング言語のリスト内包表記はここからきているのだと思います。

$$ A = \{x^2 | x \in  \{1..5\}\} $$

$$ A = \{1,4,9,16,25\} $$

F#ではリスト内包表記があります。

 

関係(relation)

高知工科大学の高校生向けの資料(関係を図で表現する道具(坂本 明雄))がすごくわかりやすいです。

2つの集合A、Bの直積集合A×Bの部分集合Rを関係と呼びます。それは、XY座標でも表示できるし、関係グラフ、有向グラフ、関係行列でも表示できます。

https://ja.wikipedia.org/wiki/直積集合

 

プログラミングで理解する反射律・対称律・推移律・反対称律

集合Aの直積集合A^2の部分集合をA上の関係と呼びます。A={1,2,3}だった時AxA={(1,1),(1,2),(1,3), (2,1),(2,2),(2,3), (3,1),(3,2),(3,3)}が直積集合となります。部分集合R={(1,2),(2,1),(3,3)}としたら、このRをA上の関係と呼びます。

写像(map)

先ほどのおさらい、2つの集合A、Bの集合AxBの部分集合Rを関係と呼びます。さらに、

集合Aの各要素に、それぞれBの要素がただ1つ対応している関係をAからBへの写像(map)といい微分積分の分野では、関数と呼びます。

 

非交和

https://ja.wikipedia.org/wiki/非交和

 

二項関係

論理(Logic)

論理(Logic)も同様ですが、数学のタイトルや項目を見るとちゃんと、集合と集合演算として分かれています。論理でも論理と論理演算となっていて、あらためて昔はテストの勉強のために問題を解いていただけなんだと思いました。

論理演算の英語はLogic Operation

命題関数

 

代数系

大人になってからの再学習 の★群・環・体 – 大人になってからの再学習 が分かりやすいです。数学の教科書を開く前にこの表をみてみるのが良いですね。

http://hooktail.sub.jp/algebra/FundamentalTheorem/

http://sun.ac.jp/prof/hnagano/houkoku/h26informationmath-13.html#1101

http://qiita.com/taketo1024/contributions

資料

Mathjaxの記号の書き方

http://www.mathsisfun.com/sets/index.html