Python -(マイナス)記号をつける場所を注意しましょう

Pythonに限ったことではないと思うんですが。とりあえず、私は機械学習のことをやるまでは、あまり数学的なことにプログラミングで取り組んでいなかったので、今回思わぬところにはまってしまったので書いておきます。

下記のような式があります。

[(x[0],x[2],r*((-1)**(x[1]!=hoge))) for x in trainExamples]

これは、次のように分解できるかと思います。

trainExamples =[
                 [3,1,2],
                 [4,-1,1]
                 ]
hoge = 1
r = -1

for x in trainExamples:
    a = x[0]
    b = x[2]
    c = r* ((-1) ** x[1] != hoge)

    print(a, b, c)

次の

c = r* ((-1) ** x[1] != hoge)

部分なんですけど、

x[1] != hoge

はTrue かFalseなので、1か0ということだと思います。

つまりは -1**True か -1**Falseってことですね。

 

しかし、

-1**True

ってやっても

-1**False

ってやっても、答えは -1 なんです。ん?そもそも判定の意味ないぞー?

って思ってたら、元のコードをよく見ると

(-1)**True

(-1)**False

ってやらなきゃいけなかったんですね( ゚Д゚)

 

(-1)**True は -1

(-1)**False は 1

です。

 

-1**True、-1**False とか、1に1乗するか、1を0乗するかした後、マイナス1をかけているので、どちらも-1になるわけです。

カッコの場所でエライ違いだった。

はぁー、むずかし。

 

ちなみに、0乗とか?-1乗とか?についてさっぱり忘れてしまったので、次のサイトさんを参考にさせて頂きました。m(_ _)m

べき乗とは何か。ゼロ乗・マイナス乗・分数乗・無理数乗ってどういう意味?

https://atarimae.biz/archives/20521

 

PHPでデバッガを使うメリット 8選

弊社のスタッフさんに

「僕はPHPではデバッガ使わないです。」

って言われて衝撃を受けました。

私は自分の中でデバッガを使うのは当たり前!便利だし!と思っていたけれども、すぐに

「デバッガはここがいいんだよーん」

と力説もできなかったので、すごすごと引き下がりチキンなので「PHP デバッガ メリット」とかググってみました。

しかし、デバッガの使い方とかが上位に出てきて、あんまり「これだ!」ってのなかったので、自分で書いちゃいます。いつか同じことを聞かれた誰かが読んでくれるといいな~ と思います。

というわけで、私が思う、PHPでデバッガを使うメリットを、ランキング形式でお届けします♪

①var_dumpデバッグは(以下print_r、echoでも同じ)、var_dumpと書くのが面倒

ハエある第一位は、これ。

そして、書いたら消さないといけないのだ。それも面倒。うっかりコミットしちゃったりもする。どっかに書かれたvar_dumpが残っていやしないかい~??

②var_dumpデバッグは、見づらい。

型とか文字数とか…あと、階層になってるのを自分で解読しないといけないのがつらい。脳みそは別のことに使いたい。

③var_dumpデバッグは、2つ以上の変数の中身を見る時に、自分で名前をつけて出力しないといけない。

あんまりピンとこないと思うので、そろそろコードを書くとしよう…。

$hogehoge = "ほげほげ";

$clilin = "クリリン";

print"これはhogehogeの分"; //これが面倒!
var_dump($hogehoge);

print"これはクリリンの分"; //これが面倒!
var_dump($clilin);

上記例のように、変数が$hogehogeと$ukikiの二つがあって、二つの中身を見たい時、var_dumpの前に、この変数は何の変数だよと説明しないと、いけない。

④var_dumpデバッグだと、関数やループなどがあった時のその後の状態を監視するのに、いちいちvar_dumpで出力しないといけない。

これも下記のコードサンプルで。

$hogehoge = "ほげほげ";

$hogehoge = changeString($hogehoge);

print"これはchangeStringの後のhogehoge";
var_dump($hogehoge);

$hogehoge = changeParameter($hogehoge);

print"これはchangeParameterの後のhogehoge";
var_dump($hogehoge);

関数などを通過した後の変数の中身を調べるために、その都度var_dumpを書かないといけないのです。面倒!!

⑤プログラムの流れや実行順序がわかる

難しい言葉でいうと、コールスタックがわかるってことです。意外と大事で、このメソッドどっから呼び出されてるんだろう~ とか、不具合の原因が上流のメソッドにある場合も多いからです。

