OmniAICreator/Qiita-1.07M huggingface dataset:
windows上のTomcatに対して、サーバ証明書(自己証明書(オレオレ証明書))を作成してSSLを有効化する方法

#概要
TomcatでSSLを有効化する方法を以下に記載する。
なお、SSL証明書はオレオレ証明書(自己証明書)を作成してそれを利用する。
#手順
##１．Keytoolで「オレオレ証明書」を作成する。
###1. JDKをインストールする
OracleのサイトよりJDKをダウンロードしてインストールする。
ここでは、Program File配下に「jdk1.8.0_161」をインストールしている。
###2. keystoreファイルを格納するフォルダを作成する。
ここでは、「C:\tmp」としておく。
###3. インストールしたJDKフォルダ配下に「keytool.exe」が格納されていることを確認する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/48d5ad92-86d0-ed71-1938-e495b44ce91f.png)
####4. コマンドプロンプトを立ち上げて、上記フォルダに遷移する。
```:遷移コマンド
cd C:\Program Files\Java\jdk1.8.0_161\bin
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/693557ce-e3c3-deb8-e7fc-fbf972fcd87b.png)
####5. keystoreファイル作成コマンドを実行する。
```:コマンド
keytool -genkey -alias tomcat -keyalg RSA -keystore C:\tmp\.keystore
```
パスワードの入力などを求められるが、適当なものを入力する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/f9d3b544-44e0-8524-3aa2-36cfec2788ef.png)
####6. keystoreファイルの作成結果を確認する。
「C:\tmp」フォルダ配下に「.keystore」ファイルが存在することを確認する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/2f38e35e-6ebe-7c13-a370-d0d8d23b5632.png)
####7. 作成したkeystoreファイルを適当なフォルダに配置する。
ここでは、tomcatフォルダ配下にsslフォルダを作成してその中に格納する。
```:フォルダ
C:\00_myspace\01_server\01_tomcat\apache-tomcat-9.0.6\ssl
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/461f7d39-fe69-1d14-0426-86d7146955dc.png)
####8. 「server.xml」をテキストエディタで開く。
```:「server.xml」の格納先
C:\00_myspace\01_server\01_tomcat\apache-tomcat-9.0.6\conf\server.xml
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/c147ff21-bd9a-4ecd-1f23-b29c37444fee.png)
####9. ポートの解放とkeystoreファイルの格納先を定義する。
```xml:定義内容
<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="8443"
maxThreads="200"
scheme="https"
secure="true"
SSLEnabled="true"
keystoreFile="C:/00_myspace/01_server/01_tomcat/apache-tomcat-9.0.6/ssl/.keystore"
keystorePass="aiueoaiueo"
clientAuth="false"
sslProtocol="TLS"
/>
```
***※keystorePassには、keystoreファイルを作成する際に入力を求められたパスワードを入力する。***
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/0cf89c1a-8aa8-0858-8180-5cf4d0f4756a.png)
#####オリジナルとの差
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/ae1788c1-a86d-0e6a-51cc-c8c81a3dfa1d.png)
####10. tomcatを起動してhttpsでアクセスする。
```:アクセスURL
https://localhost:8443/
```
***※証明書不正のメッセージが表示されるが、そのまま続行する。***
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/26b085ca-7b14-083f-23fb-cd5fd2001c4b.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/f7abe4ab-2bca-35d7-4465-52d647fc4700.png)

これで、TomcatでのSSLを有効にする手順は完了。
トリム平均を求めるpythonコード

最近統計学の勉強を始めたのですが、数学が嫌いで避けてきたこともあり、
計算が苦手やったんで計算式をコード化して考え方を身に着けようとしています。

トリム平均についての解説はネットのコピペなのでコードを追って頂いた方が正しいと思います。

```python:トリム平均.py
# トリム平均とはデータを昇順に並び替え、最小値付近、最大値付近のデータを除外して計算する平均値のこと

# import処理
import random
import statistics


# n個 の値を持つリストを作成する。
test_data = []

# リスト内の値の個数はrandom.randint()にて100～1000個の値を生成する。
# リスト内の値は0～100の間をランダムに格納する。
for _ in range(random.randint(100, 1000)):
    test_data.append(random.randint(0, 100))

# トリム平均では最小値、最大値から指定した割合のデータを削除する必要があるので昇順ソートします。
sorted_data = sorted(test_data)

# ソートしたリスト内をすべて表示する。
print('ソートしたリスト')
print(sorted_data)
# リスト内の値の個数を表示する。
print('このリスト内の値の個数は' + str(len(sorted_data)) + '個です')
# リストの平均値を表示する。
print('このリストの平均値は' + str(statistics.mean(sorted_data)) + 'です。')

print()
print()

# 削除するデータの個数を決定します。
# ここでは0.1(10%)をリスト内の値の個数にかけることで、10%トリム平均を求めます。
trim = len(sorted_data) * 0.1
# 平均を求めると大体小数になると思うので、小数以下を切り捨てて整数に変換します。
trimed = int(trim)


# 最小値から全体10%の値を削除します。
del sorted_data[0:trimed]
# 最大値から全体10%の値を削除します。
del sorted_data[trimed * -1:]

# 削除後のリストを表示します。
print('最大値、最小値から10%を削除したリスト')
print(sorted_data)
# 削除後のリスト内の値の個数を表示します。
print('削除後のリスト内の値の個数は' + str(len(sorted_data)) + '個です')
# 10%トリム平均値を表示する。
print('10%トリム平均値は' + str(statistics.mean(sorted_data)) + 'です。')
```
この結果をヒストグラムにプロットすればわかりやすくなるんかな。
2-3、InputとOutput

##出力
「print()」関数を使って、文字列の出力ができます。例えば、下記のように

```py
>>> print("hello,python")
hello,python
```


「print()」関数は沢山の文字列を一気に出力することもできます。文字列の間に「,」を使います。

```py
>>> print('Tomorow', 'will', 'be batter!')
Tomorow will be batter!
```

「print()」関数は、この例で「,」を自動「space」に変換するので、結果は「Tomorow will be batter!」となります。
もちろん、「print()」関数は数字あるいは計算の出力もできます。

```py
>>> print(50)
50
>>> print(20+60)
80
```
「50+60」を計算式として出力したいであれば：

```py
>>> print('20 + 60 =', 20+60)
20 + 60 = 80
```
ここで、Pythonは「20+60」を計算し「80」を出力したが、「'20 + 60 ='」を数学式ではなく、文字列として認識しています。

##入力
「print()」関数を使うと、出力ができたが、ユーザーから入力したい場合であれば、どうしましょう？「input()」関数を使うと、文字列としての入力ができて、変数として保存もできます。

```py
>>> address = input()
Gunnma
```

ここで、「address=input()」を入力し、「Enter」キーを押すと、Pythonはユーザーの入力を待ちます。何か単語でもを入力し、「Enter」キーを押すと、何も表示しませんが、入力完了です。では、先入力した内容はどうなったの？それは「address」変数に保存されています。その変数を入力すると、変数の内容を見えることできます。

```py
>>> address
Gunnma
```

変数は何ですか？中学校の数学知識を思い出してください。
正方形の辺長はaとして、面積は a × a　となります。ここで、aを変数として使うと、正方形の面積計算ができます。
 a = 3 であれば、面積は a × a = 3 × 3 = 9
 a = 2.2 であれば、面積は a × a = 2.2 × 2.2 = 4.84
プログラムの計算中、変数は整数、小数として使えるが、文字列も扱うこともできます。
変数の内容を出力したい場合、直接変数を入力する以外には、「print()」関数でもできます。

```py
>>> print(address)
Gunnma
```

入力と出力ができると、前回の「hello.py」を意味あるプログラムに改造することができます。
例えば、一行目にユーザーの名前を入力し、二行目はこの名前に対して「hello」を言う。

```py:hello.py
name = input("please enter your name:")
print('hello',name)
```

コメンドプロンプトで「python hello.py」を入力すると、「hello xxx」が表示されます。

```
C:¥work>python hello.py
please enter your name:Tanaka
hello Tanaka
```

ここで、毎回の入力が違うと、毎回の出力も違います。

##まとめ
　すべてのプログラムは何か仕事を実行するために開発した。入力があれば、PCに情報を教えることができる。出力があれば、プログラムの実行結果がユーザーに教えることができる。
　入力はinput(),出力はprint()。まとめると、Input/OutputあるいはIOと呼ばれることがあります。

##練習
print()を利用して、「640 * 480 = xxx」を出力してください。

前章　[2-2、Python開発のエディタ](https://qiita.com/ousrok/items/baff667324fbc1ca01d5)
次章　[3-1、Pythonの基礎](https://qiita.com/ousrok/items/871ddad90a4e71397a1f)
目次　[python 勉強完全まとめ(素人向き)](https://qiita.com/ousrok/items/135734b5f66afb497253)

(この記事はshiracamusさんのご協力でわかりやすくになりました。ありがとうございます。)
AnsibleでDocker inspectのフォーマットを指定して値を取得する方法({{}}のエスケープ)

AnsibleでDockerコンテナのIPアドレスを取得したいと思いshellモジュールでやってみたのですがうまくいかなかったので調べた結果の備忘録です。

# Playbook

`'{% raw %}{% endraw %}'` で括ると文字列で扱われてフォーマットが指定できました。

```yaml
---
- name: Get docker container ip address.
  hosts: localhost
  gather_facts: no
  vars:
    docker_container: test
  tasks:
    - shell: "docker inspect -f '{% raw %}{{ .NetworkSettings.IPAddress }}{% endraw %}' {{ docker_container }}"
      register: r

    - debug: msg="{{ r.stdout }}"
