OmniAICreator/Qiita-1.07M huggingface dataset:
レイをトレースしたい　第3.5回　レイマーチング

前回は方程式による解の形でレイの衝突判定をしましたが、それとは別にレイマーチングによる衝突判定をしたいと思います。レイマーチングについては他に詳しい記事もありますので、あまり説明しないこととして実装のみを載せます

参考
https://wgld.org/d/glsl/g009.html


```cpp
#include <bits/stdc++.h>
#include "Eigen/Core"
using namespace std;
using namespace Eigen;
/*
Vector3d
Matrix3d
(i,j)の形で要素アクセス
A.array().sin()で要素ごと演算
A.norm()
A.normalize()
a.dot(b)
*/

const double PI = 3.141592653589793238;
const double PI2 = 6.28318530718;
const double eps = 1e-6;




double df_sphere(Vector3d pos, double size){
    double l = pos.dot(pos);
    return sqrt(l)-size;
}

double hit_sphere(Vector3d center, Vector3d ray, Vector3d camera_pos, double size){
    double a = ray.dot(ray);
    double b = ray.dot(camera_pos-center)*2.0;
    double c = (camera_pos-center).dot(camera_pos-center)-size*size;
    double D = b*b-4*a*c;
    if (D < 0){
        return -1.0;
    }else{
        return (-b-sqrt(D))/(2.0*a);
    }
}


double saturate(double d){
    double ans = 0;

    if(d < 0){
        ans = 0.0;
    }else if(d > 1){
        ans = 1.0;
    }else{
        ans = d;
    }
    return ans;
}

void write_ppm(vector<vector<vector<int>>> pic){
    ofstream out;
    out.open("test.pnm");
    out << "P3" << endl;
    out << pic.size() << " " << pic[0].size() << endl;
    out << 255 << endl;
    for (int i = 0 ; i < pic.size(); ++i){
        for (int j = 0; j < pic[0].size(); ++j){
            out << pic[i][j][0] << " " << pic[i][j][1] << " " << pic[i][j][2] << endl;
        }
    }

}

class camera{
    public:
        camera();
        Vector3d direction;
        Vector3d position;
        double angle;
        double rad_ang_half;
    Vector3d ray(double x, double y){
        Vector3d temp;
        temp << sin(rad_ang_half)*x, sin(rad_ang_half)*y, cos(rad_ang_half);
        temp = temp.normalized();
        return temp;
    }
    private:
        
};

camera::camera(){
    angle = 60;
    rad_ang_half = angle*PI/180;
    direction << 0,0,1;
    position << 0,0,-3;
}

int main(void){
    int height = 512;
    int width = 512;
    double xstep = 2.0/width;
    double ystep = 2.0/height;
    vector<vector<vector<int>>> pic;
    pic = vector<vector<vector<int>>>(height,vector<vector<int>>(width,vector<int>(3,255)));
    camera cam ;
    Vector3d sp_pos;
    sp_pos << 0,0,0;
    const int march_max = 64;
    for (int i = 0; i<height; ++i){
        for(int j = 0; j < width; ++ j){
            double u = xstep*j-1.0;
            double v = 1.0-ystep*i;
            Vector3d ray = cam.ray(u,v);
            Vector3d rpos = cam.position;
            double rlen = 0.0;
            for (int k = 0; k < march_max; ++k){
                double dist = df_sphere(rpos,1.0);
                rlen += dist;
                rpos = cam.position + rlen*ray;
            }

            double is_hit = df_sphere(rpos,1);

            if (abs(is_hit < 0.0001)){
                pic[i][j][0] = 0;
                pic[i][j][1] = 255;
                pic[i][j][2] = 0;
            }

        }
    }
    write_ppm(pic);
    return 0;
}
```

出力は前回と同じものになります。レイマーチングは衝突判定に使う距離関数の合成によって様々な形状が描きやすいことがメリットだと思ってるのですが、どうにもCPU演算では重いようでGLSLによるフラグメントシェーダでの実装などをとったほうが良さそうです
$ conda install opencv で Ver3.4.2 ならインストールできた 2019年 4月

Anaconda に OpenCV インストールするのに，
以前はできなかったと記憶している

```
$ conda install opencv
```
でもインストールできてしまいました嬉（ちなみにホスト OS は Windows 7 と Ubuntu 18.04.1 LTS）
ただし Version 3.4.2 でした泣

最新版 4.1.0 には従来どおり

```
$ conda install -c conda-forge opencv
```
https://anaconda.org/conda-forge/opencv
railsのいろいろなこと

#はじめに
Railsの勉強を初めてしばらく経つが、ここで知識をもう一度おさらいしていこうと思い、この記事をまとめることに至った。
主にここでは見出しと細かな知識をまとめていき、何かもう少し詳しく調べていきたいと思った時は、その部分を新たな記事としてまたまとめ直そうと思う。

##contorller, mdoel作成
`rails g`コマンドを用いてcontrollerを作成する時は、作成したいcontroller名を複数形にして作成する。

```
rails g controller tweets
```

同様に、modelを作成する時は、作成したいmodel名を単数形で作成する。

```
rails g model tweet
```

controllerは複数、modelは単数形ということに注意。

##<%= yield =>
application.html.erbに記述されている`yield`だが、これはこの部分をそれぞれのビューファイルに置き換えることを示している。
またapplication.html.erbは全てのページに共通するヘッダー、フッター部分となる。

##<%= %> と <% %>
rubyのコードをhtmlでも用いたい時は、<% %>でコードを挟む必要がある。
またそこに<%= %>に変えると、変数を用いてそれを展開してビューに表示することができる。

##params
paramsとはRailsにて送られてきた値を受け取るためのメソッドである。基本は、ハッシュオブジェクトと捉えても良い。送られてくる情報は、getのクエリパラメータとpostでformを用いて送信されるようになっている。
受け取り方は`params[:カラム名]`で受け取ることができる。

newのビューでformを用いてデータを送信、createのcontrollerでparamsを受け取るのが一般例。その時の呼び出しだが、ストロングパラメータ(permitメソッド等)として設定することで、不要なカラムを取り出すことのないようにしている。

```tweet_controller.rb
def create
  Tweet.create(tweet_params)
end

private
def tweet_params
  params_permit(:name, :text)
end
```

##binding.pry
`gem pry-rails`を取り込むことでbinding.pryを使うことができる。これを挿入した部分において、Railsの処理を止めることができる。処理を止めている間はコンソールと同様に扱うことができるため、変数の値などを確認することができる。`exit`コマンドで中断していた処理を再開することができる。

##gem devise
gemfileにて`gem devise`をインストールすることで、ユーザーのログインを管理できるようになる。そのあとに、`rails g devise:install`コマンドにより必要なファイルの生成を行うことができ、実際にログイン機能を持ったモデルを作成する時は`rails g devise user`をすることで、devise機能によりログイン機能を持ったuserモデルを作成することができる。

##カラムの追加
テーブルにカラムを追加する時は、マイグレーションファイルを作成する必要がある。コマンドは`rails g migration AddNicknameToUsers nickname:string`キャメル形式で行う。この場合では、Userテーブルにnicknameカラムをstring型で追加する。
また削除する時は、`rails g migration RemoveNicknameFromUsers nickname:string`のコマンドを用いる。

##アソシエーション
モデル間の結びつきを表現するための手法。親モデルには`has_many :[子供モデル名]`、こモデルには`belongs_to :[親モデル名]`をつけることにより、モデル間の親子関係の結びつきを表現することができる。
そのほかの条件として、子モデルの方に所属を明示する`親モデル名_id`というカラムを準備しておく必要がある。
参照方法は直感的に扱うことができるようになり、親モデルのカラム.子モデル名.子モデルのカラム名、のような形で、親コントローラの中でも子モデルのカラムを参照することができるようになる。

##includesメソッド
なんとなく使っていたincludesメソッド、もう一度見返したらこれはn+1問題を解決するためのものだった。そもそもn+1問題は、データベースへのSQL文の発行が多くなってしまう問題である(詳しくはまた今度)。
そのためこの問題を解決するために、includes(モデル名)とすることで関連しているレコードも同時に取得することが可能なる。

##ネスト
ネストとは、ある記述に入れ子構造でもう一つ記述をすることをいう。色々な面においてこのネストが使われるが、今回はルーティングにおいてのネストに注目したい。
ルーティングでネスト構造を用いて記述した際は、中の入れ子のモデルの情報に外の入れ子の情報を付随して用いることができる。具体的には、paramsの情報として親のネストの情報を利用することもできる。アソシエーション先のレコードのidをparamsに追加しているということ。

#最後に
この記事は随時更新して言うつもりです。自分の知識の引き出しを増やしていきたい所存。
Watson StudioのJupyter NotebookからICOSへファイル出力をする

Watson StudioのJupyter NotebookからICOS(IBM Cloud Object Storage)にファイルを出力する方法のメモです。
それ以外のファイルの取り扱いに関しても整理してみました。
具体的には、以下の1から4の操作です。
ICOSへのファイル出力は4の操作です。

