Firefox QuantumでTree Style Tabを使う時タブバーを消したかった

マッコウクジラは鯨の中でも特に深海に特化した進化をしていて、海面で息継ぎをしてから3000メートルを一気に潜ってしまうそうです。頭部にびっしり詰まっている脳油を海水と血液で冷やしたりし温めたりて比重を変えることで潜ったり浮いたりする様は、潜水艦よりも高度とさえ言えるのかもしれない。

さて、最近爆速になって登場したFirefox Quantumを使っているのですが、WebExtension版のTree Style Tabを使っていても画面上の方にタブバーが一緒に出てきてしまって邪魔でした。

基本的には
Firefox Quantum(57以上)で上部のタブバーを消す – Qiita
の通りなのですが、それだけだとなぜか動かなかったので、もう少し調べた結果出てきたこちら
Firefox Quantum (ver >= 57) – How Can I Hide the Horizontal Tab Bar with TreeStyle Tabs? – Super User
を適用すると動きました。

合わせると、新規作成するuserChrome.cssには次のような内容を書けばOKです。

@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
#tabbrowser-tabs {
  visibility: collapse !important;
}
#sidebar-header {
  visibility: collapse;
}

Macだとちょっとだけウィンドウのタイトルバー?がおかしいですが、困るものではないのでまぁいいでしょう。

完全に自分用メモ。

cupyで2次元ガウス窓を生成する

8000メートルなどを超えるような超深海では、超高圧のためタンパク質の構造自体が保てなくなる(水分子が侵入し破壊される)ことから、通常の構造の延長としての生物は生息できないのだそうです。そこにいる生物は、TMAOという物質がもつタンパク質に侵入する水分子をブロックする性質を利用して生きているのだとか。したたかです。

さて、Pythonを使って2次元のガウス窓を生成したくなりました。
1次元でのscipy.signal.gaussianの多次元版にあたるものです。

具体的には、画像として描画するとこんなかんじになるような配列の生成が目的です。

Continue reading

Dashにchainerのドキュメントを登録する

魚について調べる時、(Wikipediaもいいんですが)FishBase : A Global Information System on Fishesとかは結構分量も凄くて、英語中心ですがときどき役に立ちます。

さて、Macを3年ぐらい使ってきてて恥ずかしながらわりと最近までドキュメントのインクリメンタルサーチができるDashを知らなかったんですけども、ちょっと前から使うようになりました。仕事や趣味でChainerを使うんですが、ChainerのドキュメントはDashで提供されてないので、自分でドキュメントをDash用に変換する必要があります。

とは言えChainerはSphinxでドキュメントが書かれているので、doc2dashというpipを使えば一発でできます。

なのですごい簡単なんですが、環境を新しくする度にやり方を調べてやってる気がするので、メモ。
別にchainer限定ではなくて他の何にでも当てはまる一般的な話なんですが、あえてchainer specificな話題にしてみました。

# 準備。doc2dashを入れる。
% pip install doc2dash

# Cloneしてくる
% git clone https://github.com/pfnet/chainer.git --branch v2.0.0
% cd chainer/docs

# Optional: アイコンに使う画像をダウンロードしてくる。ここではTwitterから。
% wget https://pbs.twimg.com/profile_images/606654945438203905/D7LygzpN_400x400.png -O chainer_logo.png

# ドキュメントをビルドし、dash形式に変換
% make html
% doc2dash build/html -n chainer2 -i chainer_logo.png
# % doc2dash build/html -n chainer2   #アイコンが不要な場合

これを実行すると、chainer2.docsetというディレクトリが生成されます。Sphinx等はもちろん入っている必要があるので、怒られた場合は指示に従って入れてください。
Dashをインストール済みのMacでFinderにてこのディレクトリをダブルクリックすると、検索できるドキュメントとして追加されます。

ぼくの場合手元のMacだと、2017/7/3現在でのmasterのときsphinxのビルド(上記のmake html)がこんなかんじで失敗することがあったので、Linux環境でmakeしました。また、いきなりmake htmlするとエラーで死ぬんですがmake dirhtmlしてからmake htmlすると通ることも度々ありました。ちょっと謎。