下記のような関数もあるようですが、やっぱり書くのは面倒ですよね。

debug_backtrace()

⑥プログラム実行中に、変数の値を書き換えられる

上記の④までは、かなりアナログな説明で、駆け出しプログラマーでも理解できると思いますが、そろそろ、デバッガの真の実力について語る時が来たようだ
(`・ω・´)

ここでこんな値が来たら、こう動いてほしい… その動作を確実に把握できますし、意外な値が入ってきたとしたときの動作も確認できます。

⑦プログラム実行中に、ちょっとした式が書ける

Expressionsという機能で、とある変数に何かしたらどうなるんだろう?ということを、式を書いて検証できます。

式をプログラムに書いて、実行!とする試行錯誤の手間が省けますよね。

⑧プログラムの中身が自分で思った通りになっているか確認できる

えー、実のところ、私にはこれが意味深いかな。なんというか、いろんな変数、いろんな関数の動作が、意図したタイミングで意図した通りになっているか、確認したい。

そのために、デバッガを使うことが多いです。そうすると、安心もできますしね。

 


 

もちろん、デバッガは他にも機能があって、非常に便利なのですが、私が思うメリット8選は上記でした。

弊社では、スタッフさんに自由に開発してもらっているので、開発スタイルは個人に任せています。(新人に教えるのはまた別)

デバッガ使うのイヤって気持ちも、わからないでもないんですよね。
デバッガ起動するのに、多少の時間がかかりますからね。

PHPって高速だから、一瞬で実行できるし、ちょっとしたことを調べたいなら、画面出力デバッグでいいと思うんです。

なんで、最終的には早く、品質がいいものができればいいんですけどね。

Python リスト内包表記2 リストの中に複雑な関数を書く

以前、

Python リストの中に関数を書く

って投稿を書きましたが、リスト内包表記の例文として出している

counts = [self.Nsa[(s, a)] if (s, a) in self.Nsa else 0 for a in range(self.game.getActionSize())]

について、掘り下げていなかったので、掘り下げますね!

分解すると、リスト内包表記は

[リストの中身になるもの for i in リストの中の要素の数]

です。

なので、一見複雑なこの式は

self.Nsa[(s, a)] if (s, a) in self.Nsa else 0

の三項演算子でのif文判定と

for a in range(self.game.getActionSize())

の要素の数の部分に分けられます。

なんというか、三項演算子の存在を忘れていたので、前半の書き方について、しばらくわかりませんでした(;^ω^)

この例題だとこの例題で完結しないので、簡単な例です。

s = 1
list = [1,2,3,4]

list2 = list if s in list else 0
print(list2) #[1, 2, 3, 4]が出力される

counts = [ list if s in list else 0 for a in range(10)]
print(counts) #[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], ...] [1,2,3,4]が10個あるリストが出力される

Python 可変性オブジェクトの引数は、関数に渡すと呼び出し側も変わってしまう

私は一番慣れている言語がJava, PHPなので、Pythonのこの流儀になれずによく間違ってしまうので、書いておきます。

def changer(x,y):
    x = 2
    y[0] = ["hogehoge"]

x = 0
L = ["hage", "moke"]

changer(x , L)

print(x) # 0 が出力されます
print(L) # [['hogehoge'], 'moke'] が出力されます

 

xは整数で不変性オブジェクトなので上書きされません。Lはリストで可変性オブジェクトなので変化があります。

ちなみに、下記のように丸ッとリストを変更してしまうと、呼び出し側が変更されませんので、気を付けましょう。

def changer(x,y):
    x = 2
    y = ["hogehoge", "ukiki"]

x = 0
L = ["hage", "moke"]

changer(x , L)
print(x) # 0 が出力されます
print(L) #['hage', 'moke']が出力されます

Android Buildできない Caused by: java.lang.RuntimeException: Job failed, see logs for details at com.android.build.gradle.internal.transforms.ProGuardTransform.transform

表題のエラーでビルドできずに四苦八苦 (>_<)

下記のStack Overflowさんに

https://stackoverflow.com/questions/51535419/taskexecutionexception-while-trying-to-generate-signed-apk

Proguardが

minifyEnabled true

だとむちゃくちゃする

と書いてあったので、

minifyEnabled trueをコメントアウトしたら、Buildできるようになりました…。