OmniAICreator/Qiita-1.07M huggingface dataset:
git logに出てこないコミットの内容を確認する


rebabse で squash したコミットの中に最新のソースには残っていないコードがあった。
↓
それを復活させる必要がでてしまった。
↓
コピペで済ませたいのでコードが存在したときの hash が知りたい。
↓
けど squash したコミットは git log では hash が確認できない。
↓
困った。

という時のお話。

当たり前のことなのかもしれないが、備忘録としてメモメモ。

## Answer

`.git/logs/HEAD` を見る。

## 詳しく

※ 実際に復活させたかったのは仕事のコードなのでここには載せられません。代わりに OSS で説明します。

これが `git log` の状態。
最後のコミットがいくつかのコミットを squash したもの。
当然 squash されたコミットは出てこない。

```
$ git log
commit bda4848fdbff6bf95fe45eeaae0d972cce1837ac
Author: tommarute <tommarute@gmail.com>
Date:   Wed Dec 19 19:55:42 2018 +0900

    marathon-sd - use Tasks.Ports instead of PortDefinitions.Ports if RequirePorts is false (#5022)

    Signed-off-by: tommarute <tommarute@gmail.com>

commit dbd1d58c894775c0788470944b818cc724f550fb
Author: Simon Pasquier <spasquie@redhat.com>
Date:   Mon Dec 17 16:12:01 2018 +0100

    *: cut v2.6.0 (#5008)

    Signed-off-by: Simon Pasquier <spasquie@redhat.com>

```

しかし `.git/logs/HEAD` には log が残っている。

```
$ less .git/logs/HEAD
(omit...)
612e4f44dd3c9d11452fa469c8658850365e3ee0 3bdfd8f909275f08a84fe59aac5529fbc898d075 tommarute <tommarute@gmail.com> 1545911430 +0900      commit: Rename marathonTestAppListWithPortDefinitionsRequirePorts and its test
3bdfd8f909275f08a84fe59aac5529fbc898d075 25eb66b5c26b2422e52a1b3412e39bed0f768cd3 tommarute <tommarute@gmail.com> 1545911520 +0900      commit: Undo marathonTestAppListWithPortDefinitions
25eb66b5c26b2422e52a1b3412e39bed0f768cd3 76f2adc84401a2def5d8c7c34bd445a1f98f3cc7 tommarute <tommarute@gmail.com> 1545911700 +0900      commit: Remove marathonTestAppListWithContainerNetworkAndPorts
```

あとはお目当てのコミットの hash を URL に入れてブラウザで見るだけ！

`https://github.com/tommarute/prometheus/commit/{hash}`

以上
matplotlib: 箱ひげ図 + 点のプロット

(完成形ではなく、そのうち拡張します)

matplotlibで箱ひげ図を描くことがあったのですが、要望として「どのように各点が散らばっているか、図示してほしい」と言われました。
seabornを利用すれ簡単にできそうですが、matplotlibだけで試しました。

```python
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
import pandas as pd

def show_boxplot(data, xvar, title="", ylabel=""):
    '''
    data:   taple data
    xvar:   array label data for each value name
    title:  string
    ylabel: string
    '''
    fig, ax = plt.subplots()
    bp = ax.boxplot(data)
    ax.set_xticklabels(xvar)
    ax.set_ylabel(ylabel)
    ax.set_title(title)

    for y, i in zip(data, range(len(xvar))):
        # "jitter" to the x-axis 
        x = np.random.normal(i+1, 0.05, size=len(y))
        ax.plot(x, y, '.', color="C{}".format(i))

    ax.grid()
    plt.show()

data1 = np.random.normal(50, 10, 100)
data1 = np.append(data1, 100)             # 外れ値
data2 = np.random.normal(45, 15, 100)
xvar = ["data1", "data2"]
show_boxplot((data1, data2), xvar)
```