% make dirhtml
...
...
reading sources... [ 76%] reference/generated/chainer.links.StatelessLSTM
reading sources... [ 76%] reference/generated/chainer.links.VGG16Layers
reading sources... [ 76%] reference/generated/chainer.links.caffe.CaffeFunction
reading sources... [ 77%] reference/generated/chainer.links.model.vision.googlenet.prepare
reading sources... [ 77%] reference/generated/chainer.links.model.vision.resnet.ResNetLayers
reading sources... [ 77%] reference/generated/chainer.links.model.vision.resnet.prepare
reading sources... [ 77%] reference/generated/chainer.links.model.vision.vgg.prepare
reading sources... [ 78%] reference/generated/chainer.optimizers.AdaDelta
/Users/hoge/Work/chainer/chainer/docs/source/reference/check.rst:30: WARNING: failed to import chainer.gradient_check.check_backward
/Users/hoge/Work/chainer/chainer/docs/source/reference/check.rst:30: WARNING: failed to import chainer.gradient_check.numerical_grad
/Users/hoge/Work/chainer/chainer/docs/source/reference/check.rst:30: WARNING: toctree references unknown document 'reference/generated/chainer.gradient_check.check_backward'
/Users/hoge/Work/chainer/chainer/docs/source/reference/check.rst:30: WARNING: toctree references unknown document 'reference/generated/chainer.gradient_check.numerical_grad'
/Users/hoge/Work/chainer/chainer/docs/source/reference/check.rst:43: WARNING: failed to import chainer.testing.assert_allclose
/Users/hoge/Work/chainer/chainer/docs/source/reference/check.rst:43: WARNING: toctree references unknown document 'reference/generated/chainer.testing.assert_allclose'
/Users/hoge/Work/chainer/chainer/docs/source/reference/check.rst:53: WARNING: failed to import chainer.testing.unary_math_function_unittest
/Users/hoge/Work/chainer/chainer/docs/source/reference/check.rst:53: WARNING: toctree references unknown document 'reference/generated/chainer.testing.unary_math_function_unittest'
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.Chain.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.ChainList.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.Link.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/Work/chainer/chainer/docs/source/reference/core/optimizer.rst:4: WARNING: failed to import chainer.Hyperparameter
/Users/hoge/Work/chainer/chainer/docs/source/reference/core/optimizer.rst:4: WARNING: toctree references unknown document 'reference/core/generated/chainer.Hyperparameter'
WARNING: /Users/hoge/Work/chainer/chainer/docs/source/reference/datasets.rst:57: (WARNING/2) autodoc: failed to import class 'ConcatenatedDataset' from module 'chainer.datasets'; the following exception was raised:
Traceback (most recent call last):
  File "/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/sphinx/util/inspect.py", line 169, in safe_getattr
    return getattr(obj, name, *defargs)
AttributeError: module 'chainer.datasets' has no attribute 'ConcatenatedDataset'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/sphinx/ext/autodoc.py", line 664, in import_object
    obj = self.get_attr(obj, part)
  File "/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/sphinx/ext/autodoc.py", line 554, in get_attr
    return safe_getattr(obj, name, *defargs)
  File "/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/sphinx/util/inspect.py", line 185, in safe_getattr
    raise AttributeError(name)
AttributeError: ConcatenatedDataset
/Users/hoge/Work/chainer/chainer/docs/source/reference/functions.rst:30: WARNING: failed to import chainer.functions.tree_lstm
/Users/hoge/Work/chainer/chainer/docs/source/reference/functions.rst:30: WARNING: toctree references unknown document 'reference/generated/chainer.functions.tree_lstm'
/Users/hoge/Work/chainer/chainer/docs/source/reference/functions.rst:216: WARNING: failed to import chainer.functions.layer_normalization
/Users/hoge/Work/chainer/chainer/docs/source/reference/functions.rst:216: WARNING: toctree references unknown document 'reference/generated/chainer.functions.layer_normalization'
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.BatchNormalization.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.Bias.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.Bilinear.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.BinaryHierarchicalSoftmax.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.BlackOut.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.CRF1d.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.Classifier.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.Convolution2D.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.ConvolutionND.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.Deconvolution2D.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.DeconvolutionND.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.DepthwiseConvolution2D.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.DilatedConvolution2D.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.EmbedID.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.GRU.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.GoogLeNet.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.Highway.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.Inception.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.InceptionBN.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.LSTM.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.LayerNormalization.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.Linear.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.MLPConvolution2D.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.Maxout.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.NStepBiGRU.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.NStepBiLSTM.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.NStepBiRNNReLU.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.NStepBiRNNTanh.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.NStepGRU.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.NStepLSTM.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.NStepRNNReLU.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.NStepRNNTanh.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.NegativeSampling.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.PReLU.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.ResNet101Layers.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.ResNet152Layers.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.ResNet50Layers.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.Scale.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.SimplifiedDropconnect.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.StatefulGRU.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.StatefulPeepholeLSTM.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.StatelessLSTM.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.VGG16Layers.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.caffe.CaffeFunction.init_scope:19: WARNING: Unexpected indentation.
/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/link.py:docstring of chainer.links.model.vision.resnet.ResNetLayers.init_scope:19: WARNING: Unexpected indentation.
Exception occurred:
  File "/Users/hoge/.pyenv/versions/3.6.1/lib/python3.6/site-packages/chainer/optimizer.py", line 598, in __get__
    return getattr(obj.hyperparam, self._attr_name)
