OmniAICreator/Qiita-1.07M huggingface dataset:
Simple RESTful API With Golang

[Create A Simple RESTful API With Golang](https://www.youtube.com/watch?v=t96hBT53S4U)
RESTでの値の受け取り方を学べたらいいな

Listenportの指定しないといけないことと、SSL(HTTP)が無効である点を注意

#環境準備
```
go get github.com/gorilla/mux
```
なくてもできるかも　だけどライブラリのインストールしました。

```
mkdir myproject
cd myproject/
vi main.go　　　　　//プログラミング
go build
./myproject
```
***SampleAPI***

```
package main

import (
	"encoding/json"
	"log"
	"net/http"
	"github.com/gorilla/mux"

)
type Person struct {
	ID		string `json:"id,omitempty"`
	Firstname	string `json:"firstname,omitempty"`
	Lastname	string `json:"lastname,omitempty"`
	Address		*Address `json:"address,omitempty"`
}
type Address struct {
	City	string `json:"city,omitempty"`
	State	string `json:"state,omitempty"`
}

var people []Person

func GetPersonEndpoint(w http.ResponseWriter, req *http.Request) {
	params := mux.Vars(req)
	for _,item := range people{
		if item.ID == params["id"]{
			json.NewEncoder(w).Encode(item)
			return
		}
	}
	json.NewEncoder(w).Encode(&people)
}

func GetPeopleEndpoint(w http.ResponseWriter, req *http.Request) {
	json.NewEncoder(w).Encode(people)
}

func CreatePersonEndpoint(w http.ResponseWriter, req *http.Request) {
	params := mux.Vars(req)
	var person Person
	_=json.NewDecoder(req.Body).Decode(&person)
	person.ID = params["id"]
	people = append(people,person)
	json.NewEncoder(w).Encode(people)
}

func DeletePersonEndpoint(w http.ResponseWriter, req *http.Request) {
	params := mux.Vars(req)
	for index,item := range people {
		if item.ID == params["id"] {
			people = append(people[:index],people[index+1:]...)
			break
		}
	}
	json.NewEncoder(w).Encode(people)
}



func main () {
	router := mux.NewRouter()
	people = append(people,Person{ID:"1",Firstname:"Nic",Lastname:"Raboy",Address:&Address{City:"Dublin",State:"California"}})
	people = append(people,Person{ID:"2",Firstname:"Maria",Lastname:"jon"})
	router.HandleFunc("/people",GetPeopleEndpoint).Methods("GET")
	router.HandleFunc("/people/{id}",GetPersonEndpoint).Methods("GET")
	router.HandleFunc("/people/{id}",CreatePersonEndpoint).Methods("POST")
	router.HandleFunc("/people/{id}",DeletePersonEndpoint).Methods("DELETE")

	log.Fatal(http.ListenAndServe(":1234",router))


}
```

#Advance REST Clientからリクエストを送信
***全リストの取得***

```
GET　http://(DNS)/people
```
***特定Personの取得***

```
GET http:/(DNS):1234/people/3(id)
```
***Personの追加***

```
PUST　http://(DNS):1234/people/3(newid)
```

```
Body　{"firstname":"Can","lastname":"jon"}
```
***特定Personの削除***

```
DELETE　http://(DNS)/people/3
```
![キャプチャ4.PNG](https://qiita-image-store.s3.amazonaws.com/0/347413/08909d68-7250-a63f-4597-58b5e7ac9cfa.png)
![キャプチャ5.PNG](https://qiita-image-store.s3.amazonaws.com/0/347413/4c77b232-9457-9eca-d51d-47f9041d275b.png)

#EC2からのリクエスト送信
***全リストの取得***

```
curl -X GET http://localhost:1234/people
```
***特定Personの取得***

```
curl -X GET http://localhost:1234/people/2
```
***Personの追加***

```
curl -X POST -d '{"firstname":"Can","lastname":"jon"}' http://localhost:1234/people/3
```
***特定Personの削除***

```
curl -X DELETE http://localhost:1234/people/3
```

![キャプチャ6.PNG](https://qiita-image-store.s3.amazonaws.com/0/347413/55d1007f-2b10-cdf9-88fc-28508c4bcd6a.png)
最新の物体検出手法「M2Det」の筆者実装コード（Linux向け）をWindows上で動かす


# はじめに

MaskR-CNN, SSD, YOLO等を超える最新の物体検出手法として[M2Det](https://arxiv.org/abs/1811.04533)が出てきました。
嬉しいことにその[筆者実装コード](https://github.com/qijiezhao/M2Det)が公開されているので、試したい方も多いはず。
ただ、たぶんWindows環境だとコンパイルの段階でつまづいてしまう。
とりあえずで動かすことはできたので、同じように困った方のために書いておきます。

# 確認した環境

OS : Windows 10 Pro
GPU : NVIDIA GeForce GTX 1080Ti
CPU : intel Core i7-8700K

# 前準備

- Visual Studio
- Anaconda(Python)
- cuda, cudnn
- PyTorch

あたりは入れておいてパスを通しておくといいです。

# 手順
## 1. M2Detとpy-faster-rcnn-windowsをとってくる
```
git clone https://github.com/qijiezhao/M2Det
git clone https://github.com/MrGF/py-faster-rcnn-windows
```
## 2. M2Detフォルダへpy-faster-rcnn-windowsから必要なファイルをコピー

```
copy py-faster-rcnn-windows\lib\setup.py M2Det\utils\
copy py-faster-rcnn-windows\lib\setup_cuda.py M2Det\utils\
copy py-faster-rcnn-windows\lib\nms\gpu_nms.cu M2Det\utils\nms\
```
## 3. ファイル編集

**M2Det\utils\setup.py**

 - （Python3の場合）61行目を以下に変更

    変更前：`for k, v in cudaconfig.iteritems():`
    変更後：`for k, v in cudaconfig.items():`


 - 128～136行目の以下の箇所をすべてコメントアウトする。
  
```python

    Extension(

        "utils.cython_bbox",

        sources=["utils\\bbox.pyx"],

        #define_macros={'/LD'},

        #extra_compile_args={'gcc': ['/link', '/DLL', '/OUT:cython_bbox.dll']},

        #extra_compile_args={'gcc': ['/LD']},

        extra_compile_args={'gcc': []},

        include_dirs = [numpy_include]
    ),
```

**M2Det\utils\setup_cuda.py**

 - 61行目を以下に変更
  
変更前：`nvcc_compile_args = ['-O', '--ptxas-options=-v', '-arch=sm_35', '-c', '--compiler-options=-fPIC']`
変更後：`nvcc_compile_args = ['-O2', '--ptxas-options=-v', '-arch=sm_35', '-c', '--compiler-options=-fPIC']`
ここでGPUに合わせて-archは変更してもいいと思います。

 - 100行目と101行目の間に以下を追記

```python
                #Remove ',ID=2'
                elif ',ID=2' in c: cmd[idx] = c[0:len(c)-5]
```

## 4. コンパイル実行

```
cd M2Det/utils
python setup.py build_ext --inplace
python setup_cuda.py build_ext --inplace
```

# 確認
m2det512_vgg.pthをダウンロードしてM2Det/weights/に置く。
`python demo.py -c=configs/m2det512_vgg.py -m=weights/m2det512_vgg.pth --show`
がうまく実行できればOK。
22日目: 超解像に向けて

# 超解像(Super-Resolution)に向けて
## 背景
- 今後，超解像の研究のサーベイを進めようと思ったが事前知識がなかった
- したがって，サーベイのためのサーベイを行った．
 - 新しい分野を始める際にはどうしてもベーシックな手法から理解していきたい．
 - 基本的には，和文記事で紹介されている研究は対象としたくない．
 - やっぱりベーシックなメソッドは既に和文で紹介されている．
 - 悲しいからそれらをまとめよう．（Q.E.D.）

## 超解像まとめ記事
- [DeepLearningによる超解像の進歩](https://www.slideshare.net/HHiroto/deep-learning-106529202)
 - DeNAのAI研究開発エンジニアの方のまとめスライド．
 - Slide Shareなので概要だが，大雑把に全体がわかるので良かった．
- [GANによる超解像がもたらす新しい方向性と「The Perception-Distortion Tradeoff」の話](http://keiku.hatenablog.jp/entry/2018/07/22/220158)
 - こちらも全体概要がざっくりまとまっているので良かった．
 - 特に評価指標周りの話が書かれている．

ざっくりとまとめると，深層学習ベースの超解像手法は歴史的には以下のように派生？している．
　SRCNN -+-> SRResNet or EDSR  (CNNベースの手法)
　　　　　+-> SRGAN or ESRGAN   (GANベースの手法)
で，この辺の手法がベースラインとしてよく用いられる．

## 手法のリファレンス
- SRCNN: [Image Super-Resolution Using Deep Convolutional Networks](https://arxiv.org/abs/1501.00092v3)
- EDSR: [Enhanced Deep Residual Networks for Single Image Super-Resolution](https://arxiv.org/abs/1707.02921v1)
- SRGAN（[要約](https://qiita.com/masataka46/items/4a291ec0aff41875378b)）: [Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network](https://arxiv.org/abs/1609.04802)
- SRResNet: SRCNNをResNetで組んだ版でSRGAN論文の中で比較対象として新たに提案された手法
- ESRGAN: [ESRGAN: Enhanced Super-Resolution Generative Adversarial Network](https://arxiv.org/abs/1809.00219v2)

## その他の研究の話題
 - アップサンプリング手法：Deconvolution，Upsampling+Convolution, PixelShuffler
 - 評価指標：PSNR，BRISQUE，，，（ピクセル的な誤差を取るか，人間の主観的な良さを取るか）

## 所管
色々読みながらまとめて1時間くらい．明日は時間が取れれば上記のベースライン手法あたりをまとめようかなと思います．
Raspbian に Visual Studio Code を インストールする

はじめに
----
[ここ](https://code.headmelted.com/)にあるインストールで上手く行かなかったが、少々の修正で上手く行ったので記しておく。

シェルスクリプトの修正が必要
----
Raspbian では次のコマンドを実行しろとある。

```
$ sudo -s
# . <( wget -O - https://code.headmelted.com/installers/apt.sh )
```
実行すると、「--allow-unauthenticated」スイッチが無いとか、どうとか言うエラーがでた。
（コピペするのを忘れた）

そこで、「apt.sh」をダウンロードしてエディタで見てみた。
すると、49、50行目が次のようになっていた。

```
apt-get install -t ${repo_name} -y ${code_executable_name};
#apt-get install -t ${repo_name} -y --allow-unauthenticated ${code_executable_name};
```
これを、

```
#apt-get install -t ${repo_name} -y ${code_executable_name};
apt-get install -t ${repo_name} -y --allow-unauthenticated ${code_executable_name};
```
こう編集して、

```
$ bash ./apt.sh
```
とすれば正常にインストールできる。
コマンドプロンプトで、

```
$ code-oss
```
で実行できる。
スタートメニューのプログラムにもアイコンが追加されている。
日本語の短文の極性判定に面白そうなデータが落ちていたので綺麗にしてタグ付けした話

# あのー、自然言語処理系のデータ欲しいんですけど…
まあ、なんとかして集めて

とある卒業研究でこのような一幕がありまして、結局手打ちとかてラベリングとかする羽目になって大変に苦労した(4ヶ月位かかりました)ので、できるだけそういった後輩を増やさないようにしてあげたいなーという気持ちになっている修士課程一年生です。

# おっ、良いデータがあんじゃーん
 https://github.com/sugiyamath/bert にて良い感じのTwitterの極性判定のデータが公開されていたので、これ良いじゃん！となって色々眺めていました。

すると、データの前処理とか(url 消したり)したらもっと良くなるんじゃないか、後は多少身銭を切ってもGoogle様の極性判定ツールで極性付け直したら良くなるんじゃないかと思い、それを行いました。

コードの説明は要求があればしますが、多分それは皆さんのしたい研究の本質ではないでしょう。こんなところで時間を取られないで下さい。

# URLはよ
https://github.com/MokkeMeguru/JAS-refine

~~のbakup~~ に入っています。ブランチを指定してcloneする方法は調べて下さい。

詳細は readme.org の **生データ** の章を見て下さい。(他は自分やコードを見たい人のメモです。)

# あとがき
人力極性判定は人手(つまり人件費)が必要なのでこれが限界です。[ボルガ博士、お許しください!](https://dic.nicovideo.jp/a/%E3%83%9C%E3%83%AB%E3%82%AC%E5%8D%9A%E5%A3%AB%E3%80%81%E3%81%8A%E8%A8%B1%E3%81%97%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%21)
弊はこの手のお金や計算機なんかも私費でやる方針なのでだいぶお金が厳しい…(興味本位で GCE で BERT を訓練するんじゃなかった…)
はじめてのC++ 【35日目】

#はじめに
花粉か黄砂かしらないけどくしゃみめっちゃでてくる。
##キャスト

```cpp
(int)c;
int(c);
```
先日の投稿の内容が間違っていたのでもう一度調べてみる。

```試した.cpp
#include <iostream>

int main(){
  double a = 5.5;
  double b = 5.5;
  double c = 5.5;

  std::cout << (int)a  << std::endl;//出力結果 5
  std::cout << int(b) << std::endl;//出力結果 5
  std::cout << static_cast<int>(c) << std::endl;//出力結果 5
}
```
出力結果にどれも違いが見られなかったので、それぞれの違いは内容だとわかる。
###(int)cについて
これは、明示的型変換という。今の型から強制的に違う型にする方法である。
しかし、このキャストは一時的な変換しかできない。

```例.cpp
#include <iostream>

int main(){
  double a = 5.5;

  std::cout << (int)a  << std::endl;//出力結果 5
  std::cout << a << std::endl;//出力結果 5.5 ←ここでdoble型に戻っていることがわかる。

}
```
###int(c)について
調べていたら、変数宣言と書いてあった。しかし、キャストとは無関係なので違うかもしれない。
もう少し調べてみる。
一応プログラムを書いてみたが `(int)c`　との違いは見られなかった。

```例.cpp
#include <iostream>

int main(){
  double a = 5.5;

  std::cout << int(a)  << std::endl;//出力結果 5
  std::cout << a << std::endl;//出力結果 5.5

}
```
##ロベールのC++
###Argument Dependent Lookup(実引数依存の名前探索)
*実引数依存の名前探索 とは、C++において関数呼出時に与えられた引数の型に依存して、呼び出す関数を探索 する仕組みのことである。*([wikipedia参照](https://ja.wikipedia.org/wiki/%E5%AE%9F%E5%BC%95%E6%95%B0%E4%BE%9D%E5%AD%98%E3%81%AE%E5%90%8D%E5%89%8D%E6%8E%A2%E7%B4%A2))
この機能のおかげで、前の投稿の `getline()` が `std::getline()` と書かなくてもコンパイルエラーが出なかった理由である。ただこの機能は、便利だがコードを読みにくくする機能なので使わないほうがいい。 `using namespace std` と同じで害悪である。
###ファイルについて
コメント欄にて便利な方法を教えてもらったので試してみる。

```str.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>

int main() {
  std::ifstream file;

  file.open("test.txt");
  if(!file){ //変更した
    return EXIT_FAILURE;
  }

  std::string str;
  str << file.rdbuf();//変更

  std::cout << str << std::endl;
}
```
これでも文字を `test.txt`　からコピーできる。一応実行できて正しく出力できていた。
しかし、 `operator error`　がコンパイルで出てきた。今日は時間がないので明日また調べ直す。
###08-06　テキストとバイナリ
ファイルは1バイト単位のデータが並んでいるだけ。ファイルんのデータ構造はメモリと変わらない。このデータを何も変換せずに出力するのが **バイナリモード** という。　しかし、バイナリモードでは何が書いてるのかわからないため、テキストモードがある。それがテキストファイルである。

c/c++では、改行コードは `¥n`に統一されている。しかし、これをwindowsのメモ帳で開くと、改行コードがwindowsと違うため改行がおかしくなる。

テキストモードだと、臨機応変に改行コードを変換してくれるが、バイナリモードだとその変換がない。

バイナリモードを開くときは `ios::binary`　を使うみたい。

#終わりに
眠たいので調べ物が丁寧にできなかった。明日やろうと思う。
おやすみなさい
Go + Revel を用いたWebアプリ作成チュートリアル

# 1. はじめに
2019年4月現在での「Go + Revel を用いたWebアプリ作成」について、自分への備忘録としてまとめてみました。ご参考になれば幸いです。

---
# 2. このスライドを見てできること
- Go + Revel を用いたWebアプリ「It works!」が作成できるようになる。

---
# 3. 前提条件
- OS：Windows10Pro（GoおよびRevelがインストールされていれば他OSでもOK）

---
# 4. Goのインストール
1. [Go Downloadsサイト](https://golang.org/dl/)からインストーラをダウンロードする。
2. ダウンロードしたインストーラを実行する。

- インストーラを用いたインストール方法以外に、chocolateyパッケージマネージャ（Windows版のapt-getみたいなもの）を用いる方法もあるらしい。
- インストール方法の違いにより、環境変数GOROOTのフォルダパス設定が異なるらしい。
- 詳しくは [こちら](https://qiita.com/yoskeoka/items/0dcc62a07bf5eb48dc4b) を参照ください。
 
---
# 5. Revelのインストール
- コマンドプロンプトからインストールコマンドを実行する。（2、3分待つこと。）

```shell:コマンドプロンプト
# Revelフレームワークのインストール
$ go get github.com/revel/revel

# revelコマンドのインストール
$ go get github.com/revel/cmd/revel

# goバージョンの確認
$ go version

# revelバージョンの確認
$ revel version
```

---
# 6. Webアプリの作成
- revel newコマンドを用いてWebアプリの雛形プロジェクト「myapp」を作成する。

```shell:コマンドプロンプト
# GOPATHフォルダに移動（Mac、Ubuntuの方は cd $GOPATH です。）
$ cd %GOPATH%

# srcフォルダに移動
$ cd src

# アプリケーションの作成（5秒程度かかる）
$ revel new myapp
```

---
# 7. Webアプリの起動
- ローカル環境で作成した雛形Webアプリを起動します。

```shell:コマンドプロンプト
# Webアプリの起動（自動でWebアプリサイトがブラウザに表示されます）
$ revel run myapp

```

- Windowsの場合、ファイアウォールの確認ウィンドウが表示される時があるので、「アクセスを許可する」ボタンをクリックする。

---
# 8. Webアプリの起動確認
- うまくいけばRevelの雛形Webアプリが起動しています。
- 手動で[http://localhost:9000](http://localhost:9000)にアクセスします。
- 停止する場合は、コマンドプロンプトで「Ctrl + C」で停止します。

![Revel.jpg](https://qiita-image-store.s3.amazonaws.com/0/240522/9ad14db7-e724-fa5f-ce52-45a9b7f492a1.jpeg)

---

# 9. おまけ（その1）
- パッケージ管理・依存関係管理ツールのdepをインストールしてみる。
- 詳しくは [こちら](https://qiita.com/Azizjan/items/66564b5dc7597717932b) を参照。
- [こちら](http://nekootoko3.hatenablog.com/entry/2018/08/10/214233) も詳しくdepコマンドの使い方を解説してらしておすすめです。

```shell:コマンドプロンプト
# depパッケージ管理・依存関係管理ツールのインストール
$ go get -u github.com/golang/dep/cmd/dep

```
---

# 10. おまけ（その2）
- [goreturnsのインストール方法と使用方法を調べました](http://tsujitaku50.hatenablog.com/entry/2017/01/12/213834)

---
# 11. おわりに
Go + Revel 学習の参考になれば幸いです。

2019/04/06 TAKAHIRO NISHIZONO
EC2とlocalPC間のファイル、ディレクトリのコピー

#EC2とlocalPC間のファイル、ディレクトリのコピー
[情報科学屋さんを目指す人のメモ（FC2ブログ版）](http://did2.blog64.fc2.com/blog-entry-302.html)

C:\Program Files\PuTTY¥pscp.exe　を使う　
pscp.exeはPuTTYに含まれる
Pageantに共通キーをいれていないとできないかも

#LinuxからWindowsへコピー
***Linuxのホームディレクトリにあるファイルtestを Windowsのカレントディレクトリへコピーします。***

```
pscp.exe ec2-user@(IP):test .
```
ローカルPCのUSER NAMEにコピーされる

***Linuxのホームディレクトリにあるファイルtestを Windowsのダウンロードディレクトリへコピーします。***

```
pscp.exe ec2-user@(IP):test C:\Users\10001176313\Downloads
```
***Linuxのhelloディレクトリ内のarray.goをダウンロードディレクトリにコピーします。***

```
pscp.exe ec2-user@(IP):hello/array.go C:\Users\(user)\Downloads
```
*** LinuxのexecディレクトリからWindowsへディレクトリ丸ごとコピー***

```
pscp.exe -r ec2-user@(IP):exec C:\Users\(user)\Downloads
```
#WindowsからLinuxへファイルを1つコピー
***Windowsのダウンロードディレクトリのtest.txtをLinuxのホームディレクトリにコピー***

```
pscp.exe C:\Users\10001176313\Downloads\test.txt ec2-user@3.91.104.214:
```

***WindowsのダウンロードディレクトリのファイルをLinuxの./helloディレクトリにコピー***

```
pscp.exe -r C:\Users\10001176313\Downloads\test-dir ec2-user@3.91.104.214:./hello
```
高スループットのローパスフィルタを作成


##前書き
機械学習も高スループットになってきました。FPGAはニューラルネット系で各レイヤーにパイプラインを組むことができるため高スループットを実現しています。そのようシステム向けに高スループットのローパスフィルタを設計しました。

###フィルタ部
1000 Hz以降の信号電力を低減するフィルタを固定小数点Q30で作りました。何故無駄に大きいサイズで作ったかというと，フィルタパラメータに対する数値表現力を上げるに適当に大きくしておきました。入力はバイナリ，クロック100 MHzとしてレイテンシ20ns,出力レートは100MHzです。

```ht_lpf.vhd

module ht_lpf(input wire clk,　input wire in, output wire [31:0] out);

//Unsigned Q30 format

//Filter parameters
	//cutoff:gpd=1000*2pi (1000 Hz),sampling time:Ts=10e-9 (100 MHz)
localparam [31:0] n1=32'h000083c4; //(Ts*gpd)/(2.0+Ts*gpd);
localparam [31:0] n2=32'h3FFEF899; //(2.0-Ts*gpd)/(Ts*gpd+2.0);

reg inz1=1'b0;
reg [33:0] mv=1'b0;
reg [63:0] ar=1'b0;
reg [31:0] res=1'b0;

always@(posedge clk)
begin
	inz1<=in;
	//res=n1*(in+inz1)+n2*resz1;
	mv <= n1*{in&inz1,in^inz1};	//in+inz1
	ar <= n2*res;
	res <=mv[31:0]+ar[61:30];
end

assign out=res;

endmodule

```

###動作確認

フィルタへの入力に白色雑音を入れます。白色雑音として，25次のM系列信号(擬似白色)を生成しました。

```mseq.vhd

module mseq(input wire clk,output wire out);

// Irreducible polynomial: x^25+x^3+1
reg [24:0] seq=25'b0110100101101101100101101;
always@(posedge clk) seq<={seq[24]^seq[2],seq[24:1]};
assign out=seq[24];

endmodule

```

テストベンチは以下のように作成。

```tb.vhd

module tb();

parameter cycle=10;
reg clk=1'b0;

always#(cycle/2) clk<=~clk;

wire z;
mseq mseq_u0(.clk(clk),.out(z));

wire [31:0] out;
ht_lpf ht_lpf_u0(.clk(clk),.in(z),.out(out));

integer fd;

initial
begin
	fd=$fopen("output.dat","w");
	repeat(1000000)
	begin
		$fdisplay(fd,"%b %d",z,out);
		#cycle;
	end
	$fclose(fd);
	$finish;
end

endmodule

```


この生成雑音に対するローパスフィルタの出力は以下のように。M系列がバイナリなので平均値は0.5に収束。

<img width="639" alt="twave.png" src="https://qiita-image-store.s3.amazonaws.com/0/43995/ff4c9b4e-e887-4a53-96fc-1c33ed275913.png">

M系列信号とフィルタ出力のパワーは以下のようになりました。フィルタ出力は1000 Hzからパワーが減衰しました。低域のパワーがM系列より高いのは，固定少数点数を使用して表現力を落としたことに起因すると思います。

![fft.jpg](https://qiita-image-store.s3.amazonaws.com/0/43995/7c2dbd4f-f6e1-e759-272a-3bf77aa096b1.jpeg)
EC2で自身のVPC_IDをmetadataから取得する

instance metadataからVPCのID取れないかなと思って調べたらあっさりできました。

```bash
MAC_ADDRESS=$(curl http://169.254.169.254/latest/meta-data/mac)
VPC_ID=$(curl http://169.254.169.254/latest/meta-data/network/interfaces/macs/$MAC_ADDRESS/vpc-id)
echo $VPC_ID
```

## 参考
* https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
自己(本当に)啓発記事

#テスト
markdownね。知ってる知ってる。
あれでしょ。めくるマール、めぐるめぐる、風ェ〜〜〜。
ショッピングモール。ポッピンQ。

```math
E = mc^{2}
```

おっけーまる。理解した。完全に理解した。

Rubyって等価な書き方が複数、メソッドだな、メソッドで等価なのが複数在るのよね。
複雑な気分になるけど、まあそれは、分かってる人が書けば良いんだと思う。
分かっている人なら分かる。自由度が高いだけだという、ポジティブに考えています。
部分的に一致しているだけだと、全く同じメソッドというわけではなかったりするのでね。
nilとかendとかアレだし、破壊的変更とか、クラスのアレとか、
純粋関数型言語信者からしたらヤバイなというのは分かる。
Haskellの好きな私が未だにRubyを書くのは何故なのか？？？

```ruby:1upto10.rb
p (1..10).to_a
p [*1..10]
p (1..10).map{|i| i }
```

他にもループで書くというのが在るけど、それは馬鹿なんじゃないか。
イテレータの方が直感的に決まってる。
関数は数学用語であるし、より数学の関数のように書きたいし、書いたほうが良いと思っている。見地的にも数学的見地だろうと思うのでね。
map関数は好き。返り値に配列が返ってくるの良い。

```Haskell:rle.hs
import Data.List
rle = concatMap (\s -> head s : show (length s)) . group
```

関数の返り値をバンバン関数に渡していくのと、煩わしい副作用と処理の冗長だったりする記述が一切ない(これはね)。
だから美しいなあと思っちゃう。

何だかお酒飲みながら書きましたらポエムになっちゃいましたねこれ。
取り敢えずアウトプットする意思表示ということで、
先ずは試してみようみたいな感じで数行だけのつもりでしたけど、
しょうもなく綴ってしまいました。すみません。
次からはまともな記事を書くことをここに誓い、宣言します。
おやすみなさい。
CodilityのBinaryGapを競プロ未経験が解いてみた

# BinaryGapとは

簡単に言うと、**２進数の1と１に囲まれた0の数で最大の値を求める**問題です。
例えば**1000010100010**であれば、1と1の間の0の個数は左から4, 1, 3となるので、ここでは4が答えとなります。

正直、自信はありませんが100%のスコア判定をもらうことができました。Pythonのスペシャリストではない割には簡潔に書けたのではないかと思います。


## 1. Python コード

```python

def solution(N):
    return len(max(str(bin(N)).replace("0b", "").split("1")[:-1]))
```


### Step. 1
`str(bin(N))`で与えられた１０進数を２進数に変換します。その際に文字列型へ変換も行います。

### Step. 2
`.replace("0b", "")`二進数を文字列に変換すると最初にリテラルの0bがくっつきます、これを`replace(,)`で削除します。

### Step. 3
`.split("1")`1で文字列を分解し、0だけの配列を作成します。

### Step. 4
`[:-1]`でスライスし、最後の要素を削除します。これは、*1000*や*101000*のように最後の0は1で囲まれてるとは言えないためです。

### Step. 5
`str(bin(N)).replace("0b", "").split("1")[:-1]`の時点で[0, 00000, 00, 00, 0]のような配列が出来上がります。これを`max(  )`で文字数(０の数)が一番多い要素を抜き出します。この例だと00000です。

### Step. 6
5で00000となったので、`len()`で0の個数を数えます。この値がBinaryGapの答えとなります。




## Java

Javaのバージョンも書いて見ました。Javaはあまり慣れていないので、もっといい書き方があるかもしれません。基本的には上記のPythonと同じアルゴリズムです。
違う点としては与えられる引数Nが割り切れる数か判定している所とPythonでは`max()`で求められた配列内の最大文字数要素を求めるのを自作している点です。
割り切れるかどうか判定した理由としては`1000100101`のような文字列を1で分割した際にPythonでは`["", "000", "", "00", "", "0", ""]`のような配列が帰ってくるので最後の要素を削除することで、必ず１で囲まれた０になることが保証されますが、Javaの場合は`[, "000", , "00", , "0"]`のような配列になってしまい`1001`のような場合に挙動が変わってしまうからです。

```java
class Solution {
    public int solution(int N) {
        String[] zeros = Integer.toBinaryString(N).split("1");
        int index = zeros.length;
        int max = 0;

        /* 割り切れる数かどうかの判定 */
        if (N % 2 == 0) {
            index = index - 1;
        }

        /* 最大値の判定 */
        for (int i = 0; i < index; i++) {
            if (zeros[i].length() > max) {
                max = zeros[i].length();
            }
        }

        return max;
    }
}
```

## まとめ

今回は、アルゴリズムプログラミングに初めてトライしました。今後はCodilityの他のLessonや~~Java~~(2019/4/6追記)などでもトライしていこうと思います.
[iOS]UIBezierPath, CAShapeLayer, UIColor.init(patternImage:) でUITabBarの形、色、外観を変える

Swift4.2とSwift5　で動作確認済


実現したかったUITabBar
![IMG_1664的副本.PNG](https://qiita-image-store.s3.amazonaws.com/0/392332/d7e96714-a75a-b8d5-17ba-d8046ebec49d.png)

https://itunes.apple.com/sg/app/pripara/id1039257927?mt=8
（香港のAppStoreじゃないとダウンロードできません）


実現できたUITabBar（アイコンは今回の記事と関係ないです）
![屏幕快照 2019-04-05 23.15.49.png](https://qiita-image-store.s3.amazonaws.com/0/392332/59c096ae-decc-6718-d8b8-12eed5c07030.png)

https://github.com/Satoru-PriChan/ChangeUITabBarAppearance

方法

⑴UIBezierPathを使って、どんなグラフィックを描きたいかを定義します。今回は、スタート地点のY座標をマイナスとし、縦に少し拡張しているだけです。

```swift:MyTabBarController.swift
    func createLengthExpandShape() -> CGPath {
        let path = UIBezierPath()
        
        //Starting point (left top) then draw lines until the it returns to the starting point with close().
        let startX: CGFloat = 0
        let startY: CGFloat = -37

        path.move(to: CGPoint.init(x: startX, y: startY))
        path.addLine(to: CGPoint.init(x: self.tabBar.frame.width, y: startY))
        path.addLine(to: CGPoint.init(x: self.tabBar.frame.width, y: self.tabBar.frame.height))
        path.addLine(to: CGPoint.init(x: startX, y: self.tabBar.frame.height))
        path.close()
        
        return path.cgPath
    }
```
参考　https://medium.com/@philipp307/draw-a-custom-ios-tabbar-shape-27d298a7f4fa

(2)CAShapeLayerに(1)のパスを追加し、レイヤーの形を変えます。

```swift:MyTabBarController.swift

　　 override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        //中略　ここでUITabBarControllerの他の設定を色々することになると思います

        //Change tabbar shape
        self.changeTabBarShape()
        
    }

    func changeTabBarShape() {
        let shapeLayer = CAShapeLayer()
        
        //Get CGPath
        shapeLayer.path = self.createLengthExpandShape()
        
        //Set image
        shapeLayer.fillColor = UIColor.init(patternImage: UIImage.init(named: "MyImage.png")!).cgColor
        
        //Set layer
        self.tabBar.layer.insertSublayer(shapeLayer, at: 0)
    }
```


(3)UIColor.init(patternImage:) でセットしたい画像を用意し、Xcodeにドラッグ＆ドロップで追加してください。その際Copy Items If Neededにチェックを入れることをお勧めします。

今回作った画像
![lace-1174578_640的副本8.png](https://qiita-image-store.s3.amazonaws.com/0/392332/5ce09871-7652-d083-ec9e-3b001891b4f8.png)

画像の準備が一番わかりにくい点です。
画像はランタイム時上下逆にして使われるので、画像編集ソフトなどで画像の内容をあらかじめ上下逆にしておいてください。また画像が貼られ始めるのは「拡張前の」レイヤーの左上角からという点に注意してください。

今回、画像下のピンク色で雑に塗りつぶしただけの部分がUITabBarの本来の左上から貼られます。

その上のCAShapeLayerで拡張した部分には、画像上のレースのひらひら部分が貼られます。

ひらひら部分と、塗りつぶしただけの部分の間をpngで透過しておくと、UITabBarが画像に合わせて複雑に形を変える（ように見える）ため、デザイン性が増します。

CAShapeLayerの拡張法をもっと複雑に変えたい場合は、画像の中身も調整する必要があると思います。今回は縦長にしただけなので、簡単に済んでいます。

全プロジェクト
https://github.com/Satoru-PriChan/ChangeUITabBarAppearance

気に入ったら、GitHubの方に星もらえると助かります。

もっとエクセレントなやり方があると思うので、誰か教えてください・・・

以上
デベロッパーツールのタブは移動して使いやすくしよう

## デベロッパーツールのタブは移動して使いやすくしよう
例えばVueのデベロッパーツールを入れている場合、タブが一番最後になるため使いにくいです。

タブをドラッグすることで移動できるので、使いやすい左の方に動かすと良いです。
![Screen Shot 2019-04-05 at 23.41.26.png](https://qiita-image-store.s3.amazonaws.com/0/250231/37a5d595-c2c1-ed75-766c-48500d148741.png)
このようにできます。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
Emacsの行番号表示にモヤモヤした話

# linumからdisplay-line-numbersへ移行
これまでEmacsで行番号を表示するといったらlinumが一般的だったが、ver.26からはdisplay-line-numbers-modeが使えるようになったらしい[^1]。linumよりも速いとか。早速導入してみる。

```elisp
;; display line numbers
(if (version<= "26.0.50" emacs-version)
    (progn
      (global-display-line-numbers-mode)
      ;; テーマはdeeper-blueを使用している。これに合わせた色を選んだつもり
      (set-face-attribute 'line-number nil
                          :foreground "DarkOliveGreen"
                          :background "#131521")
      (set-face-attribute 'line-number-current-line nil
                          :foreground "gold")))
```

# 最終行どうなってるのか分からん問題
で、見た目はこんな感じになる。
![Screenshot from 2019-04-05 22-58-34.png](https://qiita-image-store.s3.amazonaws.com/0/352170/4ee11a88-4a13-b883-30a4-7447c1a7e62b.png)
まあ悪くないのだが、最終行（画像でいうと5行目）に改行があるのかないのか、見分けがつかないのが気になる[^2]。すなわち、空行があってもなくても同じ表示であり、カーソルを終端まで移動させないと空行の有無がわからない。フォーマットによっては最終行を空行にすることが推奨されているので（例えばYAML）、見ただけでわかるようにしたい[^3]。他のエディタ（例えばPyCharm）では、空行にも行番号が振られているので分かりやすい。

# 妥協案
いろいろ調べてみたものの、満足なソリューションが見つからなかった。バッファの最後に`[EOB]`のような記号を表示させるとか、whitespace-modeで行末を表示させる、といった方法はありそうだが、やりたいことに対して手間をかけすぎている気がする。現状採用しているのは次の設定。

```elisp
(setq-default indicate-empty-lines t)
(setq-default indicate-buffer-boundaries 'left)
```

フリンジ（フレームの左端にある領域をこう呼ぶらしい）に空行やバッファの終端を表示できる。次のように表示される：
![Screenshot from 2019-04-05 22-59-03.png](https://qiita-image-store.s3.amazonaws.com/0/352170/fb57aa8e-f1af-75d0-a306-9c1a7d899ae3.png)
これは5行目に改行があるとき。

![Screenshot from 2019-04-05 22-59-14.png](https://qiita-image-store.s3.amazonaws.com/0/352170/8f3de27c-3931-595b-c81c-65059217ea61.png)
こちらはないとき。カギカッコのようなマークが点線（空行を表す）と繋がっていないので異常と気が付きやすい。

[^1]: 参考：[emacs 26で入ったdisplay-line-numbersを利用する](http://garaemon.hatenadiary.jp/entry/2018/07/08/181003)
[^2]: display-line-numbers-modeだけの話ではなく、linumでも同様である。Emacsの基礎的な部分に関わることで簡単には修正できないのかも。
[^3]: 保存時に警告させるとか、別なソリューションがあることに執筆時点で気がついた。
postcss-preset-envでpostcss-nestingを使う

[postcss-preset-env](https://github.com/csstools/postcss-preset-env)を使っていて、CSSをネストさせたいなと思いました。

しかし、普通にオプション付け加えずに書いても、もちろん反映されない。

ググっても、あまりpostcss-preset-envとの組み合わせの情報はなく、[postcss-nesting](https://github.com/jonathantneal/postcss-nesting)単体のものが多かったため、書き残しておく。

# `'nesting-rules': true` を features に追記すればよいだけ

`postcss.config.js`の`features`欄に`'nesting-rules': true`を追記すればよいだけでした。

```postcss.config.js
  postcssPresetEnv({
    features: {
      'nesting-rules': true,
    },
  }),
```

他の[postcss-custom-properties](https://github.com/postcss/postcss-custom-properties)とかは`'custom-properties'`のようにしてfeatureを設定するので、同じ流れで`'nesting'`を使おうとしたら、上手くいかず少し困った経緯があります。

[postcss-preset-envのissueにいたこの人のコード](https://github.com/csstools/postcss-preset-env/issues/16#issuecomment-459464113)で、設定方法を知りました。一応、[公式](https://github.com/csstools/postcss-preset-env#features)にも記載がありました。ちゃんちゃん

# postcss-nestedよりpostcss-nesting

蛇足ですが、2つの違いについて。

Sassっぽいほうは[postcss-nested](https://github.com/postcss/postcss-nested)で、なんならnestingのほうよりいい感じの書き方な気がするのですが、[公式のCSSの草案？](https://tabatkins.github.io/specs/css-nesting/)に準拠しているほうはpostcss-nestingなので、そっちを採用しました。

やっぱり、[Sassではなく未来のCSSに準拠したい](https://blog.unresolved.xyz/postcss-with-cssnext/)という思いからです。
Dockerを使って超高速でトランザクションが使えるMongoDBを用意する

# 忙しい人のための結論(MongoDB 4.1.9版)

```bash
docker run --rm --name コンテナ名 -d mongo:4.1.9-bionic mongod --replSet レプリカセット名

docker run --rm mongo:4.1.9-bionic mongo --host コンテナのIPアドレス --eval "rs.initiate({'_id':'レプリカセット名', members:[{_id:0, host:'コンテナのIPアドレス'}]})"
```

オプションはお好みで。

# MongoDBはいいぞ！

MongoDBって便利ですよね。個人的には一番触ってて面白いと思えるDBです。このMongoDB、最近はトランザクションも入って個人のちょっとした用途だったらSQL系のDBとかもういらないんじゃないか、とも思うわけです。大規模な開発だったらSQL系、っていうかAWSのAurora便利すぎだろって感じなんですが。

MongoDBにトランザクションが入ったのはいいのですがレプリカセット構成じゃないと使えないとか制限があって、なんか構築が面倒なので結局SQL系のDBを使っちゃう、なんてことがあるわけです(私のことだ)

実はそんなに面倒でもないのではないか？と思い直し、ここいらで最短構築手順をちゃんと記録して、個人開発ではMongoDBをもっと使っていこう！と思った次第です。

# MongoDBをdocker-hubから拾って立ち上げる

それでは、実際にトランザクションが使えるMongoDBを立ち上げてみます。

まずは、MongoDB公式のDockerイメージ置き場
https://hub.docker.com/_/mongo

普通にMongoDBをdocker pullすれば公式イメージが落ちてくるのですが、トランザクションはversion4以降の機能なのでちゃんと新しめのタグで引っ張ってきます。

```bash
docker pull mongo:4.1.9-bionic
```

続いて立ち上げ。公式のHow to use this imageのところに

```bash
docker run --name some-mongo -d mongo:tag
```

と書いてあるのですが、トランザクションはレプリカセット構成でないと使えないわけです。別にレプリカ構成だからって２台以上必要なわけではなく１台でもレプリカセット構成になっていればトランザクションが使えます。

レプリカセットを設定するには、--replSelオプションをつけてmongodを実行すれば良いので、

```bash
docker run --name some-mongo -d mongo:tag mongod --replSet レプリカセット名
```

という形になります。では適当にコンテナ名やレプリカ名をつけて--rmオプションもつけた、実行サンプルです。

```bash
docker run --rm --name transaction-mongo -d mongo:4.1.9-bionic mongod --replSet transaction-set
```

ただし、これだけだとまだ普通に立ち上がるだけです。レプリカセットはrs.initiate()を実行しないと有効になりません。

# レプリカの設定を行う

同イメージを使ってmongoコマンドを実行し、コンテナ内のMongoDBでrs.initiate()を実行します。

まずはレプリカがまだ機能していないことを確認。

```bash
docker run --rm mongo:4.1.9-bionic mongo --host コンテナのIPアドレス --eval "rs.status()"
```

レプリカの設定がまだであれば短めのJSONが出力され、次のようなreplsetの設定がないってerrmsgが入ってます。

```json
	"errmsg" : "no replset config has been received",
```

それではレプリカの設定を行います。

```bash
docker run --rm mongo:4.1.9-bionic mongo --host コンテナのIPアドレス --eval "rs.initiate({'_id': 'transaction-set', members:[{_id:0, host:'コンテナのIPアドレス'}]})"
```

再度rs.status()を実行して、設定が正しく行われたことを確認します。errmsgがない長めのJSONが出力されます。

この状態でコンテナのmongoクライアントを実行すると、プロンプトが>ではなくレプリカセット用のプロンプト表示になります。

```bash
docker exec -it transaction-mongo mongo
```

```mongo
transaction-set:PRIMARY> 
```

プロンプトがレプリカ用のになっているのを確認したら、exitで抜けるなり、そのままコマンドでトランザクションを試して遊ぶなりしてください。

トランザクションAPIの公式ドキュメント
https://docs.mongodb.com/manual/core/transactions/#transactions-api

# トランザクションを使うときは、セッションを経由するのを忘れずに

```
db.コンテナ名.insert()
```

とかするとトランザクション機能が無視されます。公式ドキュメントのサンプルのように、session.getDatabase()経由でアクセスしないとトランザクションが有効にならないので注意です。

```
eventsCollection = session.getDatabase("reporting").events;
```
.htaccessによるBasic認証

#ログインシステムを5分で実装しろ
え、無理ですよ、そんなの
データベースにテーブル作って…
パスワードはハッシュ化して…
フォームやクエリからの攻撃を防いで…

え？今回はごく一部の人が使うシステムだから
セキュリティはガバガバでも良い？

**じゃぁ、できます**

##basic認証とは
Base64という暗号形式を利用したログインシステムで
.htaccessにちょいちょいと記述するだけで完成する。
でもセキュリティは弱い。

##どうやって作るの？
まずは`.htpasswd`というテキストファイルを作成し
その中に`ユーザーのID:Base64で暗号化されたパスワード`という感じに書く。

例えばユーザーIDは`tadanohito`、パスワードは`himitudesu`だったとする。
このユーザーIDとパスワードをBase64で暗号化すると`d31esqz2hqswU`となる。
(Base64の暗号化は無料のwebアプリがあるので、それを利用すると良い。)
その場合の記述は

```:.htpasswd
tadanohito:d31esqz2hqswU
```

となる。
もしユーザーを増やしたいなら、改行して追記していくだけで良い。


そしたら`.htaccess`ファイルに

```:.htaccess
AuthUserfile /admin/system/.htpasswd
AuthGroupfile /dev/null
AuthName "Please enter your ID and password"
AuthType Basic
require valid-user
```

と記述する。
それぞれ解説をすると

**AuthUserfile**
　　.htpaccessのあるパスを書く。

**AuthGroupfile**
　　グループファイルのあるパスを書く
　　のだが、グループファイルなど作らなくても良いので
　　`/dev/null`と書けば良い。

**AuthName**
　　認証時に表示する文字列を書く。
　　日本語で書くと文字化けする可能性が高いので
　　英語で簡単に書くと良い。

**AuthType**
　　認証方法を書く。
　　`Basic`と`Digest`のどちらか選択出来て
　　`Basic`の場合はパスワードをBase64で暗号化
　　`Digest`の場合はパスワードをMD5で暗号化
　　しなければならない。

**require**
　　認証を通すユーザー名を書く。
　　`valid-user`と書くと全員が通る。
　　`user ユーザー名`と書くと、そのユーザーしか通らなくなる。

##サーバーに2つのファイルをアップロードして完了
プログラミングすることなく、これでログインシステムの完成！
多分カップラーメン茹で上がるより早く完成する。

#編集後記
入社5日目
今日から管理システムページを0から作ることになって
そのログインシステムをbasic認証で実装しました。

上司「basic認証で良いよ」
僕「basic認証…？」
上司「ググれ」

となったので、少し調べてみました。
めちゃ簡単でした。
fluentdからログが転送・出力されてこない時に見てほしい記事 ( rewrite_tag_filter 使用上の注意 )

# TL;DR / 結論から先に言うと
[rewrite_tag_filter プラグイン](https://docs.fluentd.org/v1.0/articles/out_rewrite_tag_filter)は、rewrite_tag_filterが出力するときのタグが、入力時に受け付けるタグのパターンと一致したら無限ループを起こし永遠にログが転送されません。

[公式にその注意が記載されています](https://docs.fluentd.org/v1.0/articles/out_rewrite_tag_filter#with-rewrite-tag-filter,-logs-are-not-forwarded.-why?)が、これにハマってる時にこのドキュメントにたどり着けるかというと微妙かと思い、このような記事にすることにしました。

# この記事を作った目的

fluentdを使い慣れている人なら当たり前かもしれないんですが、最近fluentdを使い始めた自分が、ログが転送されない、出力されない場合があり、どハマりしたので記事として残しておくことにしました。


# 無限ループするパターンで、ログが転送されないのを確かめる

ログ転送のフローは以下の通り
- ファイルからJSONのログを読み込んでそのレコードに `example_tag.before` というタグをつける
- `example_tag.(なんでもいい)` というタグがきたら、 `example_tag.after` というタグに変更する
- `example_tag.after` というタグがきたら標準出力に出力する

```fluentd:fluent.conf
# ファイルからJSONのログを読み込んでそのレコードに `example_tag.before` というタグをつける
<source>
  @type tail
  path /var/log/nanikano.log
  pos_file /var/log/nanikano.log.pos
  tag example_tag.before
  <parse>
    @type json
  </parse>
</source>

# example_tag.(なんでもいい) というタグがきたら、 example_tag.after というタグに変更する
<match example_tag.**>
  @type rewrite_tag_filter
  <rule>
    key nantoka
    pattern /(.+)/
    tag example_tag.$1
  </rule>
</match>

# example_tag.after というタグがきたら標準出力に出力する
<match example_tag.after>
  @type stdout
</match>
```

ログに書き込んでみる

```log:nantoka.log
{"nantoka":"after"}
{"nantoka":"after"}
{"nantoka":"after"}
{"nantoka":"after"}

```

fluentdから標準出力に出力されない。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/96675/09beca20-3c4f-f756-8c83-d902a6e591cf.png)

タグ付け替え後の `example_tag.after` が、rewrite_tag_filter にマッチする条件の `example_tag.**` にマッチするから無限ループしてしまうらしい。

# 無限ループしないパターンで、ログが転送されるのを確かめる

- ファイルからJSONのログを読み込んでそのレコードに `example_tag.before` というタグをつける
- `example_tag.(なんでもいい)` というタグがきたら、 `example_tag_modddddddddddd.after` というタグに変更する
- `example_tag_modddddddddddd.after` というタグがきたら標準出力に出力する

(変更箇所がわかりやすいようにタグが目立つようにしています)

```fluentd:fluent.conf
# ファイルからJSONのログを読み込んでそのレコードに example_tag.before というタグをつける
<source>
  @type tail
  path /var/log/nanikano.log
  pos_file /var/log/nanikano.log.pos
  tag example_tag.before
  <parse>
    @type json
  </parse>
</source>

# example_tag.(なんでもいい) というタグがきたら、 example_tag_modddddddddddd.after というタグに変更する
<match example_tag.**>
  @type rewrite_tag_filter
  <rule>
    key nantoka
    pattern /(.+)/
    tag example_tag_modddddddddddd.$1
  </rule>
</match>

# example_tag_modddddddddddd.after というタグがきたら標準出力に出力する
<match example_tag_modddddddddddd.after>
  @type stdout
</match>
```


ログに書き込んでみる

```log:nantoka.log
{"nantoka":"after"}
{"nantoka":"after"}
{"nantoka":"after"}
{"nantoka":"after"}

```

fluentdから標準出力に出力される。
タグ付け替え後の `example_tag_modddddddddddd.after` が、rewrite_tag_filter にマッチする条件の `example_tag.**` にマッチ `しない`　からフィルタを抜け出し、標準出力に出力される。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/96675/162e231a-f84a-143e-4c65-f7f08b6d8568.png)

# まとめ

`rewrite_tag_filter` を使用するときは、入力時のタグと出力時のタグの形式に注意する。
入力時のタグと同じ形式の場合、無限ループを起こしてログが転送されない。
ログにもそれっぽい情報が出ないので、見当がついていないとハマる。
気がつくのに１週間くらいかかって、気づいた直後にドキュメントに記載されているのを見つけて心ポキっとした。同じ悲しみを生み出してはいけない。
node.jsを触るために簡単なチャットシステムを作る（環境構築編）

Node.js を触ってみたいと思ったので、備忘録も兼ねて以下に記します。
よりよい方法やバグ等ございましたら、アドバイスいただけると光栄です。

#Node.jsをインストールする

コマンド操作でインストールする方法もあるようですが、今回は簡単なインストーラーを使いました。
下記ページにアクセスし、左側の「推奨版」をインストールしました。
https://nodejs.org/ja/

これなら、インストーラのプログラムをダウンロードできるのであとは実行するだけです。

最後に、インストールが無事にできたかを確認するためにターミナルを起動して以下のように入力します。

```console
$ node -v
```

実行して Node.js のバージョンが表示されれば、完了です。

#Node.jsのパッケージ管理の初期化

はじめに、下記コマンドでアプリを作成するためのディレクトリを作成します。
（今回は`mychat`という名前のディレクトリを作成しました。）

```console
$ mkdir mychat
```

次に、作成したディレクトリ内に移動します。

```console
$ cd mychat
```

そして下記を実行し、パッケージ管理の初期化をします。

```console
$ npm init
```

今回は以下のように指定をして作成しました。

+ `package name` : そのままエンターキーを押す
+ `version` : そのままエンターキーを押す
+ `description` : そのままエンターキーを押す
+ `entry point` : 「**server.js**」 と入力しエンターキーを押す
+ `test command` : そのままエンターキーを押す
+ `git repository` : そのままエンターキーを押す
+ `keywords` : そのままエンターキーを押す
+ `author` : そのままエンターキーを押す
+ `license` : そのままエンターキーを押す

これで、`mychat`フォルダに、`package.json`ファイルが生成されます。
`package.json`ファイルは以下のような内容になっています。

```json
{
  "name": "mychat",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
```

#Node.jsのパッケージのインストール

それでは、`Express` と `Socket.io` をインストールします。

```console
$ npm i -D express socket.io
```

あとは個人的に好きな [Moment.js] も入れます。（この辺は好みです。）

```console
$ npm i moment
```

Javascriptで意外と面倒な日付関連の処理がすっきり書けるので、何かと便利です。

上記が完了し、`package.json`ファイルが下記のように変更されていれば完了です。

```json:package.json
{
  "name": "mychat",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "moment": "^2.24.0"
  },
  "devDependencies": {
    "express": "^4.16.4",
    "socket.io": "^2.2.0"
  }
}
```

以上でアプリを作り始めるための準備が完了です。
次は、クライアントとサーバー接続をするところまでをやってみます。

# 関連記事

+ [node.jsを触るために簡単なチャットシステムを作る：環境構築編](https://qiita.com/sunnyG/items/60b1968cd4cc390ff804)
+ [node.jsを触るために簡単なチャットシステムを作る：サーバー接続編](https://qiita.com/sunnyG/items/2e7b9d89acfc2b0938e4)
+ [node.jsを触るために簡単なチャットシステムを作る：メッセージ送信編](https://qiita.com/sunnyG/items/859aed447fa88665e601)

[Moment.js]:https://momentjs.com/
Gitで別のリポジトリの特定のコミットを取り込む・対応したコミットをおこなう

### やりたいこと

特定のリポジトリのコミットに対応して（変更を取り込んで）、別のリポジトリにコミットしたいことがあります。  
例えば、GitHub上のリポジトリにある英語の公式サイトを翻訳して、別のリポジトリの日本語公式サイトを作成している場合などです。

例: [英語公式サイトのコミット](https://github.com/node-red/node-red.github.io/commit/21b84e0bda4ad90720cc189d1ac941272e485ccc)に対応して、[日本語サイトのコミット](https://github.com/node-red-jp/node-red-jp.github.io/commit/4e106da4a31df8fdcdeaed1e8b69a6feaf3cbba7)をおこないました。

![git-cherrypick.png](https://qiita-image-store.s3.amazonaws.com/0/182261/c0a46e0c-f663-c57a-7fa2-9976368388b1.png)

**そんなときには`git cherry-pick`を使いましょう！**

### git cherry-pickとは

`git cherry-pick`とは、別リポジトリまたは他のブランチの特定コミットを自分が今いるブランチに反映できるコマンドです。

以下のようにすると、変更が取り込まれ、またコミッタ情報には元のコミットをした人に加えて新たにコミットをおこなった自分自身が入るようです。

ちなみにWikipediaによるとcherry-pickの意味は以下のとおりだそうです。

> cherry-pickingの語義は、サクランボの熟した果実を熟していないものから選別することであり、転じて「良い所だけを取る」「（特売品専門の）購買者」「つまみ食い」の意味で使用される。
>　　(略)
> Gitのようなバージョン管理システムにおいて、あるコミットで行われた変更を別な箇所に「つまみ食い」的に適用する操作がチェリーピックと呼ばれる[1]。

### 手順

上の概略図も参考にしながら、手順を参照すると少しわかりやすいと思います。

日本語サイトのリポジトリをローカルにプルしておき、ブランチ（名前は適当にここでは`dev`）を切っておきます。  

```bash
git remote add english https://github.com/abc-english/example-website.git
git fetch english
git cherry-pick {englishの対応したいコミットハッシュ値(4e106d...)}
```

英語サイトを`english`というリモートに追加、フェッチします。  
その中から日本語サイトに反映させたい・対応付けさせたいコミットをハッシュ値によって指定して取り込みます。これが`git cherry-pick`コマンドです。

日本語訳がある程度進んでいる場合には競合が発生するので、適当なエディタで編集して解消（日本語訳）をおこないます。

```bash
git add <path>
git commit -m {対応した英語サイトのコミットのコミットメッセージ}
git push --set-upstream origin dev
```

編集をおこなったファイルをステージングし、コミットをおこないます。コミットメッセージは対応したコミットのコミットメッセージをコピペしたほうが対応したことがわかりやすくなると思います。

`dev`ブランチとして日本語サイトのリモートリポジトリにプッシュして完了です。

あとはGitHubなどでプルリクエストを出すなり何なりしましょう。  
PRに含まれるコミットが英語サイトのコミットに対応したものだと、たぶん気づいてもらえるはずです！

### 参考文献

- [Gitで別リポジトリの特定コミットを取り込む方法](https://qiita.com/edo1z/items/3fa340a0b483a85ffe83)
- [異なるgitリポジトリ間でもcherry-pickはできる](https://qiita.com/takeoverjp/items/befdcd616374cf6e0a3b)
- [git cherry-pickで助かりました(他ブランチのコミットを反映させる方法)](https://qiita.com/bossunn24/items/dedb620541d852327934)
- [チェリー・ピッキング - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%81%E3%82%A7%E3%83%AA%E3%83%BC%E3%83%BB%E3%83%94%E3%83%83%E3%82%AD%E3%83%B3%E3%82%B0)
AtCoderの使用言語をRで集計した

[#WaterCellTechNight](https://twitter.com/hashtag/WaterCellTechNight?src=hash)で話をするためにAtCoderの使用言語ランキングを作成したので、方法と結果を紹介します。
（ちなみにAtCoderの話は特にしていません > [Project Eulerの話](https://nozma.github.io/wci_tech_night_3/wci_tech_night_3.html#1)）

## データソース

[kenkoooo/AtCoderProblems: Problem manager for AtCoder users](https://github.com/kenkoooo/AtCoderProblems/#submission-api)で公開されているAPIからAccepted Count for each languageを読み込みました。


## Rパッケージ

データの読み込みに`rlist`、加工に`dplyr`、可視化に`ggplot2`を使いました。

```{r, message=FALSE, warning=FALSE}
library(rlist)
library(dplyr)
library(ggplot2)
```

## データの読み込み

`list.load()`で読み込み、`list.stack()`でデータフレームにしました。

```{r}
list.load("https://kenkoooo.com/atcoder/resources/lang.json") %>% 
  list.stack() -> ac_lang
```

JSONの構造が簡単だったので、実際のところ`rlist`の機能を使う必要はありませんでした。次のように、`jsonlite::read_json()`を`simplifyVector = TRUE`で使用しても良いと思います。

```r
jsonlite::read_json("https://kenkoooo.com/atcoder/resources/lang.json", simplifyVector = TRUE)
```

## 集計

各言語について、使用者数、AC合計、AC平均（AC合計/使用者数）を求めました。

```{r}
ac_summary <- ac_lang %>% 
  group_by(language) %>% 
  summarise(
    使用者数 = n(),
    AC合計 = sum(count),
    AC平均 = round(AC合計 / 使用者数, 2)
  ) 
```

### 可視化

```{r}
plot_ac <- function(target){
  target <- rlang::enquo(target)
  ac_summary %>%
    ggplot(aes(x = reorder(language, !!target), y = !!target)) +
    geom_col() +
    coord_flip() +
    xlab("Language") +
    ylab(target) +
    theme_classic(base_family = "IPAexGothic")
}
```

まず使用者数をカウントしてみました。

```{r}
plot_ac(使用者数)
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109348/b1bc49ad-cce1-212a-6d80-31f86aeec9bc.png)


やはりC++が強いですね。その他も上位はメジャーな言語が占めているようです。

ところでTextの高順位がちょっと気になります。おそらく提出テストに使っている人がそこそこ居るのでしょう。

そこで、少し工夫してメインの使用言語を集計して、同じように可視化してみました。

```{r}
ac_lang %>% 
  group_by(user_id) %>% 
  summarise(language = language[which.max(count)]) %>% 
  ungroup() %>% 
  count(language, sort = TRUE) %>% 
  ggplot(aes(x = reorder(language, n), y = n)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  xlab("Language") +
  ylab("使用者数（メイン言語）") +
  theme_classic(base_family = "IPAexGothic")
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109348/78b79336-b7f5-aefb-3cb7-0ca14e58135b.png)

Textの順位が落ち着きました。おそらくこちらのほうが実情に近いのではないでしょうか。

次に、ACの平均をプロットしてみました。

```{r}
plot_ac(AC平均)
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109348/bacbb37a-0271-ac37-2574-538807fef957.png)

ユーザーあたりのAC数平均を求めると、意外な言語が上位に来たりして面白いですね。

AtCoderの他に、[Project Euler](https://projecteuler.net/about)についても同様に可視化を行ったのですが、以前実施したときとほとんど同じだったので、Project Eulerについては前回の記事をご覧ください。

- [RSeleniumを使ってログインにcaptcha認証の必要なページをスクレイピングする - Qiita](https://qiita.com/nozma/items/2731b36db8129439a931)
as_str()とかto_string()とかinto_vec()とか紛らわしい！

こんばんは。 Rust、よく型を明示的に変換しますよね。
`&str`から`String`とか、`Vec<T>`から`&[T]`とかが代表ですが、他にも標準ライブラリだけでもいろいろな変換メソッドが用意されています。
ところでこれらの変換メソッド、名前が`as_str()`とか`to_string()`とか`into_vec()`とかだったりして前置詞が紛らわしいんじゃ！ と思ったことはありませんか？ 実はこれにはちゃんと法則性があるということに、Rust歴7年の私はたった今気づきました。

##`as_***`
`&self`をとって、同じlifetimeの参照を返すメソッドです。 要するに、ただ参照をキャストしているだけか、メンバへの参照を返しているだけです。 標準ライブラリから適当に例を挙げると、

```rust
impl String {
  fn as_str(&self) -> &str;
}
impl<T> Vec<T> {
  fn as_slice(&self) -> &[T];
}
impl<T> Option<T> {
  fn as_ref(&self) -> Option<&T>;
}
```

などです。 `Option<T>`のはちょっと特殊ですが、まぁ気持ちはわかるのでいいです。

##`to_***`
`&self`をとって、新しくオブジェクトを作って返すメソッドです。 `as_***`と違い、多くの場合`&self`と戻り値の間にlifetimeの関係がないのが特徴です。 標準ライブラリでは例えば、

```rust
impl i32 {
  fn to_string(&self) -> String
}
impl<T> [T] {
  fn to_vec(&self) -> Vec<T> where T: Clone;
}
impl<'a, T> Cow<'a, T> {
  fn to_mut(&mut self) -> &mut <T as ToOwned>::Owned;
}
```

などがあります。 最後の`Cow`の例は特殊で、新しくオブジェクトを作るかもしれないし作らないかもしれないメソッドです。 これは`as`と`to`の境界にいる感じがしますね。

##`into_***`
`self`を食べて(`&self`ではない点に注意)、何かを返すメソッドです。 `self`は食べられるので以後使えなくなるのが特徴です。

```rust
impl<T> [T] {
  // Box<[T]>の領域を使い回す変換メソッド
  fn into_vec(self: Box<[T]>) -> Vec<T>;
}
impl String {
  // やはりStringの領域を使い回すメソッド
  fn into_bytes(self) -> Vec<u8>;
}
```
iOSの照度センサーを使って画面を暗くしたり明るくしたりする

iOSの照度センサーを使って、なにかできないか模索していたときのメモ

iPhoneのカメラ部分を触ると画面を暗くできる

```Swift
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // 近接監視が有効（true）か無効かを示すブール値
        UIDevice.current.isProximityMonitoringEnabled = true
        //照度センサーを監視
        NotificationCenter.default.addObserver(self,
                                               selector: Selector("proximityChanged"),
                                               name:UIDevice.proximityStateDidChangeNotification,
                                               object: nil)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    @objc func proximityChanged() {
        //状態を表示
        print("\(UIDevice.current.proximityState)")
    }
}

```
プログラミングとはなに？小学生に説明してみようと思う

## tl;dr

小学校からプログラミングを教えるそうで、2020年からは必修になるとのこと。

[文部科学省 小学校プログラミング教育の手引](http://www.mext.go.jp/a_menu/shotou/zyouhou/detail/1403162.htm)

わたしの職業がWebエンジニア(プログラマー)ということもあって、小学生の子どもから「プログラミングとはなにか？」と聞かれるのですが、うまい説明が見つからない…

ということでまとめてみました。


## プログラミングってなに？

プログラミングは英語で書くと「Programming」。
Program + ingということです。

現在進行形なので、無理やり訳すと「プログラムをしている状態」とか「プログラム作ること」となりますね。


## プログラムってなに？

 では「プログラム」ってなんなのか？

辞書で引いてみるとこんなふうに載っていました。

1. 物事の予定。行事の進行についての計画。
2. 映画・演劇・コンサートなどの演目や曲目，あらすじや解説などを書いた表や小冊子。
3. コンピューターに，情報処理を行うための動作手順を指定するもの。また，それを作成すること。
(三省堂 大辞林より)

もともとは「予定」とか「計画」の意味だったのものが、コンピューター用語に転用されてコンピューターに「動作手順」を指定するものになったということです。


## コンピューターの「動作手順」とは？

動作手順というのはなにかというと、コンピューターに対して

「どのように動くのか」

を命令(指示)するものです。


たとえば、コンピューターの画面にあいさつを表示させたいとすると


```ruby
puts "Hello World!!"
```

と書きます。

こうすると画面には

```
Hello World!!
```

と表示されます(ここに書いたのはRubyという言語(言葉)で書いていますが、他にもいろいろな言語があります)。

こういった命令を組みあせて、コンピューターに様々な動きをさせるのがプログラミングです。


## 終わりに


これで小学生の子どもに理解できるだろうか…？
ABC - 046- A&B&C

#AtCoder ABC 046 A&B&C
[AtCoder - 046](https://atcoder.jp/contests/abc046)

#A問題

 - 面倒だったのでMapで調べた。setでも良かった。

```java
	private void solveA() {

		Map<Integer, Integer> wk = IntStream.range(0, 3).collect(() -> new HashMap<Integer, Integer>(),
				(t, i) -> {
					t.merge(nextInt(), 1, (oldV, newV) -> oldV + newV);
				},
				(t, u) -> {
					t.putAll(u);
				});

		out.println(wk.size());
	}
```

#B問題

 - 次のボールにぬれる色は何か？
    - 最初のボールは$(K)$の中から選べる
    - 次のボールは$(K-1)$の中から選べる（選べる色は一色少ない）
    - その次のボールは$(K-1)$の中から選べる（選べる色は一色少ない）
    - 　以下、$(N-1)$まで同じ
        - 　$(N-1)$なのは、最初の1つは$(K)$の中から選んでいるので

 - $(K)*(K-1)^{N-1}$　通りの選び方がある

```java
	/*
	 * 10個 8色
	 *  8 7(8-1：隣の色を抜く) 7(8-1：隣の色を抜く)  7(8-1：隣の色を抜く) 7(8-1：隣の色を抜く) 7(8-1：隣の色を抜く) ・・・・
	 */
	private void solveB() {
		long numN = nextLong();
		long numK = nextLong();

		long res = (long) numK * (long) Math.pow(numK - 1, numN - 1);

		out.println(res);
	}
```

#C問題

|回数|比率A|比率B|票数A|票数B|合計|
|:-:|:-:|:-:|:-:|:-:|:-:|
|1|2|3|2|3|5|
|2|1|1|3|3|6|
|3|3|2|6|4|10|

 - 常に前の票数以上にならないといけない
 - 前の票数が $A:B$　であり、 次の比率が $x:y$ の場合 $A ≤ nx ∧ B ≤ ny $　を満たす $整数n$ を求める
 - $整数n=max(⌈A/x⌉, ⌈B/y⌉)$

```java
/*
	 * 床関数 x 以下の最大整数を表す
	 * 天井関数
	 */
	private void solveC() {
		int numN = nextInt();

		long[][] wk = IntStream.range(0, numN).collect(() -> new long[numN][2],
				(t, i) -> {
					t[i][0] = nextLong();
					t[i][1] = nextLong();
				}, (t, u) -> {
					Stream.concat(Arrays.stream(t), Arrays.stream(u));
				});

		/*
		 * 得票数を保持する配列
		 */
		long[][] memo = new long[numN][2];
		/*
		 * 最初の値はそのまま得票数
		 */
		memo[0][0] = wk[0][0];
		memo[0][1] = wk[0][1];
		chkC(wk, memo, 1);

		out.println(memo[numN - 1][0] + memo[numN - 1][1]);
	}

	private void chkC(long[][] wk, long[][] memo, int currentI) {

		if (currentI >= wk.length) {
			return;
		}

		/*
		 * 今回の比率
		 */
		long x = wk[currentI][0];
		long y = wk[currentI][1];

		/*
		 * 前回の得票数
		 */
		long a = memo[currentI - 1][0];
		long b = memo[currentI - 1][1];

		/*
		 * 前回の得票数A <= n * 今回の比率A
		 * 前回の得票数B <= n * 今回の比率B
		 * 上記を満たす最小のn（ただし整数）を求める
		 *
		 * 式としては下記
		 * 前回の得票数A / 今回の比率A <= n
		 * 前回の得票数B / 今回の比率B <= n
		 * 普通に割ると小数が出てしまうのでBigDecimalでRoundUpしている
		 */
		long p13 = new BigDecimal(a).divide(new BigDecimal(x), RoundingMode.UP).longValue();
		long p24 = new BigDecimal(b).divide(new BigDecimal(y), RoundingMode.UP).longValue();

		/*
		 * nを求める
		 * 小さい方のnだと片側の条件を満たさないため、大きい方
		 */
		long base = Math.max(p13, p24);

		/*
		 * nを求めたので今回の投票数が決まる
		 */
		memo[currentI][0] = base * x;
		memo[currentI][1] = base * y;

		chkC(wk, memo, currentI + 1);
	}
```
無料SSLサーバー証明書「Let's Encrypt」を使ってみる①

というわけで、Chrome等のブラウザが常時SSL化され、httpのサイトは「保護されてない通信」と警告が出るようになってます。

サイト管理者となると、そういった警告は嫌であるので、常時SSL化に対応してみたいと思います。

常時SSL化するにあたり証明書を取得するには、いままであれば有料の証明書しかなかったですが、2016年4月に無料で証明書を発行できる認証局ができました。

**それが「[Let's Encrypt](https://letsencrypt.org/)」であります。**

「Let's Encrypt」をVPSなりAWSのEC2で利用するには、「[certbot](https://certbot.eff.org/)」というプログラムを使うのが一般的ではあるようですが、使い勝手が非常に悪い（個人的見解です）ので、使い勝手の良い「[acme.sh](https://acme.sh)」というのを使ってみたいと思います。

今回は、EC2で「[acme.sh](https://acme.sh)」が利用できるまでを紹介したいと思います。

※EC2のインスタンスは「Amazon Linux」をベースにインスタンスが立ち上がっている状態で進めます。
※当然、apacheやnginx等のWEBサーバーを想定してます。

#### （１）githubからダウンロードするための準備
gitコマンドをインストールします。すでにインストール済みの時はスキップしてください。

```shell
# yum -y install git
```

#### （２）「acme.sh」をgithubからダウンロード

```shell
# git clone https://github.com/Neilpang/acme.sh
```

#### （３）環境設定をします。

「[acme.sh](https://acme.sh)」をインストールするのと同時に設定ファイルの保存ディレクトリや発行したSSL証明書を保存するディレクトリの設定をしています。
併せて、更新するためのcron設定もされます。

```shell
# cd acme.sh
# ./acme.sh --install --home ~/.acme.sh --config-home ~/.acme.sh/data --certhome /etc/httpd/certs
# source ~/.bashrc
```

#### （４）インストールできたか確認！
コマンドを実行するとバージョン情報が表示されます。

```shell
# acme.sh --version
```

以上で「[acme.sh](https://acme.sh)」を利用できる状態までの手順でした。

次は、実際に証明書を取得する手順をお伝えできればと思います。
bashで過去のコマンドを検索する方法3つ

# Motivation
gitとかdockerとかkubectlとか、引数やオプションがてんこ盛りのコマンドを使っていると、過去に実行したコマンドを検索して参照したくなる。

# 最も簡単な方法：reverse-i-search
ターミナルで`C-r`をタイプすると、過去のコマンドをインクリメンタル検索できる。検索は部分一致。`C-r`をタイプするたびに別な候補が表示される。このようにして順に表示した候補は、`C-s`で逆順に表示できる。ただし、`C-s`はスクリーンロックという機能にバインドされていることが多い（ターミナルが反応しなくなったように見えて焦る。`C-q`で解除できる）。以下のコマンドを実行してこの機能のバインドを解除しておく。

```bash
$ stty stop undef  # 毎回実行するのが面倒なので、.bashrcに書いておくとよい
```

検索したコマンドは、リターンキーでそのまま実行することもできるし、カーソルを移動して一部を編集することもできる。

# 複数の単語で絞り込む：history + grep
historyコマンドを実行することで、過去に実行したコマンドを一覧できる。これらのコマンドには番号が振られており、例えば番号42のコマンドなら、

```bash
$ !42
```

のように実行できる。実行するのではなく、入力された状態（リターンキーを押せば実行できる状態）にしたければ、コマンド末尾で`ESC C-e`をタイプする。

historyコマンドの結果は、もちろんgrepできる。

```bash
# 例：gccのバージョン切り替えってどうやってたっけ？
$ history | grep gcc | grep alternative
```

エイリアスにしておくと使いやすいのでは。

```bash
$ alias hg='history | grep $1'  # .bashrcに書いておく
$ hg gcc | grep alternative     # タイプ量が少なくなった
```

# 凝ってみる：peco
正直なところ、上記の2手段で十分だと思うが、オーバーエンジニアリングする。Emacsのhelmみたいに、`{検索ワード1} {検索ワード2} ...`と入力するたびインタラクティブに絞り込みしたい。

調べてみると、[peco](https://github.com/peco/peco)というインタラクティブなフィルタツール（コマンド？）を使うのが良さそう。[bash/zshのヒストリをpecoで便利にする](https://qiita.com/comuttun/items/f54e755f22508a6c7d78)を参考に導入してみる。

まずはpecoをインストールする。幸いbrewにformulaeがある。

```bash
$ brew install peco
```

ターミナルから使うための設定を.bashrcに書く。

```bash
peco_search_history() {
    local l=$(HISTTIMEFORMAT= history | \
                  sed -e 's/^[0-9\| ]\+//' -e 's/ \+$//' | \
                  sort | uniq | \
                  peco --query "$READLINE_LINE")
    READLINE_LINE="$l"
    READLINE_POINT=${#l}
}
bind -x '"\C-r": peco_search_history'
```

historyコマンドの結果に対し、sedで行頭の空白とコマンド番号を取り除く[^1]。また、行末の余分な空白も取り除いておく。その後、sortとuniqで重複したコマンドを取り除く（sedで行末の空白を取り除いておかないと、見た目が同じコマンドが空白の有無のせいで重複して残ってしまうことに注意）。この結果をpecoに受け渡す。

[^1]: historyコマンドではなく、単に`cat .bash_history`でもいいのかも。こうすればsedで行頭の不要部分を取り除く手間がいらない。

また、検索を`C-g`で中止するため、~/.peco/config.jsonを作成し、設定を書く：

```json
{
    "Keymap": {
        "C-g": "peco.Cancel"
    }
}
```

これで、`C-r`でhelmライクな過去コマンド検索ができるようになった。