```

**実行結果**

```shell-session
[root@localhost ~]# ansible-playbook main.yml
 [WARNING]: Could not match supplied host pattern, ignoring: all

 [WARNING]: provided hosts list is empty, only localhost is available


PLAY [Get docker container ip address.] **************************************************************************************************************************

TASK [command] ***************************************************************************************************************************************************
changed: [localhost]

TASK [debug] *****************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "172.17.0.2"
}

PLAY RECAP *******************************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0
```

# 参考

https://github.com/ansible/ansible/issues/10156#issuecomment-99918769
【メモ】mbed thread

```c++:main.cpp
#include "mbed.h"

DigitalIn button(USER_BUTTON);
DigitalOut led(LED1);
Thread thread1;

void function1(){
   for(int i=0;i < 5;i++){
       led = !led;
       wait(1);
   }
   thread1.terminate();
}

int main(){
   int b;
   button.mode(PullUp);
    while(1){
        b=button;
        if(!b){
            thread1.start(function1);
            while(b == 0){
                b=button;
            }
        }
    }
}
```
MySQLのコマンドメモ

MySQLのヘルプを転記。個人的な備忘録です。
コマンドの最後の';'を忘れないようにしたいです。

記載内容は、Version：8.0.12で確認。
内容は随時更新していきます。（2018.09.19 現在 更新中です）

##1. バージョンの確認
ステータス情報取得のコマンドで確認できます。

```ruby:ステータス情報取得
mysql> status;
```

##2. MySQLを終了する

'exit' もしくは 'quit'コマンド

```ruby:終了コマンド１
mysql> exit;
```
```ruby:終了コマンド２
mysql> quit;
```

##3. データベースの作成
CREATE DATABASE文を使います。
"DB"部分にデータベース名を入れます。

```ruby:データベースの作成
mysql> create database DB;
```

##4. データベースへ接続
USE文を使います。
"DB"部分にデータベース名を入れます。

```ruby:データベースの作成
mysql> use DB;
```

##5. テーブルの作成
'TABLE01'の部分にテーブル名を入力します。
下記のイメージです。
> create table テーブル名(
フィールド名 データ型
フィールド名 データ型
フィールド名 データ型

データ型は・・・
'int'は数値型（の整数型）
'varchar'は文字列型（の可変型）
・・・です。

```ruby:テーブルの作成
mysql> create table TABLE01(
    -> id int,
    -> Productsname varchar(40),
    -> Price int,
    -> detail varchar(200)
);
```

##6. データの追加
データベースへ接続した上で、INSERT文を使います。
文字列型のデータは' 'で囲う必要があります。
'TABLE01'の部分はテーブル名です。

```ruby:データの追加
mysql> insert into TABLE01 (id, Productsname, Price, detail) values(1, '鉛筆', 100, '黒');
```

部分的にデータを追加することも可能です。

```ruby:部分的にデータ追加
mysql> insert into TABLE01 (id, Productsname, Price ) values(1, '鉛筆', 100 );
```

##7. テーブルの削除
DROP TABLE文で削除が可能です。

```ruby:テーブルの削除
mysql > DROP TABLE テーブル名;
```
テンプレートメソッドの解説 -オブジェクト指向設計実践ガイドを読んで-

[オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方](https://af.moshimo.com/af/c/click?a_id=1022937&p_id=170&pc_id=185&pl_id=4062&s_v=b5Rz2P0601xu&url=http%3A%2F%2Fwww.amazon.co.jp%2Fexec%2Fobidos%2FASIN%2F477418361X)を読んで、テンプレートメソッドについて学習したので解説します。

## テンプレートメソッドとは?

> スーパークラス内で基本の構造を定義し、サブクラス固有の貢献を得るためにメッセージを送るテクニック

これだけ読んでピンとくる人はいないと思います。

## 具体的なサンプルを用いた説明

抽象化された言葉で説明されてもこの手の概念はスッキリ理解しづらいところがあります。
とにかく具体例を見て感覚を掴みましょう。

### 状況設定

今回の例の状況を設定します。

- 自転車を管理するアプリケーションを作成している
- アプリケーションでは自転車のスペアパーツを一覧表示できる
- タイヤのサイズやチェーンのサイズを持っている

クラス同士の関係はこんな感じになっています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/202653/c9f780fd-0f1b-d849-4753-c479861620ca.png)

要件は次のようになっています

- 自転車はチェーン（chain）とタイヤサイズ（tire size）を持つ
- 全ての自転車はチェーンについて同じ初期値を共有する
- サブクラスは、タイヤサイズについて独自の初期値を持つ
- サブクラスの個々のインスタンスは初期値を無視し、インスタンス固有の値を持つことが許される

### 例

```ruby:bicycle.rb
class Bicycle
  attr_reader :size, :chain, :tire_size

  def initialize(args={})
    @size = args[:size]
    @chain = args[:chain] || default_chain
    @tire_size = args[:tire_size] || default_tire_size
  end

  def default_chain
    '10-speed'
  end
end
```

```ruby:road_bike.rb
class RoadBike < Bicycle
  # ...
  def default_tire_size # <- サブクラスの初期値
    '23'
  end
end
```

```ruby:mountain_bike.rb
class MountainBike < Bicycle
  # ...
  def default_tire_size # <- サブクラスの初期値
    '2.1'
  end
end
```

このように```Bicycle```はサブクラスに共通のアルゴリズムを提供しています。
サブクラスがアルゴリズムに影響を与えることを許す場所に関して```Bicycle```はメッセージ(ここでは```default_tire_size```)を送っています。
一方サブクラス側ではそれと同じメソッドを定義することによって、そのアルゴリズムの役割を果たせるようにしています。

このように記述することによって
- 抽象的なベースのクラスには不変的なアルゴリズム
- 具体的なサブクラスには詳細なアルゴリズム

を実現することができます。

### 不完全なところ

しかし上のコードではまだ不完全な部分があります。
コードが今のままなら不都合は浮き出てきませんが、新たなサブクラスが追加された時に不都合が出てきます。

ここでは例としてサブクラスを```RecumbentBike```とします（そういう自転車があるらしい）
上記のアルゴリズムの設計者なら何の問題もなく追加のサブクラスを実装できるかもしれませんが、ここでは設計者以外のプログラマーがサブクラスの追加を行ったとします。

```ruby:recumbent_bike.rb
class RecumbentBike < Bicycle
  # some code
end
```

追加を行ったプログラマーが上記の設計を理解しないまま```default_tire_size```の実装を怠ったとします。
上記の設計はサブクラスに```default_tire_size```があることを前提としているのでもちろんエラーが出ます。

今回のプログラマーが起こすようなエラーを想定して

```ruby:bicycle.rb
class Bicycle
  attr_reader :size, :chain, :tire_size

  def initialize(args={})
    @size = args[:size]
    @chain = args[:chain] || default_chain
    @tire_size = args[:tire_size] || default_tire_size
  end

  def default_chain
    '10-speed'
  end

+ def default_tire_size
+   raise NoImplementedError,
+     "This #{self.class} cannot respond to:"
+ end
end
```
このようにエラー文が出るようにしておくことで、もし間違いが起きてもすぐに原因を発見できるようになります。
ausyscallコマンドの使い方

#1 ausyscallコマンドとは?
システムコール名から番号を調べるコマンドです。

#2 環境
VMware Workstation 14 Playerの仮想マシン(1台)を使いました。

```console:OS版数
[root@server ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[root@server ~]# uname -r
3.10.0-693.el7.x86_64
```

#3 オプション一覧

```
[root@server ~]# ausyscall
usage: ausyscall [arch] name | number | --dump | --exact
```


#4 システムコール一覧を表示する方法(--dump)

```
[root@server ~]# ausyscall --dump
Using x86_64 syscall table:
0       read
1       write
2       open
3       close
4       stat
5       fstat
-中略-
327     preadv2
328     pwritev2
329     pkey_mprotect
330     pkey_alloc
331     pkey_free
332     statx
```

#5 名前が部分的に一致するシステムコールを検索する方法

openという文字列の入ったシステムコール一覧を表示してみます。

```console:openの場合
[root@server ~]# ausyscall open
open               2
mq_open            240
openat             257
perf_event_open    298
open_by_handle_at  304
```

bindという文字列の入ったシステムコール一覧を表示してみます。

```console:bindの場合
[root@server ~]# ausyscall bind
bind               49
mbind              237
```

#6 名前が完全に一致するシステムコールの検索方法(--exact)

```console:openの場合
[root@server ~]# ausyscall open --exact
2
```

```console:bindの場合
[root@server ~]# ausyscall bind --exact
49
```

#7 システムコールの番号からシステムコールの名前を調べる方法

```console:openの場合
[root@server ~]# ausyscall 2
open
```

```console:bindの場合
[root@server ~]# ausyscall 49
bind
```

#Z 参考情報
clojureでスクレイピングする

# 使用するライブラリ
- [http-kit](https://github.com/http-kit/http-kit)
- [enlive](https://github.com/cgrand/enlive)

http-kitはhttpクライアントとして使います。
enliveはhtmlをparseするのに使います。

# プロジェクトにライブラリを追加
dependenciesにライブラリを追加してインストールします。

```project.clj
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [enlive "1.1.6"]
                 [http-kit "2.3.0"]]