以下のように表示されます。
![matplot_boxplot.png](https://qiita-image-store.s3.amazonaws.com/0/292158/46ec92ab-1205-0c50-7f2e-ff7a08cd4910.png)
DynamoDBに複数項目を追加する

備忘録としてまとめます。

## はじめに
複数項目の追加をputとbatchWriteの2パターンの方法でやってみました。
AWS.DynamoDB.DocumentClientを使用します。

飲み物テーブル(DRINK)に飲み物名(name)と値段(price)の項目を追加します。
サンプルコードは関数内での使用を想定したものです。

## put を使う
forでまわして1件ずつ追加をします。

```javascript
const aws = require('aws-sdk');
const docClient = new aws.DynamoDB.DocumentClient();

function put() {
    var promise = new Promise(function (resolve) {
        // 追加するアイテムたち
        var items = [
            { name: 'コーヒー', price: 230},
            { name: '紅茶', price: 230},
            { name: 'オレンジジュース', price: 210}
        ];
        
        // 1件ずつ追加する
        for (var i = 0; items.length > i; i++) {
            const params = {
                TableName: 'DRINK',
                Item: {
                    name: items[i].name,
                    price: items[i].price
                }
            };

            docClient.put(params, function (err, data) {
                if (err) {
                    console.log('[ERROR] ' + err);
                    resolve(null);
                } else {
                    resolve(data);
                }
            });
        }
    });
    return Promise.all([promise]);
}
```

## batchWrite を使う
一度にたくさん追加できるbatchWrite さんです。

```javascript
const aws = require('aws-sdk');
const docClient = new aws.DynamoDB.DocumentClient();

function put() {
    return new Promise(function (resolve) {
        // 追加するアイテムたち
        var items = [
            { name: 'コーヒー', price: 230},
            { name: '紅茶', price: 230},
            { name: 'オレンジジュース', price: 210}
        ];

        // 追加する項目のオブジェクト生成
        var putRequest= [];
        items.forEach(function (item) {
            let obj= {
                PutRequest: {
                    Item: item
                }
            };
            putRequest.push(obj);
        });

        // テーブルの指定・追加項目をセット
        var params = {
            RequestItems: {
                DRINK: putRequest
            }
        };

        docClient.batchWrite(params, function (err, data) {
            if (err) {
                console.log('[ERROR] ' + err);
                resolve(null);
            } else {
                resolve(data);
            }
        });
    });
}
```


リクエスト構文(batchWriteに渡すparameterの部分)は以下です。

```javascript

var param = {
    RequestItems: {
        "テーブル名": [
            {
                PutRequest: {
                    Item: {
                        "項目名1": "値",
                        "項目名2": "値"
                    }
                }
            },
            {
                PutRequest: {
                    Item: {
                        "項目名1": "値",
                        "項目名2": "値"
                    }
                }
            }
        ]
    }
 }
```


###### 余談：batchWrite 失敗時
スループットによる追加失敗時はUnprocessedItemsにエラーデータ(未処理データ)が入ります。
項目名の指定ミスなどは追加前に拒否をされるためUnprocessedItemsではなくValidationExceptionとしてエラーに入ります。

### 感想
batchWrite の存在を知らずに無理くり put をしていましたが、とても便利ですね。
25件以上の追加エラーではUnprocessedItemsに入ると思ったのですが、でてきたのはValidationExceptionでした。大量追加の方法は使う機会ができたら調べてみようと思います。
slimをerbにだいたい変換する

# 概要
* 表題ままですが、過大な期待はしないでください:relaxed:

# 目的
* erbメインのプロジェクトで、web上のslim形式のファイルをコピペしてerbファイルに使いたいという、 ~~意識が低い~~ アプリです。
* 。。。といいつつ個人的には結構便利につかっています。コピペでざっくり概要つかむと便利だし。

# 制限
* erbに変換といいいながら、Slimが付け加えるerbの箇所はエスケープ表記が入ります。
* 後述の動作動画を見てもらえばわかりますが、修正しないと使えないので、まあ、ゆるーい気持ちでつかってください。
 
# サイト
https://like-slim2erb.herokuapp.com/

# コード
https://github.com/junara/like_slim2erb


# 動作
* erbが埋め込まれていないslim
[![Image from Gyazo](https://i.gyazo.com/b589d7147d7e83963ce21056f1fe5df9.gif)](https://gyazo.com/b589d7147d7e83963ce21056f1fe5df9)

* erbが埋め込まれているslim
[![Image from Gyazo](https://i.gyazo.com/6ee2c265bdc5e7be8d46423dd14443b1.gif)](https://gyazo.com/6ee2c265bdc5e7be8d46423dd14443b1)

# 原理
* [Class: Slim::ERBConverter](https://www.rubydoc.info/gems/slim/Slim/ERBConverter)の `call` を叩いているだけです。

# コード
重要なのはここだけです。フォームで渡されたテキスト（slim） を `Slim::ERBConverter.new.call(@slim_text)` で処理して表示します。

```app/controllers/home_controller.rb
class HomeController < ActionController::Base
  def index
    @slim_text = params[:slim] && params[:slim][:text]
    @erb_text = @slim_text ? Slim::ERBConverter.new.call(@slim_text) : nil
  end
end
```

以上。
Go#4

##なかなかわからなかったエラー
dataが定義されてないよ！！とういうエラーが10個くらい、、、
var data ... でも data := ...でも　func data ...でもなかった。<img width="291" alt="スクリーンショット 2019-02-10 19.22.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/239663/1579b63f-2f59-0a9d-6780-9d12391d2633.png">

階層はこんな感じなんだけど

dataはデータ系(`model`)のもの　`package名　data`
public,templateは(`view`)
その他は`controller`です。
railsの怠けが抜けてなくて、階層同じだし勝手に読み込んでくれるやろ、、、ってなめてた、

#main.goとはrout_~~.goでdataを使う時は`import "./data"`が必要！！！

TAKE CARE!!!

a tour of goとかなんもやらずにいきなりアプリ作ろうとしたバチですね。
Failed building wheel for cryptography というエラーが出た時

[setup script exited with error: command 'x86_64-linux-gnu-gcc' failed with exit status 1](https://stackoverflow.com/questions/26053982/setup-script-exited-with-error-command-x86-64-linux-gnu-gcc-failed-with-exit)

$ sudo apt-get install python-dev

大事なのは２系や3.3, 3.4, 3.5, 3.6, 3.7それぞれ違うものをインストールしないと解決しない事。
cocoapods使わないでreact nativeでgoogle mapsを表示する

# 目的
cocoapodsを使わずにgoogle mapsをreact nativeのプロジェクトで表示させる。
cocoapodsを入れて余計な依存関係を増やしてエラーと戦いたくないのでgoogle maps SDKとの連携は手動で行う。

# 環境
Mac
Xcode10
react native 0.57


# 手順
1.

https://github.com/react-native-community/react-native-maps/blob/master/docs/installation.md

```
yarn add react-native-maps
```
npmでももちろん良い

※※react-native linkはしてはいけない


2.
https://developers.google.com/maps/documentation/ios-sdk/start
のstep1, step2(install manually), step3, step4を行う。
view画面はreactで、pod installはしないのでstep5以降は飛ばす。

xcode projectにframework関連ファイルを追加する時、
GoogleMaps.bundle以外は↓画面のようにチェックをつける。
GoogleMaps.bundleの追加の時はcopy items if neededのチェックを外す

<img width="711" alt="スクリーンショット 2019-02-10 18.26.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/283557/1c1d4331-7cb7-0ebf-812e-0ea2ecec54ba.png">


3.
手順2と同じようにnode_modules/react-native-maps/lib/ios/AirGoogleMapsとnode_modules/react-native-maps/lib/ios/AirMapsをxcodeプロジェクト/Frameworks下に追加する。
参考
https://github.com/react-native-community/react-native-maps/issues/693

この時上画面のようにチェックする。

ここまで終わると
<img width="265" alt="スクリーンショット 2019-02-10 18.46.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/283557/045d13ed-895a-1e54-bdf2-52f30eef3e79.png">

こんな感じに追加されているはず。

4.
Build Settings →　Search Paths → Framework Search Pathsに
```$(HOME)/Documents/GoogleMaps-2.7.0/Base/Frameworks```
```$(HOME)/Documents/GoogleMaps-2.7.0/Maps/Frameworks```
を追加する。
DebugとRelease両方に追加する。
追加しないと、AppDelegate.mの @ import GoogleMaps;がnot foundエラー吐く。

5.
Build Settings →　Apple Clang - Preprocessing → Preprocessor Macrosに
```HAVE_GOOGLE_MAPS=1```
を追加する。
参考
https://github.com/react-native-community/react-native-maps/issues/2573

<img width="569" alt="スクリーンショット 2019-02-10 18.54.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/283557/03823cdd-4a62-cdf0-b69d-d1af48c8d28f.png">

これをやらないと
Use of undeclared identifier 'overlay'エラーがでる

<img width="277" alt="スクリーンショット 2019-02-10 17.53.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/283557/55afa95c-49ab-0dad-d454-0c1fc0a660da.png">


ここまでやればビルドはできる。

6.
実際にコンポーネントを使ってみる。
使い方はhttps://github.com/react-native-community/react-native-maps
を見ればオッケー。

簡単に、下のようにかける。


```index.js
import React, { Component } from 'react';
import {
  View,
} from 'react-native';
import MapView, {
  PROVIDER_GOOGLE,
  Marker,
} from 'react-native-maps';

type Props = {
  // 省略
};

class Map extends Component<Props> {
  // 省略
  render() {
    const marker = {
      latitude: 35,
      longitude: 135,
      latitudeDelta: 0.0922,
      longitudeDelta: 0.0421,
    };

    return (
      <View
        style={styles.viewContainer}
      >
      　　<MapView
       　　　provider={PROVIDER_GOOGLE}
        　style={styles.map}
        　initialRegion={marker}
       　>
        　　<Marker
         　　　coordinate={marker}
          　title="title"
          　description="description"
         />
       　</MapView>
      </View>
    );
  }
}

export default Map;
```


<img width="435" alt="スクリーンショット 2019-02-10 19.20.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/283557/cdd64223-c484-18a6-93d3-b1db8cdbdbc6.png">


ちなみにStyleSheet.createでwidthを指定するなどしないと地図が表示されずにあれーー？？？ってなる。(なった。)
Laravel5.7でbeginTransaction,commitメソッドの実行ログを出力する

# 概要
Laravel5.7で、DBファザードの`beginTransaction`メソッド、`commit`メソッドの実行ログを出力する方法。

`DB::getQueryLog()`を実行することで、QueryBuilderが生成したSQLを出力を取得することができますが、`beginTransaction`、`commit`メソッドの実行ログは出力されません。transactionの流れを確認をしたいことがあったので、下記の方法で確認しました。

詳細な説明は省いていますが、ご参考になれば幸いです。

# 方法

`app/Providers/EventServiceProvider.php`の`boot()`に下記処理を追加する。

```php5:app/Providers/EventServiceProvider.php
    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();

        Event::listen('Illuminate\Database\Events\TransactionBeginning', function () {
            \Log::debug('beginTransaction');
        });

        \DB::listen(function ($query) {
            \Log::debug($query->sql);
        });

        Event::listen('Illuminate\Database\Events\TransactionCommitted', function () {
            \Log::debug('commit');
        });

        Event::listen('Illuminate\Database\Events\TransactionRolledBack', function () {
            \Log::debug('rollBack');
        });
    }
```
VueとFirebaseで野球の走力判定アプリを作った

どうも草野球おじさんです。
おじさんになると、走力の衰えを感じます。
そこで Vue, Firebaseで自分の走力がどれくらいなのか測れるアプリを作ってみました。

## 概要

FirebaseのHostingを利用する。
Vue.jsで全て書いた。


デモはこちら： https://vue-baseball-8142f.firebaseapp.com/

打った瞬間にストップウォッチのスタートボタンを押して、一塁ベースを踏んだ瞬間にストップボタンを押してください。
すると同等のプロ野球選手の名前が出ます。

スクリーンショット
![スクリーンショット 2019-02-10 19.10.42.png](https://qiita-image-store.s3.amazonaws.com/0/336934/70192bbd-45fc-19ae-3c77-3a6f76246ea3.png)

コード断片です。
main.cssは省略です。

```index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>走力ウォッチ</title>
    <link href="./main.css" rel="stylesheet">
  </head>
  <body>
    <div id="app">
      <p>バッターが打った瞬間にストップウォッチのスタートボタンを押し、一塁ベースに到達した瞬間にストップボタンを押して下さい</p>
      <p> {{ time }} </p>
      <p> {{ player }} の走力です</p>
      <button v-on:click="Start">スタート</button>
      <button v-on:click="Stop">ストップ</button>
      <button v-on:click="Reset">リセット</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.js"></script>
    <script src="./main.js"></script>
  </body>
</html>
```

```main.js
let id;
let isRunning=false;
let player_time=0.00;

var app = new Vue({
    el: '#app',
    data:{
        time:'00.000',
        player:"-",
        startBtn:'スタート',
        stopBtn:'ストップ',
        resetBtn:'リセット'
    },
    methods: {
        Start: function(){
            this.player="-";
            if(isRunning === false){
                let vm = this;
                let startTime = Date.now();
                let count;

                count = function() {
                    let countup = Date.now() - startTime;
                    //console.log(countup);
                    player_time=countup;
                    let sec = Math.floor(countup % 60000 / 1000);
                    let msc = countup % 1000;
    
                    sec = ('0'  + sec).slice(-2);
                    msc = ('00' + msc).slice(-3);
                    vm.time = `${sec}.${msc}`; 
                    id = setTimeout(count, 10);
                }
                count();
                isRunning = true;
            } // if (isRunning === false) 
        },
        // Stopボタンを押したときの処理
        Stop: function() {
            if (isRunning === true) {
                clearTimeout(id);
                isRunning = false;
                console.log(this.time);
                if (player_time <= 3750){
                    this.player = "横浜DeNAベイスターズ 宮本 秀明 並";
                } else if (player_time <= 3780){
                    this.player = "中日ドラゴンズ 京田　陽太 並";
                } else if (player_time <= 3800){
                    this.player = "広島東洋カープ 田中　広輔 並"; 
　　　　　　　　　.
　　　　　　　　　.
　　　　　　　　　.
                } else {
                    this.player = "オリックス・バファローズ　Ｃ．マレーロ 並";
                }
            }

        },

        // Resetボタンを押したときの処理
        Reset: function() {
            if (isRunning === false) {
                this.time = '00:00.000';
                this.player = "-";
            }
        }
    }
})
```
SVN脳の私がGitを触ってみた話

今までSVNしか触ってきたことのない私ですが、ついにGitでソース管理している仕事に関わることになりました。独学で用語は調べたり本を読んでいたものの、複数人開発で使ってみるとまた違う・・・。やはり実際開発で使ってみるのが一番良いですね。

というわけで、Gitの基本とSVNとの違いを、自分の備忘メモとして残しておきます。

##Gitとは
分散型バージョン管理システムのこと。SVNは集中型バージョン管理システムと呼ばれている。

## ローカルリポジトリとリモートリポジトリ
#### リモートリポジトリ
サーバー上のリポジトリのこと。SVNのリポジトリと同じイメージ。
#### ローカルリポジトリ
自分のPC内にあるリポジトリのこと。リモートリポジトリをクローンして作る。SVNのチェックアウトに近いイメージ。

## コミットとプッシュ
#### コミット
ローカルリポジトリに変更を反映すること。SVNは直接リモートリポジトリへ変更を反映する。

#### プッシュ
ローカルリポジトリにリモートリポジトリに変更を反映すること。
SVNではコミットだけだったけど、Gitはコミットしたらプッシュ。

## プルとフェッチ
#### プル
リモートリポジトリから変更をローカルリポジトリに取り込むこと。SVNでいう更新。

#### フェッチ
リモートリポジトリの最新の状態を取得する。ローカルリポジトリに変更は反映されないので、リモートの最新状態を取得したいときに使う。

## ブランチについて
Gitにはtrunkと呼ばれるものはなく、全てブランチと呼ぶ。Gitでmasterブランチと呼ばれているものがSVNのtrunkに相当するものになる。

他にもまだまだ機能はあるけど一旦ここまで。

## Git使ってみて感じたこと
リモートリポジトリとローカルリポジトリに分かれている、ということを理解するのがなかなか難しかったです。また、SVNより気軽にブランチを切れたり、プルリクエストでソースレビューも出来たりでSVNより開発効率が上がりそう！な気がしました。Gitをもっと使いこなせるようになりたいなと思ってます。
goofysを利用したS3マウントの動作確認

作業メモとして記載している為、不適切な内容が含まれている可能性がございます。

# 実施内容
1. Amazon Linux 2 環境に goofys を使ってS3をマウント
2. goofysの動作確認

# 前提環境

* Amazon Linux 2 を利用

```
[root@ec2-localhost ~]# cat /etc/os-release 
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
[root@ec2-localhost ~]#
```

# 1. Amazon Linux 2 環境にgoofysを使ってS3をマウント

* goofys利用の為のセットアップ

```
[root@ec2-localhost ~]# yum install golang fuse
```

* aws cli の設定

```
[root@ec2-localhost ~]# aws configure
AWS Access Key ID [None]: ********************
AWS Secret Access Key [None]: ********************
Default region name [None]: us-east-2
Default output format [None]: json
[root@ec2-localhost ~]# 
```

* S3バケットの作成

```
[root@ec2-localhost ~]# aws s3 mb s3://1429takahiro-goofys-test
make_bucket: 1429takahiro-goofys-test
[root@ec2-localhost ~]# 
[root@ec2-localhost ~]# aws s3 ls s3://1429takahiro-goofys-test
[root@ec2-localhost ~]# 
```
`バケットには何もないのでlsの結果は何もなしで正しい`


```
[root@ec2-localhost ~]# yum install git
[root@ec2-localhost ~]# go get github.com/kahing/goofys
[root@ec2-localhost ~]# go install github.com/kahing/goofys
```

* 効率化のためPATHにgoofysコマンドのPATHを追加
 
```
[root@ec2-localhost ~]# cat .bash_profile
~略~
PATH=$PATH:$HOME/bin:$HOME/go/bin
~略~
[root@ec2-localhost ~]#
```

* マウントポイントの作成

```
[root@ec2-localhost ~]# mkdir -p /AP/s3
```

* goofysでのマウント実行

```
[root@ec2-localhost ~]# goofys 1429takahiro-goofys-test /AP/s3
[root@ec2-localhost ~]# 
```

* マウントの確認

```
[root@ec2-localhost ~]# ps -ef | grep -v grep | grep goofys 
root     31248     1  0 13:13 ?        00:00:00 /root/go/bin/goofys 1429takahiro-goofys-test /AP/s3
[root@ec2-localhost ~]# 
[root@ec2-localhost ~]# df -h | grep goofys
1429takahiro-goofys-test  1.0P     0  1.0P   0% /AP/s3
[root@ec2-localhost ~]#
```

# 2. goofysの動作確認

* goofysでマウントした領域に新規ファイル作成/ファイルへの書き込み（成功）

```
[root@ec2-localhost ~]# touch /AP/s3/goofys_test.txt
[root@ec2-localhost ~]# echo "goofys test" >> /AP/s3/goofys_test.txt
[root@ec2-localhost ~]# cat /AP/s3/goofys_test.txt
goofys test
[root@ec2-localhost ~]#
```

* 追記されたファイルの更新（失敗）

```
[root@ec2-localhost ~]# echo "goofys test" >> /AP/s3/goofys_test.txt
-bash: echo: write error: Operation not supported
[root@ec2-localhost ~]# cat /AP/s3/goofys_test.txt
goofys test
[root@ec2-localhost ~]#
```

* mvコマンドでファイルごと上書き（成功）

```
[root@ec2-localhost ~]# echo "goofys test update" >> /AP/s3/goofys_test_update.txt
[root@ec2-localhost ~]# mv /AP/s3/goofys_test_update.txt /AP/s3/goofys_test.txt
mv: overwrite ‘/AP/s3/goofys_test.txt’? y
[root@ec2-localhost ~]# 
[root@ec2-localhost ~]# cat /AP/s3/goofys_test.txt
goofys test update
[root@ec2-localhost ~]# 
```



# 参考にしたサイト
goofysのセットアップ
https://qiita.com/kooohei/items/a14f22cb0381342d1861
Mac で GIF 画像を作る技術

# はじめに

[こちら](https://qiita.com/takasp/items/368d9da90520c3ea48dc)の記事で操作する GIF 画像を作るのに困って調べた結果、動画から GIF 画像作成サービスや、フリーソフトを試したのち、個人的にある程度綺麗な作り方が出来たのでまとめておきます。

# 環境
* macOS High Sierra Version 10.13.6
* QuickTime Player Version 10.4
* ffmpeg 4.1

# QuickTime Player を使った操作の録画

標準でインストールされている QuickTime Player を起動しましょう。
Launchpad からであればその他から起動できます。
![Open QuickTime Player](https://qiita-image-store.s3.amazonaws.com/0/129299/029952bf-fa1d-e08e-ace1-72e61ddc4d9d.png)
アプリケーションメニューの「File」-「New Screen Recording」から録画画面を開きます。
<img alt="New Screen Recording" src="https://qiita-image-store.s3.amazonaws.com/0/129299/967bd427-53c6-63ae-52c1-104d905cb3e2.png" width=70%>
赤い丸をクリックすると録画の準備が始まります。
<img alt="Preparation for recording" src="https://qiita-image-store.s3.amazonaws.com/0/129299/bbaf1b5b-9610-45d6-c2a0-d42703fde275.png" width=70%>
スクリーン全体を録画するのであれば、中央をクリックします。
画面の一部を録画するのであれば、ドラッグして範囲を指定します。
![Record whole or part](https://qiita-image-store.s3.amazonaws.com/0/129299/43dccfac-26f3-26ad-53a4-f4089450449d.png)
今回は一部を録画したいので、ドラッグして範囲指定します。
中央の「Start Recording」をクリックすると録画が始まります。
<img alt="Start Recording" src="https://qiita-image-store.s3.amazonaws.com/0/129299/91ceac6a-38e6-4c59-1334-59e444980900.png" width=70%>
録画したい操作が完了したら、右上部のステータスメニューの停止をクリックすると録画が終了します。
<img alt="Stop recording from status menu" src="https://qiita-image-store.s3.amazonaws.com/0/129299/745083d4-e8b8-6e66-cfb1-739341c415e3.png" width=90%>
タッチバー付きの Mac であれば、「Stop」をタップすると録画が終了します。
<img alt="Stop recording from Touch Bar" src="https://qiita-image-store.s3.amazonaws.com/0/129299/80c951a2-3f40-037d-893d-e7f4d062ab4a.png" width=70%>
動画の長さを編集するのであれば、「Edit」-「Trim」から可能です。
<img alt="Trim" src="https://qiita-image-store.s3.amazonaws.com/0/129299/891276b5-28f5-7824-4885-507bf6224e84.png" width=80%>
必要に応じて編集後、名前を付けて保存すれば、録画完了です。

# ffmpeg のインストール

録画した操作動画を ffmpeg を使用して GIF 画像に変換します。
Mac 環境では、Homebrew でインストールしていきます。

```bash
$ brew install ffmpeg
```

# 動画を GIF 画像に変換

動画内で使用している色を最適化するために、パレット画像を生成します。

```bash
ffmpeg -i input.mov -vf "palettegen" -y palette.png
```

GIF 画像を出力します。
サンプルでは、`-r` オプションでフレームレートを 24 に設定しています。

```bash
ffmpeg -i input.mov -i palette.png -r 24 -y output.gif
```

# さいごに

QuickTime Player で操作を録画し、ffmpeg で GIF 画像を作成するまでをご紹介しました。
サンプルの GIF 画像作成では、フレームレートを指定したのみですが、
画像ファイルサイズに制限がある場合や画像サイズを小さくして表示を早くしたい場合などは、フレームレートやピクセルサイズを調整すると良いと思います。
また、より精度の高い GIF 画像を作成するのであれば、参考ページや ffmpeg のドキュメントを参考にしてください。

# 参考
[MacでQuickTime Playerを使った画面録画とGIFアニメーションに変換する方法](https://blanche-toile.com/tools/screen-recorder-mac-gifanime)
[ffmpegで動画を綺麗なgifに変換するコツ](https://life.craftz.dog/entry/generating-a-beautiful-gif-from-a-video-with-ffmpeg)
[ffmpeg Documentation](https://ffmpeg.org/ffmpeg.html)
PHPとJavaScriptでその月の最後の日を取得する

かなり久々のQiitaの投稿です。
しばらくは以前に技術ブログに書いた内容を（修正が必要な箇所は修正して）Qiitaに少しづつ投稿していこうと思います。
後は最近Pythonでの機械学習も少しづつ勉強しているので、そちらの方もどこかで投稿できればと思います。
今回は[この記事](https://yk0807.com/larablog/posts/8)のQiitaへの移転です。

2月ももうすぐ中旬になろうとしていますね。今年は2月は28日までですが、うるう年だと29日までなんですよね。
月によって30日で終わったり31日で終わったり、2月だと年によって28日だったり29日だったり日付ってたまに扱いに困るとこがありますよね。 プロ野球選手でも、[当日が11月31日と勘違いして契約更改すっぽかして大変な事になった選手](https://ja.wikipedia.org/wiki/%E6%9E%B6%E7%A9%BA%E3%81%AE%E6%97%A5%E4%BB%98#11.E6.9C.8831.E6.97.A5)もいるそうです。

というわけで、PHPとJavaScriptである月の最終日を取得する方法について書こうと思います。

まずはPHPでのやり方です。 PHPだとこんな感じで簡単に取得できます。

```PHP
echo date('Y-m-d', strtotime('last day of 2019-2'));
```

こうすると、2019-02-28と返ってきます。 他にも、こんなやり方もあります。

```PHP
echo date('Y-m-t', strtotime('2019-2-10'));
```

こちらも同様に2019-02-28と返ってきます。ちなみに、date('Y-m-t', strtotime('2019-2-29'))だとstrtotimeの中は2019年2月の最後の日である28日の次の日、すなわち3月1日と解釈されて2019-03-31が返ってきます。逆に、date('Y-m-t', strtotime('2019-2-0'))にするとstrtotimeの中は2019年2月の最初の日の1日の前の日（1月31日）と解釈されて、2019-01-31が返ってきます。

次はJavaScriptです。こちらは直感的には少ししっくり来ないところもあるかもしれないけど、慣れれば大丈夫です。 例えば、ある日が2019年2月10日として、その日と同じ月の最終日は何日かを調べる場合はこんなやり方になります。

```JavaScript
var current_day = new Date('2019-02-10');
var last_day    = new Date(current_day.getFullYear(), current_day.getMonth() + 1, 0);
```

こうすると、last_dayの中には2019年2月28日に相当するDateクラスの値が入り、console.log(last_day);の結果は

```
Thu Feb 28 2019 00:00:00 GMT+0900 (JST)
```
となります。

日付を扱うテクニックは言語を問わず重要なので、きっちり押さえておきたいところです。これで契約更改をすっぽかさずに済みますね。 PHPでの日付はCarbonを使うともっと楽になるんですが、Carbonについては別の機会に紹介しようと思います。
libfreenectを使ったKinect v1の開発②

[前回](https://qiita.com/int_main_Nick/items/e4e3949148afc352fb47)の続き.
Depth画像に続きColor画像を表示しようとしたがなぜか画像が切られた状態で表示される問題が発生したのでメモ. 

#ソースコード
今回は省略した形で掲載.

コールバック関数

```cpp:
void video_cb(freenect_device *dev, void *rgb, uint32_t timestamp)
{
	cv::Mat temp = cv::Mat(480, 640, CV_8UC3, rgb);
	//imshowで正しく表示するためにBGRをBGRに変換
	cv::cvtColor(temp, temp, CV_RGB2BGR);
	//幅を480のままにするとおかしなことになる
    memcpy(color.data, temp.data, 640*(480 + 950));
}
```

コールバック関数内のmemcpyで640 * 480にすると画像が途中で切れてしまうが, [ここ](https://gist.github.com/jayrambhia/5677608)を参考にして480に950を足すことでそれを解決できた.
コールバック関数を前回のコードと同様に呼び出せばカラー画像が表示される.

#実行結果
+  失敗例
![color.png](https://qiita-image-store.s3.amazonaws.com/0/316006/75b4c052-b63c-6e6b-d405-a94d0ee9e037.png)

+ 成功例
![color.png](https://qiita-image-store.s3.amazonaws.com/0/316006/4af7e4f3-c1a4-2107-a9a5-92f4e0d08254.png)
Phoenixで作成したアプリケーションのCIにWerckerを使う時の設定

# はじめに
Phoenixで作成したアプリケーションのCI環境をwerckerを用いて構築するのにつまづいた箇所がいくつかあったのでまとめてみました。

# 環境
1. Phoenix 1.4.0
2. Elixir 1.7.3

# `wercker.yml`の設定
今回は以下のような`wercker.yml`を用いてCIを回せるようにしたいと思います。
ちなみに今回のCIではフロントエンドのテストは行なっていません。

```yml:wercker.yml
box: elixir:1.7.3

services:
  - id: postgres
    env:
      PASSWORD: postgres
      USER: postgres

build:
  steps:
    - script:
      name: setup system
      code: |
        export MIX_ENV=ci
        apt-get update
        apt-get install -y build-essential

    - script:
      name: setup mix
      code: |
        mix local.hex --force
        mix deps.get --force
        mix local.rebar --force

    - script:
      name: lint test
      code: mix format --check-formatted

    - script:
      name: background test
      code: mix test
```

ポイントは`MIX_ENV`を`ci`にしているところです。
これはPhoenix側でDB周りの設定を行うのに`config/ci.exs`として新たな環境を構築するようにしているために必要な設定です。
また、`setup mix`はテストを行うのに必要なライブラリのインストールを行なっています。この`script`を飛ばしてしまうとうまくテストを行うことができなくなってしまうので注意してください。

# Phoenix側の設定
Phoenix側では、主に以下の二つを行うので、順番に説明していきたいと思います。

1. `ci.exs`の作成
2. `mix.exs`の修正

## `ci.exs`の作成
先ほど`wercker.yml`では`MIX_ENV`を`ci`に設定しました。
これはtest環境とは別に、wercker用のDB設定を行うためのconfigファイルを使用するためです。

ちなみにwerckerでテストを回せるようにするのにここで一番つまづきました。

作成する`config/ci.exs`は以下の通りです。
`blog_app`、`BlogAppWeb`、`BlogApp`はご自身のアプリケーションに合わせたものに修正しましょう。

```exs:config/ci.exs
use Mix.Config

# We don't run a server during test. If one is required,
# you can enable the server option below.
config :blog_app, BlogAppWeb.Endpoint,
  http: [port: 4002],
  server: false

# Print only warnings and errors during test
config :logger, level: :warn

# Configure your database
config :blog_app, BlogApp.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: System.get_env("POSTGRES_ENV_USER"),
  password: System.get_env("POSTGRES_ENV_USER"),
  database: "postgres#{System.get_env("TEST_ENV_NUMBER")}",
  hostname: System.get_env("POSTGRES_PORT_5432_TCP_ADDR"),
  port: System.get_env("POSTGRES_PORT_5432_TCP_PORT"),
  pool: Ecto.Adapters.SQL.Sandbox

```
注目していただきたいのは`config :blog_app, BlogApp.Repo`の部分です。ここに書いてある環境変数の説明は
https://devcenter.wercker.com/administration/services/examples/postgresql/
にあります。これらの設定をしないとwercker上で正しくDBの作成を行うことができません。
ちなみにこれらの設定方法はRailsのDB設定を行ってくれるパイプラインの
https://github.com/wercker/step-rails-database-yml
を参考にしています。

## `mix.exs`の修正
前項で`ci.exs`の作成をしましたが、これだけではまだ正しくCIを回すことができません。
理由は、`mix.exs`に記述されているtest環境用の設定が、`MIX_ENV`を`ci`にしてしまったためにwercker上で適用されなくなってしまっているためです。
よって、最後に`mix.exs`のtest環境用の設定がCI環境にも適用されるように修正します。

`mix.exs`で修正を行うのは以下の部分です

```exs:mix.exs
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]
```
この設定を`ci`にも適用させるようにするため、以下のように設定を追加します。

```exs:mix.exs
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(:ci), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]
```
これで基本的な設定は完了です。テスト用にライブラリを入れている場合は、適宜CI環境でもインストールするように`defp deps`を書き換えましょう。

# 最後に
今までwerckerはRuby、Railsでしか利用したことがなかったので、Phoenixで使用するのにかなりてこづってしまいました（https://github.com/wercker/step-rails-database-yml を何も考えずに使用していたことを反省しました）
werckerは個人開発ではとても重宝するサービスだと思っているので、これからもつまづくことがあったら記事にまとめていきたいです。
GitHubとSlackの連携

GitHubの通知をSlackに投げる設定の備忘録。(2019/02/10時点)
基本、[Slack 公式ドキュメント](https://get.slack.help/hc/ja/articles/232289568-GitHub-%E3%81%A8-Slack-%E3%82%92%E9%80%A3%E6%90%BA%E3%81%95%E3%81%9B%E3%82%8B)の手順通りです。
## GitHubの設定
通知対象のリポジトリが存在すればOK

## Slackの設定
### ワークスペースに GitHubアプリ をインストールする
SlackのWebページより、GitHubアプリを検索してインストールする。
``https://{ワークスペース名}.slack.com/apps``
<img src="https://qiita-image-store.s3.amazonaws.com/0/215847/57a2e7c5-dacb-a385-55ca-44f86971d621.jpeg" width=70%>
インストール押すと、認証許可やチャンネルについて聞かれるので、それぞれ選択してインストールする。
インストールが完了すると、Slackにメッセージがくる。
<img src="https://qiita-image-store.s3.amazonaws.com/0/215847/b9015629-8e0f-5000-73a1-3d54e77aa588.jpeg" width=70%>

### リポジトリ登録
通知を受けたいチャンネルで、リポジトリを登録するためのコマンドをメッセージ送信する
``/github subscribe owner/repository``
（owner/repository は 自分のリポジトリにする）

以上で、連携完了。　
登録したリポジトリに更新（※）があると通知が飛んでくる。
<img src="https://qiita-image-store.s3.amazonaws.com/0/215847/7722d856-158a-0fcf-f964-f4f692d17f96.jpeg" width=50%>
※デフォルトで通知される機能は公式を参照。
[Slack 公式ドキュメント](https://get.slack.help/hc/ja/articles/232289568-GitHub-%E3%81%A8-Slack-%E3%82%92%E9%80%A3%E6%90%BA%E3%81%95%E3%81%9B%E3%82%8B)
BiopythonでBLAST結果をファイルに保存せずに解析する [バイオ]

biopythonでのblast結果の解析には
`NCBIXML.parse(open('blast結果のxmlファイルパス'))`
がよく使われると思う。
しかし、blastの結果がファイルでない or ファイルに保存したくないこともしばしば。

こんな時は、 
`NCBIXML.parse(io.StringIO(blastの結果))`
 を用いることで、blastの実行結果をファイルに保存せずに解析することができる。

```python:blast_do_not_save_results.py
#!/usr/bin/env python3

import io
from Bio.Blast.Applications import NcbiblastnCommandline
from Bio.Blast import NCBIXML

db_path='path/to/the/blast_db'
fasta_path='path/to/the/query/fasta'

# blastの結果を out に入れる
out=NcbiblastnCommandline(db=db_path, query=fasta_path, evalue=1e-5, outfmt=5)()[0]
# blastの結果をparse
blast_records=NCBIXML.parse(io.StringIO(out))
for blast_record in blast_records:
    for alignment in blast_record.alignments:
        for hsp in alignment.hsps:
            print('****Alignment****')
            print('sequence:', alignment.title)
            print('length:', alignment.length)
            print('e-value:', hsp.expect)
            print(hsp.query[0:75] + '...')
            print(hsp.match[0:75] + '...')
            print(hsp.sbjct[0:75] + '...')

```

上記のスクリプトは以下と同じ。
ただし、以下はblastの結果をxmlファイルに書き出す。

```python:blast_save_results_as_xml.py
#!/usr/bin/env python3

import io
from Bio.Blast.Applications import NcbiblastnCommandline
from Bio.Blast import NCBIXML

db_path='path/to/the/blast_db'
fasta_path='path/to/the/query/fasta'

# blastの結果を out に入れる
out=NcbiblastnCommandline(db=db_path, query=fasta_path, evalue=1e-5, outfmt=5)()[0]
# blastの結果をxmlファイルに保存
with open('blast_out.xml', 'w') as outfile:
    outfile.write(out)
# 保存したxmlファイルをファイルオブジェクトにする
result_handle=open('blast_out.xml')
# blastの結果をparse
blast_records=NCBIXML.parse(result_handle)
for blast_record in blast_records:
    for alignment in blast_record.alignments:
        for hsp in alignment.hsps:
            print('****Alignment****')
            print('sequence:', alignment.title)
            print('length:', alignment.length)
            print('e-value:', hsp.expect)
            print(hsp.query[0:75] + '...')
            print(hsp.match[0:75] + '...')
            print(hsp.sbjct[0:75] + '...')
```

# ポイント
[こちら](https://www.haya-programming.com/entry/2018/07/03/042203)によると、io.StringIO は「ファイルオブジェクトのように見えるオブジェクト」を作るらしい。
`io.StringIO` は python3のみで使用可能なので注意。
python2では `io.BytesIO` を使うことで同じことができる。

# 環境
Python 3.7.1
biopython 1.72
BLAST 2.8.1+
Ubuntu 18.04
PhpStormのビルトインサーバーを使ってPHPを動かしてみた

#背景
手軽にPHPを動かして勉強したいと思っていたところ、PhpStormのビルトインサーバーを使ってローカル環境にサーバー環境を作らずにPHPを動かすという方法を学んだので備忘がてらにメモしておきます。

#前提
- MacOS Mojave 10.14.3
- PHP 7.2.1
- PhpStorm 2018.3.4

PhpStormは有料版と無償版（お試し期間30日間）ありますが、筆者はEAP版（開発中のβ版のようなもの）を導入しました。

EAP版のライセンスはそのビルドに付随していて、期限は「リリース」から1ヶ月間ですが、1～2週間で新たなビルドがリリースされるので、アップデートすればライセンス期限がさらに1ヶ月に伸びる点でEAP版を選びました。

#Step

###PHPファイル作成
まずはPhpStormを立ち上げて、適当にプロジェクトファイルとその中にPHPファイルを作ります。
続いてPHPファイルに出力したい内容を記述します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/310353/82ed941a-2250-eb6b-45a5-7e809bff9e3f.png)

###ブラウザにアクセス
とりあえずこの状態で、PHPファイル編集画面の右上に出てくるブラウザアイコンから、ブラウザを立ち上げてみます。

すると、以下のように「502 Bad Gateway」というエラーメッセージ（＝ページをリクエストしたけど、無効なレスポンスが帰ってきました）が表示されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/310353/a3a78f8a-74ad-7df0-7231-4fa7bddf23c3.png)

PhpStormに戻ると、右下に以下のようなエラーメッセージが表示されてます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/310353/aa516c90-7f9e-f68a-8fcb-20fd8ceb1ed7.png)

###CLI Interpreterの設定

PhoStormの左上にあるPhpStormを選択し、Preferenceを開きます。
Languages & FrameworksにあるPHPを選択すると、以下のような画面になるかと思います。

デフォルトでは、Interpreterの設定がないので、CLI Interpreterの右側の「…」をクリックして設定を変更します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/310353/bdc47569-bd9a-4d91-6412-79a6ce80f921.png)

左上の「＋」をクリックして、PHP実行ファイルを指定します。
すると、以下のような状態になるので、名前とPHP実行ファイル(PHP executable)を指定してOKボタンを押します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/310353/e63eabf0-4122-42d7-5047-3e074c39679d.png)

設定画面に戻り、先程作成したCLI Interpreterを設定して適用・OKボタンを押します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/310353/442f027b-85a0-6af2-ff9e-e87713e86cd7.png)


###ブラウザに再アクセス
先ほどブラウザにアクセスした時と同じ手順を実行してみると、PHPファイルの記述内容が表示されれば成功です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/310353/9a9f71bb-68ea-79d3-1ae6-365be02738a0.png)



PhpStormのビルトインサーバーを使うことで、簡単にPHPを動かすことができました。
ArchLinuxのpodmanで非特権コンテナを使ってみる

注意
----
- 調べながら書いた記録なので間違った内容があるかもしれません。間違いを指摘してもらえると嬉しいです…
- ネットワークに関しては調べられていません

podman
-------
![image.png](https://qiita-image-store.s3.amazonaws.com/0/30426/1aff6891-ed2c-382c-4cf7-2ca60a4a4084.png)
https://github.com/containers/libpod

podmanはRedHatが開発しているコンテナランタイムで、[2019/1/17に1.0がリリースされ][podman1.0]話題になりましたね。RHELやFedoraには既に搭載されているようですが、今回はArchLinuxで試してみます。
podmanはDockerと異なりデーモンを常駐させる必要がなく、またDocker相当の機能が3つのプロジェクトに分かれているようです

- [Buildah](https://github.com/containers/buildah)（コンテナの構築）
- [Podman](https://github.com/containers/libpod)（コンテナの実行）
- [Skopeo](https://github.com/containers/skopeo)（コンテナの共有/発見）

[podmanの目標として掲げられている](https://github.com/containers/libpod#overview-and-scope)のは以下の機能です

- 既存のDocker/OCIのイメージに対応
- 認証や検証を含む様々なダウンロード方法への対応
- コンテナイメージの管理（ファイルシステムのoverlayやイメージの階層の管理）
- コンテナライフサイクルの完全なサポート
- Pod（コンテナのグループ）のサポート
- コンテナ、Pod間のリソースの分離
- CRI-Oインターフェースの提供

コンテナ実行環境はrunC等のOCI互換なランタイムに、イメージの構築はBulidahに、コンテナの配布はSkopeoにそれぞれ任せているようです。

[podman1.0]: https://www.publickey1.jp/blog/19/red_hatdockerpodman10.html

### 参考リンク

- [Red Hat Enterprise Linux 8 Betaを発表 ](https://www.redhat.com/ja/blog/rhjapan-powering-its-future-while-preserving-present-introducing-red-hat-enterprise-linux-8-beta%3Fsource%3Dbloglisting)

Install
--------
ArchLinuxではAURに以前からパッケージが存在していましたが、2019/1/26に[communityリポジトリに追加されました](https://www.archlinux.org/packages/community/x86_64/podman/)。同時に[Docker互換CLI(podman-docker)](https://www.archlinux.org/packages/community/x86_64/podman-docker/)も提供されています。

```
pacman -Sy podman podman-docker
```

非特権コンテナ
--------------
Dockerの問題点として権限の問題があります。Dockerの動作にはRoot権限のデーモンを必要とし、またコンテナ内のRootプロセスはホスト側でもRootプロセスとして振る舞ってしまいます。
実際に複数人数で共有するサーバーでDockerを使おうと思うと、ユーザーをdockerグループに追加する必要があり、これはほとんど無制限のsudo権限をあげるようなものです。

そこで必要になるのがコンテナ内でのユーザーIDをホスト側のユーザーIDと別のIDに割り当てる方法です。コンテナ内のRootがホスト側の起動したユーザーのUIDになればホスト側でユーザーが可能な動作しか出来なくなりますね。
この機能はユーザーが別のUIDでプロセスを起動出きることを意味するのでArchLinuxではデフォルトで無効になっています。有効化するには

```
sysctl -w kernel.unprivileged_userns_clone=1
```

を実行します。これで現在のセッションに対して有効になるので、必用に応じてsysctl.dで永続化します。

### sub{uid,gid}

さてこれでUIDがマップ出きるようになりましたが、このままだと自分のUIDにしかマップできません。このままだとコンテナ内で新しくユーザーを作ることが出来なくて不便ですね。それを解決するためにLinuxでは自分が使うことが出来るサブのUID/GIDをそれぞれ`/etc/subuid`と`/etc/subgid`で設定する事が出来ます。というかこれを設定しないとpodmanが動いてくれません。

```plaintext:/etc/subuid
root:100000:65536
```

```plaintext:/etc/subgid
root:100000:65536
```

これでそれぞれ`root`ユーザーに`100000`番から`65536`個のUID/GIDをサブIDとして使えるようにします。自分のユーザーでpodmanを起動するには自分のユーザー名で登録する必要があります。良く分かりませんが一つも自分のユーザーのエントリが無いとpodmanを起動できません。

これでpodmanが起動出来るはずです。

```
podman ps
```

podmanのコマンドは`alias docker=podman`として動くようになっているので後は使い慣れたdockerと同じように使えます。

### 参考リンク

- [Linux Containers > はじめに](https://linuxcontainers.org/ja/lxc/getting-started)
- [Linux COntainers - ArchWiki](https://wiki.archlinux.jp/index.php/Linux_Containers)
- [第16回　Linuxカーネルのコンテナ機能 [6] ─ユーザ名前空間](https://gihyo.jp/admin/serial/01/linux_containers/0016)
【Unity】呼び出された時に絶対に初期化が行われるシングルトンなオブジェクト

シングルトンなオブジェクトは便利。だけど初期化のタイミングが難しいという問題がありました。
その時解決策として考えた、自分用メモです。

**以下の仕様を満たすことを条件としました**
1. Awake、Startに依存しない
2. 初期化メソッドが必ず定義されてなくてはならない
3. 初期化メソッドはAwakeより前に呼び出された場合でも実行される

# 1.Awake、Startに依存しない
プロパティを使った遅延初期化を行う。
FindObjectOfTypeを使った例が多いですが、ヒエラルキー内全てのオブジェクトを検索する為、規模によって初期化時間に大きく影響する為、
今回は[テラシュールブログ](http://tsubakit1.hateblo.jp/)さんの[Unityで少しだけ高速なシングルトン(Singleton)](http://tsubakit1.hateblo.jp/entry/20140709/1404915381)をベースに行います。

# 2.初期化メソッドが必ず定義されてなくてはならない
シングルトンを作成する基底クラスに、以下の抽象メソッドを追記します。

```SingletonMonoBehaviour.cs
protected abstract void Init();
```

これにより、SingletonMonoBehaviourを継承したクラスは、必ず**Init()**を宣言する必要があります。

# 3. 初期化メソッドはAwakeより前に呼び出された場合でも実行される
基底クラスから初期化のタイミングでInitを呼び出す必要があります。
MonoBehaviourを継承しているならSendMessageが使えます。
しかも、Unity2018から.Net4xが推奨。今まで引数が文字列参照だったのがnameOf演算子で指定ができる！

Awakeより前の呼び出しなら

```SingletonMonoBehaviour.cs
    protected static T instance;
    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                Type type = typeof(T);

                foreach (var tag in findTags)
                {
                    GameObject[] objs = GameObject.FindGameObjectsWithTag(tag);

                    for (int j = 0; j < objs.Length; j++)
                    {
                        instance = (T)objs[j].GetComponent(type);
                        if (instance != null)
                        {
                            instance.SendMessage(nameof(Init));
                            return instance;
                        }
                    }
                }

                Debug.LogWarning(string.Format("{0} is not found", type.Name));
            }

            return instance;
        }
    }
```

Awake後なら

```SingletonMonoBehaviour.cs
    virtual protected void Awake()
    {
        CheckInstance();
    }

    protected bool CheckInstance()
    {
        if (instance == null)
        {
            instance = (T)this;
            instance.SendMessage(nameof(Init));
            return true;
        }
        else if (Instance == this)
        {
            return true;
        }

        Destroy(this);
        return false;
    }
```

実装側は

```Player.cs
public class Player : SingletonMonoBehaviour<Player>
{
    protected override void Init()
    {
        Debug.Log("呼び出された時に必ず実行される初期化");
    }
}
```

これでシーン上に配置されてることを前提とした場合、どのタイミングで呼ばれても（Awake実行前に呼ばれても）、
派生クラスで呼ばれてなくてはならい初期化が必ず実行された上で、安全に扱うことができます。
課題としては、その通りこのオブジェクトがシーン上に配置されてることが前提になります。
誤って削除されたとか、テストしようとしたシーンにないとか、そういうときにも対応しなくてはなりません。
まだまだシングルトンは模索中ですが、なにかよさそうな方法とか、こうやってるよ！みたいな意見があったら教えてください！
React - 16.4 New Lifecycle

![圖片 1.png](https://qiita-image-store.s3.amazonaws.com/0/150367/942f5c7b-2f8d-3419-4125-77ac5bad9e4c.png)

# Deprecated Methods (will be removed in the React 17.0 release)

* componentWillMount()
* componentWillUpdate(nextProps, nextState)
* componentWillReceiveProps(nextProps)


http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
https://medium.com/@nancydo7/understanding-react-16-4-component-lifecycle-methods-e376710e5157
Hello! After World!! - 初心者がelixirでオンラインゲーム製作に挑戦してみた クライアント編(第0章)

# Hello! After World!! - 初心者がelixirでオンラインゲーム製作に挑戦してみた クライアント編(第0章)

# はじめに
本記事は[Hello! After World!! - 初心者がelixirでオンラインゲーム製作に挑戦してみた](https://qiita.com/GKBR/items/653c8f56f5ac86ab81b0)のクライアント編です。最終目標はサーバ編で作成したゲームサーバに接続し、多人数でプレイすることです。完成まで長丁場となります。年内に終わるかな。。。

# ・目次


## クライアント編
- 第0章　概要 (2019/2/10公開)
- 第1章　ウインドとキャラクタの表示 (2019/2月下旬公開予定)
- 第2章　タスク・シーン機能 (2019/3月公開予定)
- 第3章　ネットワーク機能 (2019/4月公開予定)
- 第4章　チャット機能 (2019/5月公開予定)
- 第5章　スキル機能 (2019/6月公開予定)
- 第6章　未定
- 第7章　未定
- 第8章　未定
- 第9章　未定

## サーバ編
- [こちらからどうぞ](https://qiita.com/GKBR/items/653c8f56f5ac86ab81b0)

## 開発ツール編
- 2019年公開予定


# ・参考文献
|No.|書籍名|著者|出版年|
|:--|:--|:--|:--|
|1|Windowsプロフェッショナルゲームプログラミング|やね うらお|2002|
|2|Windowsプロフェッショナルゲームプログラミング2|やね うらお|2003|
|3|ゲームエンジンプログラミング|赤坂 玲音|2005|
|4|超本格! サンプルで覚える　C言語　3Dゲームプログラミング教室|大槻 雄一郎|2014|




# ・仕様
クライアントはWindowsPCで動作するアプリケーションとして作成します。
本アプリケーションは主に3つの画面で構成予定です。

![図1.png](https://qiita-image-store.s3.amazonaws.com/0/256958/81a4c0d9-a0cf-3949-68f9-199f1f6ed9a0.png)

- タイトル画面  
  ゲームタイトルの表示、および画面遷移先の選択を行います。
- メイン画面   
  ゲームのメイン画面を表示します。FF14やドラゴンクエストX等のようにゲーム空間内を多人数が同時に移動でき、かつ任意のカメラアングルからプレイ可能とします。ゲーム内では町やマップ上の移動、敵との戦闘は全てシームレスかつリアルタイムに発生させる予定です。
- コンフィグ画面  
  ゲームの設定画面を表示します。ゲーム内の様々な設定をここで行う予定です。

ゲームで使用するキャラクタモデルや効果音等はフリー素材を使用予定です。必要になった際、記事内で参考サイト等をお知らせします。


# ・開発環境
本アプリケーションの開発環境です。

|OS|Windows10|
|:--|:--|
|CPU|Intel Core i5-3330S 2.7GHz|
|Memory|8GB|
|GPU|Intel HD Graphics 2500|
|IDE|VisualStudio2017|
|言語|C++|

# ・ライブラリ
本アプリケーションで使用するライブラリです。グラフィックスはDirectX11を使用予定ですが、素のままでは実装作業量が多くなるため、今回は[DXライブラリ](https://dxlib.xsrv.jp/)を使用予定です。
ネットワークも作業量の都合上libuvを使用予定です。

|グラフィックス|[DXライブラリ](https://dxlib.xsrv.jp/)|
|:--|:--|
|ネットワーク|libuv|

# ・まとめ
- 今回はクライアントアプリケーションの基本的な構成、開発環境、ライブラリ等を決めました。
- 次回はWindows上でのウインド・キャラクタ表示の実装を行います。


最後まで読んでいただきありがとうございました。
Ajaxのクロスドメイン問題を知らずにプログラミングして、全部作り直した話

# 結論
- Ajaxは同一ドメインでしか実行できない(クロスドメイン問題)
- AjaxでドメインAのAPIと通信し、そのAPIからcCRL関数でドメインBのAPIを叩いて対処した
![写真 2019-02-10 17 53 44.jpg](https://qiita-image-store.s3.amazonaws.com/0/271583/70bc74a4-18a1-093d-c4d1-67ba650752bf.jpeg)

# 補足
そもそもクロスドメイン問題を知りませんでした。
プログラミング中にクロスドメイン問題に鉢合わなかったのは、ドメインBに該当するシステムも絶賛他所で開発中で、テスト用のAPIを同一ドメインであるドメインAに配置してしまったからでした。
問題そのものはググってわかったものの、対処がわからず、期日も迫っていたため、サンプルプログラムを書いていただいたら、見覚えのあるコードだったので、ああこれクロスドメイン問題に対応したプログラミングだったんだと気づきました…。
またひとつ勉強になりました。
CodePipline Tips

CodePipelineで気をつけたほうが良い項目をTipsとして随時追加していきたいと思います

#  アクションプロバイダ「手動承認」は最も古い承認待機状態がコンソールに表示される
CodePiplineではアクションプロバイダに「手動承認」を追加できます。
コンソール上で「承認」することで後続のステージを実行することができるようになります。

ただし、「承認」または「拒否」が選択されるまで、コンソール上に選択待ち状態が表示されたままになります。

この時に、複数回パイプラインが実行されると、最初に実行した状態の「手動承認」の選択待機状態がコンソール上では表示されるので間違えて「承認」しないよう注意が必要です。
各ステージブロックの右上「現在のリビジョンを表示」ボタンからリビジョンを確認できるので、手動承認を選択する場合はリビジョンが最新のものか確認しておいたほうが良いです。

## 例

1. パイプラインを１時間おきに３回実行させます。この時、それぞれのリビジョンを`A`,`B`,`C`とします
1. この時コンソール上では「手動承認」以前のステージはリビジョンCのログが表示されます。
1. しかし、「手動承認」ステージではタスクAの承認待機状態が表示されます。
1. そのため、この状態で承認した場合、後続のステージはリビジョンAとして実行されます。
1. リビジョンCとして承認以降のステージを実行するためには、リビジョンA、Bの「手動承認」を拒否する必要があります。
    * リビジョンCの「手動承認」の待機状態が表示するまで手動承認を「拒否」していきます。




# 設定を変更すると「再実行」ボタンで途中からの再開はできない
CodePipelineではあるステージの処理が失敗した場合、そのステージから「再実行」することができます。
しかし、CodePipelineの設定を変更した場合、コンソール上では「再実行」ボタンを押すことができますが、エラーとなり
途中からの再実行はできなくなります。
そのため、CodePipelineの設定を変更した場合、最初のステージからやり直す必要があるので気をつけてください。

# クロスリージョン対応
2018年11月から一つのパイプラインで複数のリージョンのリソースを作成できるようになりました。
ただし2019年02月10日現在、コンソール上からクロスリージョンの設定の追加・変更はできません。
クロスリージョン対応にする場合、aws-cliで設定を更新する必要があります。

詳細はドキュメントに書いてあるのでご確認ください

* https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/actions-create-cross-region.html
Laravelのヘルパーについて～ブログ作成を踏まえて～

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている<@yuka_pon>です。
今回は「[ドットインストール Laravel5.5入門](https://dotinstall.com/lessons/basic_laravel_v2)」のブログ作成を踏まえて、Laravelによく登場する**ヘルパー**ついて記します。
Laravelはこのヘルパーの使用が欠かせないので、知っておくと操作がしやすくなります。


#「ヘルパー」とは？
そもそも、**ヘルパー**とは一体何でしょうか？
ヘルパーとは、「ヘルパー関数」のことを指しており複数のグローバル関数が定義されている、非常に便利な関数です。
フレームワークが事前に設定されているので、自由自在に使用できます。
そのヘルパーには様々な種類があり、今回はブログ作成に使用したものをいくつか挙げます。


###envヘルパー
まず、Laravelのインストール（方法は[コチラ](https://techacademy.jp/magazine/11521)）が終われば、早速アプリケーションの設定（データベースの設定などの実行）を行います。
その時に使用するのが、**envヘルパー（関数）**です。
環境変数の値を取得し、できなければデフォルト値として返します。
つまり、第一引数の値が設定されていなければ第二引数の値が使用されるということです。
.envファイル（インストール時に作成）を用いて、データベースを設定していきます。
※例は下記の通り

```php
.env
1 DB_DATABASE=laravel_lessons
2 DB_USERNAME=myblog
3 DB_PASSWORD=myblog

```


###oldヘルパー
これは、私が一番感動したヘルパーです（笑）
**oldヘルパー（関数）**とは、フラッシュデータ（データ格納）に保存されている直前の値を取得します。
主に、バリデーションを使って値を保持するよう設定したいときに用います。
※記入例は下

```php

  <input type="text" name="title" placeholder="enter title" value="{{ old('title') }}">

（省略）

  <textarea name="body" placeholder="enter body">{{ old('body') }}</textarea>

```

他にも様々なヘルパーがあります。
詳しく知りたい方は、[コチラ](https://laraweb.net/knowledge/835/)。
ちょっとおもしろい重複チェック

重複してるアイテムを抽出できる。位置とか取れないし、可読性悪いし、実用性低いけど。

```golang
package main

import (
	"fmt"
)

func main() {
	list := []string{
		"foo",
		"bar",
		"baz",
		"foo",
		"bar",
	}
	dups := map[string]bool{}
	for _, item := range list {
		_, dups[item] = dups[item]
	}
	fmt.Printf("%+v", dups)    // map[foo:true bar:true baz:false]
}
```

https://play.golang.org/p/HqaCcCZijHE

キモは

```go
_, dups[item] = dups[item]
```

の一行で、mapのキー存在チェックが2つ目のリターンで取得できることに依ってる。

1. `dups` に `item` がキーとして存在しない
2. `dups[item]` で `false, false` が返る
3. `_, dups[item] = false, false` となるため `item` が `dups` のキーに入る。値は `false`。
4. もう一度同じ値の `item` で処理すると、 `dups[item]` で `false, true` が返る
5. `_, dups[item] = false, true` となるため、 `dups[item]` が `true` になる 

Twitterでつぶやくだけつぶやいてたんだけど、「なんか重複チェックについてすげーひらめき昔しなかったけ」となって、
無駄に期待する羽目になった（そしてやっぱり役に立たずがっかりした）のでQiitaにも転載しとく。
Wiresharkを使って一定時間でパケットを自動保存するバッチファイル

#1 はじめに
解析等でネットワークパケットを保存したい場合、Windows OSではWiresharkを使ってパケットキャプチャするのが一般的だと思います。また、毎日、長時間パケットキャプチャする場合は、PCが突然落ちてしまうことも考え、一定時間で自動保存してほしいです。
そのバッチファイルを作成したので共有します。
※WiresharkのGUIからでもできます

#2 やりたいこと
・Wiresharkを使いたい
・一定時間でパケットを保存したい
・日毎にパケットをフォルダに分けたい
　※毎日バッチを実行、終了する前提
・バッチファイルで実行したい

#3 動作確認環境
Wiondows 10
Wireshark Version 2.0.5

#4 バッチファイル
```auto_save_packet.bat
@echo off
@Rem 保存するフォルダを指定する
Set BASE_DIR=C:\packets\

@Rem BASE_DIRで指定したフォルダの下で日付のフォルダを作成する
Set TODAY=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%
Set FILE_DIR=%BASE_DIR%%TODAY%
Mkdir %FILE_DIR%

@Rem ネットワークインターフェイスを表示する
@echo ネットワークインターフェイス一覧
"C:\Program Files\Wireshark\tshark.exe" -D

@Rem ネットワークインターフェイスを入力する
set /p interface_id="パケットをキャプチャしたいネットワークインターフェイスを入力してください："

@Rem パケットの保存間隔を入力する
set /p time_duration="保存間隔(分)："
set /a "time_duration *= 60"

@echo Wiresharkでパケットを保存します。終了させたい場合はCtrl+Cを押してください。
"C:\Program Files\Wireshark\dumpcap.exe" -i %interface_id% -b duration:%time_duration% -w %FILE_DIR%\packet.pcapng
```

#5 解説
保存フォルダを指定します。好きなフォルダを指定してください。

```
Set BASE_DIR=C:\packets\
```
指定した保存フォルダに日付名でフォルダを作成します。

```
Set TODAY=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%
Set FILE_DIR=%BASE_DIR%%TODAY%
Mkdir %FILE_DIR%
```


ネットワークインターフェイス番号を表示します。Wireshrakのインストールされているフォルダにあるtshark.exeを指定します。-Dのオプションでインターフェイス番号を表示することができます。

```
"C:\Program Files\Wireshark\tshark.exe" -D
```

パケットキャプチャしたいネットワークインターフェイスの番号、パケットの保存間隔(分)を入力してもらいます。後述しますが、dumpcap.exeは秒間隔での指定となるため、分から秒に換算しています。

```
@Rem ネットワークインターフェイスを入力する
set /p interface_id="パケットをキャプチャしたいネットワークインターフェイス番号を入力してください："

@Rem パケットの保存間隔を入力する
set /p time_duration="保存間隔(分)："
set /a "time_duration *= 60"
```

Wireshrakのインストールされているフォルダにあるdumpcap.exeを指定します。

```
"C:\Program Files\Wireshark\dumpcap.exe" -i %interface_id% -b duration:%time_duration% -w %FILE_DIR%\packet.pcapng
```

各オプションの説明は以下のとおりです。

| オプション | 説明 |
|:-----------|:------------|
| -i | ネットワークインターフェイス番号を指定する |
| -b duration | 保存間隔(秒) |
| -w | キャプチャ結果をファイルに保存する |



#6 実行結果
コマンドプロンプトの出力は以下の通りになります。
![auto_save_packet.png](https://qiita-image-store.s3.amazonaws.com/0/242136/e8fc6630-3aa8-1dac-e6e6-5c9c0438250c.png)

パケットは指定したフォルダ以下に自動で保存されます。パケットのファイル名には自動で連番が振られます。
![packets.png](https://qiita-image-store.s3.amazonaws.com/0/242136/e072f3e8-f8d0-b5c7-ccfe-78ceaf986bb7.png)

#7 参考サイト
https://knowledge.sakura.ad.jp/6311/
forループ内の処理結果が反映されていない？（超絶素人の質問です）

動作環境：Windows10、Python3.7.2
本人のスキル：超絶素人

img1,img2の画像を比べ、一致している箇所はそのままimg3に格納し、
異なっている箇所は「255」としてimg3に格納することで、
2つの画像の差分を抽出したく下記のコードを書きました。

しかし、出力されたimg3は真っ黒な画像で、
forループ内の処理結果が反映されていないようです。

配列要素の扱いに問題があるのでしょうか。
アドバイスいただきたくお願いいたします。
-------------------
import numpy as np
import cv2

img1 = cv2.imread('aaa/a1.jpg',cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('aaa/b1.jpg',cv2.IMREAD_GRAYSCALE)
img3 = np.zeros((720,1280),np.uint8)

i = 0
j = 0
while j < 1279:
    while i < 719:
        if img1[i,j] != img2[i,j]:
            img3[i,j] = 255
        else:
            img3[i,j] = img1[i,j]
        i += 1
    j += 1
cv2.imshow('img3',img3)
------------------------