![WS000000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404032/f2ca4a39-39a3-1282-ffb3-7f2ef44cc434.jpeg)


## 1. PCからICOSへアップロード
Watson Studioを利用している場合は、「Data Assetsへのデータの登録」という操作になりますが、物理的にはファイルはICOSに置かれます。
プロジェクトのAssets画面等で、1010マークをクリックして、アップロードしたいファイルをドラッグドロップするだけです。
(日本語が含まれる場合は、ファイルのエンコードはUTF-8にして下さい)

![WS000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404032/ee7565f2-c49b-ad46-6e1b-6b7a1950095b.jpeg)



## 2. ICOSのファイルをJupyter notebookに取り込む
Jupyter Notebookを起動して、1010マークをクリックし、取り込みたいファイルを「Insert pandas DataFrames」してください。

![WS000002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404032/dc75003f-75ae-a39d-0af9-d7decbe6867c.jpeg)

以下のようなコードが自動生成されます。

```py3
import types
import pandas as pd
from botocore.client import Config
import ibm_boto3

def __iter__(self): return 0

# @hidden_cell
# The following code accesses a file in your IBM Cloud Object Storage. It includes your credentials.
# You might want to remove those credentials before you share your notebook.
client_ABC = ibm_boto3.client(service_name='s3',
    ibm_api_key_id='xxx',
    ibm_auth_endpoint="xxx",
    config=Config(signature_version='oauth'),
    endpoint_url='xxx')

body = client_ABC.get_object(Bucket='xxx',Key='potato_list.csv')['Body']
# add missing __iter__ method, so pandas accepts body as file-like object
if not hasattr(body, "__iter__"): body.__iter__ = types.MethodType( __iter__, body )

df_data_1 = pd.read_csv(body)
df_data_1.head()
```
このセルを実行すると、ファイルはPandasのデータフレームに取り込まれて、データフレームの最初の10行が表示されます。
![WS000003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404032/03ddf9f4-3620-11f6-ce18-9a7cbb5633b0.jpeg)

## 3. ICOSのファイルをファイルシステムに取り込む
以下の1行でできます。
Bucketやkeyの指定は、上記のclient_ABC.get_object の内容をそのままコピーして下さい。
Filenameはファイルシステムに取り込んだときに付けたい任意の名前を指定してください。

```py3
client_ABC.download_file(Bucket='xxx',Key='potato_list.csv',Filename='potato_list_copy1.csv')
```
ファイルシステムに保存されたファイルは、以下のように、lsやcatで確認、参照することができます。
![WS000004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404032/2a3b93b5-bdd5-3993-8bfb-2dfe676832ac.jpeg)

## 4. ファイルシステムのファイルをICOSへアップロードする
ここがこの記事のメインですが、操作は1行だけです。

Filenameはファイルシステムにあるファイルを指定してください。keyはICOS上のファイル名として、任意の名前を指定してください。

```py3
client_ABC.upload_file(Filename='potato_list_copy1.csv',Bucket='xxx',Key='potato_list_copy2.csv')
```
実行しても何も出力はありません。
確認するには、プロジェクトのAssetsタブ等を開いて、1010マークのFilesから確認してください。

![WS000005.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404032/829bf8b1-807c-a0a6-6d42-89ebe25854a7.jpeg)

この時点ではData Assetsとして登録されていませんので、以下のようにすることでData Assetsとして登録することも可能です。

![WS000006.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404032/ea7cfe6c-2a62-8bb1-02e8-7a04eab4b090.jpeg)
/mysql/init.d:/docker-entrypoint-initdb.dが実行されない。

docker-composeに
**- ./mysql/init.d:/docker-entrypoint-initdb.d**
こんな感じで書いたらinit.dディレクトリにある.sqlとか.shとか実行してくれるらしいので試して見たところ実行された感じがしなかった。

```
  mysql:
    image: mysql:5.6
    ports:
    - 3306:3306
    environment:
    - MYSQL_ROOT_PASSWORD=root
    - MYSQL_DATABASE=message
    - MYSQL_USER=user
    - MYSQL_PASSWORD=user
    volumes:
    - ./mysql/init.d:/docker-entrypoint-initdb.d
    - dbdata:/var/lib/mysql
```

なので一旦コンテナを全部削除して再度buildし直したら別のエラーが出た
$ docker-compose up --build を実行したら別のエラーが出た

```
[ERROR] Plugin 'InnoDB' init function returned error.
[ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
[ERROR] Unknown/unsupported storage engine: InnoDB
[ERROR] Aborting
```

以下やったこと

```
# とりあえずコンテナを全部止める
$ docker-compose down

$ docker volume ls
# たくさんのVolumeが出てきた、エラーでストレージがなんとかかんとか言ってるので全部削除
$ sudo docker volume rm $(sudo docker volume ls -qf dangling=true)
```

$ docker-compose up --build を実行したら起動しました。
init.dディレクトリに入れておいたファイルも実行されてた。
ソース修正しながら何度も起動したり停止したりを繰り返してたので何処かのタイミングでデータがおかしくなっていたのかもしれない。
一旦全部消してみるは大切だな〜
CI用 beeline コンテナの最新化と軽量化

# 背景

我々のチームでは大容量データの分析のための基盤を運用しており，その中で Hadoop/hive での ETL を CI で廻す作業が多い．CI 用の beeline コンテナとして，当初 mapr のレポジトリを登録して beeline を apt-get で下記のように入れていたのだが，beeline のバージョンが低く，最近更改して hiveserver2 に冗長性を持たせた環境への接続が難しくなって困っていた．

```
RUN curl http://package.mapr.com/releases/pub/maprgpg.key | apt-key add -
RUN echo "deb http://package.mapr.com/releases/v5.2.0/ubuntu/ mapr optional" >> /etc/apt/sources.list
RUN echo "deb http://package.mapr.com/releases/ecosystem-5.x/ubuntu binary/" >> /etc/apt/sources.list
RUN apt-get update && apt install -y --no-install-recommends --allow-unauthenticated mapr-hive && \
        apt-get clean && rm -rf /var/lib/apt/lists/*
RUN ln -s /opt/mapr/hive/hive-1.2/bin/beeline /usr/bin/beeline
```

具体的にはこういうのが動かない．

```
beeline -n hive -u "jdbc:hive2://zk01.example.com:2181,zk02.example.com:2181,zk03.example.com:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2"
```

# 対処方針