```

そしてライブラリをrequireします。

```core.clj
(ns foo.core
  (:gen-class)
  (:require [net.cgrand.enlive-html :as html]
            [org.httpkit.client :as http]))
```

# http-kitでhttpリクエスト

http-kitではリーダーマクロの@を使うことでリクエストを同期的に扱うことができます。
レスポンスはstatusなどいろいろ返ってきますので、必要なbodyだけ取り出します。

```core.clj
(def res (http/get "http://example.com"))
(def html-data (:body @res))

```

# enliveで欲しいデータを抜き出す

`html/html-snippet`でhtmlをparseして、`html/select`でtitleタグの中身を取得しています。

```core.clj
(def title
  (-> html-data
      (html/html-snippet)
      (html/select [:title])
      (first)
      (:content)
      (first)))
```

以上です。
aptチートシート

# 取得したパッケージのローカルリポジトリ（キャッシュ）をクリアする

```sh
sudo apt-get clean
```

# 不要になった依存パッケージを削除する

```sh
sudo apt-get autoremove
```

# パッケージのバージョンを確認する

例として`dash`のバージョンを確認してみる。

```sh
apt-cache policy dash
```

# パッケージの依存関係を見る

`apt-cache depends package`でpackage **が** 依存しているパッケージを、`apt-cache rdepends package`でpackage **に** 依存しているパッケージの一覧を見れる。

https://qiita.com/catatsuy/items/83ca8a5f85c14eac5cb7

# パッケージの依存関係をグラフ化する

`debtree`を使う。

```sh
apt-get install debtree
debtree gnuplot-nox | dot -T png -o out.png
```

参考: https://iww.hateblo.jp/entry/20120503/debtree

# apt-get install でインストールしたファイルの一覧を見る（インストール先を確認する）

```sh
dpkg -L パッケージ名
```

http://kyotoforest.blog82.fc2.com/blog-entry-22.html
PillowでマルチページTIFFを分割する


## 前置き

マルチページのTIFF画像の各ページにアクセス、分割して保存する方法のメモ。

## コード

各ページを保存する例。

```python
from PIL import Image, ImageSequence

img = Image.open('sample.tiff')

for i, page in enumerate(ImageSequence.Iterator(img)):
    page.save("image_file_{}.jpg".format(i), format='jpeg', quality=95)

```

`image_file_0.jpg`という形式で連番のファイルが作成される。

`ImageSequence`を使わない場合は`try-except`構文で`seek(i)`を実行して`EOFError`という例外をトラップする。

まあ素直に`ImageSequence`使うべし。

## そのほか

ファイルに書き出したくないときは`io.BytesIO()`と組み合わせればいけるはず。

## ネタ元

[Python PIL For Loop to work with Multi-image TIFF - Stack Overflow](https://stackoverflow.com/questions/18602525/python-pil-for-loop-to-work-with-multi-image-tiff/47788797#47788797)
【Docker入門】公式Docsの「Get Started」を日本語で要約しながらやってみる（Part3）

## イントロダクション

Part3では、アプリケーションをスケールさせ、負荷分散を可能にさせる。

そのために、コンテナの一つ上の階層「サービス」に移っていく必要がある。

- スタック（stack）
- サービス（services） ←今ここ
- コンテナ（container）


## サービス（Services）について

アプリケーションの中にある、様々なパーツのことをサービス（services）と呼ぶ。

例えば、ビデオシェアのサイトの場合。

アプリケーションのデータを扱うサービスがあるのだろうし、ユーザーがアップロードしたビデオを変換するようなサービスや、フロントエンドのサービスなどもあるだろう。

こういったアプリケーションの様々なパーツがサービスと呼ばれている。

サービスの実態は、ただのコンテナ。

一つのサービスは一つのイメージしか稼働させない。しかし、イメージがどのように稼働するかを決めるのもサービスとなっている。（例えば、どのポートを使うとか）

アプリケーションがスケールしていくことで、ソフトウェアを稼働させているコンテナのインスタンスの個数が変わる。

つまり、より使われているサービスに大きなリソースを割くということ。

Dockerを使えば、非常に簡単にサービスを定義し、稼働させ、スケールさせることができる。`docker-compose.yml`を言うファイルを書きさえすれば良い。


## 最初の`docker-compose.yml`

`docker-compose.yml`はYAML形式のファイルで、コンテナがproduction環境でどのように振る舞うのか定義することができる。

```
touch docker-compose.yml
```

Part2でやった、イメージをプッシュしていることと、下記のymlファイルの「username」の部分を自分のものに変更することが必要なので、忘れないように。

```docker-compose.yml
version: "3"
services:
  web:
    # replace username/repo:tag with your name and image details
    image: username/get-started:part2
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "4000:80"
    networks:
      - webnet
networks:
  webnet:
```

このdocker-composer.ymlは、以下のことをDockerに伝えている。

- part2で作った、get-startedイメージをプルする
- `web`という名前のインスタンスを5つ稼働させる。これらのインスタンスは一つあたり最大10%のCPUと50MBのRAMを使う
- 一つのコンテナが落ちたら、即再起動させる
- ホストの4000番ポートを、`web`の80番ポートにマップする
- `webnet`という名前の負荷分散ネットワークと80番ポートを共有する
- `webnet`という負荷分散ネットワークをデフォルト設定で定義する


## 新しくなった負荷分散アプリケーションを稼働させる

まずはじめに、

```
docker swarm init
```

を実行。（このコマンドの意味はPart4で触れる）

それでは、稼働させてみよう。アプリケーションに名前を与えてやる必要がある。

ここでは、`getstartedlab`として進める。

```
docker stack deploy -c docker-compose.yml getstartedlab
```

この一つのサービスのスタックは、ホストに5つのコンテナのインスタンスを稼働させている。これらのインスタンスは、私たちがデプロイしたイメージのインスタンスだ。

このことを確認してみる。

```
docker service ls
```

ちゃんと動いてることを確認。

一つのサービスの中で稼働しているコンテナはタスクと呼ばれる。

タスクにはユニークなIDが割り振られている。以下のコマンドで確認。

```
docker service ps getstartedlab_web
```

ちゃんと５つ動いていて、IDがユニーク。

サービスでフィルタリングされていないが、全部のコンテナをリストアップする時にも出現する。

```
docker container ls -q
```

`http://localhost:4000/`にアクセスし、何度かリロードしてみよう。

Hostnameの部分が変わるはず。コンテナIDが変わっているということ。

コンテナIDが変わって出てくるのは、5つのタスクがリクエストに対して、交替で対応しているから。


## アプリケーションをスケールさせる

アプリをスケールさせるには、`docker-compose.yml`の`replicas`の値を変えてやれば良い。

変更を保存し、`docker stack deploy`コマンドで再起動させる。

```
docker stack deploy -c docker-compose.yml getstartedlab
```