AttributeError: 'NoneType' object has no attribute 'hyperparam'
The full traceback has been saved in /var/folders/y1/tp8l6j7n67bgbz8tpm0_05b40000gn/T/sphinx-err-6hlmrj53.log, if you want to report the issue to the developers.
Please also report this if it was a user error, so that a better error message can be provided next time.
A bug report can be filed in the tracker at <https://github.com/sphinx-doc/sphinx/issues>. Thanks!
make: *** [dirhtml] Error 1

また、DashのWindows/Linux版であるZealを使っている場合、上記の手順でビルドしてできたchainer2.docsetディレクトリを、Zealのdocsetsディレクトリに入れることでZealに見えるようになります。

% mv chainer2.docset ~/.local/share/Zeal/Zeal/docsets/

(docsetsディレクトリの場所は環境によって異なる可能性があります。optionsで確認できます)

✌(‘ω’✌ )三✌(‘ω’)✌三( ✌’ω’)✌たのしい!

なお、後になってDash-User-ContributionにChainerがあることを知った…
https://github.com/Kapeli/Dash-User-Contributions/tree/master/docsets/Chainer
常に自分の責任で最新に追従させたいわけじゃなければ、これで十分。メンテナのmitmulさんは同僚ですw

rakeとかでwarning: already initialized constant Rake::VERSIONみたいなエラーが出た

世界の総水産量は年間約9000万トン(養殖含め)だそうですが、世界の鯨が1年に食べる魚類の量は2.8億トンから5億トンになると試算されており(1)、人間の数倍もの水産物が鯨によって消費されているそうです。ヒトの生物量でもせいぜい3億トンかそこら(50kg*70億人=3.5億トン)ですから、すごい量です。とはいえオキアミや微生物など水産物として競合しないものもあるので単純な比較はできませんが。

さて、rails開発していて、見たことのないこんなエラーに遭遇しました。

% rake -T
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:2: warning: already initialized constant Rake::VERSION
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:2: warning: previous definition of VERSION was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: already initialized constant Rake::Version::MAJOR
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: previous definition of MAJOR was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: already initialized constant Rake::Version::MINOR
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: previous definition of MINOR was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: already initialized constant Rake::Version::BUILD
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: previous definition of BUILD was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: already initialized constant Rake::Version::OTHER
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: previous definition of OTHER was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:7: warning: already initialized constant Rake::Version::NUMBERS
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:7: warning: previous definition of NUMBERS was here
WARNING: Possible conflict with Rake extension: String#ext already exists
WARNING: Possible conflict with Rake extension: String#pathmap already exists

...(つらつら続きます)...

/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task_arguments.rb:107: warning: already initialized constant Rake::EMPTY_TASK_ARGS
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/task_arguments.rb:107: warning: previous definition of EMPTY_TASK_ARGS was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/invocation_chain.rb:54: warning: already initialized constant Rake::InvocationChain::EMPTY
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/invocation_chain.rb:54: warning: previous definition of EMPTY was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/early_time.rb:20: warning: already initialized constant Rake::EARLY
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/early_time.rb:20: warning: previous definition of EARLY was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/late_time.rb:16: warning: already initialized constant Rake::LATE
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/late_time.rb:16: warning: previous definition of LATE was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:3: warning: already initialized constant Rake::Backtrace::SYS_KEYS
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:3: warning: previous definition of SYS_KEYS was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:4: warning: already initialized constant Rake::Backtrace::SYS_PATHS
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:4: warning: previous definition of SYS_PATHS was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:7: warning: already initialized constant Rake::Backtrace::SUPPRESSED_PATHS
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:7: warning: previous definition of SUPPRESSED_PATHS was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:11: warning: already initialized constant Rake::Backtrace::SUPPRESSED_PATHS_RE
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:11: warning: previous definition of SUPPRESSED_PATHS_RE was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:15: warning: already initialized constant Rake::Backtrace::SUPPRESS_PATTERN
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:15: warning: previous definition of SUPPRESS_PATTERN was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake.rb:69: warning: already initialized constant FileList
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake.rb:69: warning: previous definition of FileList was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake.rb:70: warning: already initialized constant RakeFileUtils
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake.rb:70: warning: previous definition of RakeFileUtils was here