ということで，dockerhub にあるものを試してみた．我々のクラスタは Hortonworks Hadoop (cloudera に社としては統合されたが，まだ製品ラインナップは別)なので，素直にやるとすると，[github/akanto/beeline](https://github.com/akanto/beeline) / [dockerhub](https://hub.docker.com/r/akanto/beeline/)か．

で，サクっと動いた．もうこれでいいかとも思ったが，イメージサイズが2GBか……．上記でもともと使っていたのが debian ベースで 557MB．もうちょいなんとかならないかな，ということで今後も最新化に追従するためにも自分で素の Apache Hadoop から alpine ベースで作り直すことにした．

参照したのは[このへん](https://docs.hevodata.com/hc/en-us/articles/360014040414-How-to-install-a-Beeline-Client-to-connect-to-Hive-Metastore)．

# 実装

```
FROM openjdk:8-jre-alpine

RUN apk add bash procps curl jq
RUN mkdir /opt/beeline \
        && curl -SL https://archive.apache.org/dist/hadoop/core/hadoop-3.2.0/hadoop-3.2.0.tar.gz \
        | tar -xzC /opt/beeline \
        && curl -SL https://archive.apache.org/dist/hive/hive-3.1.1/apache-hive-3.1.1-bin.tar.gz \
        | tar -xzC /opt/beeline

ENV HADOOP_HOME /opt/beeline/hadoop-3.2.0
ENV HIVE_HOME /opt/beeline/apache-hive-3.1.1-bin
ENV PATH $PATH:$HIVE_HOME/bin
```

# 結果

690MB．うーん，/opt/beeline/hadoop-3.2.0/share/doc だけでも 589M(圧縮前)とかになってるから，このへん削ればなんとかなりそうだけど，まぁとりあえずこれでいいか．

ref. https://hub.docker.com/r/skame/beeline

# 後日談

冗長化したほうのクラスタにつながるので一安心していたら，古いほうのクラスタにつながらずにCIがコケるという事態に．

```
org.apache.hive.org.apache.thrift.TApplicationException: Required field 'client_protocol' is unset! Struct:TOpenSessionReq(client_protocol:null, configuration:{use:database=default})
```

マジかー，といろいろ調べたところ，`hive-jdbc-1.2.x` と `hive-jdbc-2.x` との間で下方互換性がない，ということのようだ．マジかー．ということで，`skame/beeline:mapr` と `skame/beeline:latest` を併用するという恰好悪い状況に．最新版の beeline で hive-jdbc だけ 1.2 にする手もあるかもしれないけど，面倒だからもうこれでいいや．早く hdp を 3 系に移行してしまおう．

https://community.hortonworks.com/questions/138021/getting-error-required-field-client-protocol-is-un.html
https://blog.suganoo.net/entry/2018/10/10/182058
ざっくりと "ゼロから作るDeepLearning" を読むノート

# この記事は
Deep Learning初心者がざっくりと
["ゼロから作るDeep Learning"(オライリー・ジャパン)](https://www.oreilly.co.jp/books/9784873117584/)
を読むノートです。


# 第6章 学習に関するテクニック
損失関数(loss function)の値をできるだけ小さくするパラメータをみつけたい。=> 最適化問題

機械学習フレームワークには、様々な optimizer が用意されています。

## SGD (Stochastic Gradient Descent) 確率的勾配降下法
- パラメータ: Weight、Gradient、Learning-Rate
- 勾配の方向が、本来の最小値ではない方向を指している課題がある
- ジグザグ状に収束していくため、遠回り

## Momentum
- パラメータ: Weight, Gradient, Learning-Rate, __Verocity__, __alpha__
- Velocity は速度、alpha はインピーダンス(摩擦、空気抵抗みたいなもの)
- ゆれ方向に減速することで、ジグザグ状を軽減する

## AdaGrad (Adaptive Gradient)
- パラメータ: Weight, Gradient, Learning-Rate, __h__
- h はこれまでに経験した勾配の値の2乗和
- 大きく動いたLearning-Rateを次第に小さくしていく

## RMSProp
- AdaGradの改良
- 過去の勾配を少なく、新しい勾配の影響を大きく反映されるようにする

## Adam (AdaGrad + Momentum)
- 原著論文 -> [Adam: A Method for Stochastic Optimization](https://arxiv.org/abs/1412.6980)
- ハイパーパラメータ: Learning-Rate, beta1, beta2
    - beta1: 0.9, beta2: 0.999 が標準値

---
# 重みの初期値
Abemaビデオを、PinP再生するためのブックマークレットを、雑に作った＋もっと使い勝手のいいブックマークレットがあったので紹介する

#### やりたいこと
- [abemaビデオ](https://abema.tv/video)でyoutubeみたくPinP表示したい。 参考:[PC版Chromeがピクチャ・イン・ピクチャに正式対応。](https://japanese.engadget.com/2018/10/20/pc-chrome-youtube/
)
- 調べたら、videoタグで`.requestPictureInPicture()`を叩けば出来そうなことが分かった。 参考:[Picture-in-Picture](https://wicg.github.io/picture-in-picture/
)
- 頑張らない。

#### 出来たもの

`javascript:document.querySelector("#main > div > main > div > div.c-video-EpisodeContainer-thumbnail.c-vod-PlayerContainer-container.c-vod-PlayerContainer-inlined > div > div.c-vod-PlayerContainer-screen.com-vod-VODScreen-container > div.com-a-Video__container > div > video:nth-child(7)").requestPictureInPicture();`

このAPIで他に同じようなことをしてる人いそうだな―、と思って調べたら、もっと汎用性のあるブックマークレットがありました。
abemaビデオ以外にもabemaTV/amazonビデオで動作したので、こちらの方が間違いなく使い勝手が良いです。以下に転載します。

`javascript:document.querySelector("video[src]").requestPictureInPicture();`

https://twitter.com/rikulist/status/1076906609878564864

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">chromeで追加されたpicture in picture (pip)機能、切り替えが.requestPictureInPicture();のようなので現状使えないサイトでは対応するまでお気に入りに登録しとく幸せになれるかも<br>例えばamazon prime videoだとjavascript:document.querySelector(&quot;video[src]&quot;).requestPictureInPicture(); <a href="https://t.co/W7JaT33Xmg">pic.twitter.com/W7JaT33Xmg</a></p>&mdash; りくだい (@rikulist) <a href="https://twitter.com/rikulist/status/1076906609878564864?ref_src=twsrc%5Etfw">2018年12月23日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Qiitaの仕様上、ブックマークレットのリンクの作成は出来ないようです。
もし登録や動作確認したい人は、↑をコピーして、ブックマークのURLに貼り付けてください。

#### やったこと
記憶ベース。使用環境/ブラウザはwindows10 home/chrome。デバッグや調査は省略。

1. abemaビデオを再生中にデベロッパーツールを開く。
2. Elementsタブで`<video>`タグを検索する。
3. 複数あったので、一つ一つ右クリックして→Copy→Copy JS Pathで要素を取得＋PIP化するAPIを着けてconsoleタブで実行。以下を実行でPinP再生成功。
 `document.querySelector("#main > div > main > div > div.c-video-EpisodeContainer-thumbnail.c-vod-PlayerContainer-container.c-vod-PlayerContainer-inlined > div > div.c-vod-PlayerContainer-screen.com-vod-VODScreen-container > div.com-a-Video__container > div > video:nth-child(7)").requestPictureInPicture()`

5. `javascript:;`でブックマークレット化して、冒頭の『出来たもの』の完成。

#### 備考

- 当初は[abemaビデオで、再生対象の動画を『ブラウザ全画面』するブックマークレットを、ものすごく雑に作る。](https://qiita.com/iHok/items/de52f28790a0886206d2)＋ブラウザを最前面に固定で観ようとしていたのですが、数日で無用に。
- CMの所とかで、CMが流れながら本編動画が流れたり、自動遷移した後にPinPの画面が残ってたり、若干不整合があります。
herokuでbash: gunicorn: command not foundが出て動かなくなった件

何がどうなったのかはわからない。

それまでは普通に動いていたものが、
あるとき
`$ git push heroku master`
したら動かなくなってしまった。

rest_frameworkを追加したり、色々している最中なので、原因はそれだと思う。
（ローカルでは問題なく動いている。）

フロント面ではherokuのエラー画面が出て

`$ heroku logs --tail`

してみろというので、言われるがまま確認したところ

```
2019-04-26T01:53:00.814411+00:00 heroku[web.1]: Starting process with command `gunicorn xxxxxx.wsgi --log-file -`
2019-04-26T01:53:02.370146+00:00 heroku[web.1]: State changed from starting to crashed
2019-04-26T01:53:02.305820+00:00 app[web.1]: bash: gunicorn: command not found
```

「gunicornのコマンドが見つからない」とのこと。

確認してみると、確かにrequirements.txtにgunicornがない。

以前はあったはずなのだが…。

```
$ pip install gunicorn
```

をして

```
$ pip freeze > requirements.txt
```

requitements.txtを作りなおして再挑戦。

依然として直らない。

暗中模索していると

https://stackoverflow.com/questions/33021874/heroku-gunicorn-not-working-bash-gunicorn-command-not-found/33024680#33024680

という記事を発見。

> If you have both requirements.txt and Pipfile in the project root, then I would recommend to delete the Pipfile and have all your requirements listed in requirements.txt file (including gunicorn).

プロジェクトルートにrequirements.txtとPipfileが両方あるなら、Pipfileは削除した方が良いよ、と。

確認してみると、確かにPipfileとPipfile-lockが存在している。
意図して作ったものではないので、試行錯誤している時に勝手にできてしまったのだろう。

これらを削除し、requirements.txtを残した上で再挑戦。

直った。
Power Query エディターでテーブルにフィルターを適用するときは、その条件をみっちり確認したほうがよいですよ

テーブルの行に対してフィルタリングをするとき、Excel ワークシート上の操作では気にすることはほぼ皆無なのだけど Power Query エディターの同じような操作ではそうでなかったりするのですよ。

# どういうことか
テーブルに対しこのあと必要な行だけを抽出したい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/bace2dc6-a1d2-706f-72d1-f45a84c09a57.png)
"A" と "B" と "C" だけを仲間にしたいのでそれらを選ぶ操作をした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/ea3ce6e7-69f7-8299-0166-2314dd4b339e.png)
よしよし。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/32c95f72-3cb7-2f85-f362-adc7c54b9fcf.png)
ソーステーブルにあらたな行"F"が現れた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/05486524-0391-fedd-2f08-26753e21ef8d.png)
"F" も仲間に加わった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/c0a11c6e-0f1c-b13d-ff87-68f9cfb56c86.png)

# なぜなのか
"選択"と"除外"という認識がなされていて、効率が良い方をPower Query エディターが決定している
## しきい値は 50%
**選択されているアイテム数が半数以下の場合は選択**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/8fbd44db-4b10-d5db-b584-ea1cc27ba5c3.png)

```text:選択(AかB)
let
    Source = #table(type table [Column1 = text],List.Transform({"A".."E"}, each {_})),
    FilteredRows = Table.SelectRows(
        Source,
        each (
               [Column1] = "A"
            or [Column1] = "B"
        )
    )
in
    FilteredRows
```
**選択されているアイテム数が半数を超える場合は除外**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/f8457299-d5e4-a2a8-867e-c92ea6c27330.png)

