NumPy.add.atなどのユニバーサル関数+at

NumPyについて書くシリーズの続きです。

ユニバーサル関数(ufunc)とは、ベクトル化演算です。いくつもの要素がある中で、一つ一つ処理するよりも、一度に処理したほうが早いですよね。そういうことをやってくれる関数です。

たい焼きを焼くときに、一つ一つ焼いていると大変です。しかし、たい焼き屋さんでは、いくつものたい焼きの穴が開いている鉄板で一度にたくさんのたい焼きをバシッ!!と作りますよね。あんこを足すときも、一度にできて早いですよね。あれのイメージです。

で、今回は、特にそのユニバーサル関数を at と組み合わせた時の動作がちょっとわかりづらかったので書いておきます。

下記の公式サイトにある
https://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.at.html
例なのですが

import numpy as np

a = np.array([1, 2, 3, 4])
np.add.at(a, [0, 1], 1)
print(a)
#下記が出力されます。
array([2, 3, 3, 4])

これを例にとって説明するとadd.atの

・1番目の引数は処理する配列

・2番目の引数は処理したいインデックス

・3番目の引数は、addしたい数

です。

私はPHPとかJavaとかが長いので、こういう「1を加算する」的な処理はついついfor文とかでループで書いてしまいがちなのですが、速さが違うので、NumPyのユニバーサル関数を使いこなしていきたいと思います!!

Python assertの使い方

Pythonにassertという宣言があり、こんな使い方ができますという紹介です。

めっちゃ簡単な話ではありますが…。

Pythonのコードを見ていると、ちょいちょいassert出てきて、ほげー と思ってたんですよね。

なんというか、assert はテストコード内で使うというイメージ。

しかし、Pythonでは、致命的なエラーなどを起こした場合、プログラムを止めることができ、しかも、それはデバッグ版だけで起こせるので、開発に便利だよ~ という感じです。

print("before")

a = 1
assert a == 2, "2じゃない"

print("after")

上記を実行すると

before
Traceback (most recent call last):
File "G:/ai_delivery/study12.py", line 4, in
assert a == 2, "2じゃない"
AssertionError: 2じゃない

Process finished with exit code 1


ってなります。

assertのところで終了しているので、print(“after”)は実行されません。

んで、開発の時にデバッグするためのものだよ~ という話なのですが、本番の時にこんなエラー起きたら大変!とか、理由を解明するのも「ええい、面倒!!」ということがあれば、次のようにコマンドラインオプション -Oをつけて実行すればAssertionErrorが出ません。

G:\ai_delivery>python -O study12.py
before
after

これは、大文字のO(オー)です。ゼロじゃないよ。

MySQL CASE文でNULL判定

前回

MySQL SELECT時にCASE文で値をわかりやすく出力するサンプル 

でCASE文の話をしましたが、これでNULL判定するときは気を付けましょう。

サンプルは前回と同じく下記のようなデータですが、4番目の null だけ追加しています。下記のテーブルをcallsとします。

id | driver_id | created
1 | 13 | 2018-11-19 11:23:25
2 | 15 | 2018-11-19 11:25:30
3 | 16 | 2018-11-19 11:26:30
4 | null | 2018-11-19 11:26:30

このテーブルからnullでないドライバーIDの場合は、1、そうでない場合は0を返したい場合、いかにも、下記のように判定できそうですが

SELECT
   id, 
CASE
   driver_id WHEN NULL THEN 0 ELSE 1 
END
FROM
calls

なんとこれではダメです。全部、1が返ってきます。

NULL判定は、CASE文の中でしないといけないそうです。

SELECT 
    id, 
CASE 
    WHEN driver_id IS NULL THEN 0 ELSE 1 
END 
FROM 
calls 

これで、ちゃんと driver_id がNULLの時、0になります。

 

MySQL SELECT時にCASE文で値をわかりやすく出力するサンプル 

MySQLにCASE文やIF文があるのを知っていても、使うシチュエーションがわからない、なんだか使いづらい…と感じている方も多いのではないでしょうか。

ここでは、SELECTするときに、CASEを使う方法を書いておきます。
私、思うにフラグを立てるような処理とかに使うといいと思います。(๑•̀ㅂ•́)و✧

calls というテーブルの中に、下記のようなデータがあったとして

id | driver_id | created
1 | 13 | 2018-11-19 11:23:25
2 | 15 | 2018-11-19 11:25:30
3 | 16 | 2018-11-19 11:26:30

ドライバーIDが “15” の時だけフラグを立てる的にわかりやすく出力したい、という場合があったとするとCASE文を使って次のように書けます。

SELECT
   id, 
CASE
   driver_id WHEN 15 THEN 1 ELSE 0 
END
FROM
calls

 

結果は

id | CASE driver_id WHEN 15 THEN 1 ELSE 0 END 
1 | 0
2 | 1
3 | 0

となります。
フィールドの名前がいやなので、エイリアスつけておきます。

SELECT
   id, 
CASE
   driver_id WHEN 15 THEN 1 ELSE 0 
END
 as driver_himself
FROM
calls

結果は

id | driver_himself
1 | 0
2 | 1
3 | 0

となります。

This support library should not use a different vesion than the compileSdkVersion

Android supportライブラリなどで利用するべきバージョンについて(サンプル有)

Androidのgradleのdependenciesのimplementation(旧 compile)でよく出るこのWarning。

StackOverflowとかで見て、このエラーでビルドできないからこれ、と闇雲にライブラリのバージョンを指定していると、こうなりますよねw

ほっといてもビルドできる時もありますが、時にできなくなって、できない時は本当にカオスでわけわかめになります。

なので、ちゃんとやった方がいいです。

じゃあ、どのバージョンを指定したらいいのー??ってなりますが、その方法を書いておきます。

下記のようにアプリケーションのbuild.gradleファイルを作ったとすると

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'


android {
    compileSdkVersion 27
    buildToolsVersion '28.0.3'
    defaultConfig {
        applicationId "hogehoge"
        minSdkVersion 14
        targetSdkVersion 27
        javaCompileOptions {
            annotationProcessorOptions {
                includeCompileClasspath false
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
    useLibrary 'org.apache.http.legacy'
    productFlavors {
    }
}

dependencies {
    compile project(':rateThisApp')
    compile 'com.android.support:support-v4:27.1.1'
    compile 'com.google.android.gms:play-services-location:16.0.0'
    compile files('lib/osmbonuspack_v4.2.9.jar')
    compile files('lib/osmdroid-android-4.1.jar')
    compile files('lib/osmdroid-third-party-4.1.jar')
    compile files('lib/slf4j-android-1.6.1-RC1.jar')
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support:design:27.1.1'
    implementation 'com.google.firebase:firebase-messaging:17.3.4'
    implementation 'com.google.android.gms:play-services-maps:16.0.0'  // GoogleMapを使うために追加する

}

compileSdkVersion 27のこの数字にサポートライブラリのバージョンの最初の数字を合わせます。

サポートライブラリとは、

'com.android.support:support-v4:27.1.1'

いたいなやつのことです。上記の意味は、com.android.support:support-v4というライブラリのバージョン27.1.1ですよ!ってことです。

つまり、compileSdkVersion が27だから、ライブラリのバージョンの最初の数字は27です。

後のやつはどうやって決めるの?というと、下記のサイトで探します。

Recent Support Library Revisions

https://developer.android.com/topic/libraries/support-library/revisions?hl=ja

例えば、上記のサイトを見ると、バージョン27だと、現在(2018/12/04)で
Revision 27.1.1
が最新ということになります。

なので、

'com.android.support:support-v4:27.1.1'

として、27.1.1を指定します。