自分の場合はrbenvを使っていたので、rubyの処理系を一旦消した上でもっかい入れ直し、さらにvendor/bundleを消したらなおりました。

% rbenv uninstall 2.4.1
% rbenv install 2.4.1
% rbenv rehash
% rm -rf vendor/bundle
% gem install bundler
% bundle install
% rake -T
rake about                              # List versions of all Rails frameworks and the environment
rake app:template                       # Applies the template supplied by LOCATION=(/path/to/template) or URL
rake app:update                         # Update configs and some other initially generated files (or use just update:configs or update:bin)
rake assets:clean[keep]                 # Remove old compiled assets
rake assets:clobber                     # Remove compiled assets
...

原因は、rails newしたあと一回普通にbundle installしたのですが、その後でbundle install –path=vendor/bundleをしてしまったため、rbenvの下のrubyの中にgemがどばどば入ったのと、railsアプリ内のvendor/bundleの下に入ったgemが一緒にロードされてしまったためです。

上の対処法では両方消した形になりますが、本当は片方だけで良いはず。
自分はついでに.bundle/configの中からBUNDLE_PATHを除去し、vendor/bundleではなくruby処理系の中に入れることにしました(自分のruby使用頻度だとそれであんま困らないので)

備忘録でした。

tqdmをムリヤリprocess safeっぽくするdirty hack

生物界で最大の目(光を検知する器官)を持っているのはダイオウイカおよびダイオウホウズキイカと言われ、その大きさは30〜35cmほどにもなるのだそうです。

さて、世界70億人のPythonプログラマが手放せないのが、tqdmというプログレスバーを簡単に表示できるようにしてくれるライブラリです。
しかしながらtqdmは(当然と言えば当然ですが)複数のプロセスから1つのプログレスバーを管理することができるような設計にはなっていません。
たとえば高速化のためにmultiprocessingを用いて並列処理をしながらプログレスバーを出したいとき、tqdmはそのままでは使えないことになります。

例えば、下記のようなコードで単にtqdmのインスタンスを子プロセスに渡して中でupdateをすると…

import tqdm
import multiprocessing

def worker(pbar):
    pbar.update()

ar = [i for i in range(100)]
with tqdm.tqdm(ar) as pbar:
    jobs = []
    for t in ar:
        job = multiprocessing.Process(target=worker, args=(pbar,))
        job.start()
        jobs.append(job)
    for job in jobs:
        job.join()

実行結果はこんな感じ。

% python usage.py
  1%|▉                                                                                                 | 1/100 [00:00<00:25,  3.89it/s]

こんなふうに、100%まで行ってくれません。
端的に説明すると、100個forkされた内部カウント0の状態をそれぞれ+1するのが100回走るだけ、だからです。

じゃあ内部カウントが常によろしく増えるために、内部カウントを無視して共有メモリで常に正しくカウントしてればいいよね、っていう単純な発想による汚いハックをしてみました。

Continue reading

大量のサーバに同じファイル(でかい)を効率的にコピーする

インド洋では、夏頃にイワシの大群が押し寄せるサーディンラン現象というのがあるのだそうです。その個体数、にわかには信じがたいですが億のオーダーにもなるとのことです。すげーな!

さて、あるサーバ1台が数百GBにもなる巨大なファイル(群)を持っているとします。
このファイル群を、そのサーバに接続された他の複数(大量)のサーバのローカルディスクにコピーしたいです。
以後これを便宜的にbcast cpと呼ぶことにします。

rsyncを1台ずつ回すのが頭悪い方法なのは明らか。当然NFSなどを立てて共有するというのも本質的にはそれと同じ。
同僚のiwiwiさんがちょうど集団通信アルゴリズムの話をしていたのを聞いて、それを活用して効率的にファイルをバラまくようなアドホックなスクリプトを書いて、ときどき使えそうなのでまとめておきました。

「やってみた」ぐらいの話なのでガチ勢の方たちにはƱ”-ʓ飲んで寝ていてほしいです。

Continue reading

pythonでlistを(なるべく)均等分割するスニペット

魚類というのは世界で20000種が報告されているんだそうですが、もちろん実際にはこれより遥かに多くの種が存在すると思われているそうです。食べられる魚だけでも一体何種いるんでしょう。

