OmniAICreator/Qiita-1.07M huggingface dataset:
Rのデータ分析に便利なパッケージ群 (随時更新予定)

Rを使った開発、データ分析の効率化に有用そうなパッケージのメモ。

# パッケージの紹介

## 1. データ加工

### tidyverse
データフレームやリストの読み込み、加工、可視化などを扱うインターフェース的なパッケージ。
中に{dplyr}や{purrr}などのパッケージが含まれている。
{tidyverse}を使うと、簡潔かつ再利用性の高いコードを記述できるようになる。

以下の記事に詳しい紹介あり。
[俺たちのtidyverseはこれからだ！](http://notchained.hatenablog.com/entry/tidyverse)

### simputation
様々な方法の欠損値補完を1行で実装できる。
パイプ処理を前提にしており、{tidyverse}との相性も抜群。
余談だが、欠損値補完にランダムフォレストなどの機械学習モデルを使う方法は最近知った。

以下の記事に詳しい紹介あり。
[【R言語】欠損値補完パッケージ「simputation」が使いやすそう、という話] (http://skroot3.hatenablog.com/entry/2018/02/11/212451)

## 2. 分析

### caret
Rにおける様々な機械学習パッケージを統一的に扱うインターフェース。
細かいことを考えなければ、引数のmethodを"glmnet"とか"nnet"とかやるだけでアルゴリズムを変えられる。
Pythonのscikit-learn的なポジションと言えそう。
似たようなもので{MLR}というパッケージもあるが、そちらは使ったことがないのでよくしらない。

### 時系列系
(ここに何かしら挙げたいのだが、最近扱っていないので何を載せるべきかわからない……)

## 3. レポーティング

### rmarkdown
Rのデータや図表を貼ったhtmlやPDFを自動で出力できる。
分析結果をまとめる際に、いちいちパワポやエクセルに貼り付ける作業をやりがちだが、なるべくそういう作業は減らしたい。
顧客への報告などの資料の細かい見栄えまでこだわる場面では良いが……
RStudioを使えば簡単に記述・出力できるし、目的変数を変えて大量に分析するといった場合は`knitr::render()`を`forreach`とかで回せば自動で一気にレポートを作成できる。
{rmdformats}を組み合わせると見栄えもグッと良くなるのでおすすめ。

### reporteRs
どうしてもパワーポイントじゃないとダメな場合にはこっち。
Rの32bitにしか対応していないのが難点。
基本的に{rmarkdown}でhtmlを出力するほうが好きなので、あんまり使ってない。

### DT
Javascriptを使ったインタラクティブなテーブルをhtmlに表示できる。
300種類の説明変数の係数一覧とか、100点以上のグリッドサーチの結果一覧とかを全部出しても人間には理解不能だが、20件ずつ表示とかにするとぐっと見やすくなる。
{rmarkdown}と組み合わせて使うとよい。

以下の記事に詳しい紹介あり。
[DTでインタラクティブな表作り](https://kazutan.github.io/SappoRoR5/DT_demo.html)

## 4. 処理全般

### foreach
for文を高速に実行できる。
`apply`ファミリーも高速だが、再利用する時に意外と困る。`foreach`の方が概ね再利用しやすいコードが書けるだろう。
{doParallel}と組み合わせることで、簡単に並列化できるようになる点もメリット。

以下の記事に詳しい紹介あり (どちらも筆者は同じ)。
[for を捨てよ、foreach を書こう](https://www.slideshare.net/hoxo_m/for-foreach)
[【超訳】foreach パッケージの使い方 #rstatsj](https://qiita.com/hoxo_m/items/04903cbbe9d023f0ed6d)

---

その他、随時追記予定。
Embulk (csv -> gzip圧縮してファイル出力へ)

## 概要
Embulkを使う機会があったので、使い方について忘れないようメモしておく。
「sample_01.csv」ファイルからcsvを取得し、gzip圧縮してへファイル出力するサンプルをやってみる。

## サンプルを用意する
```sh:ターミナル
$ embulk example ./try2
$ gzip -d ./try2/csv/sample_01.csv.gz
```

## 「embulk-output-command」を追加する

```sh:ターミナル
## プラグインの独立したバンドルを作成する
$ embulk mkbundle bundle

## gemファイルにプラグインを追記する
$ vi bundle/Gemfile
gem 'embulk-output-command' # 追記

## プラグイン追加
$ cd bundle
$ embulk bundle
$ cd ../
```

## config.yml作成 & 修正
```sh:ターミナル
$ embulk guess -b bundle seed.yml -o config.yml
$ vi config.yml
```

```yaml:config.yml
in:
  type: file
  path_prefix: ./csv/sample_
  parser:
    charset: UTF-8
    newline: LF
    type: csv
    delimiter: ','
    quote: '"'
    escape: '"'
    null_string: 'NULL'
    trim_if_not_quoted: false
    skip_header_lines: 1
    allow_extra_columns: false
    allow_optional_columns: false
    columns:
    - {name: id, type: long}
    - {name: account, type: long}
    - {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
    - {name: purchase, type: timestamp, format: '%Y%m%d'}
    - {name: comment, type: string}
out:
  type: command
  command: "cat - > task.$INDEX.$SEQID.csv.gz"
  encoders:
    - {type: gzip}
  formatter:
    type: csv
```

## プレビュー
```sh:ターミナル
$ embulk preview -b bundle config.yml
+---------+--------------+-------------------------+-------------------------+----------------------------+
| id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+---------+--------------+-------------------------+-------------------------+----------------------------+
|       1 |       32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC |                     embulk |
|       2 |       14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC |               embulk jruby |
|       3 |       27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin |
|       4 |       11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC |                            |
+---------+--------------+-------------------------+-------------------------+----------------------------+
```

## 実行
```sh:ターミナル
$ embulk run -b bundle config.yml
```

## 作成されたzipファイルを確認する
```sh:ターミナル
$ ls -la | grep task
-rw-r--r--. 1 500 500 189  2月 26 15:41 task.0.0.csv.gz
```

以上
Vagrant ちょいネタ


0 で始まる IPアドレスを割り当てるとエラーになる
------------------------------------------------------------

Vagrant で立ち上げる仮想マシンに IPアドレスを割り当てることができるが、IPアドレスの各ブロックが 0 から始るもの (例：192.168.33.07) を割り当てると `vagrant up` 時に以下のエラーが発生する。0から始まらないように変えることで解決できる

```
/opt/vagrant/embedded/lib/ruby/2.2.0/ipaddr.rb:530:in `block in in_addr': zero-filled number in IPv4 address is ambiguous (IPAddr::InvalidAddressError)
```


### 参考記事

* ["vagrant up" doesn't work in v1.8.1: `block in in_addr': zero-filled number in IPv4 address is ambiguous (IPAddr::InvalidAddressError) · Issue #6745 · mitchellh/vagrant](https://github.com/mitchellh/vagrant/issues/6745)


Vagrant のアップデートの手順 (or 再インストール)
------------------------------------------------------------

現在インストールされているVagrantのバージョンを確認 `vagrant version`
アップデート出てるならその旨のメッセージが出る
(`vagrant -v` はアップデートを確認してくれない)

一応、最新バージョンにバグなどの問題がないかググって確かめ、以下手順でアップデート

1. [Download Vagrant - Vagrant](https://www.vagrantup.com/downloads.html) から最新版をダウンロード
2. 今入っている Vagrant をアンインストール。ステップ1でダウンロードした仮想ディスク内の uninstall.tool を実行 
   ターミナルが開き、アンインストールするか？と聞いてくるので Yes.
3. Vagrant.pkg (インストーラー) をクリックし、インストール。インストール用の仮想ディスクをアンマウントし削除するか聞いてくるので Yes.
4. Vagrant で仮想サーバーを立ち上げ、正常に動作しているか確認
もし、エラー `Vagrant failed to initialize at a very early stage` が出たら、`vagrant plugin expunge --reinstall` でプラグインをインストールし直す


Vagrant box のアップデートの手順
------------------------------------------------------------

* まとめて `vagrant box update`
* 個別 `vagrant box update --box **/**`


仮想マシンの削除・作り直しの手順
------------------------------------------------------------

不要なものは消しておく

* Vagrant で仮想マシンを削除 `vagrant destroy` (シャットダウンもしてくれる)
  プロジェクトディレクトリ中のデータは削除されない
* VirtualBoxを起動し、消したい仮想マシンを右クリック、メニューから削除  
(= /Users/ユーザー名/VirtualBox VMs/仮想マシン名 が削除されるはず。残ってたら手動で削除)
  【※注意】Linked Clone を使っている場合は、元となる仮想サーバーを削除しないこと

root ユーザー で実行する
------------------------------------------------------------

ログインした時のユーザーは vagrant

初期状態だと `su` （パラーメータなしで root にユーザー切替え）が使えないのでパスワードを設定する  

root ユーザーにスイッチ
`sudo -s`  

パスワードを設定（今回は vagrant とする）
`passwd root`

次回から、`su` で root ユーザーに切り替えることができる
exit で  root から 元の vagrant に戻る

### 参考記事

* [sudo と su の違い | 比較して何が勝っているのかを理解する](http://tooljp.com/windows/chigai/html/Linux/sudo-su-chigai.html)
* [コマンドについて質問です。Linuxでsuコマンドとsudoコマンドがありますが... - Yahoo!知恵袋](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11109766576)



MAMP(Xampp) と Vagrant、どっちを使う？
------------------------------------------------------------

[MAMPでなくVagrantを使うメリット](https://www.webprofessional.jp/2016/08/1695/)は大きい

### MAMP(Xampp)

ウェブサーバー、PHP、MySQL が使える環境があれば良いという場合は MAMP(Xampp) 選択肢となり得る。黒い画面への抵抗が大きい人向け。ディスク使用容量は700MB程度。
MAMP もある程度カスタマイズできるようだが、後々のことを考えると Vagrant を使う方が結局楽じゃなかろうか。

### Vagrant

ローカルPC内に仮想マシンを構築。手元のパソコンがあたかも別のパソコンになる感じ。

CentOS 6.5 で1.8GB、新たな仮想マシンを立ち上げるごとに倍増するので、ディスク容量に注意 (Linked Clone を使えば [節約できる場合](https://qiita.com/oreo3@github/items/cbc99f92a4a62be79dde)もある)

任意の OS (Linux, Windows 他) をインストールしたり、サーバー設定をいじったり、プログラム言語やモジュールを追加したり自由にできる。初期化、スナップショット、バージョン管理(プラグイン)が容易にできるので失敗を恐れず色々できる。Boxで他の人と同じ環境をワンステップで構築できるメリットも

コマンド操作に抵抗がある人でも、[ドットインストール Vagrant入門](https://dotinstall.com/lessons/basic_vagrant) をひと通りやってみたら案外いけると思う人が多いんじゃないだろうか。
Postgres.app で新規DBを作成する


https://postgresapp.com/
↓こんなやつが目印

![Screen Shot 2018-02-26 at 15.52.52.png](https://qiita-image-store.s3.amazonaws.com/0/109241/e2bb227e-8e94-7a9d-0cd8-ba6fd4b6e5fa.png "Screen Shot 2018-02-26 at 15.52.52.png")

`template1` をダブルクリックしたら

![Screen Shot 2018-02-26 at 15.54.01.png](https://qiita-image-store.s3.amazonaws.com/0/109241/d8993728-3c2f-5e67-1aa3-7da5bafb3a5d.png "Screen Shot 2018-02-26 at 15.54.01.png")

ターミナルが開くので

![Screen Shot 2018-02-26 at 15.55.26.png](https://qiita-image-store.s3.amazonaws.com/0/109241/302278fa-0261-08f5-91c4-bf7e19b7ec60.png "Screen Shot 2018-02-26 at 15.55.26.png")

```
CREATE TABLE [テーブル名];
```
numpy についてのメモ

numpy についての個人的メモです。
わからなかったメソッドや変数を都度メモしていきます。

# shape
配列の大きさを調べる。
###shape
行列の大きさを調べる
###shape[0]
行列の行数を調べる
###shape[1]
行列の列数を調べる


# ones
指定されたshapeをもつ要素が１の配列を返す


#vstack
配列を縦に結合する

#hstack
配列を横に結合する

#linspace
指定した数字間の数字を生成する
###linspace(first, last, step)
first:最初の数字
last :最後の数字
step :firstからlastまで到達するまでの回数

# newaxis
numpyの配列に次元を追加する
Embulk (gzip -> 解凍:csv -> 標準出力へ)

## 概要
Embulkを使う機会があったので、使い方について忘れないようメモしておく。
「sample_01.csv.gz」ファイルからcsvを取得し、標準出力へ表示するサンプルをやってみる。

## サンプルを用意する
```sh:ターミナル
$ embulk example ./try1
```

## config.yml作成
```sh:ターミナル
$ cd ./try1
$ embulk guess seed.yml -o config.yml
```
```yaml:config.yml
in:
  type: file
  path_prefix: ./csv/sample_
  decoders:
  - {type: gzip}
  parser:
    charset: UTF-8
    newline: LF
    type: csv
    delimiter: ','
    quote: '"'
    escape: '"'
    null_string: 'NULL'
    trim_if_not_quoted: false
    skip_header_lines: 1
    allow_extra_columns: false
    allow_optional_columns: false
    columns:
    - {name: id, type: long}
    - {name: account, type: long}
    - {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
    - {name: purchase, type: timestamp, format: '%Y%m%d'}
    - {name: comment, type: string}
out: {type: stdout}
```

## プレビュー

```sh:ターミナル
$ embulk preview config.yml
+---------+--------------+-------------------------+-------------------------+----------------------------+
| id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+---------+--------------+-------------------------+-------------------------+----------------------------+
|       1 |       32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC |                     embulk |
|       2 |       14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC |               embulk jruby |
|       3 |       27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin |
|       4 |       11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC |                            |
+---------+--------------+-------------------------+-------------------------+----------------------------+
```

## 実行

```sh:ターミナル
$ embulk run config.yml

1,32864,2015-01-27 19:23:49,20150127,embulk
2,14824,2015-01-27 19:01:23,20150127,embulk jruby
3,27559,2015-01-28 02:20:02,20150128,Embulk "csv" parser plugin
4,11270,2015-01-29 11:54:36,20150129,
```

以上
R Studioでデータ解析入門

R Studioを使ってデータ解析の練習をしてみます。

#1. R Studioをインストール
- 下記[Rによるデータ解析入門](https://www.biwako.shiga-u.ac.jp/sensei/kumazawa/R/c2.pdf)資料の付録C.に詳しい手順が載っています
- 通常通りダウンロードしてきて解凍→インストールすれば稼働します

<img width="1680" alt="スクリーンショット 2018-02-26 16.35.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/125842/81e77828-24d2-7e04-4866-e83883b82124.png">



#2. R Studioを使ってみる
- plot(iris)
- iris2<-iris[51:150, 3:5]
- svm<-ksvm(Species ~., data=iris2)
- plot(svm, data=iris2[,1:2])

<img width="760" alt="スクリーンショット 2018-02-26 16.32.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/125842/90a7067d-d22d-8bdb-37cd-0570dec70d85.png">

- 下記[R言語で始めよう、データサイエンス（ハンズオン勉強会） 〜機会学習・データビジュアライゼーション事始め〜](https://www.slideshare.net/yasuyukisugai/r-28544592?from_action=save)に良い説明が載っています


#3. データ解析入門
- tbfi

#4. 機械学習入門
- 回帰
    - (一般化)線形回帰
    - ロジスティック回帰
    - サポートベクターマシーン(SVM)
- 木
    - 決定木
    - ランダムフォレスト 

# 参考情報
1. [Rによるデータ解析入門](https://www.biwako.shiga-u.ac.jp/sensei/kumazawa/R/c2.pdf)
- [R言語で始めよう、データサイエンス（ハンズオン勉強会） 〜機会学習・データビジュアライゼーション事始め〜](https://www.slideshare.net/yasuyukisugai/r-28544592?from_action=save)
- [はじめての「R」](https://www.slideshare.net/m884/japan-r-15432969?from_action=save)
- [R言語入門](https://to-kei.net/r-beginner/)
- [ドットインストール - R言語入門](https://dotinstall.com/lessons/basic_r)
- [初心者のためのRとRStudio入門 vol.2](https://www.slideshare.net/owllearnbiz/rrstudio-vol2)
- [R-Tips](http://cse.naro.affrc.go.jp/takezawa/r-tips/r.html)
- [初心者用 R言語講座](http://chianti.ucsd.edu/~rsaito/ENTRY1/WEB_RS3/PDF/JPN/Texts/R_Stats2.pdf)
GitHubGistに書いたPHPのコードをわかりやすくしたい!! シンタックスハイライトさせる方法!!

##はじめに
インターン先でプログラミング勉強中の文系学生。

ある日のこと
「わからないところがあるんで、ちょっとコード見てもらえますか?」
「はいはい。…って、コード汚ねぇ」

はい、わかりやすくします!!

##現状
GitHubGistでPHPのコードをシェアしたら、汚いと言われた。
自分でも見てみると、全部の文字が黒い。

こりゃあ我ながら汚ねぇ。

見るからにシンタックスハイライトができていない。
何か特別な処理が必要なのかな?

##解決策
とりあえず調べてみるか。
「GistHub 文字色」で検索したところ、[GitHub Gistを使うとブログにコードを簡単、綺麗に表示できる【プラグインやライブラリ不要】](https://uranaka-shobou.com/github-gist/#i-8)というサイトを見つけた。

このサイトによると、`ピリオド+拡張子`のファイル名にしないと、シンタックスハイライトが表示されないみたい。

でも、ちゃんとファイル名には`～.php`って入れたんだけどな…?


ちょっと下の情報も見てみるか。

><?php?>間のコードでシンタックスハイライトがされないことがある

…あ
`<?php?>`入れてないや!!

一番最初の宣言?って必要なのね。
「ファイル名にphpってあるから良いよね」って書いてなかった…

次からちゃんと書きます。

##まとめ
GistHubGistでphpのコードをシンタックスハイライトさせるなら、`<?php?>`が必須!!
基礎こそ大切に取り組んでいこう!!
Vagrant の Linked Clone について


同じBoxで複数の仮想マシンを立ち上げる場合は Linked Clone は有効に、1台しか立ち上げない場合は無効にすると効率的

メモ
------------------------------------------------------------

* 設定：site.yml の `linked_clone: ` の値を true/false で切替え

Linked Clone とは
------------------------------------------------------------

> BoxごとにマスターVMを持つことになるので、BoxのクローンVMを初めて起動するときにマスターVMの作成が自動で行われます。そのため、初回はLinked CloneなしのVM作成の時間とほとんど変わりません。
> Linked Cloneはデータセンター仮想化製品ではメジャーな、一つのマスターVMを元にして複数のクローンVMを作り出す機能です。普通にVMをコピーするのではなく、クローンVMはマスターVMの差分データのみを持つことから'Linked'という冠が付いています。VMの初回作成(vagrant up)時の時間が短縮されるのと、仮想ディスクのサイズが差分のみで済むメリットがあります。
参照元：[Linked CloneとSnapshotを試してみた ｜ Developers.IO](http://dev.classmethod.jp/tool/vagrant-linked-clone/)


Linked Clone 有効/無効 で容量を比較
------------------------------------------------------------

VCCWデフォルト設定での例

### Linked Clone 無効の場合

VirtualBox VMs/ に生成される容量が約2GBもあるディスクイメージが、仮想マシンを立ち上げるごとに作成される

* 1台目：2GB
* 2台目：2GB (累計4GB)
* 2台目：2GB (累計6GB)
* 2台目：2GB (累計8GB)

### Linked Clone 有効の場合

増えるのはマスターとの差分のみなので、かなりのディスク使用量が節約できる。
サーバーの構成要素のアップデート等を行った際、マスターをアップデートすれば全ての仮想マシンに反映されるのも効率的

* 1台目：2GB (マスター) + 300MB
* 2台目：300MB (累計2.3GB)
* 2台目：300MB (累計2.6GB)
* 2台目：300MB (累計2.9GB)


Linked Clone 有効/無効 でファイル構成を比較
------------------------------------------------------------

仮想マシンイメージの保存場所は、
`ユーザーディレクトリ/VirtualBox VMs/projectname1.localhost/`
(サンプルでは、仮想マシン名を "projectname1.localhost" とした)

### Linked Clone 無効の場合

```
projectname1.dev
  |- box-disk1.vmdk
  |- kunai.dev.vbox
  |- kunai.dev.vbox-prev
  |- Logs
```

### Linked Clone 有効の場合

```
vccw-xenial64_default_1477168387480_42113_1480041556524_84136
  |- box-disk1.vmdk
  |- vccw-xenial64_default_1477168387480_42113_1480041556524_84136.vbox
  |- vccw-xenial64_default_1477168387480_42113_1480041556524_84136.vbox-prev
  |- Snapshots
        |- {2e99947e-b229-48f2-a5ea-acbdc32db2d8}.vmdk
```

```
projectname1.dev
  |- projectname1.dev.vbox
  |- projectname1.dev.vbox-prev
  |- Snapshots
  |     |- {3fcb178a-79a8-417c-990a-d8d392b6dad1}.vmdk
  |- Logs
```

## 注意

Vagrantで Linked Clone を有効にして構築している仮想マシンを全て削除(destroy)しても、マスターは削除されずに残る。以降使う予定がなければ容量を食うだけのゴミになるので、Virtualbox で削除する。~/VirtualBox VMs/ 内の該当ディレクトリも消えてるか確認すること
jstatを使用したJavaアプリのメモリ計測

## Javaの使用メモリサイズの調査
Javaアプリで実際に使用しているメモリは、topコマンドでは取得不可能です。**topコマンドを実行しても、JVMが全体で確保しているメモリのサイズがわかるだけです。**
今回は、jstatツールを使用して、Javaの実際に使用しているメモリのサイズの大まかな値を確認する方法を説明します。本方法を使うことで、アプリの改修無しに、処理にあまり影響を与えず、大まかな使用メモリ量を見ることができます。

## jstatの準備
[jstat](https://docs.oracle.com/javase/jp/8/docs/technotes/tools/windows/jstat.html)はJava仮想マシンの統計データの監視ツールです。JDKに含まれているため、JDKをインストールすれば同時にインストールされ使用可能な状態となります。ただし、公式のドキュメントによると試験的な機能とのことなので、今後のvrersionでなくなる可能性があることに注意してください。


## 解析用プログラム
適当な処理のサンプルアプリを動かします。Javaの起動時に以下のオプションをつけ、ヒープメモリの最大、最少サイズはどちらも20GBに指定しています。
``` -Xms20G -Xmx20G ```
開始から終了まで約3000秒かかるバッチ処理を行うアプリです。
プログラムの詳細については割愛します。

## jstatの実行
サンプルアプリを起動したら、jpsコマンドでアプリのプロセスIDを確認します。

```
$ jps
29366 Jps
31781 sampleApp
```

sampleAppのプロセスIDは31781です。jstatコマンドを実行し、その結果をファイルに書き出したいと思います。以下のコマンドを実行します。

```
$ jstat -gcutil -t 31781 1000 > jstat.tsv
```

今回、1秒毎に、GCの統計情報とアプリ起動からのタイムスタンプを一緒に表示するようにしています。"jstate.tsv"という名前のファイルとして出力しています。
jstatコマンドのオプションに関しては、公式ページを参照していただきたいです。


## jstatコマンドの出力
jstatコマンドの出力は以下のようになりました。

```
Timestamp         S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
39.8              0.00   0.00  38.00   0.00  17.13  19.75      0    0.000     0    0.000    0.000
40.8              0.00   0.00  44.00   0.00  17.13  19.75      0    0.000     0    0.000    0.000

             ～～中略～～

3019.0            63.30  74.99 100.00  53.52  96.26  86.35    753  414.206    25  581.636  995.842
3020.0            78.67  74.99 100.00  53.52  96.26  86.35    753  414.206    25  581.636  995.842
```

## 使用メモリサイズの解析
jstatコマンドの出力から、実際に使用しているメモリの調査を行っていきます。
**使用しているメモリの大まかな推移を調査するには、jstatの出力の"O"(Old領域メモリ割り当て率 = 使用率)の項目だけに注目すれば大丈夫です。**

"Timestamp"の数値を横軸、"O"の数値を縦軸にしたグラフが以下になります。  


![old領域割り当て率のグラフ](https://i.imgur.com/okIZO5d.png)

このグラフから、メモリの使用量を読み取ることが可能です。ただ、一見しただけではメモリの割り当て率が50% ~ 100%の間で激しく推移していて良くわかりません。
**Old領域には、そのタイミングで実際に使われているデータと、もう使われていないデータが混在しているため、その中から使われているデータの量だけを見つける必要があります。**
上のグラフにFull GCの実行タイミングを青の破線で重畳させたのが以下のグラフとなります。


![old領域割り当て率のグラフ(FGC実行明示)](https://i.imgur.com/7yHWka9.png)

Full GCが起こった後にメモリの使用量が低下していることがわかると思います。**このFull GC直後のメモリが低下したタイミングのメモリ割り当て率のみを見ることで、アプリの実際のメモリ使用量がわかります。**
下の図では、低下したタイミングの値を赤の実線で結んでいます。そして、この値がおおよその実使用メモリの推移となります。

![old領域割り当て率のグラフ(ヒープメモリ概要)](https://i.imgur.com/54NGSRX.png)

上のグラフを確認することで、以下のようなことがわかるかと思います。

 - アプリ起動後の2900秒付近(アプリの終了間際)で、メモリの使用量が最大になる。
 - メモリの使用量最大のタイミングで使用割合は85%程度。メモリの使用量は 20GB * 0.85 = 17GB程度。

加えて、アプリのログと照らし合わせることで、各処理での大体のメモリ使用量を確認することが可能です。

## 本方法の簡易説明
なぜ、Old領域のFullGC後のサイズを見るだけで、メモリの使用量がわかるのでしょうか？
理解するにはJVMのメモリ管理の仕組みを知る必要がありますが、以下非常に単純化したものを順に説明します。

1. Javaのアプリケーションでは、ある程度の期間メモリに残っているデータは、全てメモリのOld領域に保存される。
2. Old領域がいっぱい(90%以上程度)になったら、Full GCが走り、Old領域のデータを全て精査、使用されていないデータがあったらメモリを解放し、使われているデータのみをOld領域に残す。
3. FullGC直後のOld領域のデータ量を見ることで、解放のできない（アプリで実際に使用中の）メモリ量を知ることができる。


## まとめ
jstatコマンドを使用したJavaアプリのメモリ使用量の確認方法をまとめました。
この方法でざっくりと処理毎のメモリの使用量を確認し、その後、特にメモリを使用している処理において、各オブジェクトのメモリ使用量を調査していく流れが良いかと思います。
俺のプロキシ設定メモ

# はじめに
社内や学内ネットワークの場合はセキュリティの都合上、プロキシ配下の環境の場合が多い。その場合はプロキシの設定が必要である。
今までやってきた設定を備忘録としてまとめておく。
ここにまとめる方法や唯一解ではなく、自分の場合はこれでうまくいったというものです。

# wget
```
# vi /etc/wgetrc
http_proxy=http://<proxy_ip>:<proxy_port>/
https_proxy=http://<proxy_ip>:<proxy_port>/
```

# curl
```
$ vi ~/.curlrc
proxy = "http://<proxy_ip>:<proxy_port>/"
```

# yum
```
# vi /etc/yum.conf
proxy=http://<proxy_ip>:<proxy_port>/
```

# rpm
```
# rpm --httpproxy <proxy_ip> --httpport <proxy_port> -Uvh <package>
```

# apt
```
# vi /etc/apt/apt.conf
Acquire::ftp::proxy "ftp://<proxy_ip>:<proxy_port>/";
Acquire::http::proxy "http://<proxy_ip>:<proxy_port>/";
Acquire::https::proxy "http://<proxy_ip>:<proxy_port>/";
```

# add-apt-repository
```
# http_proxy=http://<proxy_ip>:<proxy_port>  https_proxy=http://<proxy_ip>:<proxy_port> add-apt-repository  ppa:<repository>
```

# pip
```
# pip install <package> --proxy=<proxy_ip>:<proxy_port>
```

# gem
```
# gem install <package> -r -p http://<proxy_ip>:<proxy_port>
```

# td-agent-gem
```
# td-agent-gem install <package> -p http://<proxy_ip>:<proxy_port>/
```

# go
環境変数による設定で解決しました。

# git
```
$ git config --global http.proxy http:/<proxy_ip>:<proxy_port>
$ git config --global https.proxy http://<proxy_ip>:<proxy_port>
```

# gradle
```
$ vi ~/.gradle/gradle.properties
systemProp.http.proxyHost=<proxy_ip>
systemProp.http.proxyPort=<proxy_port>
systemProp.https.proxyHost=<proxy_ip>
systemProp.https.proxyPort=<proxy_port>
```

# docker(Ubuntu16.04, docker 18.06.0-ce)
```
$ sudo mkdir -p /etc/systemd/system/docker.service.d
$ sudo vi /etc/systemd/system/docker.service.d/http_proxy.conf
[Service]
Environment="HTTP_PROXY=http://<your_proxy_ip>:<your_proxy_port>/"
$ sudo vi /etc/systemd/system/docker.service.d/https_proxy.conf
[Service]
Environment="HTTPS_PROXY=http://<your_proxy_ip>:<your_proxy_port>/"
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
```

# 環境変数による設定
```
# 設定
$ export http_proxy="http://<proxy_ip>:<proxy_port>/"
$ export https_proxy="http://<proxy_ip>:<proxy_port>/"
# 解除
$ unset http_proxy
$ unset https_proxy
```
#Quantopian Algorithm で order

## order

order 関数は，株数を指定する注文関数です．銘柄と株数を指定すれば，成り行き注文が入ります．（成り行き以外は`style`で指定）

`order(asset, amount, style=OrderType)`
>asset: Equity/Future オブジェクト
amount: 株数
style: 注文方法（指定方法は[order](https://www.quantopian.com/help#api-order "order")を参照）

## アルゴリズム例

例は，
株価が急騰した時Longするという単純なアルゴリズムを書いてみたいと思います．
**急騰**＝過去5日の株価平均よりも現在価格が１％以上高いという定義にします．
ポジションを持ったあと，現在価格が平均価格より低くなった場合はポジションを閉じます．

今回は，1銘柄（アップル）だけを見ます．
元ネタは[Basic Algorithm](https://www.quantopian.com/help#sample-basic "Basic Algorithm")です．

```python
def initialize(context):
    # AAPL
    context.security = sid(24)

    # rebalance 関数を毎日クローズ一分前（15：59）に実行するように指定
    schedule_function(rebalance, 
                      date_rule=date_rules.every_day(),
                      time_rule=time_rules.market_close(minutes = 1))

def rebalance(context, data):
    # 過去5日間の平均を取得して，今日の価格よりも１％大きければLong
    # 今日価格が移動平均より小さければ，ポジションクローズする

    # 過去5日間のヒストリカルデータを取得．
    # 【注意】https://www.quantopian.com/help#ide-history に説明があるとおり，
    # 日中にヒストリカルデータを複数日分取得すると，
    # 「過去4日分と今現在の価格」が取得できます．現在価格はhistorical data 同様，アジャストされた価格です．
    price_history = data.history(
        context.security,
        fields='price',
        bar_count=5,
        frequency='1d'
    )
    # price_historyを出力
    # log.info(price_history)

    # 平均値
    average_price = price_history.mean()
        
    # 現在の価格
    current_price = data.current(context.security, 'price') 
    # log.info(current_price)
    
    # 注文しようとしている銘柄が，現在上場されているか確認
    if data.can_trade(context.security):
        # 平均値より，１％大きければ，Long
        if current_price > (1.01 * average_price):
            # 成り行きで10株買う
            order(context.security, 10)
            log.info("Buying %s" % (context.security.symbol))
        # 平均値より小さければ，ポジションをクローズ    
        elif current_price < average_price:
            # 0と注文することでポジションを精算することになる
            order_target(context.security, 0)
            log.info("Selling %s" % (context.security.symbol))
    
    # 平均値と現在価格を描画
    record(current_price=current_price, average_price=average_price)
```

## メモ

`rebalance` 関数は毎日取引終了1分前に実行されるようにスケジュールしています．よって，条件に会えば毎日でも10株買い足して行くというアルゴリズムになります．

## 次はこれ

気が向いた時に，アルゴリズムの注文方法を少しずつ書いていこうと思います．

次回は，`order_value` です．

## 他のオーダー方法

[#Quantopian Algorithm で order_value - Qiita](https://qiita.com/shinseitaro/items/16f0f12ad65f428c2f4b "#Quantopian Algorithm で order_value - Qiita")
[#Quantopian Algorithm で order_percent - Qiita](https://qiita.com/shinseitaro/items/943cfafe00dd3841a79e "#Quantopian Algorithm で order_percent - Qiita")
[#Quantopian Algorithm で order_target](https://qiita.com/shinseitaro/items/f1ea0245bba1e7ccc82d "#Quantopian Algorithm で order_target - Qiita")
[#Quantopian Algorithm で order_target_value](https://qiita.com/shinseitaro/items/7f9b45ab6fd5149e7a1e "#Quantopian Algorithm で order_target_value - Qiita")
PyCharm on Windows 設定メモ

# 目的

Python3 で開発するのだけど、Windows でコマンドラインアプリを作りたい。

# 次のことは書かない

0. Python 3 のインストール方法
1. PyCharm のインストール方法

# Ubuntu On Windows のインストール

1. コントロールパネル - プログラム - プログラムと機能 - Windows の機能の有効化または無効化 から
「Windows subsystem for Linux」を有効化する。
2. Windows の再起動(半強制)。
3. アプリストアから Ubuntu を選択する。

# PyCharm の Terminal で bash を起動後の venv の有効化

PyCharm では、プロジェクト作成時に venv が作成される。
PyCharm で Teminal を開く。
`$ source ./venv/Scripts/activate`

# library の追加

pip でやってもいいけど PyCharm でやるのが楽しそう。
File - Settings - Project - Project Interpreter から追加する。

# Python3 の実行

[このGist](https://gist.github.com/Qooh0/3bfb0ee1a20f90d227f686682c1d4aaa) をコピペして動けば OK
`venv/Scripts/python.exe app.py`

# 次回予告

ライブラリ共有部分は、ほかの人と開発するときはどうするんですかね？
依存ライブラリリストを作成して、適当に他の人のところでコマンドを実行すると再作成してくれるといいな。
ありそうだけど。
今 Conda は、ハマっている人が多いみたいなので近づきたくないなぁ...
PHPプロファイルを解析してDBを含めて影響調査を簡単に行う（Cytoscape）

#やりたいことは、特定のソース、テーブルを修正したら、どこをテストしたり影響を考慮したらよいのか？

一発で「ココガ影響シマス」ってだしてくれたら幸せ

#データも含めてコールグラフがみたい
- メソッドを修正したときに何処に影響するのかサクサクしらべて、ポイントを明確にしたら便利
- 既存のプロファイル解析ツールにはXHProf、KCacheGrind、WinCacheGrindなどがあるが・・・コードに仕掛けをしたり、プロファイル毎にしか解析できない。もしかしたら他に方法があるのかもしれないが見つからなかった
- プロファイルの重ね合わせができない！重ね合わせてみたい
- 既存のツールでは解析がプロファイル単位なのでファイル名がどのイベントなのか管理しなければならない
- grepつかって調査して・・・なんて面倒なことから解放されたい

# いろいろやってみた結果

こんなことができるようになったよ

![item_call.PNG](https://qiita-image-store.s3.amazonaws.com/0/185049/9506fb9b-e91b-4a8d-4eb2-38649f6af646.png)
↑画像はitemテーブルをコールするメソッドを表示したもの。
ここまではgrepで似たようなことはできる
画像のメソッド名は隠ぺいのためにコード[12c3]にしてますが実際はgetXXXXitemXXXのような感じです。

![item_call_up.PNG](https://qiita-image-store.s3.amazonaws.com/0/185049/97ce71f6-38b4-c07c-4744-273197a06851.png)
↑さらにメソッドを上がった画像
これをgrepでやるのはつらい。
IDEでもできない。
画像のメソッド名は隠ぺいのためにコード[12c3]にしてますが実際はgetXXXXitemXXXのような感じです。
色分けはクラスのネームスペースや種類で適当に分けている。
赤色はイベント発生を示す色で、ITEMテーブルに影響している
イベントは４つあることが分かる

#以下やったこと

##前提
- PHP 5.5（古い）他のバージョンで同じことができるかわからない
- 自動テストでカバレッジを高くしておかないとそもそもプロファイルが取れない

##プロファイルを理解して解析する
- xdebugのバージョンによってフォーマットがことなるので注意です。
- xdebugとフォーマットのバージョンが記入されていて、定義＞コール＞定義＞コールが規則的に書かれている（多いときは１Gバイトくらいになる）。
- 解析したデータはMYSQLに保存することで、いくつものファイルを重ね合わせて保管。一度取り込んでしまえば・・・その後はプロファイルが不要になる。

##テーブル（データベース）もコールグラフに含めたい
- メソッド＞テーブルの関係を求めたら便利そう。
- SQLの解析をおこないテーブルを持ってくる必要があるので、PDOに出力しているSQLを自作のプロファイルに記録する。
- PDOそのものを使っている場合はとても面倒くさいが、ラッパー関数をつかっている場合は数行追加するだけ。
- SQLのプロファイルは解析して関係をMYSQLへ保存する。SQL解析器はたくさんあるので適当に動くものをチョイスすればいい。

##MYSQLから検索するツールを作る
以下のようにnode（メソッド、テーブル）を検索するツールを考えた。
- メソッド名、クラス名、文字の一部、ネームスペースで検索して影響元を求める
- 影響元をコールしている要素を再帰的に求めていく＞これでテスト対象が網羅
- 影響元がコールしている要素を再帰的に求めていく＞これで影響先が網羅
影響調査が一発で漏れなくできるし、必要な情報しかでてこないので余計なコールグラフを見る必要がなくなる。事前解析してMYSQLにデータが保存してあるのでサクサクに動くはず。

##検索した結果をみる
- 結果を効果的に見る方法がなかなかない
- 検索結果をテキストでみてもイマイチピンとこないので、dot語にかいてグラフ化してみたが、残念な感じ
- Cytoscapeに読ませてみたらいい感じだったので、Cytoscapeメインで使えるように改良
- RESTIFが使えるので連携して、検索＞表示まで操作を省略できた
- Cytoscapeがいろんな表現ができるので物によって表現を変えて見やすくすることができるが、ほとんど自己満足の世界。
- ３Dで表現してみたがイマイチなので諦めた

#サンプル
![oome.PNG](https://qiita-image-store.s3.amazonaws.com/0/185049/193e0f89-ae4a-4438-46f6-43355b64da60.png)
オーガニックな配置
赤色がイベントで、緑がテーブル、黄色がビジネスロジック、紫？がデータアクセス

![kaisou.PNG](https://qiita-image-store.s3.amazonaws.com/0/185049/3d087b34-eeec-f503-ccb6-1e05c15ce4dc.png)
階層構造配置

# 感想
**だいまんぞく**
RubyでGraph APIのNotificationを使ってFacebookに通知を送る方法（なるべく分かりやすく）

# まずはじめに

とあるサービスで「Facebookでユーザーに通知を送りたいね。」となりました。

↓みたいなやつです。
![Facebookのサンプル画像](https://scontent-nrt1-1.xx.fbcdn.net/v/t39.2178-6/12057061_533833823448604_2011025726_n.png?oh=0b5c29e23bc4f53031b1cbb9c0134c5d&oe=5B105541)

これはFacebookからの通知ではなく、Facebookユーザーがアカウント連携しているwebサービスから送信可能な通知です。
しかも特別な権限をユーザーに求める必要はありません。最低限の権限で通知を送れます。
確かに、あのFacebookに自社から通知を送れるとなるとリテンションがかなり上がりそうです。

ネットを検索すると少ないながら、その方法をソースコードとともに紹介していただいているブログなどがありますが、API慣れしていないひよっこエンジニアである私はかなりハマってしまったので、改めて紹介しようと思います。

## 注意点

現在NotificationのAPIでは、**web版のみ**にしか通知を送れません。
スマホアプリには送られない、ということです。

# 環境

言語： Ruby 2.3.1
Facebook API 2.5

今回はgemなどは使わずに、純粋なPOSTだけでおこないます。
また、事前にFacebookのAPIを利用したログイン認証のシステムが出来ている前提になります。

# コード


app_access_tokenやuser_idはダミーです。
見ての通り、適切なURLにPOSTすれば通知が送れる簡単仕様です。

```ruby
require 'net/https'

app_access_token = '1234567890123456 |fd987654ab1234d8e1b81491d7654321'

user_id = '123456789012345'

uri = URI.parse("https://graph.facebook.com/v2.5/#{user_id}/notifications?access_token=#{app_access_token}&href=/&template=hello,world!")

http = Net::HTTP.new(uri.host, uri.port)

http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

req = Net::HTTP::Post.new(uri.request_uri)

p req #確認用

res = http.request(req)

p res.body #確認用
```

# 結果

これによって送られるのが、以下のような通知

<img width="436" alt="スクリーンショット 2018-02-26 14.11.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/98204/413f6306-f7ea-a6c3-1347-b57175ee69b3.png">

# 解説

## app_access_token

まずハマったのが`app_access_token`でした。
GraphAPIを深く読み込まずに情報をあさり続けてると、どれが正解か分からなくなってしまいました。
というのもGraphAPIには「アクセストークン」と名のつくトークンが多いです。。。

- ユーザーアクセストークン
- アプリアクセストークン
- ページアクセストークン

などなど。混乱してしまいました・・・。

### 正解

```
app_access_token=アプリID|app secret
```

https://developers.facebook.com にアクセスして自分のアプリのダッシュボードを開きます。
「設定」>「ベーシック」の`アプリID`これが`|`の左側になります。

「設定」>「ベーシック」にある、`app secret`が`|`の右側になります。

↓のアプリIDとapp secretです。

<img width="1223" alt="スクリーンショット 2018-02-26 14.26.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/98204/573dc056-d409-2aa3-4f26-091e998943fd.png">


## user_id

これはユーザーが自社サービスにログインした時に取得できます。
ユーザーとアプリごとに固有で、一度認証したらずっと固定です。DBに保存するとよいです。

Koalaというgemを利用して、fabebookログインを実装している場合、`uid`というkeyでresponseが返ってきてる思います。
雑ですが他のライブラリでも、Facebookログイン時のresponseでその他のユーザー情報と共に15桁の数列が返ってきてる場合は、それだと思います。

これがuser_idになります。

## href

通知をクリックした時に表示したいページの相対パスになります。
例えば、`https://qiita.com/trend`を表示したい場合は`href=/trend`と書きます。

## template

通知に表示するメッセージ文言です。なんでもいいですが、長すぎるとカットされます。

# 最後に

拙い文章になりましたが、お読みいただきありがとうございます。
アクセストークンやユーザーIDなどをPOSTするだけで通知を送れるのは便利ですね。

体感だとあまり利用しているサービスは多くない気がします。個人的にはWantedlyをよく見かけます。

便利ですが、送りすぎはよくないです。

>リファレンスをよく読み、用法用量を守ってPOSTしましょう。

## 参考

[railsからfacebookにnotification APIで通知を送る](http://kansiho.hatenablog.com/entry/2017/02/01/rails%E3%81%8B%E3%82%89facebook%E3%81%ABnotification_API%E3%81%A7%E9%80%9A%E7%9F%A5%E3%82%92%E9%80%81%E3%82%8B)
xamppでwordpressインストールしたら、ログインできなかった事件を解決！

# xamppでWordpressをインストールします

こちらのリンクを参考に、xamppからWordpressをインストールしました。
(xamppはインストールしている前提です)
http://xn--web-oi9du9bc8tgu2a.com/xampp-wordpress-install/

# ログインできねぇぇぇ！！なんで！

さっき設定した名前とパスワードを入力しているのに、ログインできない！なぜ！
しかも、パスワード再発行しようと思って、メールアドレスを入力して送信しても、メールが来ない。
どういうこっちゃ・・・

#解決策はコレだ！
解決策はこのリンクに書いてありました。
http://anque-mix.com/wordpress-2/1351.html

神です。ありがとうございました。
WRF > WPS > ./metgrid.exe > ERROR: Couldn't open file ./geo_em.d01.nc for input.

```txt:動作環境
CentOS 6.8 (64bit)
on VMWare workstation
for WRF3.9, WPS3.9
  Open MPI v2.1.1
  gcc version 4.9.2 (とgfortran; devtoolset-3使用)
　NetCDF v4.4.1.1, NetCDF (Fortran API) v4.4.4
WRF3.9
WPS3.9
NCL v6.3.0 (ncl_ncarg-6.3.0.Linux_RHEL6.4_x86_64_gcc447.tar.gz)
```

WRF(Weather Research and Forecasting Model)とその前処理であるWPS。

### metgrid.exe実行時エラー

./metgrid.exeを実行しようとすると以下のエラーとなる。

```
Processing domain 1 of 3
ERROR: Couldn't open file ./geo_em.d01.nc for input.
--------------------------------------------------------------------------
MPI_ABORT was invoked on rank 0 in communicator MPI_COMM_WORLD
with errorcode 0.

NOTE: invoking MPI_ABORT causes Open MPI to kill all MPI processes.
You may or may not see output from other processes, depending on
exactly when Open MPI kills them.
--------------------------------------------------------------------------
```

### geo_em.d01.nc

geo_em.d01.ncは何かというと、geogrid.exeにより生成されるファイルだった。

http://www.lowtem.hokudai.ac.jp/multi-sphere/cloud/kawasima/WRF/wrf_3.5.1.html
> *地形データの処理
[maro@shear7 WPS_20150910_FNL]$ ./geogrid.exe
[maro@shear7 WPS_20150910_FNL]$ ls -l 
geo_em.d01.nc ... ができていることを確認. 

### geogrid.exe実行時エラー

```
$ ./geogrid.exe 
Parsed 25 entries in GEOGRID.TBL
Processing domain 1 of 3
ERROR: Could not open /home/y_okada/WPS/GEOG_DATA/topo_gmted2010_30s/index
--------------------------------------------------------------------------
MPI_ABORT was invoked on rank 0 in communicator MPI_COMM_WORLD
with errorcode 0.

NOTE: invoking MPI_ABORT causes Open MPI to kill all MPI processes.
You may or may not see output from other processes, depending on
exactly when Open MPI kills them.
--------------------------------------------------------------------------
```

- symbolic linkの間違いが見つかった
- ユーザ名変更していることに気づいた
    - 設定ファイルの編集が必要
    - または
    - そのユーザを作り設定をし直す
Ruby 25 周年記念パーティでデバッグ出力を行う gem つくってきた


[ブログ記事](http://secret-garden.hatenablog.com/entry/2018/02/24/234821)からの転載です。

今日 2018年2月24日は Ruby が誕生してちょうど 25年目！
ということで[記念パーティ](http://25.ruby.or.jp/)に行ってきました。
まあなんとなく行ってきたんですが、別に偉い人の話を聞いてもしょうがないので会場ではひたすら Ruby のコードを書いていました。<del>人の話を聞いているよりもコードを書いている方が有意義なのじゃ</del>
そして、ついこの間 2.5 がリリースされたと思ったらもう [Ruby 2.6.0-preview1](https://www.ruby-lang.org/ja/news/2018/02/24/ruby-2-6-0-preview1-released/) が出ていますね…早い…。
ちなみにこのバージョンではわたしが[投げたパッチ](https://bugs.ruby-lang.org/issues/14223)も取り込まれているようでよかったよかった。
そんなわけで Ruby 25周年記念でつくったデバッグに便利そうな gem を公開しました。

## インストール

```shell
$ gem install binding-debug
```

## binding-debug とは

例えばデバッグ出力をする際に `変数名 : 値` みたいな形で出力されてほしい事があると思います。
しかし、このような形式で出力したい場合、毎回自分で変数名を記述する必要があります。

```ruby
hoge = 42
# 自前で毎回こんな感じの出力フォーマットを定義する必要がある
puts "hoge : #{hoge}"
```

これをどうにかしたかったのでいい感じにデバッグ出力できる gem をつくりました。

## 使い方

デバッグ出力を行いたいコンテキスト情報(変数名とか)を取得するために `Kernel.#binding` を利用します。
以下のようにして `Binding#puts` に対して評価したい変数（式）を渡すことで `変数名（式） : 評価した値` みたいな感じで出力されます。

```ruby
require "binding/debug"

# 要 refinements
using BindingDebug

hoge = 42
binding.puts "hoge"
# output: "hoge : 42"

# Binding#p だと Kernel.#p で出力
binding.p "hoge"
# => "hoge : 42"
```

また、複数の式を評価したい場合は、`%{}` 記法を利用することが出来ます。

```ruby
# %{} を利用すれば以下のように書くことも
def plus a, b
	a + b
end

foo = "homu"
binding.puts %{
	foo.to_s.upcase
	plus 1, 2
	(0..20).to_a
	foo.class.name
}
# output:
# foo.to_s.upcase : HOMU
# plus 1, 2 : 3
# (0..20).to_a : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
# foo.class.name : String
```

思ったよりもいい感じに書けますね。

## 経緯

元々は `instance_eval` + `method_missing` で以下のように『ブロック内で呼び出されたメソッドに対してフォーマット出力する』ことを考えていました。

```ruby
hoge = 42
# method_missing でいい感じに hoge の呼び出しに対してフックしていい感じに出力する
binding.puts { hoge }
```

しかし、上記の場合、`hoge` という呼び出しが『メソッド呼び出し』ではなくて『キャプチャした変数』を優先して呼び出してしまうため意図した呼び出しが出来ませんでした。

```ruby
hoge = 42
# 明示的にレシーバを付けて呼べばメソッド呼び出しとして評価されるので method_missing で呼び出せるが…
binding.puts { self.hoge }
```

会場でつくっている途中でこの問題に気づいて「うーん、どうしようかな…」と悩んでいたら偶然にも会場に来ていた強い Rubyist の人に「`%{}` 記法を使うのはどうだろうか、ブロックっぽいし」と助言を貰ってシンプルに文字列を渡して評価する実装にしました。
一応、

```ruby
homu = "homu"
binding.puts { self.homu.upcase }
```

みたいにチェーン呼び出しにも対応させる実装は書いたんですが、文字列を評価するようにするほうが実装もずっとシンプルになりとてもよい。
ぶっちゃけ勢いで雑に公開したので実際に使ってみて問題がいろいろと治す予定ではあります。
っていうか、探せば類似 gem はありそうだけどそんなの気にしない！

## 所感

と、言うことで 25周年記念パーティ会場でせっせとつくった gem でしたー。
わたしは Ruby 歴 3年ぐらいのにわかですが、みなさん Ruby 愛が強くてすごいですね。
今後は mruby なんかもいい感じに盛り上がってほしいと思っています（<del>その前に cruby と mruby で仕様がぶれているのをどうにか…</del>
わたしは Rails が全く出来ませんし Ruby ＝ Rails みたいな世の中は本当にクソだなと心の底から思っていますが、Ruby 自体は書いていてとても楽しい言語なので、これからも役に立たない面白いコードやライブラリなんかを書いて行きたいです！！！
Ruby は書いていて楽しいのでみんな Ruby 沼んいハマろう！！
<br>
ちなみに関係ありませんが今年は C++ 35周年の年でもあります！
みんな C++ ちゃんも祝ってあげよう！！！
そんなわけで Ruby パパの Matz、Ruby コミッタ、関係者のみなさん、楽しい Ruby をありがとうございます！
Mac の Virtual Box で Guest からホストフォルダを共有する方法

Mac の Virtual Box で Guest の CentOS7 と Windows 10 とホストのフォルダを共有する方法をメモする。
（他の投稿では抜けている箇所が幾つかあったので…）

## Guest の CentOS に Virtual Box の拡張機能を追加
CentOS7 で Virtual Box の共有フォルダマウント機能を利用するには、vboxadd service が必要。以下手順。

### 事前準備

```shell
# yum update -y
# reboot
```

1.共有フォルダマウント用ソフトの準備
ホストで対象仮想マシンを選択して、Virtual Box のメニュー [Device] => [Insert Guest Additions CD images] を選択して Guest の CentOS にイメージをマウント

2.Guest の CentOS で CD イメージをマウント

```shell
# mount /dev/cdrom /mnt
```

3.vboxadd のビルドに必要なパッケージをインストール(この2つが必要なはず)

```shell
# yum -y install gcc kernel-devel 
```

4.vboxadd のインストール

```shell
# cd /mnt
# ./VBoxLinuxAdditions.run
```

5.終了

```shell
# shutdown -h now
```

6.共有フォルダの設定
Virtual Box の [設定] => [共有フォルダ] で [+] をクリックしてマウント先のフォルダを選択。
永続化と自動マウントにチェックを入れる。

7.共有フォルダの確認

```shell
# ls /media/sr_<shared_folder_name>
```
でマウント先のファイルやフォルダが表示されれば OK!

## Guest の Windowns に Virtual Box の拡張機能を追加
1. CentOS7 の 1. と一緒
2. CD/DVD から VboxWindowsAdditions を起動
3. インストールウィザードに沿ってインストール
4. 再起動
失敗したData Pumpジョブの後始末を試す（Oracle Database 12c Release 2)

# Data Pumpジョブの失敗
Data Pumpは、実行時に接続ユーザー（useridパラメーター）のスキーマにジョブの状況を管理するテーブルを作成します。一般的に知られているテーブル名は、DBA_DATAPUMP_JOBSビューのJOB_NAME列と同じ名前のテーブルです。自動作成されるテーブル名はData Pump実行時のパラメーターによって変化しますが、SYS_EXPORT_SCHEMA_01やSYS_IMPORT_FULL_01等になります。

# Data Pumpジョブの後始末
　Data Pumpジョブを強制的に止めた場合、ジョブ名がDBA_DATAPUMP_JOBSビューに残ることがあります。ジョブを削除するために、同一名称のテーブルを削除することでData Pumpジョブのクリーンアップを行います。

```
SQL> SELECT OWNER_NAME, JOB_NAME FROM DBA_DATAPUMP_JOBS;
OWNER_NAME   JOB_NAME
------------ -----------------------
APLUSER      SYS_IMPORT_SCHEMA_01

SQL> DROP TABLE APLUSER.SYS_IMPORT_SCHEMA_01;
表が削除されました。

```


次にジョブ名以外のテーブルも作成される現象を説明しています。

ある日から統計情報を取得する DBMS_STATS.GATHER_SCHEMA_STATS プロシージャがが失敗するようになりました。

```
SQL> BEGIN
  DBMS_STATS.GATHER_SCHEMA_STATS (
	ownname => 'APLUSER',
        options => 'GATHER',
        estimate_percent => 15,
        cascade => TRUE
  );
  END;
  /
BEGIN
*
行１でエラーが発生しました。
ORA-20000: Statistics collection failed for 2 objects in the schema
ORA-06512: "SYS.DBMS_STATS", 行38928
ORA-06512:　"SYS.DBMS_STATS", 行38257
ORA-06512:　"SYS.DBMS_STATS", 行38225
ORA-06512:　"SYS.DBMS_STATS", 行38285
ORA-06512: 行2
```

失敗するオブジェクトを探していると、ET$で始まる見慣れないテーブルを見つけました。

```
SQL> SELECT TABLE_NAME, LAST_ANALYZED FROM USER_TABLES ORDER BY 2;
TABLE_NAME 		       LAST_ANA
------------------------------ ---------
TABLE_A				18-02-20
...
ET$001910FB0001
ET$0019836D0001

200行が選択されました。
```

このテーブルに対して統計情報を取得すると、Data Pumpが自動作成するテーブルらしいということがわかりました。

```
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS('APLUSER', 'ET$001910FB0001');
BEGIN DBMS_STATS.GATHER_TABLE_STATS('APLUSER', 'ET$001910FB0001'); END;

*
行１でエラーが発生しました。
ORA-20011: Approximate NDV failed: ORA-29913:
OCIEXTTABLEOPENコールアウトの実行中にエラーが発生しました。KUP-11024:
この外部表は、データ・ポンプ・ジョブ内からのみアクセスできます。ORA-06512: "SYS.DBMS_STATS",
行36873
ORA-06512: "SYS.DBMS_STATS", 行36507
ORA-06512:　"SYS.DBMS_STATS", 行35428
ORA-06512:　"SYS.DBMS_STATS", 行33883
ORA-06512:　"SYS.DBMS_STATS", 行32254
ORA-06512:　"SYS.DBMS_STATS", 行32234
ORA-06512:　"SYS.DBMS_STATS", 行33472
ORA-06512:　"SYS.DBMS_STATS", 行35304
ORA-06512:　"SYS.DBMS_STATS", 行36230
ORA-06512:　"SYS.DBMS_STATS", 行36716
ORA-06512: 行1
```

このため該当テーブルを削除するとDBMS_STATSジョブが正常に稼働するようになりました。
【Swift4】キーボードの上にUIToolbarを実装する方法

## 実行環境
【Xcode】Version 9.2
【Swift】Version 4.0.3

## 概要
iOSキーボードの上にツールバーを追加する方法のメモです。

## 方法
### 下準備
適当にUItextFieldを追加しておきます。
<img width="372" alt="a.png" src="https://qiita-image-store.s3.amazonaws.com/0/238595/cb8ed6b4-9810-6bdc-0563-ec42a35e54dc.png">

### 実装

```ViewController.swift
class ViewController: UIViewController, UITextFieldDelegate {
    
    // textFieldのアウトレットを指定
    @IBOutlet weak var textField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // ツールバーのインスタンスを作成
        let toolBar = UIToolbar()
        
        // ツールバーに配置するアイテムのインスタンスを作成
        let flexibleItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
        let okButton: UIBarButtonItem = UIBarButtonItem(title: "OK", style: UIBarButtonItemStyle.plain, target: self, action: #selector(tapOkButton(_:)))
        let cancelButton: UIBarButtonItem = UIBarButtonItem(title: "CANCEL", style: UIBarButtonItemStyle.plain, target: self, action: #selector(tapCancelButton(_:)))

        // アイテムを配置
        toolBar.setItems([flexibleItem, okButton, flexibleItem, cancelButton, flexibleItem], animated: true)
        
        // ツールバーのサイズを指定
        toolBar.sizeToFit()
        
        // デリゲートを設定
        textField.delegate = self

        // テキストフィールドにツールバーを設定
        textField.inputAccessoryView = toolBar
    }
    
    // ボタンを押したときのメソッド
    @objc func tapOkButton(_ sender: UIButton){
        // キーボードを閉じる
        self.view.endEditing(true)
    }
    @objc func tapCancelButton(_ sender: UIButton){
        // テキストフィールドを空にする
        textField.text = ""
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
}
```

## 完成形
<img width="315" alt="スクリーンショット 2018-02-26 14.06.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/238595/26fe8404-6db6-57ee-3ea9-7ae8a18585e0.png">
GitHubで認証エラーが発生するようになった


いつも通り最新ソースを取得しようとした。

```
$ git fetch origin develop 
```

すると、認証時にエラーが発生し ID/PWD を求められた。
今までならWindowsに記憶してある資格情報を利用してアクセスできていた。

```
Fatal: HttpRequestException encountered.
   この要求の送信中にエラーが発生しました。
Username for 'https://github.com': 
```

資格情報マネージャーにて、一旦削除 → 再登録してもダメ。
ID/PWDを入力すれば認証は通る。

Gitの設定情報を確認したが、
Windowの資格情報を利用する設定になっていた。

```
$ git config --list
credential.helper=manager
```

gitconfig を再設定してみたが、結果は変わらず。

```
git config --global --unset credential.helper manager
git config --global credential.helper manager
```

検索したところ、Git のバージョンをあげろとのこと。
https://github.com/Microsoft/Git-Credential-Manager-for-Windows/issues/488

Git のバージョンを確認してみた。

```
$ git --version
git version 2.10.1.windows.1
```

古かったので、最新版（2.16.2）をDLしてインストール
https://git-scm.com/download/win

```
$ git --version
git version 2.16.2.windows.1
```

新しいバージョンでは、うまく動くようになった。

```
$ git fetch origin develop
$ git merge origin/develop
Already up to date.
```
(負荷試験)sarログの手編集地獄から逃れるための改善案

先日急遽、負荷試験を行う事になりました。
自身初めての負荷試験のため、jmeterの設定とシナリオ作りに追われ、
sarコマンドの結果をどのように扱うかまで手を回すことができませんでした。
その結果、負荷試験レポートを作成するために、後輩がsarコマンドログの手編集地獄に落ちてしまいました。:innocent:
悲劇を繰り返さないため改善案です。

# 概要
## 課題
- ```sar 1 10000 | tee stress_cpu_`hostname`_`date '+%Y%m%d%H%M%S'`.txt``` すると、
sar結果の集計が大変であること

## すること
- sarコマンドの結果を切り貼りする時間がかかるため、より簡単にする

## ステップ
1.sarでバイナリファイルを作成
2.1.で作成したバイナリをsadfで必要な情報のみに削り、tsvに変換する
3.tsvをsqliteにぶっこんで平均idleタイムなどを取得

# 手順
- 1.sarでバイナリファイルを作成
    - ```sar -t -u -o sar.out 1 10000```
        - -t:データファイルに記録されている時刻（UTC）をローカルタイムに変換する
        - -u:cpu使用率
        - -o:アウトプットファイルの指定
    - 参考:[システムの状態を可視化する（その１） | K4750.net](https://www.k4750.net/2013/09/15/visualize-system-information-1/)
    - 参考:[sarによるボトルネック発見の手順(というかsysstatの使用法)をまとめてみた - end0tknr's kipple - 新web写経開発](http://end0tknr.hateblo.jp/entry/20120206/1328499420)
- 2.1.で作成したバイナリをsadfで必要な情報のみに削り、TSVに変換する
    - ```sadf -t -- -u -s 10:09:57 -e 10:10:00 sar.out | grep idle > sadf.tsv```
        - -s:出力対象のスタート時間->負荷試験の開始時間を設定する
        - -e:出力対象の終了時間->負荷試験の開始時間を設定する
    - ポイント:負荷試験の開始時間と終了時間に合わせて-sと-eを指定する
    - ポイント:grepすることでtsvを軽くして、サーバーからのログ取得をスムーズに
    - 参考:[sarによるボトルネック発見の手順(というかsysstatの使用法)をまとめてみた - end0tknr's kipple - 新web写経開発](http://end0tknr.hateblo.jp/entry/20120206/1328499420)
    - 参考:[sar で収集したリソース使用情報が sadf コマンドで TSV として出力できる - 映画は中劇](http://d.hatena.ne.jp/miyakawa_taku/20140202/1391330618)
- 3.tsvをsqliteにぶっこんで平均idleタイムなどを取得
    - https://qiita.com/nassy20/items/546f8ce86e1817f1a30a を参考にしてください

以上です。
生き返れ、後輩！:innocent:
[Wordpress]カスタム投稿をターム（カテゴリー）毎に出力する方法


以前、[こちらの投稿](https://qiita.com/noqua/items/a7502f79c74f6f462616)でカテゴリー毎に記事一覧を出力する方法を書きましたが、同じようにカスタム投稿の記事をターム（カテゴリー）毎に出力する方法の備忘録になります。

## 仕様

- 検証バージョン：WordPress 4.8.5
- ターム毎に指定した記事数分を表示
- タームは親子階層なし

実現したい表示イメージは以下の通りです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/62022/c9233c73-767c-7b0e-a2e2-4dc00a7669ce.png" "カスタム投稿表示例" width="659">

ターム毎に記事が表示され、タームに記事が無い場合はコメントを表示します。

## コード
### function.php にカスタム投稿・タクソノミーを定義
function.phpの編集に慣れていない方は、function.phpの最終行の下に追加してください。

```php:function.php
add_action( 'init', 'create_post_type' );
function create_post_type() {
	register_post_type( 'trip', // カスタム投稿のスラッグ
		array(
			'labels'			=> array(
				'name'			=> __( '旅ログ' ),	// 投稿タイプ名
				'singular_name'	=> __( '旅ログ' )	// 投稿タイプ名
			),
			'public' => true,
			'has_archive' => true,
			'menu_position' =>5,
			'supports' => array('title','editor')
		)
	);

	// カテゴリタクソノミー(カテゴリー分け)を使えるように設定する
	register_taxonomy(
		'pref',	// タクソノミー（カテゴリー）のスラッグ
		'trip',	// 適用するカスタム投稿のスラッグ

		array(
			'hierarchical' => true, // trueだと親子関係が使用可能。falseで使用不可
			'label' => '都道府県',			// タクソノミー名（カテゴリー名）
			'singular_label' => '都道府県',	// タクソノミー名（カテゴリー名）
			'public' => true,
			'show_ui' => true
		)
	);
}
```

### カスタム投稿一覧を表示するコード

カスタム投稿一覧を表示するページのテンプレートファイルに以下のコードを記入してください。
今回はindex.phpに記入しています。


```php:index.php
<?php
$taxonomies = 'pref'; // タクソノミー（カテゴリー）スラッグを指定
$args = array(
	'hide_empty' => false, // 空のタームを出力しない場合はtrue
);
$terms = get_terms( $taxonomies , $args );

// ターム（カテゴリー）別に記事を出力する
foreach ($terms as $term) :

	$args = array(
		'post_type'		=> 'trip',
		'taxonomy'		=> $taxonomies,
		'term'			=> $term->slug,
		'posts_per_page'=> 5 // 最新5記事。数を指定しない場合は-1を指定
	);

	$trip_posts = get_posts( $args );

	if ( $trip_posts ) {
	// 記事がある場合

		// ターム名（カテゴリー名）
		echo '<h1>'.$term->name.'</h1>';

		foreach ( $trip_posts as $post ) :
			setup_postdata( $post ); ?>
<section>
	<h2><?php the_title();		// 記事の見出し ?></h2>
	<div><?php the_content();	// 記事の内容 ?></div>
</section>
<?php
		endforeach;

	} else {
	// 記事がない場合

		// ターム名（カテゴリー名）
		echo '<h1>'.$term->name.'</h1>';
		echo '<p>ここにはまだ旅行していません。</p>';
	}

endforeach;

wp_reset_postdata();
?>
```

## 結果

<img src="https://qiita-image-store.s3.amazonaws.com/0/62022/c9233c73-767c-7b0e-a2e2-4dc00a7669ce.png" "カスタム投稿表示例" width="659">

### HTML

```html
<h1>京都</h1>
<section>
	<h2>京都旅行記その2</h2>
	<div>
		<p>京都旅行記その2の内容</p>
	</div>
</section>

<section>
	<h2>京都旅行記その1</h2>
	<div>
		<p>京都旅行記その1の内容</p>
	</div>
</section>

<h1>沖縄</h1>
<p>ここにはまだ旅行していません。</p>

<h1>北海道</h1>
<section>
	<h2>北海道旅行記その1</h2>
	<div>
		<p>北海道旅行記その1の内容</p>
	</div>
</section>
```

今回は```foreach```を使っていますが、もっと簡単な方法もあるのでしょうか…。
ちなみに、プラグインなどでタームの順序を変えればそれに準じて並べ替えられます。

参考になれば嬉しいです。
Cognos レポートの棒グラフのY軸を無理やりA,B,C(文字列)で表示

#概要
棒グラフでY軸をこんな風にA、B、C評価で、文字列で表示したいという場合。
RAVEを使えばできるのでしょうが、ドリルスルーとかしたいので、RAVEが使えない時の苦肉の策です。
投稿するのも恥ずかしいしょうもない実装なのですが、恥を忍んで投稿しておきます。
![001.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/65274ca1-5738-f884-a703-e8a3dd91411e.jpeg)

#実装手順
元データはこんな感じです。
![002.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/9f824809-77b4-813d-e355-a1f4624298b1.jpeg)

棒グラフのX軸にCOL1、Y軸にCOL2を置きます。
![003.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/ce99b10d-7285-f1d7-4055-438c7e9f4845.jpeg)

Y軸を選択し、プロパティの「軸の範囲」から、以下の様に、最大値、最小値、主間隔を指定します。
![004.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/2a65266e-46bb-a557-cf51-25eb1fd7945f.jpeg)

軸ラベルの前景色を白にします。
![005.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/d61c9ddf-40ca-e36e-87d1-b6afbe22df61.jpeg)

棒グラフそのもののサイズも決めておきます。
![006.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/bbe9bb4a-c2b6-1d7c-4918-be94529899f4.jpeg)

棒グラフ全体のプロパティで「メモ」を選択し、テキストに「A」を記載します。
![007.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/84615b95-ce76-e94c-8312-0691b98c5172.jpeg)

「メモ」は配置場所がピクセル単位で指定可能です。以下のように指定します。
![008.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/10e10c10-d0da-8e63-9f4f-2850e32db4b8.jpeg)

同様にメモで、「B」を作成し、以下のように配置。
![009.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/4d23fa2e-6b55-3740-598d-b0c66d13498b.jpeg)

「C」は以下のように配置します。
![010.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/2dd63e46-cfbb-5e74-3442-0cbed57d67b4.jpeg)

完成です。データを増やしてみましたが、問題なく表示されました。
![011.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/b5940d4d-b128-9560-ef15-30d4465fe823.jpeg)
ElectronのWebviewで履歴の戻る/進む ~手巻き寿司を添えて~

ドン
[<webview> Tag | Electron](https://electronjs.org/docs/api/webview-tag#webviewgoback)


>`<webview>.goBack()`
>Makes the guest page go back.
>`<webview>.goForward()`
>Makes the guest page go forward.

# 手巻き寿司

[エレクトロン手巻き寿司 - Qiita](https://qiita.com/61503891/items/6e8070155c9fc3b3b8e0)
では空の`electron-temaki-sushi/templates/index.coffee`が用意されています。
これは手巻いたときに`index.js`として`index.html`に読み込まれるので、好きなコードを記述できます。
素晴らしいですね。

寿司本体はわさび抜きで、お客の好みに合わせて自由につけてくださいって感じでしょうか[^1]

[^1]: 美味くない例え


```index.coffee
document.addEventListener 'keydown', ((event) -> 
  if event.altKey == true && event.keyCode == 37
    document.getElementById('mainWebview').goBack()
  if event.altKey == true && event.keyCode == 39
    document.getElementById('mainWebview').goForward()
  )
```


たまに使うと戻れないのが不便なので、
<kbd>Alt + ←</kbd>
<kbd>Alt + →</kbd>
で操作できるようにしました。

開発中は手巻き寿司した後の`index.js`を直接編集。
さらに`main.js`も編集し`openDevTools()`を追加すると捗る。

# 参考

* [CoffeeScriptで引数に無名関数を使う - Qiita](https://qiita.com/yahihi/items/d2c3ac3a3c84da658a1e)

`function(event) {}`
になって欲しいのに
`event(function() {})`
になってしまう問題。

あるいはES2016のアロー関数`=>`のつもりで`->`つかっていた問題。
【webpack】(2018年2月25日現時点で)ES2015 (ES6)のままminifyする方法

去年、[【webpack】(現時点で)ES2015 (ES6)のままminifyする方法](https://qiita.com/ota-meshi/items/e60fa3778c0e53ac6a56)という記事を書き、
先月も[【webpack】(2018年1月現時点で)ES2015 (ES6)のままminifyする方法](https://qiita.com/ota-meshi/items/9e9bfcbfab00e109494f)という記事を書きましたが、
[webpack](https://webpack.js.org/)`v4.0.0`がリリースされて公式にサポートされるようになったので、記事書きます。

リリース：
https://github.com/webpack/webpack/releases/tag/v4.0.0

# 結論
結論は、[webpack](https://webpack.js.org/)`v4.0.0`使えということになります。


# 設定
## package.json

[webpack](https://webpack.js.org/)`v4.0.0`からはcli起動には、`webpack-cli`が必要な様子

```json:package.json
// ・・・
  "devDependencies": {
    // ・・・
    "webpack": "^4.0.0",
    "webpack-cli": "^2.0.9",
  }
// ・・・
```

## `optimization.minimize`

https://github.com/webpack/webpack/releases/tag/v4.0.0
を見ると、`optimization.minimize`の設定でminifyの制御ができる様子。
（`webpack.optimize.UglifyJsPlugin`はもう使いません。使おうとするとエラーになります。）

`mode`の指定によってデフォルトの動作が変わるようなので、`'production'`でしかminifyしないつもりなら特別な設定は必要ないと思う。
以下は、`mode`に依存せず、常に`minify`する場合の設定。

```js:webpack.config.js
module.exports = {
  // ・・・
  optimization: {
    minimize: true,
  },
  // ・・・
}
```

ちなみに`mode`に何も設定しないと警告が出ました。

---

めでたく、ES2015 (ES6)のままminifyできました？

# その他の設定
minifyには関係ないけど、[webpack](https://webpack.js.org/)`v4.0.0`入れて、自分の設定でエラーになって書き換えたポイント

## `module.loaders[]`はもう使えない様子

これはダメっぽい。

```js:webpack.config.js
  module: {
    loaders: [
      // ・・・
    ]
  }
```

こう書きかえると動いた。

```js:webpack.config.js
  module: {
    rules: [
      // ・・・
    ]
  }
```
Raspberry Pi公式7インチタッチディスプレイへの接続

久しぶりに7インチタッチディスプレイを接続しているRaspberry Pi2のOSを入れ替えたところ、天地逆さまに表示されたため、以下ファイルへの変更を思い出したまでです(´・ω・｀)…

```bash:/boot/config.txt
lcd_rotate=2
```