```text:除外(D,Eではない)
let
    Source = #table(type table [Column1 = text],List.Transform({"A".."E"}, each {_})),
    FilteredRows = Table.SelectRows(
        Source,
        each (
                [Column1] <> "D"
            and [Column1] <> "E"
        )
    )
in
    FilteredRows
```
>**Table.SelectRows**
Table.SelectRows( table as table, condition as function ) as table
条件関数を満たす行を選択します。
選択 <code>condition</code> と一致する行のテーブルを <code>table</code> から返します。
Returns a table of rows from the <code>table</code>, that matches the selection <code>condition</code>.

条件関数 condition が変わるのです。

# 思ったこと🙄
Excel ワークシートのノリで作業をしたらだめですよ、という話。Power Query はあらかじめ全容を確認できるデータだけを扱うものではないので、得たい結果がどうあるべきなのかきちんと考えながらかな。
ほかにも Power Query エディターには 200 とか 1000 とかしきい値があるのでよーく観察して。

# その他
- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Power BI Desktop を使い始めるには](http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981)
- [Excel で Power Query を使い始めるには](http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9)

# おまけ
選択したいアイテム数が多くて Table.SelectRows の condition がとても長くなる時どうしたらよいのか。
List.Contains とか使うとよい。

```text:List.Containsでおまとめ
let
    Source = #table(type table [Column1 = text],List.Transform({"A".."E"}, each {_})),
    FilteredRows = Table.SelectRows(
        Source,
        each List.Contains({"A", "B", "C"}, [Column1])
        // each (
        //        [Column1] = "A"
        //     or [Column1] = "B"
        //     or [Column1] = "C"
        // )
    )
in
    FilteredRows
```
systemctlコマンドの罠

教えてもらったことをここにメモする

# systemctlコマンドとは
CentOSなどにおいて`systemd`で管理されているデーモンを操作するコマンド

# 罠とは？
仕組みとしてpidファイルを参照しているので、このコマンドの出力は本当にプロセスが動いているかどうかを保証しない
モノビットエンジン版 RPCメッセージを使いパラメータ同期をおこなう

##はじめに
どうもnisokaです。
今回はモノビットエンジンを使って**RPCメッセージによるパラメータ同期**を行いたいとおもいます。

環境は以下の通りです
*win10 64bit, Unity2018.3.3f1, Monobit Unity Networking2.0 v2.6*

##やること
- ルームマッチングシーン⇔ゲームシーン間の画面遷移
- 得点スコアのパラメータ同期

##RPCメッセージについて
RPC(Remote Procedure Call)遠隔手続き呼び出しとはネットワーク越しに別のコンピュータ上の関数を呼び出すことをいいます。情報を飛ばし合うオンラインゲームを作る上では必要になる機能です。
実はMUNにも、同様のRPCメッセージ機能が用意されていますのでこれを使っていきます。
RPCの使用条件は**MonobitViewアタッチ・MonobitEngine.MonoBehaviour継承・ルーム入室状態**です。

以下、RPC記述例です。