さて、Pythonでリストをあるk個のリストへなるべく均等に分割したい…というようなことが頻繁ではないけどたまーに欲しくなって、その都度何分かかけて書いてる(でときどきバグ作り込む)気がするのでスニペットとしてメモ。

やりたいこと。

 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

…というような長さ12の配列を5分割する。

[ [0, 1], [2, 3], [4, 5, 6], [7, 8], [9, 10, 11] ]

何のことはありません。

def split_array(ar, n_group):
    for i_chunk in range(n_group):
        yield ar[i_chunk * len(ar) // n_group:(i_chunk + 1) * len(ar) // n_group]

Python2なら割り算のところは//でなく/でおk。

リストを受け取ればリストを返すし、rangeを受け取ればrangeを返します。

> [list(r) for r in split_array(range(12), 5)]
[ [0, 1], [2, 3], [4, 5, 6], [7, 8], [9, 10, 11] ]

1982798万番煎じぐらいだとおもう。

MacにRMagickが入らなくてつらい人へ

大型淡水魚のピラルクーはとても特徴的な大きな鱗をもち、その硬さもあって、靴べらなどに利用されることさえあるのだそうです。

さて、Mac(El Capitan)にGemでRMagickを入れようとしたとき、

% gem install rmagick

こんなエラーで死にました。

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    /Users/hogehoge/.rbenv/versions/2.2.0/bin/ruby -r ./siteconf20170218-46131-rbo6q5.rb extconf.rb
checking for clang... yes
checking for Magick-config... no
checking for pkg-config... yes
checking for outdated ImageMagick version (<= 6.4.9)... no
checking for Ruby version >= 1.8.5... yes
checking for stdint.h... yes
checking for sys/types.h... yes
checking for wand/MagickWand.h... no

Can't install RMagick 2.15.4. Can't find MagickWand.h.
 *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/Users/hogehoge/.rbenv/versions/2.2.0/bin/$(RUBY_BASE_NAME)

extconf failed, exit code 1

Gem files will remain installed in /Users/hogehoge/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/rmagick-2.15.4 for inspection.
Results logged to /Users/hogehoge/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/extensions/x86_64-darwin-15/2.2.0-static/rmagick-2.15.4/gem_make.out

An error occurred while installing rmagick (2.15.4), and Bundler cannot continue.
Make sure that `gem install rmagick -v '2.15.4'` succeeds before bundling.

基本的にはこちらで書かれているような、pkg-config周りをちゃんとするようというようなのがよく引っかかります。
Mac OS X環境にrmagickをインストールする決定版 – Qiita

僕の場合はまた違う現象でした。
結論から言うと、新しいImageMagick7.xがシステムに入ってるとダメで、6.x系列を入れる必要がありました

% brew uninstall --ignore-dependencies --force imagemagick
% brew install imagemagick@6 && brew link imagemagick@6 --force
% gem install rmagick

この答えは、こちらのStackOverflowで発見しました。
ruby – RMagick installation: Can't find MagickWand.h – Stack Overflow

こういうので時間を溶かすのがいちばんつらいですね。

UbuntuでOpenCVをlibjpeg-turboつきでビルドする

都道府県別の一人あたり魚介類消費量では、青森県がトップで、以下秋田、鳥取、新潟、富山と日本海側の県が続きます。島国・沖縄が意外にも最下位です。

さて、OpenCVで画像をロードするのを速くしたくて、JPEGについてはlibjpeg-turboというのが使えることを知りました。
libjpeg-turboはlibjpegをSIMDなどによって高速化したものでAPIレベルの互換性を保っています。
条件が良ければデコードが数倍速くなるということで、これをOpenCVに組み込んでビルドする方法をメモ。

Continue reading

YouTube Data API V3とgoogle-api-ruby-client gemでYouTube動画検索

この度2017年1月1日を迎えました。神戸港開港150年であり、神戸港に建つ巨大な魚のオブジェ「フィッシュ・ダンス」が公開されて30年でもあります。神戸港には縁もゆかりもありません。

さて、自作サービス(Rails製)の裏側においてYouTubeでの動画検索をしたいと考えていて、YouTube Data API(V3)およびそれを叩くGoogle製のgoogle-api-ruby-client gemを使うことにしました。
しかしながらこのGemは2016年初頭に出た0.9によって大きな変更が入り、公式のものを含めネット上で閲覧可能なサンプルのほとんどが参考にならない状況になっています。
自分でも少し苦労したので、かんたんにメモ。

情報は2017年1月1日JST現在、Gemは0.9.20です。

Continue reading