ITの隊長のブログ

ITの隊長のブログです。Rubyを使って仕事しています。最近も色々やっているお(^ω^ = ^ω^)

【Play Framework】クエリパラメータを取得する

メソッドの引数からも取れる。けど、複数あるとき~/conf/routesの記述が書きづらいので、リクエストのオブジェクトから取れないかなーと思って探したらあったのでメモ。

String value = request().getQueryString("key");

これでとれます。

こいつにOptionalをかませば、nullも回避するコードがかけますねー。

久々にPlay Framework触ったのでメモ。

今週学んだことをちょっとだけ書く

今月入社した会社さんは、いわいるデータサイエンティストを職とした感じで、Python、R、SQLを主に使うとのこと。

その中で「ほほー」と思ったこと(だけ)を書く。

ちなみに、大した内容ではなく自分だけのメモでおいておく。

任意の数値区切り別にグルーピングするSQL

例えば年齢のカラムがあるとして、10, 20, 30と10区切りでグルーピングしてそれぞれ合計を出してしてください。つー課題がありました。

まず、10で区切るということは、どこからどこまでが10で、どこからどこまでが20と数字の用意と分岐を用意しなければいけないと思いました。

最初Case文を書こうとしましたが、それは無理とすぐに気づく。なぜならCaseは記述しないといけないので、例えば、70歳まであるとしたら7つ分岐をかかないといけない。これはスマートじゃない。

「うーん」と悩んでいる内に回答がきたので残念でした。

で、やり方としては「整数除算」というプログラミング言語同じみの機能を使えばできることがわかりました。

Pythonで試してみると15という数字は10区切りだと、「10(代)」に当てはまります。それを求めるには

>>> 15 // 10 * 10

何故かこれで求まります。詳細を説明すると、15 // 10を計算すると1.5になるのかなと思いますが、プログラムの場合は型で判断されるので、除算されます。なので、1となります。それに1 * 10となり、15の区切りの開始数値は10となります。

当時色々勘違いしてしまい、「15を10で割ったら1.5で掛けたら15に戻るじゃん!!?」ってずっと意味不明にタイプしていましたorz プログラマ

ちなみに、Pythonの場合だと15 / 101.5となりますので、//を使っています。

また、「どこから」の数字がわかったので、今度は「どこまで」の数字を求めます。