```C#:
// 受信メソッド
[MunRPC]
void RecvExampleFunc(int id, string name)
{
    Debug.Log("番号:" + id + ",名前: " + name);
}
// 送信メソッド
monobitView.RPC("RecvExampleFunc", MonobitEngine.MonobitTargets.Others, id, name);
```
送信者自身以外のルーム内プレイヤーに対し、サーバを介して送信します。
([参考：Mun公式-RPC(Remote Procedure Call)](http://www.monobitengine.com/vc/WebDoc/contents/Feature/RPC.htm))

##シーン遷移を通知
ルームマッチングシーンからメインゲームシーンへ遷移します。
現状だとホストだけが遷移してしまい、他プレイヤーが置いてけぼりになります。
そこで、**ホストがプレイヤー全員に遷移すること通知してあげ**ます。
ルームマッチングシーンで必要な人数が集まりマッチングを終えると、ホストだけにゲームスタートボタンが現れます。
そのボタンを押すことでゲームシーンへ遷移するという実装にします。
###RPC送信メソッド
```C#:
if (MonobitNetwork.room.playerCount >= MonobitNetwork.room.maxPlayers)
{
    if (MonobitNetwork.inRoom && MonobitNetwork.isHost)
    {
        if (GUILayout.Button("Game Start"))
        {
            MonobitNetwork.room.open = false;

            monobitView.RPC("RecvGameStart", MonobitEngine.MonobitTargets.All, null);
        }
    }
}
```
`MonobitNetwork.room.playerCount`は現在のルーム入室人数、
`MonobitNetwork.room.maxPlayers`はルーム最大入室可能人数です。
`MonobitNetwork.inRoom`はルームに入室しているかどうかです。
`MonobitNetwork.room.open = false`でホストはルームをクローズして入室不可にします。
最後に`monobitView.RPC("RecvGameStart", MonobitEngine.MonobitTargets.All, null);`で**ホスト自身を含むプレイヤー全員に対してゲーム開始を告げます。**
###RPC受信メソッド
```C#:
[MunRPC]
void RecvGameStart()
{
    SceneManager.LoadScene("InGameScene");
}
```
ホスト含め全プレイヤーがメッセージを受け取ると`SceneManager.LoadLevel("InGameScene");`を呼ばれ、順次InGameSceneに遷移します。

###RPCを使わないScene遷移

```C#:
MonobitNetwork.autoSyncScene = true;
MonobitNetwork.LoadLevel("InGameScene");
```
MUNには`MonobitNetwork.LoadLevel()`というメソッドがあり、これを使うことでRPCのコーディング無しに上記を実現できます。
`MonobitNetwork.LoadLevel()`単体では`SceneManager.LoadScene()`と動作の違いはありませんが、
`MonobitNetwork.autoSyncScene`というパラメータをtrueにすることで、同一ルームのホストがMonobitNetwork.LoadLevel()によるシーン遷移を行ったとき、ホストに合わせてルーム内の全クライアントが同一のシーン遷移を行います。
これにより、RPCのコーディングせずに読み込むゲームシーンを同期できます。

##スコアのパラメータ同期
スコアが変化した場合、ホストだけがスコア計算を行います。
その結果をゲストだけが受け取り、ゲストはそれを自身のスコアへ反映するというプロセスです。

ホスト側ではスコアが変化したときに呼び出す関数を定義します。
RPCの引数には計算後の結果を渡します。

```C#:
public void ChangeScore(int num)
{
    if(MonobitNetwork.isHost)
    {
        this.score += num;
        monobitView.RPC("RecvSyncScore", MonobitTargets.Others, this.score);
    }
}
```
続いて、ゲスト側では計算結果を反映する関数を定義します。

```C#:
[MunRPC]
void RecvSyncScore(int score)
{
    this.score = score;
}
```

##最後に
簡潔にMunRPCの使い方を紹介しました。
考え方さえ分かってしまえば、手順を踏み、用意されているメソッドを呼び出すだけなのですぐに実装できるかとおもいます。
(私はオンラインの考え方がなかなか理解できず困り果てました)

##参考リンク
- [Mun公式-RPC(Remote Procedure Call)について](http://www.monobitengine.com/vc/WebDoc/contents/Feature/RPC.htm)
- [Monobit Unity Networking2.0 公式リンク](http://www.monobitengine.com/doc/mun/)
日本の運転免許証の年齢別保有割合を可視化した

痛ましい交通事故がありました。高齢者の免許保有はどのくらいなのだろうか？気になりました。

## 運転免許統計（警視庁）
調べてみると、警視庁に免許保有のデータがありました。
運転免許統計
https://www.npa.go.jp/publications/statistics/koutsuu/menkyo.html

## 運転免許統計の可視化
そこにあるデータと、人口統計のデータを使って、運転免許証の年齢別保有を可視化しました。

資料のリンクは↓
https://driver-license.herokuapp.com/

### 1. 年齢別人口、運転免許証保有者数、割合
<a href="https://gyazo.com/d9b6475e5132753a13b1b9466305e14d"><img src="https://i.gyazo.com/d9b6475e5132753a13b1b9466305e14d.png" alt="Image from Gyazo" width="940"/></a>

1の図は年齢別人口と運転免許証の保有者数、それと年齢別の保有割合です。30歳から60歳の保有割合は9割を超えますが、60歳以降は保有割合が緩やかに低下していきます。

### 2. 免許証保有者数累計
<a href="https://gyazo.com/3fde401158288473654fbeb3d6ee66c5"><img src="https://i.gyazo.com/3fde401158288473654fbeb3d6ee66c5.png" alt="Image from Gyazo" width="904"/></a>


2の図は免許証の保有割合です。例えば、60歳のところをホバーすると、0.3063655のように出ますが、これは日本で免許証を持つ人のうち、30.6％の人が60歳以上であることを示しています。70歳の値を見ると、0.137・・と出ます。
ここは割合よりも人数の累計の方が状況が分かりやすそうですね。


<a href="https://gyazo.com/87c103a09deffb76dc42ea59743a808c"><img src="https://i.gyazo.com/87c103a09deffb76dc42ea59743a808c.png" alt="Image from Gyazo" width="906"/></a>

上記を変更して運転免許証保有の累計人数が出るようにしました。60歳以上の運転免許保有者が2521万人、70歳以上の保有者が1130万人、80歳以上の保有者が226万人となっています。

### 年代別運転免許証保有者数変化（2001年=> 2018年）
<a href="https://gyazo.com/c1735ef1df070931da52ad809162db83"><img src="https://i.gyazo.com/c1735ef1df070931da52ad809162db83.png" alt="Image from Gyazo" width="900"/></a>

3の図は年代別の免許所保有者数の変化です。2001年と2018年の値を比較しました。17年で、高齢者の免許証の保有者数が激増していることがよく分かります。
75歳以上で切られているのは、2001年の資料にはそこまでしかなかったからです。ちなみに年齢別も見つかりませんでした。

あと、2001年分はPDFしかなかったので、欲しいデータをコピーしてエクセルに張り付けてpandasで加工しました。

## まとめ
以上のように、運転免許証の保有年齢のデータを可視化しました。

データから将来を見ることはなかなか難しいのですが、人口ピラミッドのようなデータは、変化が少なく、これを見れば将来の状況がある程度わかる資料として、有名です。

１と３のデータを見ると、このままだとどうなるかは簡単に予想できそうな気がします。それは変えるべきなのか、そのままで良いのか、その辺りのしっかりとした話が行われてほしいと思い、資料を作りました。ちょうど10連休、色々な年代が集まることも多いでしょう。

ちなみに運転免許証の保有者数は2001年は7555万人、2018年は8231万人と10％ほど増加しています。

コード、データはgithubにあります。
https://github.com/mazarimono/driver-age

## 課題
スマホから見たときに、見やすく、触りやすくするためにどうすればよいか？
Kubernetes Certified Administrator (CKA) 取得したので、勉強方法をまとめてみました

仕事で Kubernetes に関連した仕事を若干していたこともあり、1年ほど前に Kubernetes Certified Administrator (CKA) の受験申し込みだけは済ませていたのですが、いよいよ期限切れが迫ってきたので慌てて試験を受けました。結果としては、無事合格しました。

折角なので、私の勉強方法を晒しておきます。Google 検索をして眺めた感じでは私の勉強法は他の人のやり方とはちょっと違ってましたが、もし良さそうであればご参考にしてください。

# 勉強に使ったコンテンツ
ここ一年(2018年-2019年)で Kubernetes (k8s) に関する日本語の書籍やオンラインドキュメントが充実してきたので、英語が苦手な人でも Kubernetes を体系的に学ぶのがとても簡単になりました。

しかしながら、最新の情報は常に英語で提供され続けており、質・量共に圧倒的に高いので、よほど苦手でないのであれば、英語のコンテンツを用いて勉強した方が良いと思います。

私が学習に使った書籍・オンラインコースは、主に次の4つです。

- Safari Online Learning (旧Safari Books Online)
  - [Kubernetes In Action](https://learning.oreilly.com/library/view/kubernetes-in-action/9781617293726/)
- Linux Fundation が提供するオンラインコース
  - [Kubernetes Fundamentals(LHS258)](https://training.linuxfoundation.org/training/kubernetes-fundamentals/)
- CNCF が提供している、CKA 用の公式カリキュラム (に該当する k8s.ioドキュメント)
  - [CKA_Curriculum_V1.13.0.pdf](https://github.com/cncf/curriculum)
- walidshaariさんのカリキュラム毎にカテゴリ分けされたブックマーク集
  - [walidshaari/Kubernetes-Certified-Administrator](https://github.com/walidshaari/Kubernetes-Certified-Administrator)

基本的には、Kubernetes in Action の内容を全て手を動かして勉強しておけば、試験では合格要件の 74% を大きく上回ることができるはずです。ただし、CRD や Helm 等、一部試験範囲外の内容も含まれているので、試験優先であれば Part III 以降は軽く読み流す程度でも大丈夫だと思います。

Linux Fundation が提供するオンラインコースの LHS258 に付いては、一通りやりましたが、操作性がイマイチで後から復習するのも面倒なので、お金を払ってまで受講する必要はなかったかも。。と思いました。それでもコンテンツ自体は良かったので、短期で一気に勉強したい人にはこちらも良いかもしれません。

walidshaari さんのブックマーク集は、かなりオススメです。実際の試験時は kubernetes.io のコンテンツ(と kubernetes のGitHub)のみ参照が許可されているため、カリキュラムのどの分野の説明が何処にあるかを事前に把握しておけば、試験時間中に調べたいことが出てきても、時間を効率よく使えます。
Chrome ブラウザに当該リンクをブックマークしておくのもオススメですが、どのあたりに何が書いてあるのかを把握しておくだけでも十分かもしれません。

# 試験範囲外だけれど、k8sを使いこなすために役立つオススメ本
CKAは Administrator 向け試験のため、実際に k8s を使ってどのようにアプリを作ったりデプロイすると便利なのか、についてはあまり触れられていません。どちらかというと CKAD(Certified Kubernetes Application Developer) がカバーする範囲にはなりますが、次のコンテンツを一読しておくと、なぜ k8s が便利なのか、どのような用途に適用すると大きな効果が得られるのかが理解できます。

- [Kubernetes Patterns](https://learning.oreilly.com/library/view/kubernetes-patterns/9781492050278/)
  - Part III の Structural Patterns 以降に書かれている Init Container, Sidecar, Adapter, Ambassador は k8s で生産性を高めるための最も大切な Container Design Pattern になります。また、Part Iv の Configuration Patterns は k8s が何にでも使える万能薬ではないことも理解できるようになっているのでとても良い情報だと思います
- [Design patterns for container-based distributed systems](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/45406.pdf)
  - k8s について、作者の Brendan Burns 氏が分散システムの Design Pattern の観点で解説した論文
  - 私は、このドキュメントを読んで、ようやく k8s には何故 Pod という概念が導入されているのか、コンテナ技術を用いて生産性を上げるとはどういうことなのか、について腹落ちできました。k8s を触る前に、一番初めに読んでおけば良かったかもしれません..
- [Designing Distributed Systems](https://learning.oreilly.com/library/view/designing-distributed-systems/9781491983638/)
  - こちらの本も、同じく k8s 作者の Brendan Burns 氏が執筆されたものになります
  - "Kubernetes Patterns" と内容が被る箇所もありますが、どちらも一読しておくと引き出しが広くなりそうです。特に、Batch Computational Patterns が網羅的に解説されているのが素敵です。この辺りを読み進めると、k8s の hadoop 的な側面が見えてきて楽しいです

# おまけ
無事 CKA にパスすると、こんなものが貰えます(電子データだけですが..)
<img width="400" alt="Screen Shot 2019-04-26 at 11.30.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96389/6cdfa6b4-acc3-e9b4-a495-2a2482d42815.png">
Nuxt.jsで静的サイトを作ってみる　〜プロジェクトの起動〜

# はじめに
いままでWordpress,HTML,CSSはいじったことがあるのですが、ちゃんとJavascriptなどを使ってサイトを作ったりしたことないと思って今回Nuxt.jsを触ってみることにしました



# 必要なもの
- Node.js
- npx

Node.jsはここからダウンロードしましょう
https://nodejs.org/ja/

Node.jsが入っていればデフォルトでnpxが入っているか確認しましょう

```
$ npx -v
```

# 雛形ファイルのインストール

```
$ npx create-nuxt-app <project-name>
```

すると7個ほど質問を受けます

1. サーバーサイドのフレームワークを選択します:
 - None (Nuxt default server)
 - Express
 - Koa
 - Hapi
 - Feathers
 -  Micro
 -  Adonis (WIP)
2. 好きな UI フレームワークを選択します:
 - None（後からでも追加できます）
 - Bootstrap
 - Vuetify
 - Bulma
 - Tailwind
 - Element UI
 - Ant Design Vue
Buefy
3. 好きなテスティングフレームワークを選択します:
 - None (後からでも追加できます）
 - Jest
 - AVA
4. Nuxtのモードを選択します。(Universal または SPA)
5. HTTP リクエストを簡単に行うために axios module を追加します。
6. 保存時にコードをチェックするために EsLint を追加します。
7. 保存時にコードを整形するために Prettier を追加します。

# ローカルサーバーの起動
```
$ npm run dev
```
するとブラウザ上で
　
http://localhost:3000
が起動します。

# 参考サイト
https://ja.nuxtjs.org/guide/installation/
色々やった結果　公式が一番しっくり来る気がしました。
VASPの計算結果からDOSを描く

## 経緯

研究でDOSを描きたい場面があり、調べてみると日本語でまとまった記事があまり見当たらなかったので、
まとめておこうと思った。私はVASPを使っているので、その出力ファイルからDOSを描いてみます。

## DOSとは

Density of Statesの略。日本語では状態密度と呼ばれる。
主に固体中における任意のエネルギーに対応する状態、軌道の量を示している。
横軸にエネルギー、縦軸がDOSになることが多い。

詳しく知りたい方は固体物理の本を読んで勉強してみてください。

<!-- https://www.researchgate.net/post/How_might_I_plot_PDOS_and_analyze_elements_contribution_in_PDOS -->

## DOS を書くには

DOSCARの7行目以降の最初の2列をプロットする。

## PDOSとLDOSを書くには

PDOSとLDOSとは何かということについては[こちら](https://www.researchgate.net/post/What_is_the_difference_between_LDOS_and_PDOS_and_how_to_visualize_these_using_VASP2)に書いてあります。
非常にふわっと表現するなら、PDOSはある特定の軌道のDOS、LDOSはある特定の原子のDOS、といったイメージです。

そのPDOSとLDOSを描くための計算の仕方は

1. ISYM=2として計算する
1. ISYM=0、LORBIT=11として再計算する  
（初めからISYM=2、LORBIT=11として計算すると間違った電荷を与えることがあるみたいです）

この計算だとDOSCARにはたくさん行がありややこしいのでPDOSとLDOSのプロットには[p4vasp](http://www.p4vasp.at/)を使うのがおすすめ。

## p4vasp のインストール方法（ubuntu）

p4vaspをWindows上で動かす方法がわからなかったので以下はubuntu上での話になります。
VirtualBoxで仮想のubuntuマシンを動かしてそのうえでp4vaspを導入しました。
(おそらくWindowsでもやりようはあるのですが私には分かりませんでした...)

以下の導入方法は[p4vasp公式サイト](http://www.p4vasp.at/)を参考にしております。

上記のp4vaspサイトにアクセスし、p4vasp をダウンロードします。



端末上で、tgzファイルを解凍します。

```
tar -xvzf p4vasp-x.x.x.tgz
```

解凍されたディレクトリに移動します。

```
cd p4vasp-x.x.x
```

`install.sh`と`install-local.sh`があるのでいずれかを実行します。
両者の違いは[こちら](http://www.p4vasp.at/#/doc/getstarted)を参照してください。私はローカルインストールにしました。

```
bash install-local.sh
```

コマンド`make`がなくて実行できない旨のエラーが表示されたら、

```
sudo apt-get install make
```

としてから再度`bash install-local.sh`してみてください。

<!-- https://vaspcode.blogspot.com/2017/10/install-p4vasp-visualization-package.html -->

## p4vaspを使ってLDOSやPDOSを描く

p4vaspで、LDOSを計算したディレクトリ（LORBIT=11）の vasprun.xml を開きます。

```
p4v vasprun.xml
```



p4vが立ち上がったら、次に左側の`DOS+bands`をクリックします。

![InkedScreenshot from 2019-04-26 10-33-06_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351891/b8d28732-0664-41b5-2b63-ddc0c3b329e5.jpeg)

バンド構造が見たければ`Show/Bands`を選択します。

PDOSやLDOSを可視化するには

- `Electronic/Local DOS+bands control`を選択

![Screenshot from 2019-04-26 10-34-37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351891/b4eb7d03-9989-968c-a3f8-7c2f34439035.png)

- `Atom selection`に自分の見たい原子の元素記号を記入
- `Spin`と`Orbital Selection`もそれぞれ指定
- `Add new line`をクリック

とするとできると思います。

PDOSかLDOSが可視化出来たら、それを.dat形式でエクスポートします。
`Show/export` でOKです。

datファイルには2列で出力されてるはずです。
1列目のデータがエネルギーで、2列目が各原子のDOSの値になっています。
$AB_2$という分子について計算した場合、まず原子Aのデータがあって、その下に原子Bのデータが来ます。
このdatファイルを使えば好きなソフトでプロットをし直せます。

## 終わりに

ところどころ日本語が拙く申し訳ありません。
間違い、捕捉などありましたらご指摘・ご指導のほどお待ちしております。
誰かのお役に立てれば幸いです。

この記事は[こちらのサイト](https://www.researchgate.net/post/How_can_I_perform_density_of_states_plot_from_vasp_output)を参考にさせていただきました。
ログファイルを漁る時にlsコマンドに渡すオプション

教えてもらったものをメモに残しておく
`ls -hltr`

- l・・・ファイル情報を詳細に表示
- t・・・更新時間でソート
- h・・・人間に読みやすい形に(ex. 1000→1kb)
- r・・・ソートを逆から表示

出力結果の更新日、サイズなどを見てどのファイルに自分が欲しい情報が書かれているか目星をつけたりする
Seleniumを使ってアラートポップアップ画面に2つの文字列を入力する方法


# 問題
下のように、ウェブサイトにアクセスした際にポップアップで認証情報(ユーザ名とパスワードの**2つ**)を要求される。
2つ入力がある場合の対応方法がわからなかったので調べてみた。

![AuthenticationRequired.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159980/39654dde-6336-adb6-35ed-b81a74f959f9.jpeg)

結論としては、Tabを入れるという原始的な方法でクリアしました。試してませんが、3つ以上の複数でも同じやり方でできそうです。

# 解決策
## 環境
ホストマシン: Windows10
Python: 3.7
Selenium: 3.141
Driver: geckodriver_v0.23-win64.exe
Browser: Firefox 67.0b5 (32-bit)

## 既存の解決策調査
そもそもこの画面はSelenium的にはalertというオブジェクトのPromptというタイプになるらしい。
alertオブジェクトへの操作については、[こちら](https://www.techbeamers.com/handle-alert-popup-selenium-python/)が参考になりました。
ただ、2つ入力枠があるものに関するやり方がなかなか見つけられず。

[Stack Overflowのこちら](https://stackoverflow.com/questions/33865528/sending-text-in-alerts-in-selenium)が全く同じことで悩んでいたが、以下のような回答をされていた。

> The problem is Selenium cannot identify the authentication popups. That is a limitation of Selenium as far as I know. You can overcome the issue with using java Robot actions to fill out the username and password.

つまりSelenium単体ではできず、RPA的なことを組み合わせる必要があるらしい。
その下ではauthenticateというメソッドでできるとあったが、公式を見ても見つけられず。

> You can try this:
> `driver.switch_to.alert.authenticate('cheese', 'secretGouda')`

## 自分の場合
RPA組み合わせるとかつらいので、入力時にTABを入れることでクリアしました。
TABの入力については[公式](https://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.common.keys)で確認。

```py
# 認証画面が出てきたら、alertオブジェクトにスイッチ
obj = driver.switch_to.alert
# 1つ目の入力と2つ目の入力の間にTABを入れる。
obj.send_keys(USERNAME + u'\ue004' + PASSWORD)
# 最後にOKを押す。
obj.accept()
```

補足としてalertというオブジェクトに関しては、OK、Cancel、(Promptの場合)入力という3つの要素しか想定していないようで、場合によってOKは「承認」とか「Accept」とか別の表現をされているケースもあるようですが、全てaccept()というメソッドでクリックできるようです。send_keysに関してもalertだけ指定すればよいみたい。
node.jsにdash button for nodeをインストールして互換性エラーが発生したときの話

## 概要
販売終了したdash buttonで何かしてみようということで、下記を参考にdash buttonのイベントを取得しようと環境を作った時の話。
>[Amazon Dash Buttonを(正しくない方向で)使ってみた](https://qiita.com/takustaqu/items/8539b33780c9675c8657)

## とりあえずやってみる
少し前に使っていたnode.jsのバージョンがv6.8.1だったので、メジャーバージョン同じなら[Dash Button for Node](https://www.npmjs.com/package/dash-button)を入れれば動くだろうと試してみると見事にMACアドレス取得時に下記のエラーが発生。

### エラー文言
dashボタンのMACを取得する際にnode.jsのバージョンが低いとボタン押下でエラーが発生する。
`$ sudo npm run scan
Scanning for DHCP requests and ARP probes on en0...
/dash_button/node_modules/dash-button/build/MacAddresses.js:12
    let hexStrings = numbers.map(decimal => decimal.toString(16).padStart(2, '0'));
                                                                 ^
TypeError: decimal.toString(...).padStart is not a function
    at numbers.map.decimal (/dash_button/node_modules/dash-button/build/MacAddresses.js:12:66)
    at Array.map (native)
    at Object.decimalToHex (/dash_button/node_modules/dash-button/build/MacAddresses.js:12:30)
    at Object.getEthernetSource (/dash_button/node_modules/dash-button/build/MacAddresses.js:8:25)
    at PcapSession.pcapSession.addListener.rawPacket (/dash_button/node_modules/dash-button/build/cli.js:44:53)
    at emitOne (events.js:96:13)
    at PcapSession.emit (events.js:188:7)
    at PcapSession.on_packet_ready (/dash_button/node_modules/pcap/pcap.js:99:10)
    at packet_ready (/dash_button/node_modules/pcap/pcap.js:44:14)
    at SocketWatcher.pcap_read_callback [as callback] (/dash_button/node_modules/pcap/pcap.js:64:45)`

最初は以前node.jsを使った際の環境をそのまま使ったためv6.8.1で試してエラー発生。
その後いくつかバージョンを変更して最終的にv8.9.1（最新版）で正常起動・・・。（最初から最新版入れておけばよかった）
試したバージョンは下記の４つ。

|バージョン|OK/NG|
|:--|:--|
|v0.12.18|NG|
|v6.8.1|NG|
|v6.11.3|NG|
|v8.9.1|OK|

## 最後に
そして解決した後にdash-buttonの[github](https://github.com/ide/dash-button)を確認すると、最新版はNode 8で動作するという記載を見つける。

> Dash Button runs on Node 8 and up on macOS and Linux.

何か起こったらとりあえず公式を見に行きましょうという教訓。
スクラムまとめ

# 全体の流れ
## 1. ロールを決定
現場の人に全員集まってもらって、各ロールについて説明した後、ロールを決定する。
ロールに最適かどうかの最も大事なポイントは、そのロールで求められていることに一生懸命取り組んでくれるかどうか。

## 2. プロジェクトについて説明
プロダクトオーナーがリードして、次の項目を決定する。

- プロダクトのゴールとミッション
<dl>
<dt>ゴール</dt>
<dd>どういうものを作れないといけないのか</dd>
<dt>現況の共有</dt>
<dd>このプロジェクトで絶対に達成しないといけないことは何か</dd>
</dl>
- エレベータピッチ
- 「我々はなぜここにいるのか」
- インセプションデッキ([スライドのテンプレはこちら](https://github.com/agile-samurai-ja/support/tree/master/blank-inception-deck))

# 3. スプリント計画ミーティング
# 4.  デイリースクラム
# 5. スプリントレビュー
# 6. スプリントレトロスペクティブ

# 用語

|      用語      | 概要                                             |
| :------------: | :----------------------------------------------- |
| アジャイル開発 | 反復的な開発手法。重要なものを優先的に開発する。 |
|     SCRUM      | 作業、会議、成果物を定めたもの                   |

|      ロール名      | 概要                                                         |
| :----------------: | :----------------------------------------------------------- |
|  スクラムマスター  | スクラム開発の進行に責任を持った人。                         |
| プロダクトオーナー | 実現したい要求をリスト(プロダクトバックログ)にして並び替える。 |
|     開発チーム     | 全員フルスタックエンジニア -> 機能横断的なチーム。外部から仕事の進む方を支持されない -> 自己組織化。 |

# 成果物
## 1. プロダクトバックログ(PB)
PBとは実現したい要求をリストにして並べたものです。PBの項目は実現したい順に並べて、優先順位の高い順に開発されます。また、PBは要求が変わったり、新たな要求が追加されたりすることがあり、常に最新の状態に保たれなければありません。

<dl>
<dt>目標の共有</dt>
<dd>PBを作成することにより、チーム内での目標を共有でき、メンバーが同じ向きを向いて開発を進めることができます。</dd>
<dt>現況の共有</dt>
<dd>PBを常に最新の状態を保つことにより、メンバーに現況について連絡することができます。そうすることにより、各メンバーが現況を把握し、同じ目標に向かって、開発を進めることができます。</dd>
<dt>PBの優先度</td>
<dd>1. 超重要<br>2. 重要<br>3. 普通<br>4. なくてもよい</dd>
</dl>
# 会議体
## 1. スプリント計画ミーティング
### 第１部
- ベロシティを考慮した上で、プロダクトオーナーがリードして、プロダクトバックログを作成する。<br>見積もりは
 - なるべくが経験がある人がリードする
 - 開発メンバーが対話を行う
 - カードを使う
 - 素早く、あてずっぽうにベストを尽くす
 - ベロシティを考慮する
- スプリントの計画内容に対しては、全力で取り組むべきだが、達成できなくてもよい。ただし、確実に終わらせる計画を立てる。
- スプリント単位でリリース可能なプロダクトを作成することが求められることを意識して、計画を立てる。

### 第２部
開発チームはどうやってそれを実現するかについて計画する。

## 2. デイリースクラム
毎日15分の朝会。スプリントのゴールを守るために毎日調査。

### 報告内容
- 前回のデイリースクラムからやったこと。
- 次回のデイリースクラムまでにやること。
- 困っていること。

開発チームのメンバーが問題を報告した場合、問題解決に必要な人を集めた別の会議を設定し、開発メンバーの貴重な時間が会議によって、奪われることを回避する。

## 3. スプリントレビュー
開発チームの成果物をプロダクトオーナーが確認する。

### 報告/議論することの例
- 完了できなかったプロダクトバックログの項目について説明
- プロダクトオーナーがプロダクトの状況やビジネス環境について説明する。
- プロダクトバックログに追加すべき項目の有無について議論する。
- プロジェクトを進めるうえで問題となる事項について説明する。
- 現在の進捗を踏まえて、リリース日や完了日を予測する。

## 4. スプリントレトロスペクティブ
スプリントの最後に行う会議。 1時間 / 1週間スプリント。

- プロセスやツールなどの観点で今回のスプリントを検査する。
- うまくいったこと、今後改善すべき点を整理する。
- 今後のアクションプランをつくる。

# その他メモ
- スプリント毎にベロシティを計算
- デイリースクラム、スプリントレビュー、スプリントレトロスペクティブの時間帯の決定
- 参考文献: https://www.amazon.co.jp/dp/4798129712/
【名古屋大学の学生向け】ブックマークバーに登録してワンクリックで学外から論文を読む

# 学外からでも論文を簡単に読みたい
VPNを使います。名古屋大学のVPNについては↓参照
http://www.nul.nagoya-u.ac.jp/db/DBannai/ezproxy/index.html



# スクリプトをブックマークに登録（Chromeの場合）
1. ブックマークバーを右クリック
2. ページを追加
3. 適当な名前をつける
4. URLの欄に以下をコピペ  

```js
javascript:l=window.location;p=l.pathname.split('/');d=p.pop();ll="https://"+l.host.split('.').join('-')+".ejgw.nul.nagoya-u.ac.jp"+p.join("/")+"/"+d+l.search;l.href=ll;
```  
※split('.').join('-')については正規表現.replace(/./g, '-')がうまく行かず、回りくどくなっています。


# 実際に学外から論文にアクセス
1. 学外にいる状態で
2. VPNログインしておく  
https://www.nul.nagoya-u.ac.jp/db/DBannai/ezproxy/  
”電子ジャーナルアクセスサービス”からログインしておく（ページは閉じてOK）
3. 見たい論文のページにアクセスして、先程登録したブックマークをクリック、見れるようになったことを確認
4. 続けて見たい論文があるときは、2を繰り返さずいきなり3でOK！  
※二時間ほど使わないとログアウトすることが考えられるので、その場合2を繰り返す必要が出ます。
svnでbinファイルと誤認される

#やりたいこと

svnでtextファイルなのにbinファイルと誤認されてるのを直したい


# 実践
propsetで設定する。

```shell
svn propset svn:mime-type 'text/plain'  file.txt
```

もしくはpropdelで消してしまえ。

```shell
svn propdel svn:mime-type file.txt
```

# 確認

```shell
svn proplist --verbose   file.txt
```
AWS ECR上のDockerイメージをpullせずにDockerタグをコピーする

やりたいことはタイトルどおり、
AWS ECR上のDockerイメージをpullせずにDockerタグをコピーしたい。

なぜかというと、CIからECSにデプロイするときに、 `hoge:current` を一旦 `hoge:old` に退避して、 `hoge:latest` を `hoge:current` に上書きしたいみたいなことがあるんだけど、イメージがそこそこサイズがでかいと、一旦 docker pull して docker tag して docker push し直すみたいなのが時間がかかる。

AWSの公式ドキュメント見てたら、やりたいことはdockerコマンドを使わずにaws-cliでできそうだったのでやってみたんだけど、

参考: AWS CLI を使用してイメージにもう一度タグを付ける
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/retag-aws-cli.html

CIに組み込もうとすると＋αで若干の工夫が必要だったので、そのへんの補足。


# ミニマム
例として、`hoge:latest` => `hoge:current` にコピーする場合は、こんなかんじ。

```bash
MANIFEST=$(aws ecr batch-get-image --repository-name hoge --image-ids imageTag=latest --query 'images[].imageManifest' --output text)
aws ecr put-image --repository-name hoge --image-tag current --image-manifest "$MANIFEST"
```

これは、まぁAWSの公式ドキュメントに書いてある。

# CIに組み込むための若干の工夫
## はまりポイント1
デプロイが途中で失敗して再ランした場合など、同じイメージダイジェストで同じタグを重複pushすると
ImageAlreadyExistsExceptionで失敗するので、ダイジェストが既に同じでないか事前にチェックしておく必要がある。

つまり

```bash
FROM_DIGEST=$(aws ecr describe-images --repository-name hoge --image-ids imageTag=latest --query "imageDetails[0].imageDigest")
TO_DIGEST=$(aws ecr describe-images --repository-name hoge --image-ids imageTag=current --query "imageDetails[0].imageDigest")
if [[ "$FROM_DIGEST" = "$TO_DIGEST" ]]
then
  # 既にコピー元とコピー先が同じダイジェストの場合は何もしない
  echo "Image already exists. Skipped."
else
  # リモートでタグをコピー
  (略)
fi
```
## はまりポイント2
`aws ecr describe-images` だと指定したタグが存在しない場合にImageNotFoundExceptionで失敗するので
`aws ecr list-images` を使う。
実装してるときに手元からawsコマンドでタグ作ったりしちゃってたから、気づかなかったんだよ。

つまり

```bash
FROM_DIGEST=$(aws ecr list-images --repository-name hoge --query "imageIds[?imageTag=='latest'] | [0].imageDigest")
TO_DIGEST=$(aws ecr list-images --repository-name hoge --query "imageIds[?imageTag=='current'] | [0].imageDigest")
(略)
```

# 完成品
`hoge:latest` => `hoge:current` にコピーする場合は、こんなかんじ。

```bash
# デプロイが途中で失敗して再ランした場合など、同じイメージダイジェストで同じタグを重複pushすると
# ImageAlreadyExistsExceptionで失敗するので、ダイジェストが既に同じでないか事前にチェックしておく
# aws ecr describe-images だと指定したタグが存在しない場合にImageNotFoundExceptionで失敗するので
# aws ecr list-images を使う
# https://docs.aws.amazon.com/cli/latest/reference/ecr/list-images.html
FROM_DIGEST=$(aws ecr list-images --repository-name hoge --query "imageIds[?imageTag=='latest'] | [0].imageDigest")
TO_DIGEST=$(aws ecr list-images --repository-name hoge --query "imageIds[?imageTag=='current'] | [0].imageDigest")
if [[ "$FROM_DIGEST" = "$TO_DIGEST" ]]
then
  # 既にコピー元とコピー先が同じダイジェストの場合は何もしない
  echo "Image already exists. Skipped."
else
  # リモートでタグをコピー
  echo "docker tag copy: latest => current"
  # https://docs.aws.amazon.com/cli/latest/reference/ecr/batch-get-image.html
  MANIFEST=$(aws ecr batch-get-image --repository-name hoge --image-ids imageTag=latest --query 'images[].imageManifest' --output text)
  # https://docs.aws.amazon.com/cli/latest/reference/ecr/put-image.html
  aws ecr put-image --repository-name hoge --image-tag current --image-manifest "$MANIFEST"
fi
```

できたー。

# 余談
本題と関係ないけど、Dockerで動的タグを使うなとか条件反射でツッコミたくなった人は `aws ecs update-service --force-new-deployment` とか `ECS_IMAGE_PULL_BEHAVIOR` でググってくれ。
GraphDBを学ぶ（２）neo4j-clientのインストール(CentOS, Ubuntu, MacOS)

# TL;DR

* グラフデータベース[neo4j](https://neo4j.com/)を触る際に，WebUIだけでなく，CUIでアクセスする[neo4j-client](https://neo4j-client.net/)をインストールします
    * Ubuntu, OSXはパッケージ管理ソフトウェア経由でインストールできます
    * CentOSは[パッケージ](https://build.opensuse.org/package/binaries/home:cleishm/libneo4j-client/CentOS_7)が用意されていますが，ソースからビルドする方法を紹介します

# neo4j-clientのセットアップ

## インストール

* MacOS, Ubuntuはパッケージが用意されているので，[neo4j-clientのドキュメント](https://github.com/cleishm/libneo4j-client#getting-started)に記載のコマンドでインストールできます
* CentOSではパッケージが用意されていないので，```yum```コマンドではインストールできません．そのため，ソースからビルドします

### MacOS

* neo4jクライアントは[homebrew](https://brew.sh/index_ja)でインストールできます

```bash
brew install cleishm/neo4j/neo4j-client
```

### Ubuntu

* ubuntuは，neo4jによってリポジトリが提供されているので，それを使用してインストールします

```shell
sudo add-apt-repository ppa:cleishm/neo4j
sudo apt-get update
sudo apt-get install neo4j-client libneo4j-client-dev 
```

### CentOS（ソースからビルド）

* ```peg```，```libcypher-parser```, ```libneo4j-client```の順にインストールします

* 最初の準備：ビルドに必要なパッケージをインストールします

```bash
sudo yum -y groupinstall 'Development tools'
sudo yum -y install openssl-devel libedit-devel
```

* [peg](http://piumarta.com/software/peg/)をインストールします
    * 0.1.18で確認しましたが，最新バージョンを確認してください
    * 下記でエラーが起きなければ，```/usr/local/bin/{peg,leg}```が作られます

```bash
cd ~/src/
wget http://piumarta.com/software/peg/peg-0.1.18.tar.gz
tar xzvf peg-0.1.18.tar.gz
cd peg-0.1.18
make
sudo make install
```

* [libcypher-parser](https://github.com/cleishm/libcypher-parser)をインストールします
    * githubからcloneしてインストールします

```bash
cd ~/src/
git clone https://github.com/cleishm/libcypher-parser
cd libcypher-parser
./autogen.sh
./configure
make -j4
sudo make install
```

* [libneo4j-client](https://github.com/cleishm/libneo4j-client)をインストールします
    * ポイントは， **PKG_CONFIG_PATH** の指定です
    * ```/usr/local/lib/pkgconfig```はデフォルト設定だとpkg-configの検索パスに入っていません

```bash
cd ~/src/
git clone https://github.com/cleishm/libneo4j-client
cd libneo4j-client
./autogen.sh
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure
make -j4
sudo make install
```

# neo4j-clientの使い方

* インストールが無事完了すると，```neo4j-client```コマンドが使用できます
    * ユーザ名（```neo4j```など）と接続先ホスト（```localhost```）を指定すると，neo4jサーバに接続できます
    * ```neo4j>```プロンプトにCypher言語でクエリを投入します
    * ```:status```などと入力すると，接続状況を確認できます

```bash
neo4j-client -u neo4j localhost
Password:
neo4j-client 2.2.0
Enter `:help` for usage hints.
Connected to 'neo4j://neo4j@localhost:7687' [Neo4j/3.5.4]
neo4j> :status
Connected to 'neo4j://neo4j@localhost:7687' [Neo4j/3.5.4]
```

# 参考

* [neo4j-client](https://neo4j-client.net/)
* [peg](http://piumarta.com/software/peg/)
GraphDBを学ぶ（１）neo4jのコンテナ稼働

# TL;DR

* Graph DBについて理解を進めるために，グラフデータベース[neo4j](https://neo4j.com/)を触る手順を紹介します
    * 本記事では，コンテナでneo4jサーバを立ち上げて，WebUIで動作確認します

# この記事について

* GraphDBは，Webに資料がたくさん掲載されています
    * 「つながりに注目したデータベース」と言われることが多い
        * そもそも結合(Join済み)のテーブル群を持つようなイメージか？
* いきなり難しすぎてわからなかったので，この記事をスタートとする一連の記事で，以下の手順を追って進めていくことにします
    * GraphDBサーバ（neo4j）を立ち上げる　(この記事で実施)
    * WebUIでノードの登録，エッジの登録を行ってみる
    * neo4jをCUIで扱うためのneo4j-clientのインストール
    * 既存のRDBMSのテーブルを登録してみる
    * いくつかのクエリを投げてみる
    * 最終的に，OLTPベンチマーク[TPC-H](http://www.tpc.org/tpch/default.asp)のテーブルをGraphDB表現でデータベースに格納して，実行することを考えます

# Dockerでneo4j導入

* GraphDBの代表的なサービスのひとつである，[neo4j](https://neo4j.com/)を実行します
    * 不揮発ボリュームはカレントディレクトリの```neo4j```をマウントします

```bash
docker run -d \
    -p 7474:7474 \
    -p 7687:7687 \
    -v ${PWD}/neo4j:/var/lib/neo4j/data \
    neo4j
```

* ```localhost:7474```にブラウザ（chromeなど）でアクセスすると，Neo4jブラウザにアクセスできます
* Neo4jサーバへのアクセス情報を聞かれるので，下記の初期情報でログインします
    * ![01_setup.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/2f764133-e883-b081-c2df-d9276b9ae716.jpeg)

| フォーム名 | 初期情報 |
|---|---|
|Connect URL | bolt://localhost:7687|
|Username | neo4j|
|Password | neo4j|

* 最初にパスワードの変更が求められるので，適切なパスワードに変更します
    * ![02_password.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/569cf7cf-5bbe-3e1c-1e5a-7d43b62b9da2.jpeg)

* 画面上部にあるコンソールを通して，[Cypher](https://neo4j.com/developer/cypher/)なる言語でクエリを発行します
    * ![03_console.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/799c9a36-8e9c-6d7b-88fc-590445681c7d.jpeg)

* 上図に記載の通り，```bolt://localhost:7687```で，他のサービスから稼働中のneo4jに接続することができます

# 参考

* [Neo4j](https://neo4j.com/)
* [Cypher Query Language](https://neo4j.com/developer/cypher/)