/var/log/study

つまり雑記

DIとリポジトリパターンは何が嬉しかったのか?がよくわからなくなった。

まだ色々考えている途中

qiita.com

上記のページからリポジトリパターンの良さを抜粋すると以下の様な事が挙げられている

テストがしやすくなる

DBエンジンの変更に対応しやすくなる

データ操作のロジックが1箇所にまとまり、管理しやすくなる

そうだよねと思いつつ、Laravel系でリポジトリパターンに言及している別のページも見て回った. 

結果、気がついた事が一つある。基本的に返り値を言及していない。

当たり前過ぎて言及されていない前提の話しなのかもしれないが。

例えば、SQLite様に書いたリポジトリsqliteのコネクションを返し、Redis様にかいたリポジトリがredisのコネクションを返したら、リポジトリインターフェースを要求しているコードはそのDBエンジンに寄ってコードを書き換える必要が出てくる. それでは本来のリポジトリパターンの意味が薄いと思った。

DBエンジンをすげ替えられるようにpythonで書いてみた

とりあえず自分で書いてみたら答えが出るかもと思って、RedisとSQLiteと単なるモックコードを切り替えられるようにした。

以下のページの183行目で生成するクラスを変更したら使われるDBが変わるようになっている

github.com

実行結果は基本的に同じようになっているはず (だが途中でめんどくなってredisあたりのconfiguとか端折ってる)

書いてみた結論として

  • たしかにテストはし易いはず
    • DI自体は例えばコントローラーのテストの際にmodelのモックが気軽に差し込めるのは良いと思う
  • リポジトリパターンでなくても良いのでは?という気持ち
    • リポジトリパターン自体はインターフェースを統一させるための存在という認識
      • RDBMS -> RDBMS (例えば, MySQLからPostgreSQL) だけを考えるならばORMが似た事をカバーしてくれそう
      • NoSQLも同じ
        • KVSならKVS向けのwrapperがあれば良い
        • ドキュメント指向ならドキュメント指向のwrapperがあれば良い
    • NoSQLとRDBMSとではリポジトリインターフェースの互換性を維持するのがそもそも大変
      • どれくらい自前のコードで吸収するか?
      • 現実問題として、RDBMSなコードをRedisやMongoにすげ替える前に考える事がもっとありそう
  • リポジトリに持たせる実装がもう少し厚い場合考えが変わるかもしれない
    • 現状リポジトリにはどの位の責務で実装を持たせたら良いのかがわかってない
    • が、DBを操作する系のメソッドが長くなるとその実装自体がテストできなくなるので…
  • リポジトリパターンってなんだ?
    • アダプタ

ということで、本日のブログ 「DIとリポジトリパターンは何が嬉しかったのか?がよくわからなくなった。」 になる。

追加の参考

blog.comnect.jp.net

上記のリンクを見るに、自分の実装ではリポジトリパターンになっていなかった。

リポジトリ内で実装をすげ替えるより、リポジトリに対して更にクライテリアをDIするほうが責務としてはきれいに別れて良さそう.

だけど根本的な疑問として、そこまでしてRDBMSとNoSQLとの互換性を保ちたいか?と聞かれると微妙なのは変わらず.

vSphereでterraformする時のポイント

VMを立てるだけならばvagrantでも良い気がするし、色々設定するならAnsibleで事足りている.

が、仮想基盤に対してリソースを用意するための適切なツールを利用する意味で、terraformを利用してみる

入門自体は以下

dev.classmethod.jp

公式ドキュメントのvSpherプロバイダページ

www.terraform.io

ポイント

  1. providerの箇所には allow_unverified_ssl = true 記述すること
    • vSpher providerのドキュメントをパクっていくと分かる
    • vCenterあるあるの証明書の話し
  2. resource "vsphere_virtual_machine" には skip_customization = true を記述すること
    • terraformを利用すると、作成したいVMのOS上の設定までいじれるらしい
    • ただ、vSphere で利用すると vsphere_virtual_machine.es: Customization of the guest operating system というエラーが出る
    • redhat系とdebian系がダメって言うなら普通はスキップする設定にしておいたほうが無難そう
  3. いつまでたっても apply が終了しない
    • 何やら、 network_interface の項目に, labelしか記述しないと正常に終了しないらしい?
      • customizationがいじれないのに、これ以上何を記述したら良いのか (´・_・`)
    • 問題のissueは以下 github.com
    • とりあえずぶち切っても大丈夫そう

所感

  • ドキュメントを見る感じ、出来ること
    • フォルダを作る
    • VMを作成
      • VMを作るための素(新しくisoからなのか、templateからなのか)
      • ネットワークの指定
  • Ansibleとの比較
    • playbookとroleとAPIでゴリゴリ設定できるAnsibleのほうが、自由度が高く出来ることも多い
      • ポートグループを作るとか
      • NSXと連携してDFWを当てるとか
    • 正直terraformのvsphereプロバイダだと...
    • ただ、オープンソースなのでコードを書いて貢献しろと言われると確かに... と言う話し
  • HCL
    • www.terraform.io
    • 使い込んでないけどYAMLより良いと思う
      • なんとなくレベルの話し

haskell で gnuplotを利用する + 利用したときの個人的な詰まりどころ

gnuplot: 2D and 3D plots using gnuplot を利用してみた

だいたい以下のページの感じで出来る.

d.hatena.ne.jp

ただし今回はもうチョット踏み込んだことをやってみる。

用意

gnuplot等の用意は上記のページを見て欲しい。

haskellのライブラリとしてのgnuplotstackで準備できるので、プロジェクト.cabalgnuplotを追記したら良い

library
  hs-source-dirs:      src
  exposed-modules:     Lib
  build-depends:       base >= 4.7 && < 5
                     , gnuplot
  default-language:    Haskell2010

で、stack build したら怒られるはずなので、 stack solver とか stack build --modify-stack-yml とかを叩いてやれば良い

棒グラフのサンプル

module Lib
    ( someFunc
    ) where

import Graphics.Gnuplot.Simple

someFunc :: IO ()
someFunc = do
  plotPathStyle [(Title "Frequency"), (XTicks (Just ["('hoge' 0, 'huga' 1, 'piyo' 2)"]))] (defaultStyle{plotType = Boxes }) [(0::Int,0), (1,1), (2,2)]
stack ghci
> someFunc

以上で実行可能

スタイルはデフォルトのまま

f:id:yaaamaaaguuu:20170416002246p:plain

gnuplotで出来ることとしてはもうちょいいい感じに出来るはずだけど、 もう少しきれいにやるなら Graphics.Gnuplot.Advances を使う必要がある。

詰まりどころ1

まず注意しなければならないのが、 おそらく GHCiからでないと利用できない様子. ドキュメントにGHCiかHugsから使えるよって書いてある.

少なくとも自分の環境ではコンパイルが上手く行った後のバイナリを動作させても、gnuplotが起動することは無かった。

ただしstackの環境であれば、 stack ghci を実行すると src/Lib.hs のモジュールを読み込む設定が最初から書かれているので、 コードを書いてghciから実行させる形で妥協したら良いと思う。

詰まりどころ2

ghciから実行させるのは良いが、gnuplot自体はおそらく非同期でコードが実行される。 非同期で実行されるから、間違ったコードで死んでるのか、処理中なのかわかりづらい。

具体的には遅延評価される重めのlistをgnuplotに突っ込もうとすると、動いているのかどうかよくわからない問題が発生する. (自分は1~2日気づかなかった)

そんなときはtopコマンドを見れば良い。

Processes: 332 total, 3 running, 329 sleeping, 1548 threads                                                                                                                                                                          00:29:13
Load Avg: 1.97, 2.12, 2.08  CPU usage: 13.71% user, 1.45% sys, 84.83% idle  SharedLibs: 174M resident, 43M data, 48M linkedit. MemRegions: 67643 total, 5202M resident, 175M private, 3489M shared.
PhysMem: 16G used (2002M wired), 22M unused. VM: 1930G vsize, 627M framework vsize, 0(0) swapins, 0(0) swapouts. Networks: packets: 256919/208M in, 222563/26M out. Disks: 870239/13G read, 162387/6235M written.

PID    COMMAND      %CPU      TIME     #TH    #WQ  #PORT MEM    PURG   CMPRS  PGRP  PPID  STATE    BOOSTS          %CPU_ME %CPU_OTHRS UID  FAULTS    COW    MSGSENT   MSGRECV   SYSBSD    SYSMACH   CSW       PAGEINS IDLEW   POWER
12713  ghc          99.8      00:17.90 5/1    0    14    1778M  0B     0B     12700 12700 running  *0[1]           0.00000 0.00000    501  525572    1375   70        34        150746+   3997      15304+    59      316     99.8

ghcがCPU利用率100%で張り付いているって言うことは、裏で頑張って処理しているんだな。ってことが分かる

入門自然言語処理 第1章

2017年度上期目標達成プロジェクトの第1週目

方針

  • 本はpython2だがpython3で通す
  • 本を読んでpython3対応するのがめんどくさくなったら以下を読む

python2 -> python3 のマイグレーション

  • nltk.download() がさっくり動かない
    • 止まった所はちまちまダウンロードする
    • それでも1こだけダウンロードできなかったやつがある
      • 一旦無視 こまったら考える
  • nltk.text.Text の generateメソッドが使えない
  • python3の dict_keys でindexへのアクセスができなくなってる
  • nltk.probability.FreqDist でplotした時の縦軸が%ではなく単語の総数となっている
    • 英語サイトを見たら、%表示では無くなってるのでまぁよしとする
      • (が,正直, plotした時の値は%軸の方が良い気がする)
  • bigrams関数が無い
    • from nltk.util import * で使えるようになる
      • generatorなのでforで回す

雑なメモ

  • 語義曖昧性解消
    • 文章内の単語と単語をくっつけて、文章の意味を正しく解釈する
  • 代名詞解析
    • 文章の流れから代名詞(theyとか)を正しく推測する
  • 言語出力の生成
    • 問に対する答えを作る?
  • 機械翻訳
  • 音声対話システム
    • bot的なもの
    • 知っている?という問いに対してyes no ではなく, 推論して解答を返す
  • 含意関係
    • 1つの文章から, 別の文章の真偽をチェックする

雑な感想

  • たしか大学の教科書って聞いてた
    • pythonの基本的な説明が多い
    • 個人的には不要
    • 初心者にはありがたいかもしれないが、python2なので改定が必要そう
  • python3でも意外と動いたり動かなかったり
  • 言語処理100本ノック
    • 1日1問くらいで、現在30問目くらい
    • 100本ノックの際はnltkがアレばだいたいokでは?って思えた
      • 便利
        • bigrams
        • collocations
  • nltk.chat.chatbots()が面白い
    • Iesha (teen anime junky)
    • が中身はちょっとしょぼい?
  • 各章ごとに演習問題がついている
    • 2章からは取り組もうとおもう
      • 正直pythonの基礎文法をやるのは怠いので

haskellで空文字列を指定するときの方法

タイトルのまんま。

結論

“\NUL"を使うと良い

発覚までの流れ

pcre-heavy: A regexp library on top of pcre-light you can actually use.

上記のライブラリを使って正規表現でマッチさせて置換しようと思った時の話

具体的な実行したいこと

現在の国号「'''グレートブリテン及び北アイルランド連合王国'''」に変更 から ' を取り除き

[[スターリング・ポンド|UKポンド]] (&pound;)UKポンド (&pound;) にしたいとき

抽象的にすると

  • ' を取り除く
  • [ を取り除く
  • ] を取り除く
  • [[$some_word| を取り除く

バグるパターン

gsub [re|('+|\[\[.*\||\[+|\]+)|] (""::String) x

これだと中途半端に動くのがタチの悪いところ

うまくいくパターン

gsub [re|('+|\[\[.*\||\[+|\]+)|] ("\NUL"::String) x

空文字列を指定するときは \NUL を使う必要がある模様. ただしHaskell的には常識的な話なのかもしれない.

どこかのwebサイトで, \NUL を指定しているのを見つけて試したらうまくいったのだが, どこのサイトなのかがわからなくなってしまったのが残念.

2017年度上期の目標

目標

入門 自然言語処理

入門 自然言語処理

半年かけて、上記の本を通そうと思う.

出来れば土日のどちらかで1.5hくらいを使って取り組みたい.

目標設定の基準は、現在自分がプライベートで取り組んでいること(直接業務とは関わりのないこと)で選んだ.

思ったこと

学年制と単位制 - Wikipedia

wikipediaを眺めると,大学の1単位は45時間の学習が目安らしい. とはいえ、実際には22.5時間で2単位でてる.

仕事をしつつとは言え, 業務とは関係のない話題を毎週1.5時間の学習が無理なのか?と問われると… 実際は可能な気もする.

最近の出来事として

write code everyday に感化されて, ハードルを低く*1, 1日1問プログラミングで問題を解くことをしてみている.

現在解いている問題は以下.

www.cl.ecei.tohoku.ac.jp

まだ初めて3weekしか立ってないので、この活動はもう少し続いたらまとめるつもり

*1:wirte code everyday の記事を読む限り, 毎日コードを書きましょうと言う意図より, 毎日ソフトウェアを開発しよう!って感じが読み取れた. 個人的に毎日ソフトウェアを開発し続けるのは様々な面で難しいと思ってる.

OSX上のHaskell stackでMecabを扱う方法

本文章は以下に書いてあることを抽出して纏めた記事である.

qiita.com

haru2036.hatenablog.com

github.com

問題点

自分のOSX環境では、なぜかHaskellからMecabを利用することができなかった

解決できたサンプルリポジトリ

github.com

git clone https://github.com/shouhei/mecab-sample-hs.git
cd mecab-sample-hs
stack build
stack exec mecab-sample-hs-exe

以上を叩くと

隣      名詞,一般,*,*,*,*,隣,トナリ,トナリ
の      助詞,連体化,*,*,*,*,の,ノ,ノ
客      名詞,一般,*,*,*,*,客,キャク,キャク
は      助詞,係助詞,*,*,*,*,は,ハ,ワ
よく    副詞,一般,*,*,*,*,よく,ヨク,ヨク
柿      名詞,一般,*,*,*,*,柿,カキ,カキ
食う    動詞,自立,*,*,五段・ワ行促音便,基本形,食う,クウ,クウ
客      名詞,一般,*,*,*,*,客,キャク,キャク
だ      助動詞,*,*,*,特殊・ダ,基本形,だ,ダ,ダ
EOS

上記の様な出力になるはず

解決方法

stack.ymlを以下を追記する

packages:
- '.'
- location:
    git: git@github.com:morishin/hsmecab.git
    commit: 2da6677fbd42bb77d3b6e61c02edfeebe248e184
extra-include-dirs:
- /usr/local/Cellar/mecab/0.996/include/
extra-lib-dirs:
- /usr/local/Cellar/mecab/0.996/lib/

次にproject.cabalに以下を追記

library
  hs-source-dirs:      src
  exposed-modules:     Lib
  build-depends:       base >= 4.7 && < 5
                     , mecab
  default-language:    Haskell2010

でもって、 stack build すると問題なく使えるようになるはず

問題を時系列に追う

  1. stack でmecabがインストールできない
Could not parse '/path/to/mecab-sample/stack.yaml':
AesonException "failed to parse field 'packages': failed to parse field 'location': when expecting a PackageLocation, encountered Null instead"
See https://github.com/commercialhaskell/stack/wiki/stack.yaml.

tanakhさんの作ったmecabバインディングではダメらしい

qiita.com

  1. githubのforkを利用する

インストールは出来るんだけど、OSX的にダメらしい

haru2036.hatenablog.com

Enter passphrase for key '/Users/shouhei/.ssh/id_rsa':
Warning: File listed in mecab-sample.cabal file does not exist: README.md
mecab-0.4.0: configure
mecab-0.4.0: build
mecab-0.4.0: install
mecab-sample-0.1.0.0: configure
mecab-sample-0.1.0.0: build
Completed all
--  While building package mecab-sample-0.1.0.0 using:
      /path/to/.stack/programs/x86_64-osx/ghc-7.10.2/bin/runhaskell -package=Cabal-1.22.4.0 -clear-package-db -global-package-db -package-db=/path/to/.stack/snapshots/x86_64-osx/lts-3.13/7.10.2/pkgdb/ /var/folders/lk/jk8fbl3s4
qgc7fzz7r3wxn300000gn/T/stack28485/Setup.hs --builddir=.stack-work/dist/x86_64-osx/Cabal-1.22.4.0/ build exe:mecab-sample-exe --ghc-options -hpcdir .stack-work/dist/x86_64-osx/Cabal-1.22.4.0/hpc/.hpc/ -ddump-hi -ddump-to-file
    Process exited with code: ExitFailure 1
    Logs have been written to: /path/to/mecab-sample/.stack-work/logs/mecab-sample-0.1.0.0.log

    Configuring mecab-sample-0.1.0.0...
    Preprocessing library mecab-sample-0.1.0.0...
    [1 of 1] Compiling Lib              ( src/Lib.hs, .stack-work/dist/x86_64-osx/Cabal-1.22.4.0/build/Lib.o )
    In-place registering mecab-sample-0.1.0.0...
    Preprocessing executable 'mecab-sample-exe' for mecab-sample-0.1.0.0...
    [1 of 1] Compiling Main             ( app/Main.hs, .stack-work/dist/x86_64-osx/Cabal-1.22.4.0/build/mecab-sample-exe/mecab-sample-exe-tmp/Main.o )
    Linking .stack-work/dist/x86_64-osx/Cabal-1.22.4.0/build/mecab-sample-exe/mecab-sample-exe ...
    Undefined symbols for architecture x86_64:
      "_mecab_get_all_morphs", referenced from:
          _cdn2_info in libHSmecab-0.4.0-0HRiBJmaGDO9FQQzxhViZD.a(MeCab.o)
      "_mecab_get_partial", referenced from:
          _cdly_info in libHSmecab-0.4.0-0HRiBJmaGDO9FQQzxhViZD.a(MeCab.o)
      "_mecab_get_theta", referenced from:
          _cdpg_info in libHSmecab-0.4.0-0HRiBJmaGDO9FQQzxhViZD.a(MeCab.o)
      "_mecab_set_all_morphs", referenced from:
          _cdSu_info in libHSmecab-0.4.0-0HRiBJmaGDO9FQQzxhViZD.a(MeCab.o)
      "_mecab_set_partial", referenced from:
          _cdWY_info in libHSmecab-0.4.0-0HRiBJmaGDO9FQQzxhViZD.a(MeCab.o)
      "_mecab_set_theta", referenced from:
          _cdVy_info in libHSmecab-0.4.0-0HRiBJmaGDO9FQQzxhViZD.a(MeCab.o)
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
 2 action
  1. ググったらcabal install のときにパラメータを指定する必要があるとのこと 

  2. cabalのパラメータをstackで実現するには?

github.com

  1. ドキュメントをみて解決