>>> (15 // 10 + 1) * 10 -1

()の中は、「どこから」の求める式の15 // 10は一緒ですが、そこに+ 1が入っています。15 // 10だと、値は1となりますが、これに+ 1することで10区切り値が繰り上がります。今回は2となり「20(代)」に入る準備ができました。

しかし求めたい値は「どこまで」なので、今回は19です。なので、その2を区切り値で掛けて20とします。そこから1引けば19となるため、求めたい値を取得することができる式ができました。

SQLで書くとこんな感じ。

select
  age / 10 * 10 as from,
  (age / 10 + 1) * 10 - 1 as to,
  count(*) as count
from
  age_tables
group by
  from,
  to

結果は、、、と思ったけど、データ用意するのが面倒なので、PythonのPandasでやります。

>>> import numpy as np
>>> import pandas as pd

# 30個ぐらいnumpyで適当にデータを用意する
# 0 ~ 100のint数値を30個ランダムで作ってくれます
>>> a = np.random.randint(0, 100, 30)
# それをDataFrameにする
>>> _data = pd.DataFrame({'age': a})
>>> _data.head()
   age
0   67
1   31
2   23
3   84
4   40

# 「どこから」の値を作成する
>>> _data['from'] = _data['age'] // 10 * 10
# 「どこまで」の値を作成する
>>> _data['to'] = (_data['age'] // 10 + 1) * 10 - 1
>>> _data.head()
   age  from  to
0   67    60  69
1   31    30  39
2   23    20  29
3   84    80  89
4   40    40  49

# グルーピングする。pandasってほとんどsqlと同じことできるよね。すごい
>>> _group = _data.groupby(['from', 'to'])
# countする
>>> _group.count()
         age
from to
0    9     2
10   19    6
20   29    2
30   39    3
40   49    2
50   59    1
60   69    6
70   79    4
80   89    2
90   99    2

ほえー。すごい。

素数を求める

エラトステネスの篩(ふるい)というのがあるとのことでした。

これを使ったら素数を求められました! 以前、同じことをやろうとして自分で実装しようとしたけど、こんなのあったのね(°ω°

まぁこれは仕事関係なさそうだけど

雑感想

最初の研修は知っていることが多く、1時間もするとすぐだれて、「早く仕事したい」なんて思っていたけど、SQLで死んだ。

SQLの達人の本は持っているが、実家においたままで、今日本屋へいって立ち読みしてみたが、すごく知りたい情報が詰まっている感じだった。サボらなかればよかったとちょっとだけ後悔(´・ω・`)

またオススメされた本を購入してきたので、今日から勉強します。あと統計も。。。これが一番の難題やorz

ビッグデータ分析・活用のためのSQLレシピ

ビッグデータ分析・活用のためのSQLレシピ

今日から新しい会社、一昨日から新しい場所に住んでいます。

東京にきました。

「前はレオパレスだから、家具家電あったけど、今度はどうしようかな。」と思っていましたが、エアコンとか小さな冷蔵庫があった。ラッキー!

ただ、冷蔵庫に関しては冷蔵庫無しの生活を送ってみたい!と、意気込んでいたので、「ええ・・・」と思っちゃいましたが。

まぁでも使わないでおこうと思います。冷蔵庫なし生活スタート。

あと寒すぎ。今財布の問題で寝袋で寝ていますが、初日死ぬと思った。エアコンなかったら死んでたわ。4月ってこんなに寒かったっけ?

んで、4/1に新しい会社さんの上司になる予定の方に呼ばれて、数名で飲みに行きました。

すごくいい人たちでとても楽しい仕事になりそう。

で、話聞く限り、いまのところサイヤ人しかいないです。この会社。

あわせて、何人か超サイヤ人になっている人たちもいます。

これは自分もサイヤ人になるか、クビになるかどっちかだな。

若干の不安あるけど、楽しみでもあります。

それじゃ、行ってきます。

【起動できませんでした】面白そうなOSS見つけた。「python-for-android」

github.com

README.mdやドキュメントだけでは起動できず、ソースを読んでオプションを試してみたけど、結局Android起動まではできませんでした。

また試してみるかもしれないので、メモしておく。

とりあえず試した

Getting Started — python-for-android 0.1 documentation

$ pip install python-for-android
$ p4a apk --requirements=kivy --private obasann/ --package=net.inclem.planewavessdl2 --name="planewavessdl2" --version=0.5 --bootstrap=sdl2

pipでインストールできた。んで、よくわからんけど、起動っぽいコマンドを実行。

NDKのパスが見つからん。バージョンが見つからん。

エラー発生です。

[WARNING]: Android SDK dir was not specified, exiting.

sdkがないー。(そのあとにndkがないー!)と言われた。

コマンドで指定してあげることもできるが、exportしてあげたほうが楽かも。

Getting Started — python-for-android 0.1 documentation

$ export ANDROIDSDK="$HOME/Library/Android/sdk"
$ export ANDROIDNDK="$HOME/Library/Android/ndk"
$ export ANDROIDNDKVER="r10e"  # Version of the NDK you installed
$ p4a apk --requirements=kivy --private obasann/ --package=net.inclem.planewavessdl2 --name="planewavessdl2" --version=0.5 --bootstrap=sdl2

AttributeError: ‘Context’ object has no attribute ‘hostpython’

build中に踏んだ。

github.com

よくわからんが、hostpython2ってのがbundle?されているやつをそのまま使うのはダメらしい。

なので、再度ビルドする必要があるとのこと。どないせーちゅーねん。

Troubleshooting — python-for-android 0.1 documentation

This is a known bug in some releases. To work around it, add your python requirement explicitly, e.g. –requirements=python2,kivy. This also applies when using buildozer, in which case add python2 to your buildozer.spec requirements.

ふむ。オプションを追加してあげれば良いのね。

$ p4a apk --requirements=kivy --private obasann/ --package=net.inclem.planewavessdl2 --name="planewavessdl2" --version=0.5 --bootstrap=sdl2 --requirements=python2,kivy

コンパイルに結構時間かかっている感じ。

謎のエラー発生

そもそもこのエラーの見方がわからん。

これを解決する時間がないので、また今度(´・ω・`)

[INFO]:    -> directory context /home/user/.python-for-android/build/bootstrap_builds/sdl2-python2/jni
[INFO]:    -> running ndk-build V=1
           working: /home/user/Library/Android/ndk/build/core/build-binary.mk:700: *** Android NDK: Aborting (set APP_ALLOW_MI...(and 58 more)  Exception in thread background thread for pid 69768:
Traceback (most recent call last):
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/threading.py", line 911, in _bootstrap_inner
    self.run()
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/threading.py", line 859, in run
    self._target(*self._args, **self._kwargs)
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/sh.py", line 1540, in wrap
    fn(*args, **kwargs)
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/sh.py", line 2455, in background_thread
    handle_exit_code(exit_code)
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/sh.py", line 2153, in fn
    return self.command.handle_command_exit_code(exit_code)
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/sh.py", line 815, in handle_command_exit_code
    raise exc
sh.ErrorReturnCode_2:

  RAN: /home/user/Library/Android/ndk/ndk-build V=1

  STDOUT:
Android NDK: WARNING: APP_PLATFORM android-15 is larger than android:minSdkVersion 12 in /home/user/.python-for-android/build/bootstrap_builds/sdl2-python2/AndroidManifest.xml
Android NDK: WARNING:/home/user/.python-for-android/build/bootstrap_builds/sdl2-python2/jni/src/Android.mk:main: non-system libraries in linker flags: -lpython2.7
Android NDK:     This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
Android NDK:     or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK:     current module
/home/user/Library/Android/ndk/build/core/build-binary.mk:687: Android NDK: Module main depends on undefined modules: python_shared
/home/user/Library/Android/ndk/build/core/build-binary.mk:700: *** Android NDK: Aborting (set APP_ALLOW_MISSING_DEPS=true to allow missing dependencies)    .  Stop.


  STDERR:


Traceback (most recent call last):
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/bin/p4a", line 11, in <module>
    sys.exit(main())
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/pythonforandroid/toolchain.py", line 754, in main
    ToolchainCL()
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/pythonforandroid/toolchain.py", line 343, in __init__
    getattr(self, command_method_name)(unknown)
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/pythonforandroid/toolchain.py", line 93, in wrapper_func
    build_dist_from_args(ctx, dist, dist_args)
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/pythonforandroid/toolchain.py", line 138, in build_dist_from_args
    build_recipes(build_order, python_modules, ctx)
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/pythonforandroid/build.py", line 561, in build_recipes
    recipe.build_arch(arch)
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/pythonforandroid/recipes/sdl2/__init__.py", line 29, in build_arch
    shprint(sh.ndk_build, "V=1", _env=env)
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/pythonforandroid/logger.py", line 173, in shprint
    for line in output:
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/sh.py", line 863, in next
    self.wait()
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/sh.py", line 792, in wait
    self.handle_command_exit_code(exit_code)
  File "/home/user/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/sh.py", line 815, in handle_command_exit_code
    raise exc
sh.ErrorReturnCode_2:

  RAN: /home/user/Library/Android/ndk/ndk-build V=1

  STDOUT:
Android NDK: WARNING: APP_PLATFORM android-15 is larger than android:minSdkVersion 12 in /home/user/.python-for-android/build/bootstrap_builds/sdl2-python2/AndroidManifest.xml
Android NDK: WARNING:/home/user/.python-for-android/build/bootstrap_builds/sdl2-python2/jni/src/Android.mk:main: non-system libraries in linker flags: -lpython2.7
Android NDK:     This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
Android NDK:     or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK:     current module
/home/user/Library/Android/ndk/build/core/build-binary.mk:687: Android NDK: Module main depends on undefined modules: python_shared
/home/user/Library/Android/ndk/build/core/build-binary.mk:700: *** Android NDK: Aborting (set APP_ALLOW_MISSING_DEPS=true to allow missing dependencies)    .  Stop.


  STDERR: