OmniAICreator/Qiita-1.07M huggingface dataset:
ZabbixServerで特定ホストのスクリーンを表示させる

# ■概要
テンプレートで設定したスクリーンへの遷移はどこからするのか分からない。。
同じ悩みを持つ人が居て、解決してくれてた！
>テンプレートのスクリーンを見る良い方法 | 日本Zabbixユーザー会 : http://www.zabbix.jp/node/2279

しかし、当方の環境では同じテンプレートを適用したホストが５０を超えているため
マップに１つずつ設定、ホストを全て表示させるのは辛かった。

# ■解決策

## １．検索
検索ボックスに対象のホスト名を入力し検索ボタンを押下する。
（例では[Web server]を検索）

![zabbix1.png](https://qiita-image-store.s3.amazonaws.com/0/35095/054a2f40-3bca-40d1-827c-92063534c909.png)

## ２．検索結果からスクリーンを選択

![zabbix2.png](https://qiita-image-store.s3.amazonaws.com/0/35095/19f8fa49-5af3-e366-1208-5333a0dd040a.png)


## ３．スクリーン表示
無事スクリーンが表示されました。
スクリーンが複数ある場合は赤枠のコンボボックスから選択してください。

![zabbix3.png](https://qiita-image-store.s3.amazonaws.com/0/35095/73b4ab48-7f36-de55-72dd-10a52825926e.png)


# ■お礼
画面キャプチャしたサーバは
**日本Zabbixユーザー会**さん
**使えるネット**さん
によって提供されたデモサーバを利用させていただきました。
http://www.zabbix.jp/documents/demo

この場を借りてお礼申し上げます。
[Swift4]ナビゲーションバーの使い方

こんばんは。東條です。

今日はナビゲーションバーの使い方について学びます。

##1.ストーリーボードでの作成方法
ストーリーボードで作る場合はNavigation Barってやつを配置します。
左右にBar Button Itemってやつを配置することで、いい感じになります。Buttonとかを使う時みたいな感じで設定しちゃってください。

##2.コードでの作成方法
ここからが本題。
ストーリーボードで作ると色々と不便な時があるので、コードで作る方法も調べてみました。

処理内容：
1.コードで最初のビューにナビゲーションバーを作成
2.遷移ボタンを押下したら次の画面に遷移&次の画面にナビゲーションバーを作成
3.戻るボタンを押すことで前の画面に戻る

このコードを試すときには、ストーリーボードでビューコントローラーをもう一つ追加して、追加したビューコントローラーのidentify inspectorのStoryboard IDにnextを設定しておいてください。


```Swift:test
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        //ナビゲーションバーを作る
        let navBar = UINavigationBar()
        
        //xとyで位置を、widthとheightで幅と高さを指定する
        navBar.frame = CGRect(x: 0, y: 0, width: 375, height: 60)
        
        //ナビゲーションアイテムのタイトルを設定
        let navItem : UINavigationItem = UINavigationItem(title: "タイトル")
        
        //ナビゲーションバー右のボタンを設定
        navItem.rightBarButtonItem = UIBarButtonItem(title: "遷移", style: UIBarButtonItemStyle.plain, target: self, action:#selector(self.myAction))
        
        //ナビゲーションバーにアイテムを追加
        navBar.pushItem(navItem, animated: true)
        
        //Viewにナビゲーションバーを追加
        self.view.addSubview(navBar)
        
    }
    
    @objc func myAction(){
        let storyboard: UIStoryboard = self.storyboard!
        let second = storyboard.instantiateViewController(withIdentifier: "next")
        

        //ナビゲーションバーを作る
        let navBar = UINavigationBar()
        
        //xとyで位置を、widthとheightで幅と高さを指定する
        navBar.frame = CGRect(x: 0, y: 0, width: 375, height: 60)
        
        //ナビゲーションアイテムのタイトルを設定
        let navItem : UINavigationItem = UINavigationItem(title: "タイトル")
        
        //ナビゲーションバー左のボタンを設定
        navItem.leftBarButtonItem = UIBarButtonItem(title: "戻る", style: UIBarButtonItemStyle.plain, target: self, action:#selector(self.returnView))
        
        //ナビゲーションバーにアイテムを追加
        navBar.pushItem(navItem, animated: true)
        
        //遷移先Viewにナビゲーションバーを追加
        second.view.addSubview(navBar)
        
        //画面遷移
        self.present(second, animated: true, completion: nil)
    }
    

    //遷移先Viewから戻る処理
    @objc func returnView(){
        self.dismiss(animated: true, completion: nil)
    }
    

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

```

ソースで見ると何となくわかったような気になれますね。
actionの内容を変えれば色々楽しめそうです。

ただUIBarButtonItemのStyleやtargetはどのような意味があってどのようにいじれるのでしょう。。。presentやdismissのanimatedとcompletionも謎です。。。
Unity2018でGUIを日本語化する方法

#Unity 2018でGUIを日本語化する方法

##Unity 2018は英語
初めて触るUnityはメニューバーが英語でもう分からない。
<img width="640" alt="englishUnity.png" src="https://qiita-image-store.s3.amazonaws.com/0/212799/3aacd17b-e014-6851-4105-6e1f4ef7e0ba.png">


##Unity2018を日本語化

1. 日本語化に必要な翻訳ファイルを以下のURLからダウンロードします。

    ```
    http://editor-localization.s3-website-ap-northeast-1.amazonaws.com/2018.1/ja.po
    ```

2. ja.poファイルを以下のディレクトリーに移動します。
    (Localizationディレクトリーは作成する必要があります)
    - Unityを単体でインストールした場合
    
        ```
        C:\Program Files\Unity\Editor\Data\Localization
        ```
   //Applications/Unity/Unity.app/Contents/Localization

 - Unity Hubを使ってインストールした場合
 (Windows)
  
        ```
C:\ProgramFiles\Unity\Hub\Editor\2018.1.0f2\Editor\Data\Localization
        ```

         (macOS)

        ```
/Applications/Unity/Hub/Editor/2018.1.0f2/Unity.app/Contents/Localization
        ```
<img width="778" alt="dragPos.png" src="https://qiita-image-store.s3.amazonaws.com/0/212799/66bb055e-0785-0545-3fa6-5197b35848b7.png">


3. Unity エディターを起動し、設定ウィンドウを開きます。
    (Windowsの場合)
    ・Edit > Preferences…
    
    (macOSの場合)
    ・Unity > Preferences
     <img width="218" alt="preference.png" src="https://qiita-image-store.s3.amazonaws.com/0/212799/a83e1a8e-aa07-6957-00e9-736b692040b5.png">

    ※Unity エディターを起動したまま.poファイルを移動した場合は、エディターを再起動してください。

4. Languageを変更します。
<img width="542" alt="language.png" src="https://qiita-image-store.s3.amazonaws.com/0/212799/96d3d24b-8664-b99b-1453-2862e2d8e5b8.png">


5. 日本語化
<img width="640" alt="japaneseUnity.png" src="https://qiita-image-store.s3.amazonaws.com/0/212799/2ac461bb-5d34-d6f6-9134-fa453dffcc80.png">

##参考
「Unite Tokyo 2018」
http://events.unity3d.jp/unitetokyo2018/index.html
「UnityConect Unityエディター日本語化フィードバック」
https://connect.unity.com/g/5aefe5b903b0024a1c8aa7bf
OrmaのバージョンアップでParseCancellationException

## 現象
- Ormaオブジェクト初期化時に発生。
- 普段テストに使っていた端末では問題なかった
- 本格的に検証を始めたときに古い端末だけで発生した。

## 原因として考えられること
- v3.2.1→v4.2.5に上げた。
- 他のライブラリのバージョンを色々上げた。


## 調べた
- 古いAndroid OS Version(4系で確認)か、ヒープの小さいエミュレーターで発生するらしい。
- [issueはこちら](https://github.com/maskarade/Android-Orma/issues/352)

## 解決
- build gradleのバージョンを戻した

```
dependencies {
        // classpath 'com.android.tools.build:gradle:3.1.2'
        classpath 'com.android.tools.build:gradle:3.0.1'
}
```

- DataBindingも一緒にバージョンを戻した(kaptのエラーが出るので)
`kapt 'com.android.databinding:compiler:3.1.2'`
↓
`kapt 'com.android.databinding:compiler:3.0.1'`

- Ormaのバージョンはv4.2.5に上げたまま

## おわり
- Android4系切れれば解決する
- 他にも影響があるかもしれません。
- ライブラリのバージョンアップ待ち。Orma v6で直る？
顧客検証での街頭アンケート（メリット・デメリット、コツ）

リーンスタートアップや
起業の科学なんかを読んでると
『顧客の抱える課題を適切に捉えられているかどうか、
製品を作る前に顧客検証しろよ』
と良く書いてあります。

顧客検証を進めていくなかで
もしかすると街頭アンケートを行うかどうか検討することがあるかもしれません。

実際に街頭アンケートをやってみて感じたメリット、デメリットや
コツについて色々思うところがありましたので、下記にまとめてみました。
何かの参考になれば幸いです。

※前提として、相手にはアンケート内容は見せず、対話式で質問しながら進めていきます。アンケート内容を相手に見せて記載してもらう形式にすると、Webのアンケートと大差がなくなってしまうので。

#街頭アンケートのメリット、デメリット

【メリット】
・質問したあとに即回答をしてもらうため、潜在的な課題やニーズを引き出しやすい
・アンケート以外の内容でも、気になる回答があれば深堀できる
・アンケートした人と仲良くなることもあり、うまくいけば今後も継続して話を聞いてもらえる関係性を築ける
・チームメンバー同士で課題に対する共通認識がとれる

【デメリット】
・次の質問してなくても、先に答えてくれたりすることがあるのでメモや質問の順番を入れ替えるのが大変
・アンケートする人の属性を指定しにくい

そして何といっても「知らない人に話しかけるのが怖い」という
心理的なハードルが大きい部分が良くないかなと思っています。
ただ、徐々に慣れてはきます。

#街頭アンケートをするコツ
・止まっている人に話しかけること
⇒話かけても動いている人は断られてそのまま逃げられる確率が高いです。そして傷つきます！
  止まっている人であれば、実感として7-8割ぐらい回答してくれたので、止まっている人に話しかけましょう。

・アンケート対象者が集まりそうな場所に行く

・2人1組で行う。
⇒1人で全部やるのは大変なので1人が質問をして、もう1人がメモを取る。
  最後にお互いでメモした回答があっているか確認する。次は担当を入れ替える。
PandasでWeb上のTableタグからデータを取得する

Pandasの使い方を知りたいので、google colaboratory環境を使って試して行きたい。

### パースエンジン(flavor指定)としてBeautifulSoup4を使うので予めインストール

```python
!pip install -q beautifulsoup4
```

### 気象庁の「アメダス(表形式)」から東京の前日分データを取得する

```python
import pandas as pd

url = "http://www.jma.go.jp/jp/amedas_h/yesterday-44132.html?areaCode=000&groupCode=30"
tables = pd.read_html(url, flavor='bs4', match="時刻", header=0, index_col=0)

print(tables[0].loc[:,["気温","降水量","湿度"]])
```

### 結果

<pre>
    気温  降水量  湿度
時刻               
時     ℃   mm   %
1   18.0  0.0  54
2   17.6  0.0  55
3   15.5  0.0  66
4   15.1  0.0  70
5   14.9  0.0  73
6   16.2  0.0  70
7   18.9  0.0  56
8   20.3  0.0  50
9   23.0  0.0  51
10  24.3  0.0  49
11  24.5  0.0  47
12  25.2  0.0  48
13  24.7  0.0  47
14  25.1  0.0  37
15  25.7  0.0  35
16  25.2  0.0  36
17  23.7  0.0  42
18  22.2  0.0  48
19  21.7  0.0  53
20  21.4  0.0  53
21  21.1  0.0  57
22  20.6  0.0  67
23  19.2  0.0  80
24  19.0  0.0  80
</pre>
vSphere HAを有効にするときに気を付けたいこと

##はじめに
クラウド基盤の構築している2年目のインフラエンジニアです。
最近、vSphere HAについて深く勉強したので、得たものをまとめたいと思います。
今回初投稿なので不明点や不備があれば教えていただけると嬉しいです。

## vSphere HAとはどういう機能か
ESXiホストに障害が発生したときにもVMの稼働を最大化する機能がvSphere HAです。
クラスタを新規作成または編集するときに、vSphere HAを「オンにする」にチェックを入れることでこの機能を有効にすることができます。
例えば、あるESXiホストで障害が発生し通信が遮断してしまった場合、vSphere HAを有効にしていればその上で稼働していたVMは自動的にクラスタ内で別の正常なESXiホスト上で再起動させることができます。

##vSphere HA有効にしていたのに障害時発動しない？
###障害の概要
今回、ESXiのストレージ側のNICを両系unusedにし、ストレージと通信ができなくなった障害が発生したという仮定の下、ESXiホスト上のVMはどのような挙動をするのか検証しました。

・vSphereのバージョンは、6.0
・クラスタのvSphere HAは有効にしデフォルトの設定のまま
・クラスタ内のESXiは3台（1台のみ障害発生）

上記の条件下だと障害が発生したESXi上のVMはvSphere HAによって別の正常なESXiホストに移動しませんでした。
vmware基盤を構築する身にとっては、障害発生時にvSphere HAが発動せず、VMの稼働が停止してしまう状態は回避したい・・・。

##解決方法
###VMCP 障害応答の設定を変更する
####VMCPとはどのような機能か
vSphereのバージョンが6.0以降の場合、**VMCP(VM Component Protection)**というデータストアのアクセス障害を検出し、VMの自動リカバリを実行する機能が搭載されているようです。
以下の2つの障害を検知します。
・APD(All Path Down)：ストレージがホストに一時的にアクセス不能、全デバイスのパスが使用不可
・PDL(Parmanent Device Loss)：永続的にデバイスが損失されている状態

####APD発生時の設定を有効
今回は、ストレージと全く通信できない状態なので、APDに関する設定を変更しました。
私はAPDが発生した場合、「仮想マシンをパワーオフして再起動: 標準的な再起動ポリシー」するように設定変更しました。
設定変更は以下の手順で行います。
[VMCP応答の構成](https://docs.vmware.com/jp/VMware-vSphere/6.5/com.vmware.vsphere.avail.doc/GUID-DF3123C3-CE63-4431-A1FE-FD41F3395BCE.html)

####設定変更後の挙動
このように設定変更し、再度ESXiのストレージ側のNICを両系unusedにしました。
その結果、ストレージアクセス障害を検知し、VMはクラスタ内の別ESXiホスト上で再起動ことが確認できました。
しかし、別ESXiホスト上で再起動するまでに要した時間は、ping応答で確認したところ4分であり、この反応の遅さが懸念事項として残りました。

####障害検知に要する時間変更
そこで、APDのオプションのデフォルト値を変更してみました。
変更した値は、以下２つです。
Apdtimeout:140s → 20s 
APD待機時間:3分 → 0
[ストレージAPDのタイムアウト制限の変更](https://docs.vmware.com/jp/VMware-vSphere/6.0/com.vmware.vsphere.storage.doc/GUID-5CC5A990-AC23-4D51-80DD-37F09175E255.html)
その結果、4分かかっていたのが2分半程度まで削減することができました。

元々APD状態を検知後、一旦待機して復旧しなければHAする機能のようです。

##まとめ
・vSphere HAはデフォルト設定のままだとデータストアのアクセス障害を検知しない。
・VMCPはvSphere6.0以降に搭載されているので、vSphere HAを有効にするときは設定をカスタマイズする必要がある。
・VMがフェイルオーバーし、再起動するまでの時間も設定変更することができる。
共有している画像にコメントできなくなったときのリカバリー

# 概要
iCloud写真共有の画像に急にコメントできなくなった。ネットで検索しても対策が見つけられなかったので、同じように困った人がいた時にお役に立てばよいなと思い記事を書いてみた。

# 現象
iCloud写真共有の画像にコメントできなくなった。現象は次の通り。
- 「コメントの追加…」をタップするとキーボードが表示される。
- このとき写真が上に移動せず「送信」が表示されない。
- 文字を入力しても「送信」が押せないのでコメントを追加できない。
 
# 環境
デバイス：iPad mini 3
iOS：11.3.1

# リカバリー方法
すべての設定をリセットするとコメントが入力できるようになった。
https://iphone-trouble.biz/iphone-all-reset-how
iOSのアップデート、キーボードの再登録、iCloud写真共有をOFF→ONなどを行ったがどれも回避できなかった。
could not launch process: EOF:Goのデバックができなくなったときの解決方法

`could not launch process: EOF`というエラーが出てGoのデバックができなくなっていた。

調べるとGoのデバッカー`delve`のバグらしい。
https://github.com/derekparker/delve/issues/1165

すでに対応済みで最新版をもう一度インストールすれば治りました。

```bash
$ go get -u github.com/derekparker/delve/cmd/dlv
```

とりあえず自分メモで残しておきます。
evtx形式のイベントログを今日を起点に過去100日分取得する

evtx形式で取得する方法の記事が少ないので、載せます

※ver2以上で動作確認済み


```powershell

# イベントログ出力関数を定義
# 引数1：ログ種別(System,Application)    引数2:出力先フォルダ(C:¥evtxlog など)
function get-evtxlog ($logname,$outpath) {




# 開始日付(100日前)と終了日付(今日)を取得し、
# イベントログの選択に使用するクエリ(XPATH形式)に格納する

        # 開始日付指定(100日前を指定する場合、100と記述する)
        $fromDay = 100

        # 開始日付
        $startTime = (Get-Date).AddDays(-$fromDay)

        # 終了日付(今日)
        $endTime   = (Get-Date)

        # イベントログの選択に使用するクエリ(XPATH形式)に渡すため、システム時刻(UTC)に変換する
        $startUtcTime = [System.TimeZoneInfo]::ConvertTimeToUtc($startTime).ToString("yyyy-MM-ddTHH:mm:ssZ")
        $endUtcTime   = [System.TimeZoneInfo]::ConvertTimeToUtc($endTime).ToString("yyyy-MM-ddTHH:mm:ssZ")

        # イベントログの選択に使用するクエリ(XPATH形式)
        $filter = @"
Event/System/TimeCreated[@SystemTime>='$startUtcTime'] and
Event/System/TimeCreated[@SystemTime<'$endUtcTime']
"@




# 出力ファイル名を作成しておく

        # yyyy-MMdd-HHmm-ss形式の今日日付(出力ファイルの名前用)
        $YYYYMMDD = $endTime.ToString("yyyy-MMdd-HHmm-ss")

        # 出力ファイル（ログ種別_yyyy-MMdd-HHmm-ss）
        $outfile = "${outpath}\${logname}_${YYYYMMDD}_.evtx"




# .Netクラスのメソッドを使って出力

        # System.Diagnostics.Eventing.Reader.EventLogSession クラスをオブジェクト化
        $evsession = New-Object -TypeName System.Diagnostics.Eventing.Reader.EventLogSession

        # ExportLog メソッドを実行 
        # 引数は、ログ種別、"LogName"(FilePathかLogName)、クエリ、出力ファイル
        $evsession.ExportLog($logname,"LogName",$filter,$outfile)




}

# イベントログ出力関数の定義終了







#### 関数実行

try {

# ログ種別エラー用テストコード（コメントアウト）
# get-evtxlog "Syste" "C:\evtlog"


# 出力先フォルダエラー用テストコード（コメントアウト）
# get-evtxlog "System" "C:\qevtlog"


# Systemイベントログを取得
get-evtxlog "System" "C:\evtlog"

# Applicationイベントログを取得
get-evtxlog "Application" "C:\evtlog"

} catch {

# 1で終了
exit 1

}

```

# 結果 
![Screen Shot 2018-05-07 at 22.16.20.png](https://qiita-image-store.s3.amazonaws.com/0/35156/30678b3e-282f-e8fb-9fc1-5d7184e6ca72.png)


# 参考
https://msdn.microsoft.com/ja-jp/library/system.diagnostics.eventing.reader.eventlogsession(v=vs.110).aspx
SparkでJOINするときの注意点

# 動機
SPARKのワーカーノードを多数建ててJOINするとき、一部のノードだけ忙しくて他のノードが使われてなかったり、速度が出ないときがある。JOINが原因であることが時々ある。

# 参考文献
High Performance Spark p.75　に詳しく書いてある

このスライドもいい。
https://www.slideshare.net/databricks/optimizing-apache-spark-sql-joins

# 例
次の例を考えてみる

```
tableA.createOrReplaceTmpView("tableA")
tableB.createOrReplaceTmpView("tableB")
joinedtable = spark.sql("""
SELECT 
a.*,
b.*
FROM tableA as a
JOIN tableB as b
ON 
a.key = b.key""")
```
# suffle join

suffle joinでは、`A.key=B.key`の比較をするためには、AとBの同一キーのレコードが同じノード上に存在し無ければならない。例えば、A.key=2のデータとB.key=2のデータがバラバラのノードに格納されていてはJOINができない。A.key=2のデータとB.key=2のデータが全部ノード1に集めてからJOINを始める。

この場合、たとえば、`A.key=2`だけ全体の8割を占めるといった、`A.key`の出現頻度に偏りが発生していると、1つのノードにテーブルAの8割が存在することになってしまう。これではいくらワーカーノードを用意しても速くならない。

# broadcast join

これはbroadcast joinにすれば解決することがある。この方法ではテーブルBをすべてのノードに配布してしまう。
全てのノードにテーブルBのすべてのデータがあれば、先ほどのようにA.key=2のデータをノード1にすべて集めてくる作業は必要なくなる。

次の書き方だとbroadcastjoin を強制できる。

まずspark-submitするときに`spark.sql.autoBroadcastJoinThreshold`の値を設定する。なんでもいいので大きい値。この値より小さいサイズのテーブル（DataFrame）はbroadcastできる。（設定してもしなくても関係ない気がする。要検証）

```spark-submit.sh
spark-submit \
--master yarn \
--conf spark.sql.autoBroadcastJoinThreshold=1099511627776 \
main.py
```

さらにpythonファイルの中でbroadcastしたいDataFrameは`broadcast(table)`しておく。

```main.py
#tableA と　tableBは事前に作ってあるものとする
from pyspark.sql.functions import *
tableA.createOrReplaceTmpView("tableA")
tableB_b = broadcast(tableB)
tableB_b.createOrReplaceTmpView("tableB_b")
joinedtable = spark.sql("""
SELECT
a.*,
b.*
FROM
tableA as a
JOIN 
tableB_b as b
ON
a.key = b.key
""")
```
ホントにbroadcast join になっているか見るには`.explain()`で確認する。

```
spark.sql("""
SELECT
a.*,
b.*
FROM
tableA as a
JOIN 
tableB_b as b
ON
a.key = b.key
""").explain() # で実行計画を表示
```
`broadcast hash join`と表示されれば成功

# まとめ
- suffle join が有効なとき
    - keyの種類がたくさんあり、かつ
    - keyの分布が均等である
- broadcast joinが有効なとき、
    - テーブルBが小さい

おわり
Swift UISegmentedControl 

```
  private let segmentedControl: UISegmentedControl = {
    let items = ["出勤" ,"退勤"]
    let font = UIFont.systemFont(ofSize: 14)
    let segmentedControl = UISegmentedControl(items: items)
    segmentedControl.translatesAutoresizingMaskIntoConstraints = false
    segmentedControl.selectedSegmentIndex = 0
    
    segmentedControl.layer.cornerRadius = 5.0
    segmentedControl.backgroundColor = .clear
    segmentedControl.tintColor = .white
  
    segmentedControl.setTitleTextAttributes([NSAttributedStringKey.font: font], for: .normal)
//    segmentedControl.frame = CGRect(x: 0, y: 150, width: 320, height: 20)
    segmentedControl.addTarget(self, action: #selector(changeValue), for: .valueChanged)
    return segmentedControl
  }()
  
  @objc func changeValue(sender: UISegmentedControl) {
    switch sender.selectedSegmentIndex {
    case 0:
      print("出勤")
    case 1:
      print("退勤")
    default:
      print("")
    }
  }

```
WP-CLIを初心者が使ってみた。

# WP-CLI
WP-CLIとはWordpressをブラウザではなく、コマンドラインから管理するためのインタフェースらしい。
Pluginをインストールして有効化したり、アップデートなども行えるのでAnsibleと組み合わせる事により、Wordpress構築の自動化ができる。と思う。WP-CLIをとりあえず、触ってみます。
### 検証環境
- Virtul Box
- VM 2台
- OS：Ubunu16.04
- Web srv(ホストオンリーアダプタ：192.168.57.200)
- DB srv(ホストオンリーアダプタ：192.168.57.201)

### WP-CLIの動作要件
\>\>\> UNIX系環境（OS X、Linux、FreeBSD、Cygwin）; Windows環境での制限付きサポート
\>\>\> PHP 5.3.29以降
\>\>\> WordPress 3.7以降

### 動作環境の確認
あまりスマートなやり方ではないが確認してみる。  
#### PHPのバージョン  

```
~$ sudo vi /var/www/html/index.php
<?php
   phpinfo();
?>

$ sudo systemctl restart apache2.service
```
ホストOS側から確認してみる  
`http://192.168.57.200/index.php`するとバージョン確認できる。  
PHP Version 7.0.22-0ubuntu0.16.04.1だったのでよし。  
<br>
WordPressのバージョン確認は、version.phpファイルに書かれている情報を見て確認する。  
#### WordPressのバージョン

```
~$ sudo vi /var/www/html/wordpress/wp-includes/version.php
(略)
$wp_version = '4.8';
```
バージョン3.7以降なのでよし。  

## WP-CLIのインストール
要件を確認が確認できたので、必要なファイルをダウンロードしてくる。

```
~$curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
```

次に、Pharファイルが動作していることを確認します。初めて見る拡張子だが、気にしないことにする。  

```
~$ php wp-cli.phar --info
PHP binary:     /usr/bin/php7.0
PHP version:    7.0.22-0ubuntu0.16.04.1
php.ini used:   /etc/php/7.0/cli/php.ini
WP-CLI root dir:        phar://wp-cli.phar
WP-CLI vendor dir:      phar://wp-cli.phar/vendor
WP_CLI phar path:       /home/hoge
WP-CLI packages dir:
WP-CLI global config:
WP-CLI project config:
WP-CLI version: 1.3.0
```
コマンドラインからwp-cli.pharこいつ（コマンド）を実行できるようにする。とりあえず、実行権限を与え、`/usr/local/bin`配下にいれる。  

```
~$ chmod +x wp-cli.phar
~$ sudo mv wp-cli.phar /usr/local/bin/wp
~$ wp --info
PHP binary:     /usr/bin/php7.0
PHP version:    7.0.22-0ubuntu0.16.04.1
php.ini used:   /etc/php/7.0/cli/php.ini
WP-CLI root dir:        phar://wp-cli.phar
WP-CLI vendor dir:      phar://wp-cli.phar/vendor
WP_CLI phar path:       /home/hoge
WP-CLI packages dir:
WP-CLI global config:
WP-CLI project config:
WP-CLI version: 1.3.0
```
余談だが、`wp-cli.phar`をリネームして`wp`にしたのでコマンドが`wp`になったが、`hogehoge`にリネームすると`hogehoge`コマンドになる。

WP-CLIをアップデートする。  

```
~$ sudo wp cli update
Success: WP-CLI is at the latest version.
```
なんと最新バージョンだったらしい。  
コマンドはタブで補完できないとこまるので、できるようにする。  
wp-completion.bashというものがあるらしい。

```
~$ curl -O https://raw.githubusercontent.com/wp-cli/wp-cli/master/utils/wp-completion.bash
```

`~.profile`で読み込むようにしておく。

```
~$ sudo mv wp-completion.bash /usr/local/bin/
~$ sudo vi .profile
#最終行に追加
source "/usr/local/bin/wp-completion.bash"
~$ source /usr/local/bin/wp-completion.bash
```
これでコマンドの補完ができるようになった。

## WP-CLIからプラグインとテーマを設定
ここからが本番。私はもともとWordpress環境ができていたので、プラグインとテーマの追加変更を行う。
プラグインのインストールと適応

```
~$ sudo wp plugin install woocommerce --activate --allow-root --path=/var/www/html/wordpress
```
テーマのインストールと適応

```
~$ sudo wp theme install storefront --activate --allow-root --path=/var/www/html/wordpress
```
`--activate`オプションで即時適応する。`--allow-root`オプションで管理者で上げれるようにする。※rootでやるのはよろしくないが。。
Javascriptのmapで、ちょっと機能不足な時

標題の通り。javascriptで、Array.prototype.mapは便利ですが、ちょっと機能不足だと思うことがあります。

1.　途中で終了したい
 for文のbreakのように途中で終わりにしたい
２. スキップしたい
 Array.prototype.filterのように、特定の要素をスキップしたい

forEachと途中終了の組み合わせなら、some / everyが応用できますが、map + 途中終了はできません。mapの後、filterを行うコード、個人的には良く書くのですが、ちょっと気持ち悪いと思うことがあります。しかも、途中終了はできません。

じゃぁ、こういう機能を持った新しいmapを定義したらいいんじゃないか？・・・と思うかもしれません。

いや、それはやめましょう。標準の文法だけで、直感的な書き方ができるからです。

```js
const filter = (x) => x > 8 ? false : x / 2;
const array = [6,4,2,8,2,10,2,3];
Array.from((function* generator(){
  for(const item of array) {
    const filteredItem = filter(item)
    if(filteredItem === false) {
      break;// 終了する
    } else if (filteredItem) {
      yield filteredItem; // 出力する
    } else {
      // スキップする
    }
  }
})());
// [3, 2, 1, 4, 1]
```

こんな感じ。Array.fromにジェネレータを実行した結果を渡してあげれば良いだけです。自前で、mapを拡張するより、ずっと可読性が高いですね。ちなみに、ジェネレータそのものを渡してもダメなので気をつけましょう。
Node.js 8.11.1 インストール手順

特に問題なくインストールできたので、基本的な流れのみ。
#1. インストーラの入手
https://nodejs.org/ja/ よりインストーラを入手する。特に最新版が必要でなければLTSでよい。
![WS000000.png](https://qiita-image-store.s3.amazonaws.com/0/92978/7fa37703-5df8-09f5-d0bc-5fd3a5021cf6.png)

#2. インストール
![WS000001.png](https://qiita-image-store.s3.amazonaws.com/0/92978/098f766f-979e-0235-644c-0317b2da52b8.png)

![WS000002.png](https://qiita-image-store.s3.amazonaws.com/0/92978/4413da09-bb7e-c565-ee94-151cefe5c79d.png)

![WS000003.png](https://qiita-image-store.s3.amazonaws.com/0/92978/9cd46c65-1d04-de77-1f84-4bea37fbc5a2.png)

![WS000004.png](https://qiita-image-store.s3.amazonaws.com/0/92978/ba9a139a-e530-0df0-d5c9-cba7c2dc0c5d.png)

![WS000005.png](https://qiita-image-store.s3.amazonaws.com/0/92978/0b04529c-f032-ea81-57f0-f6f96077308d.png)

![WS000006.png](https://qiita-image-store.s3.amazonaws.com/0/92978/be0bfdb2-6024-b9c3-bc21-dfe56ca113b2.png)

![WS000007.png](https://qiita-image-store.s3.amazonaws.com/0/92978/2d4e252c-66f0-e255-6609-ce240129ef21.png)

successfullyと出ればインストール完了！

#3. バージョンチェック
下記、コマンドでバージョンチェックができる。
![WS000008.png](https://qiita-image-store.s3.amazonaws.com/0/92978/0e30dd3e-a850-c5df-2def-802376cc0ee7.png)
one button on NavigationBar

```
// image 24x24

 func setupNaviBarButtons() {
    let searchImage = UIImage(named: "search_icon")?.withRenderingMode(.alwaysOriginal)
    let searchBarButtonItem = UIBarButtonItem(image: searchImage, style: .plain, target: self, action: #selector(handleSearch))
    
    let moreButton = UIBarButtonItem(image: UIImage(named: "more_icon")?.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(handleMore))
    
    navigationItem.rightBarButtonItem = searchBarButtonItem
//    navigationItem.rightBarButtonItems = [UIBarButtonItem(), searchBarButtonItem]
  }
```
TypedArrayで非同期的にデータの切り貼り(splice等)をしたい

もちろん、ガシガシ同期的にspliceを実装することもできるでしょう。ただ、この方法だと小さなデータなら良いでしょうが、巨大なデータをspliceする時には、長時間のブロッキングが起きてしまうので、望ましくありません。

そういう時は、非同期的にspliceと同等の処理を実装する方法があります。
1. subarrayで切り出し
2. Blobのコンストラクタでつなげて
3. readAsArrayBufferで新しいArrayBufferにデータをコピーします。
いずれの処理でも、同期的データのコピーは行われていないため、大きなデータでも問題なく動作します。

今回は、Array.prototype.spliceをエミュレートしましたが、Blob + readAsArrayBufferの応用範囲は広く、実際には、この方法を応用して、もっと自由な形で、TypeArrayを切り貼りする機会の方が多いかもしれません。TypedArrayの練習問題的な意味で・・・。

```js
// eslint-disable-next-line max-params
const spliceTypedArray = (array, startIndex, count, ...insertion) => {
  const blob = new Blob([
    array.subarray(0, startIndex),
    new array.constructor(insertion),
    count != null ? array.subarray(startIndex + count) : null,
  ]);
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = eve => {
      resolve(new array.constructor(reader.result));
    };
    reader.onerror = eve => {
      reject(reader.error);
    };
    reader.readAsArrayBuffer(blob);
  });
};
```
【初心者エンジニア目線】ハッカソン未経験の人は勇気を出して主催しよう！【WEBサービス】

#人生初のハッカソン！
スクランブル交差点の雑踏がいつになく気持ちのよいゴールデンウィーク後半戦初日。
うきうきわくわく。まるで子供が父親に遊びに連れて行ってもらったかのように胸踊らせていた２３歳の私。

<b>人生初のハッカソンに参加しました！</b>

以前、IoTのMESHランプタグで天気予報をやってみたり、ハック経験はあったものの誰かと一緒にとことんハックするのは初めて。
そんな経験を踏まえてタイトルのように、これからハッカソンに参加する人、ハッカソンに参加したいけどなかなか勇気が出せない…という方の参考になればと思います。

#そもそもハッカソンに参加するために勇気は必要ない？
結論から言うと<b>ハッカソンに参加するために勇気は必要なかった</b>です。
確かにスタートアップ企業や見ず知らずのエンジニアと一緒に参加するハッカソンは敷居が高い気がします。

#一番簡単なのは自分でハッカソンを主催すること
初めてのハッカソンなのにいきなり主催！？
とお思いの方もいるかと思いますが<b>ハッカソンを主催しちゃえば</b>恥ずかしいことは何もありません。

#初心者がハッカソンを主催するための必須条件
１．<b>現場を経験しているエンジニアの方と一緒にやる</b>　←言わずもがな
２．<b>作りたいモノを予め決めて必要な知識はインプットしておく</b>(今回はWEBサービス主にフロント側を作成しました)
３．<b>出入り自由なシェアオフィスを利用する</b>　←１日１０００円位。Wi-Fi、電源完備。イケてるエンジニアになった気分を味わえる。

#とにかく知り合いのエンジニアにお願いする
正直、ハッカソンのハの字も知らない身だったので、某スタートアップでエンジニアをしている方にお願いしました。
今回、人生初のハッカソンに参加したのは<b>自分を含めて二人だけ</b>
集まらなかったのではなくて初めから<b>二人だけでハッカソン</b>を行いました。

#二人だけのハッカソンの最大のメリット
当たり前ですけど質問や分からない部分はすぐに聞けます。
それ以外にも
・<b>自分のアイデアを反映させやすい</b>
・できないことで無駄に緊張してしまったり、周りの目を気にしたりしない
・<b>相当の裁量を任されるのでスキルアップ間違い無し</b>
・開催場所やお昼ごはんが全て自由…etc

#人生初のハッカソンで得たもの
ハッカソンを経験すると<b>自分に足りないスキル</b>が見えてきます。
<b>今まで０だった経験値に1がついただけでも大きな一歩</b>です。
これからもっとスキルを身に着けよう！とモチベーションも上がります。
あとは<b>現場を経験しているエンジニアの仕事ぶりや、サービス開発やスキルに対する熱意、ひたむきさにとても勇気づけられます。</b>

#とにかくハッカソンに参加してみよう！
以上を踏まえて<b>とにかくハッカソンに参加してみよう！</b>
将来エンジニアとしてお金を得たいけど、知り合いにエンジニアがいないという方。
近くにエンジニアの方がいないと相当、モチベーションはキツイと思いますし、技術を身につけるハッカソンにするのは難しいと思います。
まずは学校、職場、SNSでエンジニアを探しましょう(^^)

#Qiita初投稿でした
技術的なことが一切書かれてませんね・・・(画像もないし・・)
次回は今回のハッカソンで取り扱った技術やどんなサービスを作ったかの記事が書ければと思います。
乞うご期待！
チュートリアルから学ぶライフゲージの実装方法

# 概要
[前回の記事](https://qiita.com/ayaseya/items/4e3b157f2980538c8a89)のプロジェクトをベースにライフゲージのUIを追加します。
本記事は[Tanks!](https://unity3d.com/jp/learn/tutorials/projects/tanks-tutorial/tank-health?playlist=20081)（対戦型の戦車ゲーム）の内容を一部抜粋し簡略化たものになります。

![Life.gif](https://qiita-image-store.s3.amazonaws.com/0/55307/52ff7b0f-1ae4-c736-3dda-deba547a2b55.gif)

# 手順
**プレイヤーの足元にライフゲージを表示する**

1. HierarchyビューからSliderを追加する
Create > UI > Slider
1. プレイヤーに追従させるためCanvasをLowMan(Player)配下に移動する
1. Canvasについて以下の変更を加える
>
>**Canvasのサイズ変更を可能にする**
Inspector > Canvas Scaler(Script) > Render Mode > World Space に変更する
>
>**Canvasの表示位置、サイズをPlayerの足元となるように変更する**
Inspector > Rect Transform > Position (0, 0.1, 0)に変更する
Inspector > Rect Transform > WidthとHeightを2に変更する
Inspector > Rect Transform > Rotation  (90, 0, 0)に変更する

1. Sliderについて以下の変更を加える
>**SliderをCanvas全体に引き伸ばして表示する**
HierarchyビューでSliderと配下のBackground、Fill Area、Fillを同時に選択した状態でAnchorを変更する
Inspector > Anchor Presets > Altキーを押下しながら右下のstretchを選択する 
>
>**Sliderのつまみ部分のUIを削除する**
>HierarchyビューからHandle Slide Areaを削除する
>
>**ユーザー操作による変更を無効にする**
Inspector > Slider(Script) > Intractable のチェックボックスを外す
Inspector > Slider(Script) > Transition Noneに変更する
>
>**最大値を設定する**
Inspector > Slider(Script) > Max Value を100に変更する
>
>**初期値を設定する**
Inspector > Slider(Script) > Value を100に変更する
>
>**Sliderの色を任意の色に変更する**
>Slider配下のFillを選択した状態で
>Inspector > Image(Script) > Color を任意の色に変更する
>
>**ダメージを受けた場合にSliderの値をスクリプトから減算する**
>後述するLifeGaugeController.csを作成しSliderにアタッチする

**ライフゲージを円形表示に変更する**

1. Wheel.pngをローカルに保存する<br>
<img width="100" src="https://qiita-image-store.s3.amazonaws.com/0/55307/f5999bc0-b884-d7a2-fee1-ee7eb5d0d2cf.png">
1. Projectビュー > Sprites フォルダを生成
1. Spritesフォルダを選択した状態で右クリックしImport New Assets...を選択しWheel.pngをImportする
1. Wheelについて以下の変更を加える

> Inspector > Texture type > Sprite(2D and UI) に変更する
> Unapplied import settingsダイアログが表示されるのでApplyを選択する



# ソースコード

```c#:Player.cs
public class Player : MonoBehaviour
{
	// 変更がない箇所は省略
	
	LifeGaugeController m_Life;

	void Awake ()
	{
		m_Life = GetComponentInChildren<LifeGaugeController>();
	}

	public void TakeDamage (int damage)
	{
		// ライフゲージに反映
		m_Life.OnGaugeUpdate(hp);
	}
}
```

```c#:LifeGaugeController.cs
public class LifeGaugeController : MonoBehaviour {

    private Slider m_Slider;                // 現在のライフを示すスライダー
	private Quaternion m_RelativeRotation;  // シーンの開始時のローカル空間のローテーション

    private void Awake()
    {
        m_Slider = GetComponent<Slider>();
    }

    private void Start()
    {
        m_RelativeRotation = transform.parent.localRotation;
    }

    private void Update()
    {   
        // スライダーがプレイヤーの方向に追従して回転してしまうのを防ぐため
        // 初期値を設定し直す
        transform.rotation = m_RelativeRotation;
    }

    public void OnGaugeUpdate(float life)
    {
        m_Slider.value = life;
    }
}
```

# まとめ

ソースコードは[GitHub](https://github.com/ayaseya/SimpleTestGround)にアップロードしています。
Railsチュートリアル　１章から１４章作る日記　１回目

###概要

　この記事は、rails　チュートリアルを完成させる日記です。

https://railstutorial.jp/

railsチュートリアルとは、
　　ツイッターと同じ機能（厳密に言うと、違う）が作れるWEBアプリの作り方が載っているサイトです。

　なぜ人気サイトなのか
　-> プログラミング経験がない人でもできるから

###目的（この記事を書くことについて）

・私自身の復習ため

・プログラミングを意外にできるよってこと知ってもらうため

＃＃Ruby on Railsとは、

・Webアプリケーションフレームワークの王道

・個人やスタートアップ企業が簡単にWebアプリケーション

https://paiza.hatenablog.com/entry/2018/05/07/paizacloud_web_application_frameworks

###目標（この記事）

・わかりやすい記事にする
　　 -> 私自身がプログラミング未経験からこのrails　チュートリアルをやったため

・rails　チュートリアルにいくつかの機能を追加させる。
　-> なに実装するか未定　レビュー評価など検討中
エスケープシーケンスに対応する正規表現の考察

# はじめに
この記事は、考察記事です。

バグがないように、気を付けてはいますが実用する場合は利用者の責任で実行してください。

前提条件
テストはJavascriptで行っています。
テストコードは、文字列自体のエスケープを含まないため、
" ' \ などはエスケープして実行してみてください。

# 何がしたいの
エスケープ文字列に対応する正規表現を考えます。
（正規表現内で必要なエスケープではありません）

``` 
sometext "match\"text\nmulti line \\\" backslash+quotation" 
```
みたいなテキストが渡されたときに、

```
"match\"text\nmulti line \\\" backslash+quotation"
```

みたいに抽出することを目的とします。

分かりやすさを優先するために、プログラム言語で必要なエスケープは無視します。

Javascriptで、正規表現内でバックスラッシュを表すためには

``` 
"\\\\" # -> "\\" 
```

と、文字列自体のバックスラッシュが必要ですが、ここでは無視します。
（バックスラッシュ4個で、1個のバックスラッシュを表している）

# よくある解法

## eval 系コマンドを利用
evalは使いません。
*eval is evil* です。

目的は、外部から渡された文字列から、エスケープされた文字列を抽出するのに、evalは危険すぎます。

## 最長マッチの利用
最長マッチを利用すると、見かけ上は正しく取れたように見えます。

```
".*"
```

これは、内部状態を正しく評価していないため、利用しません。

## 簡単な正規表現
例えば、""で囲まれた文字列を表現するために、私が使う簡易なコードは下記の正規表現です。

``` 
"[^\"]*"
```

これは、『ダブルクオーテーション以外の文字が0個以上連結して、ダブルクオーテーションで囲まれる』
文字列にマッチしますが、エスケープされた文字列を表せません。

最初の文字列でテストをすると、

``` 
"match\"
```

と出力されます。

# 今回考えた正規表現

今回、文字列を下記のように解釈しました。

* 文字列ダブルクオーテーションで囲まれる。
* プレーンテキストは、エスケープが必要な文字と、エスケープ文字を含まない。
* エスケープ文字に続いて、エスケープが必要な文字が続く。

ここで
『プレーンテキストは、エスケープが必要な文字と、エスケープ文字を含まない。』
は、下記の正規表現となります。

``` 
[^'"\\]
```

また、
『エスケープ文字に続いて、エスケープが必要な文字が続く。』
は、下記正規表現で表せます。

```
\\["'\\\/bfnrt]
```

そのため、これから以下のように構成できると考えました。

```
"(?:[^'"\\]|\\["'\\\/bfnrt])*"
```

このコードは、現時点において正しく動いているように見えます。

検証が不十分のため、検証が終わるまでは考察として公開いたします。
org.springframework.context.MessageSource.getMessage()でデフォルトメッセージの思わぬ挙動

# やりたかったこと
　spring-bootで多言語化対応をする際に、意図しない挙動に遭遇したのでここに記します（恐らくspringも同じ）。
やりたかったこととしては、外部から言語情報を取得し、その言語のメッセージを表示するが、もし未対応の言語であれば何かしらのデフォルトメッセージを表示するということ。しかし、このデフォルトメッセージが思った通りに表示されない場合があります。
# 例

　以下のように、英語と日本語の言語プロパティファイルがあるとします。

```java:messages_en.properties
key1=hoge
key2=fuga
```

```java:messages_ja.properties
key1=ほげ
key2=ふが
```

　この時、以下のdisplay()メソッドで、中国語を指定してメッセージを取得しようとするとどうなるでしょうか？

```java
    @Autowired
    private MessageSource messageSource;

    public void display() {
        System.out.println(getMessage1(Locale.CHINESE));
        System.out.println(getMessage2(Locale.CHINESE));
    }

    /**
     * 多言語化メッセージを取得します。
     * @param locale ロケール
     * @return 多言語化メッセージ
     */
    private String getMessage1(Locale locale) {
        return messageSource.getMessage("key1", null, locale);
    }

    /**
     * 多言語化メッセージを取得します。
     * @param locale ロケール
     * @return 多言語化メッセージ
     */
    private String getMessage1(Locale locale) {
        return messageSource.getMessage("key1", null, "デフォルトメッセージ", locale);
    }
```

　こちらの[Javadoc](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/MessageSource.html)を観る限り、getMessage1ではNoSuchMessageExceptionが投げられ、getMessage2では"デフォルトメッセージ"と表示される、、、ように思われるのですが、私の環境ではそうなりませんでした。両者とも"ほげ"と出てくるのです。

# 何がいけなかったか
　上記のコードは悪くありません。原因はMessageSourceのプロパティでした。
spring-bootでは[こちら](https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html)にあるとおり、共通アプリケーションプロパティが定義されているのですが、そのなかに**spring.messages.fallback-to-system-locale**というプロパティがあります。
そのコメントには、
> Whether to fall back to the system Locale if no files for a specific Locale have been found.

とあります。訳は、
> 指定したロケールのファイルが見つからない場合、システムロケールにフォールバックするかどうか。

です。これがデフォルト（要は未定義の場合）では**true**となっています。つまり、このプロパティがtrueになっている以上、getMessage1でNoSuchMessageExceptionが投げられることはなく、getMessage2でデフォルトメッセージが返されることはありません。アプリケーションがデプロイされている環境の言語が表示されるため、今回の私の環境の場合では、該当しない言語が渡された場合は常に日本語のメッセージが出力されてしまっていたというわけです。

# どうすればよいか
　修正は簡単です。application.yml（またはapplication.properties）に以下のプロパティを設定すればよいです。

```yml:application.yml
spring.messages.fallback-to-system-locale: false
```

　もし、MessageSource をJava側で定義していた場合は、以下のメソッドで設定できます。

```java
messageSource.setFallbackToSystemLocale(false);
```

# 終わりに
　なかなか原因を見つけにくく大変でした。そして、環境依存で発覚する挙動の変化なので、自国でのテストは問題なくても、外国サーバにデプロイしたら発覚するという厄介な不具合になりかねないので注意が必要です。
逆ジオコーディングをfinds.jpに乗り換えてみた

逆ジオコーディングに使っていたライブラリを、Google Mapsからfinds.jpのものに乗り換えました。

# きっかけ

それは、ゴールデンウィーク中にGoogleから届いた1通のメールがきっかけでした。

いわく、Google Maps APIが「Google Maps Platform」になるので、課金方法などが変わる、ということでした。そして、メールを確認してみると、今までの使い方では新方式で有料となってしまう、ということが判明しました。

* 従来…APIごとに無料分を判定
* 新方式…それぞれのAPIを通じて無料分を共有

調べてみると、各APIで大幅に無料分が削減されているのですが、いま問題になっているプロジェクトでは、逆ジオコーディングの使用量が多く、これだけで（新プランの無料枠である）200ドルを突破してしまうことが判明しました。

# finds.jpへの乗り換え

そして、調べてみると、農研機構が研究成果として[逆ジオコーディングサービス](https://www.finds.jp/rgeocode/index.html.ja)を提供していることが判明しました。

見本ではエントリポイントが`http://`となっていますが、ちゃんとHTTPSにも対応したとのことで、そこを`https://`に書き換えればMixed Contentの問題も発生しませんでした。そして、JSONPに対応しているので、クロスドメインも気にせずアクセスできます（なお、`callback=`ではなく`jsonp=`なので、そこは要注意です）。また、Google Mapからの乗り換えで引っかかりそうな箇所として、経度は`lng`ではなく`lon`という名前の引数で渡します。

なお、利用制限は「10万回/日」ということなので、よほど組織的に使うのでなければ問題はないと思います。

## こっちのほうが便利かも

Googleのサービスとは違って、もちろん日本限定ではあるのですが、逆に日本に限定したから便利な面もあります。

* 返り値は日本の地名の構造に合わせて、「都道府県」「市区町村」「町名」「番地」の4段階となっています（「番地」の利用の際には注意が必要です）。
* 都道府県や市区町村については、自治体コードもセットで取れます。
備忘録　遺伝的アルゴリズムとは

いろいろな所で進化計算について話をする機会があったんで備忘録も兼ねて。

[![thumbnail](//image.slidesharecdn.com/whatisevolutonnalalgorythm-180419112730/95/slide-1-1024.jpg)](https://www.slideshare.net/tetuwo181/what-is-evolutional-algorythm)
図も交えて細かく説明したスライドはこちらから

進化計算についての話となっていますが、今回は遺伝的アルゴリズムメインで。

#遺伝的アルゴリズムとは
- 生命の進化をモデルにした組み合わせ最適化の手法
- 必ずしも最適な解を得られるとは限らない

#遺伝的アルゴリズムの流れ
1. 終了条件を設定する
2. 初期個体群を生成する
3. 個体群の中から親となる個体を選ぶ（選択）
4. 親個体を掛け合わせて子個体を生み出す（交叉）
5. 生まれた個体を突然変異させる（突然変異）
6. 子個体と親個体をマージ、適合度が高いものを残す（淘汰）
7. 終了条件を満たすまで3~6を繰り返す

※2番目以降および個体については後述

#個体とは
- 最適化するための遺伝子(genotype)と遺伝子に対して問題となる関数を適用した適合度(phenotype)を適用したもの<br>
 ex) 0と1のバイナリ記号列中に含まれる1の数の総和を返す関数を適応関数として"00101"というバイナリ記号列は"00101"というgenotypeとなり、含まれる1の総和は2となる。この遺伝子と適応した値を持つクラスのインスタンスを個体といい、それが複数存在するものを個体群という。
- genotypeはいろいろな表現ができ、上記の0と1の記号列以外にも、実数値や木構造で表すこともできる。木構造でgenotypeを表現する場合、遺伝的プログラミングという。

#それぞれの操作
- 選択:各個体の中から最大化問題であれば高い適合度（最小化問題であれば低い適合度)の個体を選ぶ操作。ルーレット選択やトーナメント戦略がある。
- 交叉: 親として選んだ個体の遺伝子を混ぜ、子供を作り出す操作。交叉そのもののアルゴリズムはgenotypeに応じて変える。0と1のバイナリ記号列であれば2点交叉や一様交叉、実数値であればBLX-αやSBXなど
- 突然変異: 生まれた子供の遺伝子を一定の確率で変化させる。こちらもアルゴリズム自体はgenotypeの表現に依存

#その他
- 必ずしも最適な解を得られるとは限らず、また、得意な分野と苦手な分野がある<br>→問題に応じて適切なパラメータチューニングが必要、また、状況によってはほかのアルゴリズムを使用することを検討する必要あり
- 広域探索が得意…とよく言われている

#最後に
色々ライブラリはありますが私もPythonでライブラリ作成しています。
[こちらのリポジトリ](https://github.com/Tetuwo181/GA)となります。まだまだできていないところもありますが、よろしければいろいろご教授いただけると助かります。
Werckerで「Mysql2::Error: Authentication plugin 'caching_sha2_password' cannot be loaded」が発生した際の対処について

## Werclerのプロセスが失敗

連休明けのとある日、いつものようにgit pushすると、CIに使っているWerckerからエラー通知が届いた。
内容を見てみるとspecにたどり着く以前の、テスト用DBを作成するステップでエラーになっていた。

エラーメッセージは「Mysql2::Error: Authentication plugin 'caching_sha2_password' cannot be loaded」。


```bash
Mysql2::Error: Authentication plugin 'caching_sha2_password' cannot be loaded: /usr/lib/mysql/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory

~(略)~

/pipeline/cache/bundle-install/ruby/2.3.0/gems/rake-11.3.0/exe/rake:27:in `<top (required)>'
Tasks: TOP => db:migrate:reset => db:drop => db:check_protected_environments
(See full trace by running task with --trace)
```

## Mysql2::Error: Authentication plugin 'caching_sha2_password' cannot be loaded

エラーメッセージでぐぐってみると、1つのブログに行き着いた。

[MySQL 8.0.4におけるデフォルト認証形式の変更](https://yoku0825.blogspot.jp/2018/01/mysql-804.html)

MySQL8.0.4からはデフォルトの認証方式が"caching_sha2_password"に変わったとのこと。
サーバー側とクライアント側でそれぞれこの認証方式をサポートしていない場合、このエラーが発生するらしい。
このブログではmy.cnfにて"default_authentication_plugin"を設定することでこの問題を解決する
方法が説明されている。


## MySQLイメージが更新されていた

[DockerのMySQL](https://hub.docker.com/_/mysql/)のレポジトリを見てみると、2日前に更新されたと記載されていた。
最新バージョンは8.0.11。
おそらくこのアップデートでMySQLのデフォルトバージョンが8になったことで、このエラーが発生するようになったのではなかろうか。

## wercker.ymlの設定を変更

CIにつかうMySQLのバージョンを以前の5系に指定してやればこの問題を回避できそう。
ということで、werckerの設定を変更。
tagでバージョン情報を明示したことで解決。

```yml
services:
  - id: mysql
    tag: 5.6 #これを追加
    env:
      MYSQL_USER: testuser
      ...
```
HTML/CSS + JavaScript on Windowsで教え始めたので記録しておく

　はっきりいって私は同業には厳しいのでこういう初心者というのは相手しない、そんな暇じゃないってことに決めていた、つーか「おめーがHTML/CSS〜ぷぷぷ」というレベルなのである。

　んだが、あれよあれよと「とりあえずUnityで自称クソゲイを作ったことがある」という子に鼻の下を伸ばしながらHTML/CSS + JavaScriptを教えることになった。しかもWindowsで。しかも高校生。

　前職のときは専門学生や実業大学生のインターンシップというのは結構相手したんだけれど、高校生、しかも実業高校生じゃないというのはさすがにはじめての経験。

　得た知見をもったいないので記録しておく。


# 使ったツール

　高校生の使っているのはMicrosoft SurfaceだったのでWindowsで使えるものを用意した。そして講義は片手で数えられる日数程度しかないので「ツールに振り回されることがなく」「導入の手間がかからないもの」にした。

- LINE（PC版）
- GitHub
  - Windows版公式クライアント
  - gh-pages
- Visual Studio Code
- Chrome
  - Web Server for Chromeプラグイン


# ツール導入でハマったこと

## Visual Studio Code

前日に案内してインストールしてきてもらってきたつもりがVisual Studio (not Code)の体験版が入っていた。惜しい。初めての子がナビゲートされるがままにVisual Studioのほうにいったとしたらこれはサイトのせいというべきだろうがハマるかも。

## GitHub Widows版公式クライアントツール

おそらくMacOS版もだと思うがあの独特の「Sync」とかといったものがなくなってて私の知ってたころのとだいぶ違ってた！

## WindowsとMacOSでのホットキーの違い

違うんだなあ…

## Windows版Chromeのメニューバーが出ない！？

これでないの？しょうがないからファイルを開くときは `Ctrl + O` を教えざるをえなかった。


# やらせたこと

やらせたこと is 「ツールの使い方なんで深く考えずに手順通りボタン押してくれ」

- GitHubクライアントでclone
- gh-pagesの設定
- GitHubクライアントでpushするとgh-pagesの機能で世界に公開できる
  - こうすれば自分のスマホでも見られる
- Web Server for Chrome プラグインでのブラウザでのプレビューのやりかた


# 教えたこと & びびったこと

- どうしてあなたのスマホでYoutubeに保存されている動画が見られるのか
- ウェブページは何からできているのか
- ウェブページはどうやってスマホにやってくるのか
- ウェブブラウザ(Chrome)とHTTPサーバの関係
  - IPを経由してるのか、ファイルシステムなのか、の違いを超ざっくり
- Visual Studio Code で書いてウェブブラウザでリロードして確認する基本的やりかた
- 「文章構造」と「見た目」の分離がなされているということ
  - h1要素の色を変えてみる、背景色を変えてみるまで
- XML・DOMの基本的な書式
  - ID指定したオブジェクトをクリックすると、別IDで指定したノードの文字を変更できるところまで
  - IDとセレクタについて
- Chrome デベロッパーツールでエラーの確認方法(コンソールログの読み方)
- 「エスケープキー」という言葉がそもそも通じない
- 「リロード」という言葉がそもそも通じない


# 参考にした、LINEで送った情報

- [Web Server for Chrome - Chrome ウェブストア](https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb/)
- [HTML5のhead内の記述 - Qiita](https://qiita.com/yuh180/items/49ba589fc014d7be542a)
- [HTMLクイックリファレンス](http://www.htmq.com/)
- [idセレクタ－スタイルシートリファレンス](http://www.htmq.com/selector/id.shtml)
- [.onの使い方(jQuery3) - Qiita](https://qiita.com/abusan/items/fa1b1db2f3c72a78849f)
- [(4) いしかわのもてなし食材 - YouTube](https://www.youtube.com/watch?v=b0T2Tfm8VC8)


# 他レポート

- [高校生がやってきた | ifDL blog](http://ifdl.jp/blog/?p=1135)
tldrコマンドをCentOS7にインストールする

[manpageは長いから読みたくない？そんなときはtldr\-pages \- Qiita](https://qiita.com/reishoku/items/e3b2157e486c4c1bf9e6)

こちらはCentOSで試してみる

## 以下の環境で確認

```bash
$ docker run --rm -i -t docker.io/centos:7.3.1611 /bin/bash
```

## インストール

yumでtldrをシステムにインストールしたいところだが、EPELに入っているnodejsのパッケージが古いので依存関係でエラーになる。仕方ないのでローカルに入れてシステムより新しいものに更新する。

```bash
// EPELにnpmがあるのでインストール
# yum install -y epel-release
# yum install -y npm openssl make gcc-c++
# useradd ymko
# su - ymko
// ローカルにインストールする
$ npm install tldr
// パスを通す
$ vi .bashrc
if [ -d ${HOME}/node_modules/.bin ]; then
    export PATH=${PATH}:${HOME}/node_modules/.bin
fi
$ source .bashrc
```

## コマンド実行

```bash
$ tldr rpm

  rpm

  RPM Package Manager.

  - Show version of httpd package:
    rpm -q httpd

  - List versions of all matching packages:
    rpm -qa 'mariadb*'

  - Identify owner of a file and show version of the package:
    rpm -qf /etc/postfix/main.cf

  - List package-owned files:
    rpm -ql kernel

  - Show scriptlets from an RPM file:
    rpm -qp --scripts some.rpm

  - Show changed, missing and/or incorrectly installed files of matching packages:
    rpm -Va 'php-*'

```


[npm のローカルモードでインストールした実行モジュールにパスを通す設定 \- Qiita](https://qiita.com/umechiki/items/a1de903a2e5e27f5c606)
正規化されていないデータを集計する際にメモリ消費量を抑える方法

正規化されていない同じタイプのデータを`CONCAT_WS`で結合して取ってくる。
こうするとメモリ使用量を抑えることができます。
たぶんNULLカラムの個数が多いほど効果あると思います。
逆にNULLカラムが存在しない場合はたぶん効果ないと思います…。
コレクションで何やかんやしたい場合は使えませんがデータ集計のバッチとかでは使えるかなと。
とある案件で数百万件のデータを集計する際に20GBほど消費していたのがこの方法で半分の10GBになりました。
（リセマラ…コロス）

```php
$data = [];
ModelClass::selectRaw("
        id,
        user_id,
        CONCAT_WS(',', card_id01, card_id02, card_id03, card_id04) as card_ids,
        CONCAT_WS(',', sub_card_id01, sub_card_id02, sub_card_id03, sub_card_id04) as sub_card_ids,
        CONCAT_WS(',', weapon_id01, weapon_id02, weapon_id03, weapon_id04) as weapon_ids
    ")
    ->orderBy('id')
    ->chunk(10000, function ($chunk) use (&$data) {
        foreach ($chunk as $v) {
            $row = $v->toArray();
            unset($row['id']);
            $data[] = $row;
        }
    });
```

カラム名が`id`でない時は`chunkById`を使う。
`chunk`を使ってもエラーが出ないので注意。

```php
$data = [];
ModelClass::selectRaw("
        primary_id,
        user_id,
        CONCAT_WS(',', card_id01, card_id02, card_id03, card_id04) as card_ids,
        CONCAT_WS(',', sub_card_id01, sub_card_id02, sub_card_id03, sub_card_id04) as sub_card_ids,
        CONCAT_WS(',', weapon_id01, weapon_id02, weapon_id03, weapon_id04) as weapon_ids
    ")
    ->orderBy('primary_id')
    ->chunkById(10000, function ($chunk) use (&$data) {
        foreach ($chunk as $v) {
            $row = $v->toArray();
            unset($row['primary_id']);
            $data[] = $row;
        }
    }, 'primary_id');
```
NuxtやVuejsとStorybookの組み合わせの際のグローバルアセットの読み込みを解決する

ちょっとしたtipsです。
グローバルSASS、SCSS、ビルド前のを読み込みたいですよね。
例えば、nuxtとかでstorybookを使う場合とか。

## webpackの設定を追加
あなたの .storybook/webpack.config.js をこんな感じに。
path解決はめんどくさいと思いますが、良い感じに頑張ってください！笑

```js
const path = require('path');
const rootPath = path.resolve(__dirname, '../')

// load the default config generator.
const genDefaultConfig = require('@storybook/vue/dist/server/config/defaults/webpack.config.js');

module.exports = (baseConfig, env) => {
  const config = genDefaultConfig(baseConfig, env);

  config.resolve.alias['@'] = rootPath
  config.resolve.alias['~'] = rootPath

  return config;
};
```

## コード例
.stories/index.js

```js
import '!style-loader!css-loader!~/assets/main.scss'
```

## 実際のサンプルコード
.stories/index.js

```vuejs
import { storiesOf } from '@storybook/vue'
import VueInfoAddon from 'storybook-addon-vue-info'
import { withKnobs, text, number, boolean } from '@storybook/addon-knobs'
import { withNotes } from '@storybook/addon-notes'
import Status from '@/components/atoms/Status.vue'
import '!style-loader!css-loader!~/assets/main.scss'


storiesOf('Atoms', module)
  .add('catarog', () => ({
    components: {Status},
    data() {
      return { size: 18 }
    },
    template: `
    <div style="display: flex; width: 300px; justify-content: space-between;">
      <div style="width: 140px; height: 35px;">
        <Status>Sample</Status>
      </div>
      <div style="width: 140px; height: 35px;">
        <Status color="bisque" :size="size">Sample</Status>
      </div>
    </div>`,
  }));
```

## 最後に
めちゃ便利ですね〜〜〜〜〜〜〜〜！
Dockerと次世代フラットファイルCMS「Grav」でmarkdown対応のウェブサイトを3分で構築する

![89b216d221a3fc4b663ceba63e6b6521801c2c5a-header.jpeg](https://qiita-image-store.s3.amazonaws.com/0/155486/98d353e6-2378-972d-ccb5-ce59a0ae1fba.jpeg)

「クールなウェブサイトやブログを作りたいけど、コンテンツは簡単にメンテナンスできるようにしたい」といった方にオススメしたいのが、 **markdown形式のテキストファイルでコンテンツを管理する次世代フラットファイルCMS「Grav」** です。本稿では「Grav」の概要と構築手順についてご紹介します。（ヘッダー画像は「GitHub『[getgrav/grav-theme-quark](https://github.com/getgrav/grav-theme-quark)』」より引用）

## 「Grav」とは

「[Grav](https://getgrav.org)」はオープンソース（[MITライセンス](https://github.com/getgrav/grav/blob/develop/LICENSE.txt)）のフラットファイルCMSです。
ウェブサイトのコンテンツを **「markdown」** で作成することができ、ブラウザ上の管理画面から **ウェブサイトの設定やブログ記事の投稿** も可能です。また **クールなデザインのテンプレートが豊富に揃っている** ため、ウェブサイトをゼロから作る必要がありません。このような使いやすさから、GravはCMS Criticが主催する『Best Open Source CMS』（2016年）、『Best Flat File CMS』（2017年）に選出されています。

## 「フラットファイルCMS」とは

「フラットファイルCMS」は最近注目されている **データベースレス** のCMS（Content Management System）です。ウェブサイトのコンテンツはデータベースで管理せず、 **「markdown」や「YAML」などのテキストファイルで管理されます。** データベースと接続する必要がないため、 **ページ表示までのレスポンスが速い** ことも注目を集める一つの理由です。

## Dockerで「Grav」を構築する

2018年4月現在、Gravは公式のDocker Imageを公開していないため、本稿では自身が作成したDocker Fileからコンテナを起動する手順をご紹介します。

### 要件

本稿で紹介するGravの構築手順に必要な環境は以下の通りです。

- Docker
- Docker Compose

### Dockerイメージをビルドする

```
$ git clone https://github.com/yosukeo/docker-grav.git
$ cd docker-grav
$ docker-compose build
```

本稿の動作環境では、`docker-compose build --no-cache`コマンドは開始から約2分半で完了しました。

```
$ time docker-compose build --no-cache
...
...
...
Successfully built 83f42b83e379
Successfully tagged dockergrav_grav:latest

real	2m39.562s
user	0m0.572s
sys	0m0.108s
```

### Dockerコンテナを作成・起動する

```
$ docker-compose up -d
```

**たった４つのコマンドを入力するだけ** ですが、以上で「Grav」の構築は完了です。

### 動作確認をする

「Google Chrome」などのブラウザから、DockerホストのIPアドレス（`xxx.xxx.xxx.xxx`）を指定してGravの画面表示を確認します。

- ホーム画面：`http://xxx.xxx.xxx.xxx`
- 管理画面：`http://xxx.xxx.xxx.xxx/admin`

#### ホーム画面

Gravがデフォルトで用意しているページが表示されます。

![grav-home (1).jpg](https://qiita-image-store.s3.amazonaws.com/0/155486/357d28b9-496a-fb97-99db-d2bf33c31d35.jpeg)


#### 管理画面（ログイン）

`docker-compose.yml`に設定している`ADMIN_USER`と`ADMIN_PASSWORD`の値を入力します。デフォルト値は以下の通りです。

- `ADMIN_USER` : `admin`
- `ADMIN_PASSWORD` : `0Gravity`

![grav-admin-login (1).jpg](https://qiita-image-store.s3.amazonaws.com/0/155486/a13312d3-39eb-b26c-f950-6a82e95054b6.jpeg)


#### 管理画面（ダッシュボード）

以下のダッシュボードからコンテンツを管理します。サイトの設定からページの編集、プラグインやテーマのインストールなどの基本的な作業はダッシュボードから操作することができます。

![grav-admin-dashboard (1).jpg](https://qiita-image-store.s3.amazonaws.com/0/155486/3e596f19-1c99-227e-93de-b62ada81671f.jpeg)

**管理者ユーザーのアカウント言語設定（language）において「日本語」を選択すると、ページを保存する際に「Unexpected character」となってページを保存することができなくなるのでご注意ください。**

### コンテナへログインする

以下のコマンドを入力することで、コンソールからコンテナへログインすることができます。本稿で使用しているDockerfileはPHP公式のDockerイメージである`php:7.2.3-apache-stretch`をベースとしていますが、 **コンソールの列数と行数を環境変数として指定しないとコンソールのレイアウトが崩れるので注意してください。**

```
$ docker exec -it --env COLUMNS=`tput cols` --env LINES=`tput lines` grav bash
```

### 最後に

`Dockerfile`や`docker-compose.yml`などの内容については、 GitHub『[yosukeo/docker-grav](https://github.com/yosukeo/docker-grav)』よりご確認ください。またウェブサイトの細かいカスタマイズについてはコンソールからファイルを編集する必要があります。Gravのカスタマイズ方法については別の機会にご紹介したいと思います。
Docker Composerではコンテナ間通信はコンテナ名を指定する

# まえがき

この記事は、"Dockerでコンテナ間で通信できない"というタイトルでしたが、
コメントなどのおかげで改善されたので記事を修正しました。
ありがとうございます。

# docker-composeのコンテナ間は、デフォルトだとコンテナ名で接続できる

今回は、WordPress開発環境を作りたかったので以下の`docker-compose.yml`を用意した。

```yml:docker-compose.yml
version: '3.4'
services:

  mysql: #<-コンテナとしてこちらの"mysql"も指定できる
    image: mysql:5.7
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_bin
    environment:
      MYSQL_ROOT_PASSWORD: root_dumy
      MYSQL_DATABASE: wordpress
      MYSQL_USER: user
      MYSQL_PASSWORD: password_dumy
    ports:
      - 3306:3306
    container_name: db_mysql #<-コンテナ名は"db_mysql"

  web:
    build: wordpress
    volumes:
      - ./html:/var/www/html
    ports:
      - 80:80
    depends_on:
      - mysql
    container_name: wordpress_web
```

その他、環境は以下の通り 
* windows10 pro(April 2018 Update)
* docker 18.03.1-ce


`docker-compose.yml`のあるフォルダに、`html`フォルダを作成しwordpress関連のファイル一式を配置する。
wordpressからDB(コンテナ)へ接続するための、DB設定ファイル`wp-config.php`の接続先をコンテナ名に書き換える。
コンテナ名は、上の設定だと`mysql` or `db_mysql`で動くみたい。

```php:wp-config.php
define('DB_HOST', 'db_mysql:3306');
```

その他、上の`docker-compose.yml`ではDBパスワードなども設定しているので、まとめて設定する。

```php:wp-config.php
define('DB_NAME', 'wordpress');

/** MySQL データベースのユーザー名 */
define('DB_USER', 'user');

/** MySQL データベースのパスワード */
define('DB_PASSWORD', 'password_dumy');

/** MySQL のホスト名 */
define('DB_HOST', 'db_mysql:3306');

/** データベースのテーブルを作成する際のデータベースの文字セット */
define('DB_CHARSET', 'utf8mb4');
```

実行は、`docker-compose.yml`のあるフォルダで

```cmd:docker起動コマンド
docker-compose up
```
ブラウザのアドレスにlocalhostを入れることで確認できるはず。


## その他知見

dockerのコンテナ内部では、個別にipを割り振れるようです。
おすすめではないですが、コンテナ間通信をipベースで行うこともできます。

以下のコマンドで、割り当てられているipを取得できます。
(`[contenaName]`を各自のコンテナ名に書き換えてね)

```bash:cmd
docker exec -it [contenaName] hostname -I
```

返り値の値を、`wp-config.php`のDB_HOSTの行を書き換えると動作しました。

```php:wp-config.php書き換え例
define('DB_HOST', '172.18.0.2:3306');
```



## コンテナ通信は調べると色々ある

コメントで教えてもらいましたが、コンテナにはいくつかの通信モードがあるみたいです。

コンテナ間通信をlocalhostで行ってみたいが、宿題。
教えてもらった、通信の仕組みが理解できれば使える様になる？？