Python ArgumentParserでコマンドラインから実行時に強制的に引数を渡させる

きっと書いておかないと忘れるので書いておきます。

ArgumentParserという便利なライブラリがあります。

公式サイトはこちら。

平たく言うと、コマンドラインから

python main.py

って走らせるときに、引数がないと動作しないようにする、とか、ヘルプを表示させたりとか、コマンドラインの引数に応じて、実行することを変えたりすることができるのです。

超シンプルな使い方は下記のようにします。

import argparse

parser = argparse.ArgumentParser(description='Process some integers.')

parser.add_argument('integers', metavar='N', type=int)

args = parser.parse_args()
print(args.integers)

コマンドラインから引数なしで実行すると、次のように表示されます。

 

G:\test>python argparse_sample.py
usage: argparse_sample.py [-h] N
argparse_sample.py: error: the following arguments are required: N

引数を渡すと、次のように引数が表示されます。

G:\test>python argparse_sample.py 5
5

Open AI Gym 初めの一歩

強化学習というのは、機械学習の一つの分野ですが、学習がうまくいっているのかどうか調べるのは難しい課題なんですよね。

そこで、Open AIのGymというツールがあります。

https://gym.openai.com/

なんか、ちょいちょい見る、トンカチみたいなのがゆらゆら揺れてる動画…。これだったんだw

やり方は、次のサイトにある通りですが

https://gym.openai.com/docs/

英語を読むのも「ええい!面倒!!」ということもあると思いますので、超簡単に記載しておきます。

pip install gym

でインスコします。

import gym
env = gym.make('CartPole-v0')
env.reset()
for _ in range(1000):
    env.render()
    env.step(env.action_space.sample()) # take a random action

これで走らせてみると、トンカチが一回転して、画面の外に消えちゃいますねw

他に、山を登る車、

'MountainCar-v0'

ってのもあります。さっきのgym.makeの中身を変えるだけです。

import gym
env = gym.make('MountainCar-v0')
env.reset()
for _ in range(1000):
    env.render()
    env.step(env.action_space.sample()) # take a random action

これも実行してみると、右往左往してまったく山を登りそうにない車が表示されます。
やはり、ランダムに何かを行ってみても何も結果は得られない… という人生の教訓を得た気になりますね!!

ちょっと進めて下記のようにします。

import gym
env = gym.make('CartPole-v0')
for i_episode in range(20):
    observation = env.reset()
    for t in range(100):
        env.render()
        print(observation)
        action = env.action_space.sample()
        observation, reward, done, info = env.step(action)
        if done:
            print("Episode finished after {} timesteps".format(t+1))
            break

実行すると、ポールが倒れたり、画面の外に行ったりしません。

一瞬おお!と思いますが、落ち着こう。

 

observationというのをprintするようにしたので、次のようにprintされますが

[-0.06550298 -0.62622142 0.12089567 0.99951833]
[-0.07802741 -0.82273366 0.14088604 1.32759199]
[-0.09448208 -0.62964272 0.16743788 1.08210892]
[-0.10707494 -0.4370784 0.18908006 0.846299 ]
[-0.1158165 -0.24496922 0.20600604 0.6185299 ]
….
Episode finished after 16 timesteps

そもそも、この4つの数字なんだ!って話ですよね。

この答え、CartPoleのソースコード見ると書いてありました。(他のところにもかいてほしぃ…)
https://github.com/openai/gym/blob/master/gym/envs/classic_control/cartpole.py

Observation:
Type: Box(4)
Num Observation Min Max
0 Cart Position -4.8 4.8
1 Cart Velocity -Inf Inf
2 Pole Angle -24° 24°
3 Pole Velocity At Tip -Inf Inf

そして、そもそも終了条件ってなんなん??

って思うと、これもソースコード見ると書いてありました。

Episode Termination:
Pole Angle is more than ±12°
Cart Position is more than ±2.4 (center of the cart reaches the edge of the display)
Episode length is greater than 200
Solved Requirements
Considered solved when the average reward is greater than or equal to 195.0 over 100 consecutive trials.

1.ポールの角度(さっきのObservationの3つ目ですね)が±12を超える
2.カートのポジション(さっきのObservationの1つ目ですね)が±2.4を超える
3.エピソードの長さが200以上
4.解決されたと思われる 平均的な報酬が100回の連続したトライアルの中で195を超える

報酬は、1回進めて、倒れなかったら1もらえるので、200回エピソードを繰り返して、195回目まで倒れなければ、そのモデルが優秀ということで、もうOKってことなんですかね。

Actionは左に行くか、右に行くかだけですが、これにVelocityなどが加わって、どのぐらいのポジションを進むかが決定されるようです。

倒れなくなったように見えますが、そうではなく、倒れようとしたところで(doneがTrueになる)env.resetされるので、倒れなくなったように見えるだけです。

 

 

GiHub(Sourcetree)のコミットの取り消し

今回原因不明のバグに遭遇してしてしまい(解決したが)、コミット前の状態に戻そうとしたら思いの外手こずったので、忘れん坊の自分のためにメモを残しておきます。

プッシュ前とプッシュ後で変わってくるので要注意!!

 

・プッシュ前のコミット

プッシュ前のコミットであれば、自分が戻したい位置のコミットにカーソルを合わせ右クリックする。次に、「現在のブランチをこのコミットまでリセット」をクリックする。

・プッシュ後のコミット

プッシュ後となると少し話が変わってくる。自分の消したいと考えるコミット内容にカーソルを合わせ右クリックする。次に、「このコミットを打ち消し…」をクリックする。

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

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