多数の点を球面上に一様分布させる(2)

一昨日の続き。最初と最後の点を極から移動(位置調整)するのを実装した。ついでに、gem 化して RubyGems.org にアップしておいた。gem install gss_generator でインストールできる。
使い方は次の通り。

^o^ > gss_gen --cartesian --relocate 1.0 600 > c600r.csv

--cartesian はデカルト座標系で出力、--relocate は位置調整のオプション。結果は CSV 形式で標準出力に出力するので c600r.csv ファイルにリダイレクトしている。

結果を一昨日と同様の図にしたものを載せる。

最初の点が極(中心)からずれて、一様性が増しているのがわかる。

多数の点を球面上に一様分布させる

ちょっと面白いものを見つけた。

 cf. LEDドームのLEDの並びを決めるのに使用した計算式 – jakaladaのブログ

球面上に任意個の点を一様分布させる、座標を求めるもの。一般化螺旋集合(generalized spiral set)というものを使っている。元の資料(論文)はここ。

 cf. 多数の点を球面上に一様分布させるソフトウェアGSS Generator

上のリンク先のブログでは Python を使っているので、Ruby でやってみた。

最初のがコマンドで、あとの2つがライブラリ。引数に球の半径と配置したい点の個数を指定すると、各店の極座標を CSV 形式で出力する。

^o^ > ruby -Ilib exe/gss_gen 1.0 600

極座標じゃなく、デカルト座標(XYZ座標)がほしい時には --cartesian オプション。

^o^ > ruby -Ilib exe/gss_gen --cartesian 1.0 600

下の図は、発生させた600個の点のうち下半分の300個を XY 平面上に投影した図。

各点を順に線でつないでみると、螺旋になっているのがよくわかる。

……なんか螺旋が逆になってるな。元論文じゃ球面を下から見たと書いてあるからそのせいか?

ともあれ、それらしいのはできた。ただし、最初と最後の点の座標を調整するのはやってない。時間があったらやってみよう。

SinatraでSECURITY WARNING: No secret option provided to Rack::Session::Cookie.というワーニングが出たときの対処法

Sinatra でアプリを作ってるんだけど、セッションを利用するとタイトルのようなワーニングが出た。もっと詳しく書くと次のとおり。

SECURITY WARNING: No secret option provided to Rack::Session::Cookie.
This poses a security threat. It is strongly recommended that you
provide a secret to prevent exploits that may be possible from crafted
cookies. This will not be supported in future versions of Rack, and
future versions will even invalidate your existing user cookies.

ググってみても見つかるのは、Rails のバージョンを上げろとか、Rack のバージョンを 1.4.1 にしろとかいうのばっかり。Rails は使ってないし、Rack は 1.6.5 なんだけどなあ。そんな中で見つけたのが↓このページ。

 cf. SECURITY WARNING: No secret option provided to Rack::Session::Cookie

config.ru で :session_secret に値を設定すればいいらしい。
具体的には次のようにした。

これでめでたくワーニングが出なくなった。

Ubuntuで作ったwheelパッケージをWindowsにインストールする

このあいだ Ubuntu で作った wheel パッケージ、Windows にインストールしてみた。
pure Python なのであたりまえだけど、何の問題もなくインストールできた。

^o^ > pip install myapp-0.0.1-py2-none-any.whl
Processing c:\users\hiro\documents\tmp\myapp-0.0.1-py2-none-any.whl
Installing collected packages: myapp
Successfully installed myapp-0.0.1

動作確認。

^o^ > myapp foo bar baz
['C:\\Python27\\Scripts\\myapp', 'foo', 'bar', 'baz']

^o^ > which myapp
C:/Python27/Scripts/myapp.EXE

へぇ、Windows だと .EXE ファイルができるんだ。

Elixir 練習問題 StringsAndBinaries-7

^o^ > cat sales.csv
id,ship_to,net_amount
123,:NC,100.00
124,:OK,35.50
125,:TX,24.00
126,:TX,44.80
127,:NC,25.00
128,:MA,10.00
129,:CA,102.00
130,:NC,50.00

^o^ > elixir practice_11_7.exs
[[id: 123, ship_to: :NC, net_amount: 100.0],
 [id: 124, ship_to: :OK, net_amount: 35.5],
 [id: 125, ship_to: :TX, net_amount: 24.0],
 [id: 126, ship_to: :TX, net_amount: 44.8],
 [id: 127, ship_to: :NC, net_amount: 25.0],
 [id: 128, ship_to: :MA, net_amount: 10.0],
 [id: 129, ship_to: :CA, net_amount: 102.0],
 [id: 130, ship_to: :NC, net_amount: 50.0]]

Elixir 練習問題 StringsAndBinaries-6