Dockerは[インプレース](http://e-words.jp/w/%E3%82%A4%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%82%B9%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89.html)にアップデートするので、更新する前にスタックやコンテナを消す必要がない。

## アプリケーションやswarmを止める

アプリケーションを止める。

```
docker stack rm getstartedlab
```

swarmを止める

```
docker swarm leave --force
```

以上でpart3はおしまい！！

Part4はこちら。

[【Docker入門】公式Docsの「Get Started」を日本語で要約しながらやってみる（Part4）](https://qiita.com/jnaiFy04EJ0cP2L/items/3ecc22deadf70e8fbf87)
dockerコンテナIDをpecoで選択してプロンプトにinsertする(anyframe)


### 前提
- zsh
- anyframe


### Source

```zsh:.zshrc
# dockerコンテナIDをpecoで選択してプロンプトにinsertする
function anyframe-widget-insert-docker-ps() {
  docker ps | tail -n +2 \
  | anyframe-selector-auto \
  | cut -d" " -f1 \
  | anyframe-action-insert
}
zle -N anyframe-widget-insert-docker-ps
bindkey '^xd' anyframe-widget-insert-docker-ps
```
https://gist.github.com/amasok/a432e1ad0dd1032826a7bcaeafe89604
上記を.zshrcに書くだけで　`docker rm`の後に`ctrl+x d`と打つだけで、消したいコンテナIDをプロンプトにinsertできる。
同様に`docker logs`,`docker stop`などにも使える。

### 参考
- [peco で Docker の container ID を楽に選択する alias](https://qiita.com/dtan4/items/839c85d2650e63f662b0)
- [zshでpecoと連携するためのanyframeというプラグインを作った](https://qiita.com/mollifier/items/81b18c012d7841ab33c3)
vim-cmdコマンドを使って仮想マシンをSSHで管理する

仮想マシンをコマンド操作で管理したいと思い、vim-cmdコマンドを実際に使ってみたのでどんな操作ができるのか簡単にまとめてみる。

#前提条件
- ESXiに1台以上のVMが乗っていること
- TeratermやPutty等でESXiにSSH接続できること


※SSHでESXiに接続できない場合は、SSH接続が有効化していない可能性があるので下記の手順で設定変更を行う。
**vSphere Web Clientからの変更法**
①対象VMが乗っているESXiを選択する
②構成タブ→設定→セキュリティプロファイルクリックする
③サービスの編集クリックしてSSHを実行中にする

#環境
本環境はクローズドで構築している。
- vSphere Client：6.0.0
- vSphere Web Client:6.0.0
- ESXiバージョン：6.0.0
- vCenter Server Appliance:6.0.0
- VMバージョン：11
- tera term：4.96


#VMの操作コマンド：vim-cmd
###①対象VMが乗っているESXiにSSHでrootログインする
※VMに直接SSHするのではなく、ESXiにRootログインするので注意。

###②vmidを取得する
ESXiに載っているVMに対してコマンド操作をするとき、VMに採番されているvmidを取得する必要があるため、以下のコマンドを実行する。

```esxi:
vim-cmd vmsvc/getallvms
```

このコマンドを実行すると、各VMの先頭にvmid が表示される。
その他にもVM名、ゲストOS、VMバージョンなどが分かる。

###VMのパワーオン・オフ
以降のコマンドは、上記のコマンドで取得したvmidを使用して操作する。

```esxi:
vim-cmd vmsvc/power.on vmid
vim-cmd vmsvc/power.off vmid
```

###VMのシャットダウン・再起動
```esxi:
vim-cmd vmsvc/power.shutdown vmid
vim-cmd vmsvc/power.reboot vmid
```

※このコマンドはVMにvmware toolsをインストールしないと使えないので注意。

【vmware toolsインストール方法】
以下の公式ドキュメントを参照。
https://kb.vmware.com/articleview?docid=1018377&lang=ja


###VMのサマリを取得
```esxi:
vim-cmd vmsvc/get.summary vmid 
```
このコマンドを実行するとかなり多くの情報が出力されるので、lessコマンドを使ってページ表示させたり、grepコマンドで取得したい情報だけを出力させると良い。

```esxi:
vim-cmd vmsvc/get.summary vmid | less
vim-cmd vmsvc/get.summary vmid | grep name
```

summary以外にもget.configやget.guestも使えるが、ほとんどget.summaryで必要な情報は得られる。

#参考文献
今回参考にしたドキュメントは以下の通り。
コマンドライン ユーティリティを使用した一般的な仮想マシン関連タスクの実行 
https://kb.vmware.com/articleview?docid=2012964&lang=ja
Git LFSのデータをgit diffする

# はじめに
Git LFSで管理されているデータを`git diff`する方法を調べると以下のようなものが見つかります。

* [Git LFS管理下にあるテキストファイルをgit diffする](https://qiita.com/gecko655/items/d3282f245d0a75e6d6a9)
* [Will there be a `git lfs diff` command?](https://github.com/git-lfs/git-lfs/issues/2498)

ただ、私の普段の使い方からすると使いにくい部分があり、少し改造してみました。

# 特徴

* ファイル名指定なしで使える。
 * 通常の`git diff`と同じように、引数なしで未コミットの変更箇所がすべて表示されます。
 * 引数でファイル名を指定した場合はそのファイルのみ表示します。
 * 元のスクリプトにあったリビジョン指定は実装していません。
* 圧縮したテキストデータが扱える。
 * zip/gz/bzip2/xzは展開してからdiffします。
* `git diff`と（なるべく）同じフォーマット出力。
 * 内部的に`git diff`そのものを使っているので色付けなども`git diff`と同じです。
 * 標準入力から`git diff`に無理矢理入れている関係で、ファイル名がハッシュ値になってしまいますが…。

# スクリプト

```bash
#!/bin/bash

GIT=git

declare -A filters
filters['bz2']='bunzip2'
filters['gz']='gunzip'
filters['xz']='unxz'
filters['zip']='unzip -p'

MODIFIED=`$GIT ls-files -m`

function lfs_diff () {
    lfs_info=`$GIT show HEAD:"./$1"`
    if [[ "$lfs_info" =~ ^version\ https://git-lfs\.github\.com/spec/v1 ]]; then
        echo $1
        ext="${1##*.}"
        filter=${filters[$ext]}
        if [[ $filter != "" ]]; then
            $GIT diff $($GIT show HEAD:"./$1" | $GIT lfs smudge | $filter | $GIT hash-object -w --stdin) $(cat "$1" | $filter | $GIT hash-object -w --stdin)
        else
            $GIT diff $($GIT show HEAD:"./$1" | $GIT lfs smudge           | $GIT hash-object -w --stdin) $(cat "$1"           | $GIT hash-object -w --stdin)
        fi
        echo ""
    fi
}

if [[ $# == 0 ]]; then
    for f in $MODIFIED; do
        lfs_diff $f
    done
else
    for f in $@; do
        lfs_diff $f
    done
fi
```

# 使い方
スクリプトを`git-lfs-diff`というファイル名で保存して実行権限を付け、パスの通ったところに置いて下さい。以下の通りgitのサブコマンドとして動作します。

```console
$ git lfs-diff
```

また、`.gitconfig`に以下の設定をすれば、`git diff`のデフォルト動作と同様にページャが使われます。

```.gitconfig
[pager]
lfs-diff=true
```
Android Intent

# No15, 16 インテントについて

## Index

1. Androidの画面遷移
2. インテント
3. ライフサイクル

## Androidの画面遷移

アンドロイドの画面遷移は、上に乗る形で行われる。

詰まる話、ダイアログやポップアップをイメージすると良い。

この仕様をリストビューと呼ぶ。

元の画面に戻るときは、今の画面を消すことによって裏にかくれていた画面が表にでてくる。

別の画面の軌道を制御する仕組みが、__インテント__であり、その中心となるクラスが`Intent`クラス。

インテントの使い方は下記の２種類の方法が存在している。

- 明示的インテント: 同一アプリ内で別の画面の軌道
- 暗黙的インテント: アプリ間での画面起動（謎？）

## インテント

アクティビティ登録

Androidアプリに画面を追加するには下記の３個の作業を行う

1. アクティビティクラスを作成する。
1. Layout.xmlファイルを作成する。
1. AndroidManifest.xmlに登録する。

`<activity android:name=".className" />`

manifestの書き方は公式を参照することとする。

#### tips

メインアクティビティはアプリの起動時アクティビティ

AndroidStudioがあらかじめ記述するもの。

上記の３作業を自動的に行ってくれるものが、AndroidStudioに備わっているので、それを利用すると良い。

File > New > Activity > EmptyActivity (間違えないようにしよう))

## 画面の起動

今の画面から別の画面を起動するには以下の手順をとる。

1. Intentオブジェクトを生成する`Intent intent = new Intent(...Activity.this, ...Activity.class);`
  - Intent(コンテキスト, アクティビティクラス);
2. `項目１`を引数としてアクティビティを起動する。 startActivity(intent);

### 遷移先の画面にデータを渡す

`putExtra(StringKey, ObjectValue)`を使用し、データを譲渡する。

```example.java
intent.putExtra("SelectedPictNo", position);

```

...tips 実際にはこの処理で、IntentのBundleオブジェクトにデータが格納されている。

![Untitled Diagram.jpg](https://qiita-image-store.s3.amazonaws.com/0/199120/05159f53-3247-e043-eae2-a147deae5b4e.jpeg)


移動先ではonCreateが起動する。

起動する側はインテントがあるのでgetしてくる。 


```遷移後の画面.java

// 遷移元から Intent を取得する。
Intent intent = getIntent();
// データの入っている extras を取得しに行く
Bundle extras = intent.getExtras();

// 何も入っていない場合はnullとなるので、validation check
if ( extras != null ){
    selectedPictNo = extras.getInt(key);
    selectedPictName = extras.getString(key);
}

```

### 解説

起動先アクティビティでデータをうけとるには以下の手順をとる

1. Intentオブジェクトを取得 `Intent intent = getIntent();`
2. Bundleオブジェクトを取得 `Bundle extras = intent.getExtras();`
3. BundleオブジェクトのnullCheckを実施 ` if ( extras != null ) {/*処理*/} `
4. Bundleオブジェクトから、`extras.get○○(key)`メソッドを使用し、データを取得


tips

`String selectedPictName = intent.getStringExtra("selectedPictName");`

上記のように、Intentオブジェクトから直接取得する方法もある。

ただし第二引数として初期値を記述しないとだめなことがほとんど(NullPointerException回避のため)

`String selectedPictNo = intent.getStringExtra("selectedPictName", "初期STR");
Vueマスターになりたい！、いやなってみせる！！

# はじめに
2017年から今年にかけて、Vueをよく使うと聞きます。実際、「[JavaScript ベスト・オブ・ザ・イヤー 2017](https://risingstars.js.org/2017/ja/)」のフロントエンドフレームワーク編でも圧倒的な人気があります（記事は古いですが）。いや自分はVueの開発現場に携わってはいません（ゴリゴリのJavaScriptファイターです）。なんだかんだ３ヶ月くらいVueを触って来たのでそのまとめでもしようと思いまして投稿します！

#Level 1（Vueを全く知らない編）
さて、全く知らない僕はどんな感じで手をつけたかというと、公式サイトのドキュメントからはじめました。環境構築的なやつはせずに最初はCDNでvue.js読み込んでやってみた！的なノリでやりました。

- [Vue.js公式サイト](https://jp.vuejs.org/index.html)
    - 学んだこと
        - データバインディング（リアクティブデータとかいうやつ）
        - v-if,v-showの違い、v-for(v-◯◯系)
        - イベントの利用（methods関連）
        - フォームの同期(v-model),修飾子（.lazy,.number,.sync）
        - トランジション&アニメーション

結局は、「**Vue.js公式サイト**」の「**はじめに**」を片っ端から攻めていった。感想というかコピペがほとんどなので「これがVue.jsか！」で終わった。とりあえずtransitionタグには感動した。

```transition.vue
<div id="demo">
  <button v-on:click="show = !show">
    Toggle
  </button>
  <transition name="fade">
    <p v-if="show">hello</p>
  </transition>
</div>

new Vue({
  el: '#demo',
  data: {
    show: true
  }
})

.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}
```
Vue専用のCSSスタイリングもあって、勉強になりました。

# Level2(本を買ってみた編)
結論から言うと本を買ってよかった！（まあ、１冊だけなんですが）
[基礎から学ぶ Vue.js](https://www.amazon.co.jp/%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6-Vue-js-mio/dp/4863542453)を買ってみました。ねこちゃんが可愛かったから買ったということもある。Level1でやったことの復習にもなったし、VuexやVue-Routerとかいう新種の技も習得できたし、、（できるとはいってない）

- Vuex
    - 状態管理（state,mutations,action）
        - $emitやpropsで状態の受け渡しができることを知ったが、こっちの方が楽そう便利そうそうしよう
        - 複数のコンポーネントでデータを共有
        - データの状態に関する処理を共通化
- Vue router
    - SPAを構築するための拡張ライブラリ
        - router-link,router-viewによってSPAができるし、アニメーションをつけたりできる

多分一番買ってよかったなあと思うのは「Vueのライフサイクルダイアグラム」。アルゴリズム的な流れが図解できていてわかりやすかった。new Vue()でVueのインスタンスを生成しいろんなライフサイクルを経て$el をコンパイルしたり等、、、わかりやすかったです。

次回はコードを踏まえてまとめていきます。
'Then' Library for Swift Initializers with ReactorKit

#**Introduction**
**Then** Library is a Super sweet syntactic sugar for Swift initializers. It makes easier to code and clean.

**Installation**
First pod init to the project and add this lines of code to podfile

```
pod 'Then'
```
Next just run pod install in terminal. Congratulation!!! you have installed it.

Example:

```swift
let btn = UIButton().then {
   $0.setTitle("Add New", for: .normal)
   $0.backgroundColor = UIColor.blue
}
```

This equivalence to:

```swift
lazy var btn: UIButton = {
  let btn: UIButton = UIButton()
  btn.setTitle("Add New", for: .normal)
  btn.backgroundColor = UIColor.blue
  return btn
}()
```
 
#Sample Code with 'Then' 

Here is the [sample code](https://github.com/SreyPichh/Todo) which is about *Then* in [GitHub](https://github.com/SreyPichh/Todo)
2-2、Python開発のエディタ

　Pythonの対話モードは、手軽に使え、プログラムのテストなどにも便利なのですが、1つ重大な欠点があります。それは、入力したプログラムが、Pythonインタープリタによって実行されるとすぐに消えてしまう、ということです。再度同じコードを実行するにはゼロから入力し直すしかありません。特に大規模なプログラムの場合はそれでは無理があります。
　実際の開発では、エディタを使って、作ったプログラムをファイルに保存し、何度でも繰り返し実行できます。では、前回作った「hello,python」をエディタで書いて、ファイルに保存しましょう。

## どのエディタを使うの？
　自分は下記の二つをよく利用しています。
　①[サクラエディタ](https://sakura-editor.github.io/download.html)
　②[Notepad++](https://notepad-plus-plus.org/) (←私はこれを使っています)
　③[atom](https://atom.io/)
　④[Visual Studio Code](https://code.visualstudio.com/)
　⑤[PyCharm](https://www.jetbrains.com/pycharm/)
　日本には、秀丸エディタが人気が高いそうですが、私個人は上記のいずれかを選ぶかと思います（昔から秀丸エディタを使っている人には異論があるでしょうが、初めて選ぶ人には、ということで）。
　**注意：Wordとメモ帳を絶対に使わないでください。**文字コードなどの問題がありまして、余計なエラーが発生します。

## Pythonファイルを作る
　インストールしたエディタを開き、下記のコマンドを入力する。それで、ファイルをあるファルダに「hello.py」で保存する。例えば、「c:\work」にする。これでこのプログラムがいつでも使えることができる。もちろん、別のファイル名で保存してもよいです。例えば、「first.py」、「tanaka.py」など。しかし、拡張子は「.py」にしないといけません。ちなみに、ファイル名に使える文字は英文字、数字と’_’（アンダーバー）の組み合わせとなります。

```
print('hello,python')
```

注意：「print」の前に「スペース」の入力をしないでください。
## .pyファイルの実行
　コメンドプロンプトとPythonの対話モードを思い出してください。
　コメンドプロンプトに「python」を入力すると、対話モードに開きます。そこで、Pythonのコマンドを実行できます。
　先ほど保存した「hello.py」ファイルを実行したいであれば、対話モードではなく、コメンドプロンプトに「python hello.py」を入力し、実行します。
　「python hello.py」を入力して、下記のエラーが発生することがあります：
![エディタ.JPG](https://qiita-image-store.s3.amazonaws.com/0/263439/491b9b6b-cff2-a734-ffe1-b230e37b572a.jpeg)
「[Errno 2]No such file or directory」はこのファルダにファイルを見つかりません。先に「c:\work\」のフォルダに移動する必要があります。実行すると下記となります。
![エディタ２.JPG](https://qiita-image-store.s3.amazonaws.com/0/263439/a3533a76-f5ce-d5f2-7607-98898fb68762.jpeg)
　ちなみに、コメンドプロンプトで実行した「.py」ファイルと対話モードで実行したコマンドがちょっと違います。対話モードでコマンドを実行したら、結果が表示されます。コメンドプロンプトで「.py」ファイルを実行したら、結果の表示はしません。
　例えば、Pythonの対話モードで下記を実行すると

```
>>>50+60
110
```

結果の「110」が表示されます。
ただ、「calc.py」のファイルに下記を保存し、コメンドプロンプトで実行すると、何も出力しません。

```
50＋60
```
![calc.JPG](https://qiita-image-store.s3.amazonaws.com/0/263439/f8fcd680-76fd-79ca-1861-ce936b85234d.jpeg)
それは、正しいです。そこで、結果を表示したいであれば、「print()」関数を使えます。

```
print(50+60)
```
もう一回実行すると、結果が表示されます。
![calc2.JPG](https://qiita-image-store.s3.amazonaws.com/0/263439/1e3cdea2-199a-96f7-d190-2c5a6a60c86e.jpeg)

##まとめ
Pythonの対話モードで、コマンドを直接入力し、すぐ実行できる。
コメンドプロンプトで「.py」ファイルの実行が出来る。

前章　[2-1、初めてのPythonプログラム](https://qiita.com/ousrok/items/bf1aa75bc53d8b6e591a)
次章　[2-3、InputとOutput](https://qiita.com/ousrok/items/41fc2f951cdd90a53c5a)
目次　[python 勉強完全まとめ(素人向き)](https://qiita.com/ousrok/items/135734b5f66afb497253)
YouTube Data APIのchannelsでパラメータとして渡す「forUsername」「id」に注意

特定ユーザーのYouTubeチャンネルに関する情報を取ってくるのに、「forUsername」か「id」を指定する必要がある。

## パラメータ

| name        | Description     |
|:------------|:----------------|
| forUsername | ユーザー名を指定   |
| id          | チャンネルIDを指定 |

（categoryId・managedByMe・mineもあるけど、ここでは割愛。）

で、この値を調べようと思ってYouTubeでユーザー名を検索すると、リンク先のURLはユーザ名が表示されるパターンとチャンネルIDが表示されるパターンがある。

例えば「ポケモン公式」で調べて表示されたチャンネルのリンク先は以下のように、ユーザー名は「PokemonCoJp」となる。
https://www.youtube.com/user/PokemonCoJp
![pokemon.png](https://qiita-image-store.s3.amazonaws.com/0/54330/93ed8ed1-b8fa-6020-6f9e-dbd37941d018.png)

しかし「abema」で調べて表示されるチャンネルのリンク先は上記と違い、「/user」ではなく「/channel」となり、チャンネルIDは「UCLsdm7nCJCVTWSid7G_f0Pg」となる。
https://www.youtube.com/channel/UCLsdm7nCJCVTWSid7G_f0Pg
![abema.png](https://qiita-image-store.s3.amazonaws.com/0/54330/84181031-3d53-c0dc-2f4b-3ba7c249546d.png)

この辺の検索の細かい仕様は不明だが、何か作るときには覚えておいて損はないかと思った。

また、ユーザー名からチャンネルIDを調べようと思ったら、以下のページ下部にある「Try this API」でユーザー名を入れてレスポンスから調べればよい。
[Channels: list &nbsp;|&nbsp; YouTube Data API (v3)](https://developers.google.com/youtube/v3/docs/channels/list?hl=ja)
※Authenticationは「Google OAuth 2.0」ではなく「API Key」にして実行したほうが手間が減って楽だったりする。
[C#] WinFormsでDoubleClickのときにClickのアクションを実行しない

WinFormsのコントロールのClickとDoubleClickに別のアクションを割り当てたいことはわりとある。しかし、DoubleClickが発火するときは、最初のクリックでClickが発火するため、DoubleClickにはClickのアクションを前提とするアクションしか割り当てられない。

そこで、DoubleClickのときはClickのアクションを実行しないように、最初のClickのアクションの実行をダブルクリックの間隔まで遅延させて、DoubleClickが発火したらClickのアクションを実行しない振る舞いを実装してみた。

```c#
private readonly SemaphoreSlim _clickSemaphore = new SemaphoreSlim(1);
private readonly SemaphoreSlim _doubleClickSemaphore = new SemaphoreSlim(0);

private async void OnClick(object sender, EventArgs e)
{
    if (!_clickSemaphore.Wait(0))
        return;
    try
    {
        if (await _doubleClickSemaphore.WaitAsync(SystemInformation.DoubleClickTime))
            return;
    }
    finally
    {
        _clickSemaphore.Release();
    }
    // クリックのアクション
}

private void OnDoubleClick(object sender, EventArgs e)
{
    _doubleClickSemaphore.Release();
    // ダブルクリックのアクション
}
```

ここでは二つセマフォを使っていて、```_clickSemaphore```はダブルクリック待ちの間に再入を防止する。```_doubleClickSemaphore```はダブルクリック待ちと同時にダブルクリックが実行されたことの判別も行う。

Microsoftに同じの趣旨の[How to: Distinguish Between Clicks and Double-Clicks](https://docs.microsoft.com/en-us/dotnet/framework/winforms/how-to-distinguish-between-clicks-and-double-clicks)という記事があったけど、まったく使えない内容だったのでカッとなって書いた。
atom-beautify でPHP-CS-FixerのWarningが出て整形されない。

Atom-Beautyをインストールして、実行しようとしたところ、以下のエラーメッセージが表示した。

The "PHP - PHP-CS-Fixer Path (cs_fixer_path)" configuration option has been deprecated. Please switch to using the option in section "Executables" (near the top) in subsection "PHP-CS-Fixer" labelled "Path" in Atom-Beautify package settings.

原因を調べたところ、PHP-CS-Fixerのバージョンが古い事が判明
PHP-CS-Fixerのバージョンは以下のコマンドで調べられる。

```terminal:
$ PHP-CS-Fixer --version
```

このバージョンで調べたところ、version1.18.xxであることが分かった。
うまく動いている人のバージョンを調べたところ、version2.0.0だったため、古いバージョンであることにあたりを付けてアップデートを試みた。

アップデートは以下のリンクから再インストールすればよい。
https://github.com/FriendsOfPHP/PHP-CS-Fixer

アップデート後

```terminal:
$ PHP-CS-Fixer --version
PHP CS Fixer version 2.0.0 by Fabien Potencier and Dariusz Ruminski
```

こちらの手順に従って、実行した所、Atom-beautyで整形することが出来た。
【将棋AI】「将棋AIで学ぶディープラーニング」を読む♪～自前モデルでコンピュータ将棋選手権やってみた

<img width="200" style="float: left;" alt="将棋AIで学ぶディープラーニング" src="https://qiita-image-store.s3.amazonaws.com/0/233744/ded117b9-37c7-1b41-033d-960e63ca5fe1.jpeg">
第十六夜は、ある意味整理するために、ここまで作成した将棋AIのどれが強いか総当たり戦をやってみた。
【重要】どうやらResnetのPGにバグがあったようです。ということで本記事は参考程度に読んでください。[ディープなNetworkモデルについて別記事](https://qiita.com/MuAuan/items/a4eef4f6b4f214a88ed1)にする予定です。
###やったこと
（１）将棋AIのlossと一致率（方策、価値）
（２）総当たり戦の結果
###（１）将棋AIのlossと一致率（方策、価値）
それぞれのNetworkモデルに名称からリンクしています。
以下の収束性を見ると、収束性はバラバラです。そして一致率の良さからはResnetのNo.Batch Normalizationのものがとてもよくて期待が持てます。
また、ほかのものはモンテカルロ木探索を使っていますが、Policyだけは方策ネットワークがいいといった手をそのまま選んでおり、ある意味純粋にDeepLearningを使っていると云えるものです。

| 名称 | loss | 一致率（方策） | 一致率（価値） |備考|
|:-:|:-:|:-:|:-:|:-:|
| [policy](https://github.com/MuAuan/dlShogi-kai/blob/master/Network/Policy/policy.py) |1.682677|0.4226734| -  |方策ネットワークのみ|
| [Policy_Value;Layer13](https://github.com/MuAuan/dlShogi-kai/blob/master/Network/Policy/policy_value.py)| 2.016|0.4204578|0.67033803|１３層の方策・価値ネットワークでMCTS|
| [Policy_Value;Layer23](https://github.com/MuAuan/dlShogi-kai/blob/master/Network/Layer23/policy_layer23.py)|2.1938|0.41157416|0.6601796|２３層のMCTS|
| [~~Resnet5~~](https://github.com/MuAuan/dlShogi-kai/blob/master/Network/Resnet5/policy_value_resnet.py)|1.844657|0.4195995|0.6717752|Resnet５block１２層|
| [~~Resnet10~~](https://github.com/MuAuan/dlShogi-kai/blob/master/Network/Resnet10/policy_value_resnet10.py)|1.818387|0.40154335|0.6761505|Resnet10block２２層|
| [~~ResnetL4~~](https://github.com/MuAuan/dlShogi-kai/blob/master/Network/ResnetL4/policy_value_resnet3.py)|2.1583886|0.39926776|0.6727783|１Block４層のResnetを５block;２２層|
| [~~ResnetNoBN~~](https://github.com/MuAuan/dlShogi-kai/blob/master/Network/ResnetNoBN/policy_value_resnetNoB.py)|1.80566|0.4327175|0.68042606|Resnet５block１２層だがBatchNormalizationなし|
###（２）総当たり戦の結果
だいたいの強さ指標としてLesserKaiを参加させてみました。
![tornament1.jpg](https://qiita-image-store.s3.amazonaws.com/0/233744/a7b52971-71e6-2d00-fffc-e110887d69ad.jpeg)
勝敗は以下のとおり、順位が出ました。
なんとなく上記の一致率やLossの値があてにならないのがわかります。
※これすごく重要なことだと思いますが、中身はわかっていません
![resultTornament.jpg](https://qiita-image-store.s3.amazonaws.com/0/233744/c2642161-e58c-5a11-b42f-6a1460fa716e.jpeg)
それぞれの対戦の結果は以下のとおりになりました。

| ---------- |L13|L23|policy|LKai|R5|R10|RL4|RNoBN|Win|Draw| Loss |Pt|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| L13|-|2|1|2|2|2|2|2|13|0|1|13|
| L23|0|-|1|2|2|2|2|2|11|0|3|11|
| policy |1|1|-|2|1|1|2|2|10|0|4|10
| LKai|0|0|0|-|2|2|2|2|8|0|6|8
| R5|0|0|1|0|-|2|2|2|7|0|7|7
| R10|0|0|1|0|0|-|1|2|4|0|10|4
| RL4|0|0|0|0|0|1|-|0.5|1|1|12|1.5|
| RNoBN|0|0|0|0|0|0|1.5|-|1|1|12|1.5|

ここでLKaiというのが将棋所に付属しているLesserKaiでレイティングは７１３ということになっています。ある意味これに勝てて初めて将棋らしくなると云えます。
今回、一番うれしかったのはPolicyがLesserKaiより上にきて、しかもすべてのNetworkモデルと互角以上で、負けなかったことです。
※最終的な目標はこの方策ネットワークによるモデルが一番強くなることです

勝敗の特徴としてはディープなものやResnetの成績が悪いということです。これは棋譜を十分に学習していないからかもしれません。もう少し学習を進めていけば真偽がわかると思います。
※どこかのフェーズで強化学習をする必要があると思っています
###まとめ
・自前モデルでコンピュータ将棋選手権をやってみた
・方策ネットワークのPolicyが案外いい結果を出した
・ディープもResnetもあまりいい結果が出なかった
・そもそも一致率やLossの値が強さの指標値になっていない

・最終的な目標はこの方策ネットワークによるモデルが一番強くなることです
・強化学習をしてみよう
lol 用語集

#地図
上路:top
中路:mid
下路:bot
打野:jg
補助:sup

通常攻撃:aa
技:skill
必殺技:ult

#能力
物理攻撃力:ad
魔法攻撃力:ap
物理防御力:ar
魔法防御力:mr
体力:health,hp
魔力:mana
移動速度:ms

範囲攻撃:aoe
瞬間移動:blink
不能時間:cd
不能時間減少:cdr
行動阻害:cc
移動不可:snare
速度低下:slow
技使用不可:silent
逃亡:fear
交換:trade
高速移動:blink
他列移動:roam
多数攻:gang

将軍:champion
#将軍種類
後半型将軍:carry
暗殺将軍:assasin
盾将軍:tank
戦士将軍:fighter
射手将軍:marksman
魔力将軍:mage

兵士:cs
光速移動:flush
疲弊:exaust
回避:dodge
視界:word
強化:buff
劣化:nelf
赤木獣:red buff
青岩獣:blue buff
対抗手段:meta
貯蓄:stack

押込:push
凍結:freezing

#将軍一覧
#上路
斧将軍:dalius

#中路
女狐:ahri

#下路

#補助
牛:arister

#打野
闇:ノクターン
趙雲:シンジャオ
楽して遊ぶUbuntu Part2 ~Ruby on Rails入れてみましょ~

## 大前提
- スナップショットを取得する
    - スナップショットとは（[スナップショット (ファイルシステム) - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%8A%E3%83%83%E3%83%97%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_(%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0 'スナップショット (ファイルシステム) - Wikipedia')) より抜粋）
    
    >ストレージ中に過去のある一時点で存在したファイルとディレクトリの集合、またはその記録処理を実現する仕組みである。
- Parallelsの場合：
    1. コントロールセンター上で、スナップショットを取得するVMを右クリック → スナップショットの管理を選択
    2. 新規ボタンを選択
    3. スナップショット名と説明を入力し、OKを選択
    4. スナップショットが作成される


## Ruby on Rails導入
- 前提：[楽して遊ぶUbuntu Part1 ~UbuntuとRuby導入~](https://qiita.com/yakitamago_san/items/1d4ef6495ff04a3e8bcf)にて、Rubyを導入済み

1. Railsインストールに必要なパッケージをインストールする

    ```
    sudo apt install -y libsqlite3-dev nodejs
    ```

2. RubyGemsをアップデートする
    - 前回の記事では任意インストールでしたが、Rails導入には必要のためインストールする

    ```
    gem update --system
    ```

3. bundlerをアップデートする
    - 前回の記事では任意インストールでしたが、(略)

    ```
    gem update bundler
    ```

4. Railsをインストールする
    ```
    gem install rails
    ```

5. Railsのバージョンを確認する
    ```
    rails --version
    Rails 5.2.0
    ```

6. Railsのフォルダを作成し、移動する

    ```
    mkdir /path/to/rails/workdirectory
    cd /path/to/rails/workdirectory
    ```
7. Railsを起動する

    ```
    rails new <project>
    cd <project>
    rails server
    ```
8. ブラウザからRailsにアクセスする
    - 下記画面が出ればOK
    <img width="590" alt="スクリーンショット 2018-06-30 14.24.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/208150/c061db48-5603-b56f-dd08-1e6925b2f9bc.png">

## 参考
- [ubuntuにRuby on Rails環境を構築してみよう！](http://exrecord.net/how-to-construct-ruby-on-rails-environment-in-ubuntu)
JVM4大地雷(仮)を避けて障害を防ごう

周囲で見聞きしてよく詰まる部分です。詳細は省略

##名前解決結果を勝手にキャッシュ
アプリのJVMレイヤーで必要ですかね？昔のなごり？

##証明書ストアが独自
OSのストアを修正しても反映されない。

## ulimit など設定忘れ
スレッドベースなので大きいプロセス1つです。
プロセスに対するOSからのリソース制限はデフォルトではたくさんあるため、
リミッターを開放しないといけない

# JMXが動かない

JVMを動かしているサーバの外部から、一部のモニタリングツール等でJMX監視するとする。
そのサーバの`/etc/hosts`か、
または`java.rmi.server.hostname`オプション等を使い、ループバックアドレスではないipを適切に設定する必要がある。

[JMX参考リンク](https://docs.oracle.com/javase/jp/8/docs/technotes/guides/management/faq.html)
[Day1] TypeScript ×  Node.jsで簡単なRESTAPI作ってみる(HelloWorld編)

## 何を作るの？
所属してるチームで使うAPI群を作ります。
Qiitaには作業の備忘録として投稿します。

## なぜNode.js？
今回は簡単なAPIなので、
軽量ですぐに実装可能なNode.jsで書きます。

## なぜTypeScript？
オブジェクト指向かつ静的型付けで記述が出来るので、
コードが汚くなりづらいのが特徴です。
※書き方によっては汚くなります（）
今回は私一人で書きますが、
今後チームでの導入も考えて触れてみることにしました。

## 開発環境
### docker
https://docs.docker.com/docker-for-mac/install/
node.jsのバージョンは推奨バージョンの8.12.0とします。
`node:8.12.0-alpine`

### swagger
yamlで書けるAPIドキュメントです。
yamlからコードも自動生成出来ます。
swaggerで書いたドキュメントを仕様として、
node.jsの実装に落とし込んでいきます。

### atom
`atom-typescript`を導入しました。
TypeScriptのbuildが出来るようになります。


## Hello World
パッケージ管理用のjsonを生成します。色々質問されますが、基本Enterでokです。
`npm init`

ルーティングを管理してくれるライブラリ
`npm install --save express`
セキュリティ対策
`npm install --save helmet` 
TypeScript
`npm install --save typescript`

app.tsを作成します。

```
import * as express from 'express';  // tsの場合はimportらしい。なんかpythonぽい。
import * as helmet  from 'helmet';
var app = express();  // ここも型定義すべき？ any型とかになるんだろうか。
app.use(helmet());    // helmetを使う(そのまま)
app.listen(50001, listen_callback); // http://localhost:50001
app.get("/", root_dir_callback);    // ルート直下でGETが呼ばれたら発火

function listen_callback() {
    console.log("start!");
}

function root_dir_callback(req, res, err) {
    res.end("Hello World!");
}
```

jsファイルに変換
`tsc app.ts`

実行
`node app.js`

http://localhost:50001
<img width="278" alt="スクリーンショット 2018-09-12 20.42.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/286417/67d63a0d-df3d-3e7b-3d6c-517f72c5963b.png">

## 感想
Any型(var)が使えるけど、これあんまり使わないほうが良さそう。
次は一旦実装から離れてDockerかSwaggerについて詳しくまとめてみます。
zshを使っていてVSCodeのcodeコマンドを使用する方法

## 環境

* Mac 10.13.6
* zsh

## 起きた問題

VSCodeのshell command installは出来るのになぜかターミナルから使用できなかった

## 解決方法

`.zshrc`をviで開く

```
$ vi ~/.zshrc
```


以下を追記する

```yaml
function code {
    if [[ $# = 0 ]]
    then
        open -a "Visual Studio Code"
    else
        local argPath="$1"
        [[ $1 = /* ]] && argPath="$1" || argPath="$PWD/${1#./}"
        open -a "Visual Studio Code" "$argPath"
    fi
}
```

追記したら、以下を実行

```
$ source ~/.zshrc
```

以上で`code`コマンドでVisual Studio Codeをコマンドラインから起動出来るようになります。
git stashはもういらない!　3分で分かるgit worktree

![alt](https://user-images.githubusercontent.com/26253721/39765058-e8d0eae4-531b-11e8-9305-4c852f269517.png)
git worktree はstashのいらないbranchのようなものだ。
git 2.7から使える。
branchを作る代わりに　worktreeという名前のフォルダを作る
以下のメリットがある。
・複数のブランチを、別々のエディタで呼び出し、並列的に修正可能。
・ブランチの切り替えという概念がなくなるため作業効率が上がる。　つまり、git stashの必要がなくなる
　以下のデメリットがある
・branchを作るのと違いgitignoreが適用されるため、１設定必要。

# git worktreeがエンジニアの生産性を大幅に上げることを証明する。

## 1.まず、作業フォルダを作る。

    mkdir workspace; cd workspace

## 2. 何かプロジェクトを作成。
    react-native init AwesomeProject; cd AwesomeProject

## 3. 以下のコマンドで、branchとworktreeを一緒に作る。
    git worktree add -b Foo ../Foo origin/master

Foo = 新しく作られるbranch名
../Foo = 新しく作られるworktree名
origin/master = origin/masterからbranchとworktreeを生やす。
 
現状以下のような構成になっている。
workspace
--AwesomeProject
----.git
--Foo (worktree)
----.git

## 4.Fooフォルダに移動してgitが使えることを確認。
    cd ../Foo; git log;
試しにFooの中でcommitしてgit pushしてみよう。

以上!!!

実務で使うときは、以下のように、あるプロジェクトのmasterと、そのworktreeだけを含むフォルダを作るといい。
その際、masterは削除できないように設定しておくともっといい。
AwesomeProject
--AwesomeProject　（master）
----.git
--Foo (worktree)
----.git
--HotFix (worktree)
----.git


便利なのはworktree間で.git以下のフォルダが同期していること。
そしてbranchが別々のフォルダにあることでそもそもgit stashをせずに作業が出来ること。
stashでなく、新しいエディタで、「直接」branchを開ける。
worktreeを消したい時は、rm -rf Fooだ。

なんて単純ながら革新的だろう。学習コストがほぼいらず、単純に生産性が上がる。
ただ.gitignoreで除外されるファイルはworktreeで同期しない。

# gitignoreされてしまう。
そう、git worktreeはgitignoreが適用されてしまう。

それを回避するためにはrsync!

```
git worktree add -b Foo ../Foo master; rsync -a --exclude='.git' ../awesomeProject(コピー元のプロジェクトの名前)/ ../Foo
```
解説すると、localのmasterからFooというbranchを切り、Fooというフォルダの中にそのbranchを入れる。
rsyncは複雑なことができるcpコマンドだ。
localのmasterをFooというフォルダに.git以外のフォルダをコピーする。
30秒ほどかかるのが欠点。gitignoreされたファイルだけ、選択してコピーするやり方がわかるbashの達人の方がいらっしゃったらコメントしてください。

npmがインストールされている人は、
npx kabatree newBranch
で上記と同じことをしてくれる。
（私が制作しているnpmライブラリです。）


もし、git worktreeの仕組みが分からなかったら、worktreeの.gitとmasterの.gitを見てみよう。worktreeは単純な仕組みなので、すぐに理解できる。
localhost:8080を使用しているプロセスを調べてkillする方法。

localhost:8080を使用しているプロセスを調べてkillする方法。

    sudo lsof -P -i:8080 
    COMMAND PID  USER   FD   TYPE      DEVICE SIZE/OFF NODE NAME
    java    123 admin   11u  IPv6      0t0  TCP *:8080 

 PIDの番号をkillする。

    sudo kill -9 123
　
pom.xml
Springでポートをkillせず自動更新してくれる。

    <!-- 編集したら自動更新される -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
    </dependency>
Item 64: Refer to objects by their interfaces

# 64.インターフェースを参照するようにせよ
## インターフェースで型を宣言しといた方が柔軟な設計になる
**適切なインターフェース型あるならば、引数、戻り値、変数、フィールド全てがインターフェース型で宣言されるべきである。**
オブジェクトクラスを参照するのはコンストラクタにおいてのみである。

以下、Setインターフェースの実装クラスである、LinkedHashSetを例に見ていく。

```java
// Good - uses interface as type
Set<Son> sonSet = new LinkedHashSet<>();
```
上記はいい例。

```java
// Bad - uses class as type!
LinkedHashSet<Son> sonSet = new LinkedHashSet<>();
```
上記は悪い例。

インターフェースで宣言した例だと、以下のように変えるだけで、実装クラスが基本的にエラーなく変えられる（インターフェースで宣言しているメソッドのみ使用しているため）。

```java
Set<Son> sonSet = new HashSet<>();
```
ただし、気を付けなくてはいけないのは、インターフェースでは規定されていない機能に依存したコードである場合には、実装クラスを変える影響があり得るということだ。
例えば、LinkedHashSetの並び変えのポリシーに依存していた場合には、HashSetに実装を変えた時に影響が出るだろう。

## 適切なインターフェースがない時
適切なインターフェースがない時は、クラスの型で宣言を行うのが正しい。

### value class
例えば、StringやBigIntegerなどの値を表すクラス（value class）を考えてみる。
value classは複数の実装があることがまずない。また、おおむねfinalなクラスであり、対応するインターフェースがない。
value classは引数、変数、フィールド、戻り値の型として適している。

### クラスベースのフレームワークを使っているとき
クラスベースのフレームワークを使用しており、適切な基盤の型がインターフェースでなくて、クラスであるときがある。
そういった場合も適したクラス（だいたいabstract）を継承するのが良い。
java.ioのOutputStreamなどはこれに当たる。

### 適したインターフェースはないが、実装クラスに適したメソッドが実装されているケース
例えば、PriorityQueueにはcomparatorメソッドがあるが、Queueインターフェースにはない。もしcomparatorメソッドに依存するプログラムを書くのであれば、PriorityQueueを参照する。ただし、このようなケースはレアである。


上記3つのケースは網羅的なものではなく、クラスで参照するなんとなくの場面について伝えたものである。

**もし適したインターフェースがない場合は、目的の機能を持っている一番抽象度の高いクラスを参照すべき。**
Active JobとSidekiqについて

# これは何？
Rails 4.2以降で標準で利用可能になったのがActive Job。
バックグラウンドでジョブを実行するために利用するという理解はしてるけど、実は全然理解できていない人向けです。

[公式ドキュメント](https://railsguides.jp/active_job_basics.html)はこちらを参照してください。

# そもそもバックグランド処理って何？
開発するアプリケーションが大規模であればあるほど、
プログラムの処理に時間がかかるようなことが出て来ると思います。
（例えば、レコメンド処理の計算とか、何かしらの解析とか）

そういった時間のかかる処理というのを非同期で実行できるようにすることでユーザビリティを向上するのがバックグラウンド処理です。

そのため、バックグラウンド処理で求められる機能は、

- ジョブの登録
- キューの操作
    - すぐ実行
    - 時間おいて実行
    - 定期実行
    - 優先度など
- ジョブの実行
    - 並列処理など
- ジョブの失敗時の対応
    - リトライ
    - エラー出力など

などなど様々なことが求められます。

# Active Jobって何？
Railsガイドによると、下記のように記載があります。

`Active Job is a new framework in Rails 4.2. It is a common interface on top of queuing systems like Resque, Delayed Job, Sidekiq, and more.`

そのため、実際にバックグラウンドでジョブを実行できるものではなく、
あくまでバックグラウンドでジョブを実行するgemの共通インターフェースになってるようです。
※ Active Job単体ではキューを実現できないようです。

要は、Active JobがキューにJobを登録して、SidekiqのようなgemがJobを実際に実行するイメージです。

# サンプルコード
## 作成イメージ
下記のようなイメージでコードを作成していきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180679/0de61bfc-9d0f-293c-7373-d5b5d8b60336.png)

ControllerからジョブがRedisにキュー登録されると、
ActiveJobをインターフェースとしたSidekiqが常にRedisを監視して新規登録があればジョブを実行するという流れ。

## 詳細
`redis`と `sidekiq`は入れておいてください。
`brew install redis`
`gem sidekiq`

```config/sidekiq.yml
:concurrency: 25
:pidfile: ./tmp/pids/sidekiq.pid
:logfile: ./log/sidekiq.log
:queues:
 - default
```
=> concurrencyは同時実行数だが、[sidekiq自身で一つカウント](https://repl.info/archives/659/)するらしい。

```config/application.rb
# ActiveJobがSidekiqを使うことを宣言
config.active_job.queue_adapter = :sidekiq
```

```shell:bash
bundle exec rails g job My
```

```ruby:my_job.rb
queue_as :default

def perform(message)
 # ジョブの実行時刻を記録します
 p Time.now
end
```

```ruby:start_controller.rb
# CSRF対策がされてるので、その回避のため
protect_from_forgery :except => [:run]

def run
 # 即時実行
 MyJob.perform_later('Task execute')
 # 時間置き実行
 MyJob.set(wait: 3.second).perform_later('Task execute')

 render plain: 'success'
end
```
=> `perform_later`メソッドはJobの`peform`メソッドを呼び出します。

```ruby:routes.rb
post 'start/run'
```

これで準備おけいです。

あとは、Redisの起動、Railsの起動、sidekiqの起動をして、リクエストを投げればsidekiq上で時刻が表示されると思います。

[ほぼこちら](https://dev.classmethod.jp/server-side/ruby-on-rails/ruby-on-rails_active-job-sidekiq/)のコードで勉強させてもらいました。ありがとうございます。


# リトライ制御
ActiveJobはリトライ制御が弱いです。
Rails5.1から`ActiveJob::Base.retry_job`と`ActiveJob::Base.discard_on`というメソッドが追加されたのですが、そこで制御してもSidekiqのリトライ回数などが優先されてしまいます。
[Rails5.1のリリースノート](https://railsguides.jp/5_1_release_notes.html#active-job)

ここで、リトライ回数を制御する必要性が出て来るわけです。
僕が色々試した中で最も良かったのは、[activejob-retry](https://github.com/isaacseymour/activejob-retry)というgemの利用です。

gemをインストールした後は、制御したいジョブクラスの中で下記のように宣言すれば制御可能です。

```ruby:my_job.rb
queue_as :default

include ActiveJob::Retry.new(strategy: :constant, limit: 3, delay: 3.seconds)

rescue_from(StandardError) do
 p("All Retry Failed")
end

def perform(message)
 p("Time：#{Time.now}：#{message}")
 error #エラーを起こすためわざと宣言してない変数を置いてます。
end
```

実行してみた感じ、きちっと3秒おきに実行されるわけではない（誰かわかる方ぜひ教えてくださいませ）のですが、
今回の目的であったリトライ回数に関してはしっかりと達成されていました。

導入も簡単なのでこちらで試してみるのがいいかもしれません。