^o^ > elixir practice_11_6.exs
Oh. A dog. Woof.

Elixir 練習問題 StringsAndBinaries-5

^o^ > elixir practice_11_5.exs
  cat
 zebra
elephant

Elixir 練習問題 StringsAndBinaries-4

^o^ > elixir practice_11_4.exs
150
100
200
20.0

Pythonのwith構文を覚えた!

基本的な使い方

ファイルを開いて読み込む処理が典型的かな。今まではこうしていた:

with 構文を使うとこう書ける:

開いたファイルは、ブロックを抜けるときに自動で閉じてくれる。

withに対応したクラス

with 構文に書けるクラスはファイルだけじゃない。__enter____exit__ の2つのメソッドを持ったクラス(のインスタンス)なら何でもいい。__enter__ はブロックに入るときに、__exit__ はブロックを抜けるときに呼ばれる。
ちょっと試してみよう。

実行結果:

takatoh@apostrophe $ python test_with.py
init
enter
hoge
exit

ブロックの中を実行する前に __enter__ が、あとに __exit__ が呼ばれているのがわかる。
as t: の部分の t には、__enter__ の返り値が代入されるので、self を返している。

ともあれ、1行短くなって見やすくなる。これからはこうやって書くようにしよう。

Python: コマンドを含むwheelパッケージを作る

Python のパッケージというと、以前は Egg だったけど最近では wheel パッケージが増えているようだ。Egg パッケージは一度作ってみたことがあるので、今回は wheel パッケージを作ってみる。ついでに、ライブラリではなく、実行できるコマンドを含んだパッケージを作る。

環境

  • Ubuntu 16.04 LTS
  • Python 2.7.12
  • wheel 0.29.0

ソースファイル

ソースの構成はこう:

takatoh@apostrophe $ tree .
.
├── myapp
│   ├── __init__.py
│   └── main.py
└── setup.py

1 directory, 3 files

myapp/main.py が実行されるコマンドのソースで、setup.py が wheel パッケージを作るためのファイル。

myapp/main.py は main 関数があるだけ。setup.py も最低限だけど、色を付けた行が実行コマンドを指定していて、'myapp=myapp.main:main'myapp コマンドを実行すると myapp/main.py の main 関数を呼び出すことを意味している。myapp/__init__.py は空でいい。

wheelパッケージの作成

setup.py にパラメータとして bdist_wheel を渡してやる。

takatoh@apostrophe $ python setup.py bdist_wheel
running bdist_wheel
running build
running build_py
creating build
creating build/lib.linux-x86_64-2.7
creating build/lib.linux-x86_64-2.7/myapp
copying myapp/main.py -> build/lib.linux-x86_64-2.7/myapp
copying myapp/__init__.py -> build/lib.linux-x86_64-2.7/myapp
installing to build/bdist.linux-x86_64/wheel
running install
running install_lib
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/wheel
creating build/bdist.linux-x86_64/wheel/myapp
copying build/lib.linux-x86_64-2.7/myapp/main.py -> build/bdist.linux-x86_64/wheel/myapp
copying build/lib.linux-x86_64-2.7/myapp/__init__.py -> build/bdist.linux-x86_64/wheel/myapp
running install_egg_info
running egg_info
creating myapp.egg-info
writing myapp.egg-info/PKG-INFO
writing top-level names to myapp.egg-info/top_level.txt
writing dependency_links to myapp.egg-info/dependency_links.txt
writing entry points to myapp.egg-info/entry_points.txt
writing manifest file 'myapp.egg-info/SOURCES.txt'
reading manifest file 'myapp.egg-info/SOURCES.txt'
writing manifest file 'myapp.egg-info/SOURCES.txt'
Copying myapp.egg-info to build/bdist.linux-x86_64/wheel/myapp-0.0.1.egg-info
running install_scripts
creating build/bdist.linux-x86_64/wheel/myapp-0.0.1.dist-info/WHEEL

すると dist ディレクトリに wheel パッケージができる。

takatoh@apostrophe $ ls dist
myapp-0.0.1-py2-none-any.whl

インストールと確認

インストールは普通に sudo pip install で。

takatoh@apostrophe $ sudo pip install dist/myapp-0.0.1-py2-none-any.whl
Processing ./dist/myapp-0.0.1-py2-none-any.whl
Installing collected packages: myapp
Successfully installed myapp-0.0.1

テスト。

takatoh@apostrophe $ myapp foo bar baz
['/usr/local/bin/myapp', 'foo', 'bar', 'baz']

うまく行った。myapp コマンドが /use/local/bin/myapp にインストールされているのがわかる。

参考ページ

 cf. Pythonでグローバルコマンドを含んだパッケージを作る – Qiita
 cf. Python: Wheel でパッケージを配布する – CUBE SUGAR STORAGE