OmniAICreator/Qiita-1.07M huggingface dataset:
ElasticsearchでICU AnalysisのAnalyzer, Tokenizer, Token Filters, Char Filtersの一覧


# Tokenizer
* ICU Tokenizer: standard tokenizeのように振る舞うが、辞書ベースで、一部アジアの言語にも対応している。

それでは試してみます。以下をみるとなんとなくできていそうです。ただ、辞書ベースのためおそらく新語などには対応できないと思います。

```json
# クエリ
GET _analyze
{
  "tokenizer" : "icu_tokenizer",
  "token_filter" : [],
  "char_filter" : [],
  "text" : "わたしは猫である"
}

# 結果
{
  "tokens": [
    {
      "token": "わたし",
      "start_offset": 0,
      "end_offset": 3,
      "type": "<IDEOGRAPHIC>",
      "position": 0
    },
    {
      "token": "は",
      "start_offset": 3,
      "end_offset": 4,
      "type": "<IDEOGRAPHIC>",
      "position": 1
    },
    {
      "token": "猫",
      "start_offset": 4,
      "end_offset": 5,
      "type": "<IDEOGRAPHIC>",
      "position": 2
    },
    {
      "token": "で",
      "start_offset": 5,
      "end_offset": 6,
      "type": "<IDEOGRAPHIC>",
      "position": 3
    },
    {
      "token": "ある",
      "start_offset": 6,
      "end_offset": 8,
      "type": "<IDEOGRAPHIC>",
      "position": 4
    }
  ]
}
```

# Token Filter
* ICU Normalization Token Filter: ICU Normalization Character FilterのToken Filter版
* ICU Folding Token Filter: ùとかᴁのようなLatin Extendedに配置されてそうな文字とかをBasic Latinに変換する。さらに、日本語の濁点なども消える。
* ICU Collation Token Filter: ソートのための照合順序設定
* ICU Transform Token Filter: ひらがなをローマ字に変換できたりする

# Character Filter

* ICU Normalization Character Filter
    * 使用できるnormalizerのタイプは以下
        * nfkc_cf(デフォルト)
        * nfc(Normalization Form C)
        * nfkc(Normalization Form KC)


# 参考
* https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-icu.html
* https://www.elastic.co/guide/en/elasticsearch/guide/current/languages.html
* http://christina04.hatenablog.com/entry/2016/08/03/123000
* http://nomenclator.la.coocan.jp/unicode/normalization.htm
* http://www.mwsoft.jp/programming/lucene/lucene_filter.html
技術英語 > Entries in the document should be sorted by [the full word], not the abbreviation. / long form of the abbreviation

@ Code Complete (No. 9685 / 36077)

> Entries in the document should be sorted by <font color=red>the full word</font>, not <font color=blue>the abbreviation</font>.

http://ejje.weblio.jp/content/abbreviation
> 省略、短縮、省略形、略語、略字

full wordは「省略していない」方。

<hr>
関連して思い出したのは

long form of the abbreviation

http://www.ncbi.nlm.nih.gov/pubmed/25554684
>  the long form of the abbreviation

これもfull wordと同じ意味で使うと聞いたことがある。

<hr>
略語の省略元を聞く時

What's the long form of the abbreviation?

Could you spell out the full word?

などが使えると思う（たぶん）。
rabbitmq

# RabbitMQ

## AMQP

- RabbitMQで使用しているメッセージングプロトコル

![hello-world-example-routing.png](https://qiita-image-store.s3.amazonaws.com/0/106550/24fd0a11-99c9-7e59-3251-ca6165ba76e5.png)

| 名称 | 説明 |
|:--|:--|
| Publisher  | メッセージを送る人  |
| Exchange  |  BindingルールをもとにmessageをQueueに配送する人 |
| Queue  | Messageをためる人  |
| Consumer  | QueueからMessageを受け取る人  |

## Exchange

- BindingルールをもとにmessageをQueueに配送する人

![exchange-direct.png](https://qiita-image-store.s3.amazonaws.com/0/106550/acaa202c-2b34-996e-abe7-b057a77d9bc1.png)

![exchange-fanout.png](https://qiita-image-store.s3.amazonaws.com/0/106550/27349149-43d6-0b37-3060-b48a8a7f71f1.png)

| 名称 | 説明 |
|:--|:--|
| Direct | messageをExchangeにbindされてる特定のQueueに配送  |
| Fanout|  messageをExchangeにbindされてる全てのQueueに配送 |
windows,Anacondaでcvxpyをインストール

# cvxpyって何

cvxoptをはじめとする他の数理最適化ライブラリのラッパーのようなものです。

このライブラリの特徴は最適化問題の標準系への変換を自動でやってくれる点です。
このおかげで、係数行列を計算がとても楽になります。

# インストールとその問題

公式ページにある通り

```bash:
conda install -c omnia cvxopt
conda install -c omnia scs
pip install cvxpy
```

でインストールできますが、実行時にエラーになります。
cvxpyの依存するライブラリのCVXcanonとfastcacheがコンパイル済みファイル(.pyd)を含んでいてこれの読み込みでエラーになります。
原因は良く分かりませんが、32bitと64bitの違いと予想しています。

# 解決方法

CVXcanonとfastcacheをいったん削除してcondaで入れなおします。
新規にインストールする場合は、先にこっちでインストールしておいた方が、二度手間にならなくていいです。

```bash:
pip uninstall cvxcanon
pip uninstall fastcache

conda install -c cvxgrp cvxcanon
conda install fastcache
```

cvxcanonのリポジトリはcvxgrpでなくともomniaでいいかもしれません。
(こことは直接関係ありませんが、Linuxではcvxgrpの方からインストールするとCVXCanonがインポートできなくで、omniaの方でインストールし直すと解決するということがありました。)

# 最後に

[Unofficial Windows Binaries for Python Extension Packages](http://www.lfd.uci.edu/~gohlke/pythonlibs/)を利用する方法もあり得ますが、コマンドを打つだけで済むこちらの方が簡単だと思います。
パッケージ版 nkf の注意点


CentOSのパッケージ版のnkfで複数ファイルの改行コードを確認した場合に、
始めに選択されたファイルの改行コードになってしまう。

#確認環境

```console
# cat /etc/redhat-release
CentOS release 6.8 (Final)
```

nkfファイル

```console
# ll /usr/bin/nkf /usr/local/bin/nkf
-rwxr-xr-x 1 root root 221448 11月 12 21:13 2010 /usr/bin/nkf			<=パッケージ版
-rwxr-xr-x 1 root root 506327  6月 21 16:25 2016 /usr/local/bin/nkf	<=ソース版
```

パッケージ版バージョン

```console
# /usr/bin/nkf -V
Network Kanji Filter Version 2.0.8 (2007-07-20)
Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa),2000 S. Kono, COW
Copyright (C) 2002-2007 Kono, Furukawa, Naruse, mastodon
```

```console
# rpm -qf /usr/bin/nkf
nkf-2.0.8b-6.2.el6.x86_64
```

ソース版バージョン

```console
# /usr/local/bin/nkf -V
Summary of my nkf 2.1.4 (2015-12-12) configuration:
  Compile-time options:
    Compiled at:                 Jun 21 2016 16:25:37
    Default output encoding:     LOCALE (UTF-8)
    Default output end of line:  LF
    Decode MIME encoded string:  ON
    Convert JIS X 0201 Katakana: ON
    --help, --version output:    STDOUT
```

適当に改行コードを変えてテストファイルを作成

```console
# ll
合計 12
-rw-r--r-- 1 root root  5  6月 21 15:16 2016 CR.txt
-rw-r--r-- 1 root root 14  6月 21 15:17 2016 CRLF.txt
-rw-r--r-- 1 root root  5  6月 21 15:16 2016 LF.txt
```

cat の -Aオプションで見るとこんな感じ

```console
# cat -A CR.txt
a^Mb^Mc
```

```console
# cat -A CRLF.txt
hoge^M$
foo^M$
bar
```

```console
# cat -A LF.txt
1$
2$
3
```

#ソース版動作

ソース版だと短縮の-g ではなく--guessでないと改行コード表示してくれないが、
正しく改行コードを表示してくれる

```console
# /usr/local/bin/nkf --guess CR.txt CRLF.txt LF.txt
CR.txt: ASCII (CR)
CRLF.txt: ASCII (CRLF)
LF.txt: ASCII (LF)
```

```console
# nkf -g CR.txt  CRLF.txt  LF.txt
CR.txt: ASCII
CRLF.txt: ASCII
LF.txt: ASCII
```


#パッケージ版動作
最初に指定したファイルの改行コードが表示される。
また、CRLFもCRで判定されてる

```console
# /usr/bin/nkf -g CR.txt CRLF.txt LF.txt
CR.txt:ASCII (CR)
CRLF.txt:ASCII (CR)
LF.txt:ASCII (CR)
```

```console
# /usr/bin/nkf -g LF.txt CR.txt CRLF.txt
LF.txt:ASCII (LF)
CR.txt:ASCII (LF)
CRLF.txt:ASCII (LF)
```

```console
# /usr/bin/nkf -g CRLF.txt LF.txt CR.txt
CRLF.txt:ASCII (CR)
LF.txt:ASCII (CR)
CR.txt:ASCII (CR)
```

1つずつ指定すると、CRLF以外は一応判定してくれる

```console
# /usr/bin/nkf -g CR.txt
ASCII (CR)
# /usr/bin/nkf -g CRLF.txt
ASCII (CR)
# /usr/bin/nkf -g LF.txt
ASCII (LF)
```


CentOSのパッケージ版のnkfで複数ファイルの改行コードを確認するときは注意！！
CentOS7では標準のレポジトリからは消えたっっぽいけど。
windowsでluigiを並列処理させたらエラーになったけど、その解決法

# luigiって何

データをいろいろ変換するときに、例えば、変換処理Aは変換処理Bに依存して、変換処理Bは変換処理Cに依存する場合、依存関係を調べて変換処理Cから順に処理を実行してくれる便利なライブラリ。
一連の処理の途中でエラーが発生した場合の対応や再実行の際に実行済みの部分はスキップしてくれるなど有能です。
依存関係がない部分は並列処理をしてくれたりもします。

詳しくは、[PythonとLuigiによるデータパイプライン構築](http://qiita.com/keisuke-nakata/items/0717c0c358658964f81e)をどうぞ。

# 何がエラーになる

並列数を２以上にすると

```py:
PicklingError: Can't pickle <function update_tracking_url at 0x0000000001E100B8>: it's not found as luigi.worker.update_tracking_url
```

といった感じのエラーになります。
multiprocessingとpickleの相性がwindowsに限り悪いようです。良く分かりません。

# 解決策

luigiのバージョンを1.2.1に下げます。
pipではバージョンを指定しないと、最新版のバージョン2.3.0が入りますが、これが罠です。

追記(2016/8/27)
condaで提供されるバージョンが2.3.0に更新されました。
また、windows向けはこのバージョンしかないようなので、pipでインストールする他ないようです。

~~anacondaの場合は~~
~~conda install luigi~~


pipの場合は、

```bash:
pip install luigi==1.2.1
```

でバージョン1.2.1が入ります。

私の環境ではこれで解決しました。
ただ、[Pickle crashing when trying to pickle "update_tracking_url" in luigi.worker?](https://github.com/spotify/luigi/issues/1423)では、バージョン2.0.1に上げると解決したといっている人もいるので、どのバージョンがいいか試す必要があるかもしれません。

## バージョン1と2の違いについて　追記(2016/8/27)
パケージに手を加えることを厭わなければ、バージョン2.1.1までは利用できます。
編集内容については、[Pickle crashing when trying to pickle "update_tracking_url" in luigi.worker?](https://github.com/spotify/luigi/issues/1423)を参照ください。

バージョン2の方が基本的には高性能なようです。
具体的には、

- 明示的に指定できるパラメータのデータ型の種類が増えた
- グローバルスケジューラのUIがきれいになった。
- グローバルスケジューラのUIで利用できるdependency graphの表示に失敗することがなくなった。
 - 私が調べた範囲では、バージョン1の方では、タスクがパラメータを持っていると表示できませんでした。

などが挙げられます。

# 最後に

marioはオリンピックに行ったのに、嗚呼、luigiよ、かわいそうに。
「ionic2」まとめ連載（其の８・「ionic serve --lab」で、エミュレーターっぽく動かす）

#「ionic serve --lab」で、エミュレーターっぽく動かす

こんにちは、mucunです。

今回の記事では、前の回（[其の５](http://qiita.com/mucunwuxian/items/c019b00271c0af69c630)）で紹介した「ionic serve」の便利なオプションについて紹介します。
それは、「--lab」オプションです。
実行するコマンドとしては、「ionic serve --lab」となります。
これは、ブラウザで実施する際に、
Android端末上、iPhone端末上、WindowsPhone上でどう表示されるかが確認できるものです。

実際にやってみましょう。
実施するのは、「ionic2」の公式サンプルです。
（公式サンプル('ω')ノ：http://ionicframework.com/docs/v2/getting-started/tutorial/ ）

先ず、オプション無しの「ionic serve」コマンドを実施します。
これは前回の通りです。
<img width="390" src="https://qiita-image-store.s3.amazonaws.com/0/126499/997b8afe-cec2-d14c-e8dd-6e5c276cec95.png">

次に、オプション有りの「ionic serve --lab」コマンドを実施します。
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/126499/166c3006-bdf3-01ad-d312-eba48ba4a12a.png">

何と美しい、、、( ﾟДﾟ)
これで、わざわざエミュレーターや実機に落とし込まなくても、
見た目や動作が確認できるという訳です。
しかし、Windows Phoneの見た目って、新鮮ですね。
まだ、あまりお目にかからないので。

今回の記事は、ここまでとなります。
ここまで読んで下さった方、ありがとうございました。(^^)/

[👈【其の７・「ionic run」でテストをする】](http://qiita.com/mucunwuxian/items/9f6ab9cb350faa02dd91)　　[👉【其の９・公開サンプルを動かす】](http://qiita.com/mucunwuxian/items/a6e02222d311bb85c0bc)
RemoteViewsでTextSize変更

#はじめに
androidのウィジェット作ろうとした時に嵌りかけて、どこにもまとまった解決法が無かったのでメモします

#.setTextViewTextSize

通常のTextViewのTextSizeを変更したい場合はこのようにセットできます。

```java
TextView　textView;

textView.setTextSize(float size);
```

しかし、RemoteViewsの場合は下記のようにいろいろ指定しないと動きません。

```java
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.layout);

remoteViews.setTextViewTextSize(int viewId, int units, float size);
```
この中で特に分かりにくかったのがunitsの要素です。
#unitsとは何なのか

googleのReferenceでは
units	int: The units of size (e.g. COMPLEX_UNIT_SP)

とされており、
どうやらTextSizeの単位(dp,sp,px...)を指定できるみたいでした。

| 単位 |       units | 
|:-----------------:|:-----------------:|
| dip/dp            |  TypedValue.COMPLEX_UNIT_DIP |   
| sp          |     TypedValue.COMPLEX_UNIT_SP |  
| px             |       TypedValue.COMPLEX_UNIT_PX |    

#例
id:test_textviewのTextSizeを40dpにしたいとき
```java
remoteViews.setTextViewTextSize(R.id.test_textview, TypedValue.COMPLEX_UNIT_DIP, 40);
```
#おわりに
これメモっとかないとアカン気がした
[Unity] Eclipseライブラリ形式でAndroidネイティブプラグインを作る

UnityでAndroidのネイティブプラグインを作る際、大きく分けて以下の３つの構成があるかと思います。

## 1. aar形式で作成

aarで作成すると、リソースファイル（resディレクトリ）やマニフェストを含めてライブラリを作成できますが、
aar内のマニフェストを確認したり、変更したりすることが簡単にできません。


## 2. jarのみ作成して、`Assets/Plugins/Android`直下にリソース、マニフェストを置く

こんな感じの構成です。

![image](https://qiita-image-store.s3.amazonaws.com/0/19872/667734a0-9d50-9c48-939b-34a796bc88d0.png)

マニフェストファイルは`Assets/Plugins/Android`直下に置いているので、
ライブラリが複数ある場合は、手動でのマージが必要になることが多いです。
間違って上書きしたりすると最悪です。



## 3. jarのみ作成して、Eclipseライブラリ形式にする

aarと同様、ライブラリ毎にresディレクトリやマニフェストファイルを配置することができます。
その上、ただのディレクトリなので、直接マニフェストを書き換えたり、ファイルを編集したりすることが簡単にできます。
Unityではこの形式が一番便利かと思います。

こんな感じの構成になります。

![image](https://qiita-image-store.s3.amazonaws.com/0/19872/5af8492b-13f1-64f6-329f-4300ab712586.png)

project.propertiesの内容はこんな感じ。

```properties:project.properties
target=android-16
android.library=true
```

この形式で作成する場合のポイントは以下の３点です。

* `Assets/Plugins/Android`直下にライブラリ用のディレクトリを作成する
* ディレクトリ内に、`project.properties`を配置する（libsやresは必要に応じて配置）
* 他の階層に、同名のディレクトリが存在しないようにする

3つ目はどういうことかというと、例えば`Assets`直下に`XXXPlugin`というディレクトリが存在する状態で、
`Assets/Plugins/Android`配下に`同名のXXXPlugin`というライブラリディレクトリを作成した場合、
うまく認識されない場合があります。

このEclipseライブラリ形式で作成したサンプルを以下に置いておきます。
（Crittercismというクラッシュレポートのプラグインです）
[Crittercism-UnityPlugin](https://github.com/tkyaji/Crittercism-UnityPlugin)

C#のスクリプトやiOS用のファイルを含めて、最終的に以下の構成となっています。

![image](https://qiita-image-store.s3.amazonaws.com/0/19872/b3734423-1733-ad5d-ec78-d9e8cdc16809.png)

# （補足1）AndroidManifest.xmlの確認

UnityでAndroidのビルドをすると、以下のようにマニフェストが作成されるようです。

* `Assets/Plugins/Android/AndroidManifest.xml` があればベースにする
* 無ければUnityが自動で作成する
* aarがあれば、aar内の`AndroidManifest.xml`をマージする
* Eclipseライブラリがあれば、Eclipseライブラリ内の`AndroidManifest.xml`をマージする

マージした結果のファイルは、ビルド時にUnityプロジェクト配下の`Temp/StagingArea/AndroidManifest.xml`に出力されます。



# （補足2）AndroidStudioでjarファイルの出力

Androidのネイティブライブラリを作る場合、私は以下のような手順でjarを出力しています。

1. AndroidStudioで新規プロジェクトを作る

2. `File -> New -> New Module -> Android Library` でモジュールを追加

3. 追加したモジュールの`build.gradle`に、以下のタスクを追加

```:build.gradle
task makeJar(type: Copy) {
    from('build/intermediates/bundles/release/')
    into('../libs/')
    include('classes.jar')
    rename('classes.jar', project.name + '.jar')
}
```

あとはビルド後に上記の`makeJar`タスクを実行して、jarファイルを取り出します。
【12ステップで作る 組込みOS自作入門】③1stステップ：スタートアップの仕組みメモ

## 仕組み
- フラッシュROMに割り込みベクタという配列（(4Byte/割り込みベクタ)×64割り込み要因）が配置される
- ある割り込みが呼ばれると、該当の割り込みベクタに格納されているアドレスにジャンプして処理を実行する
- ジャンプ先の処理を割り込みハンドルと呼ぶ
- ボードを起動するとリセットベクタという割り込みが呼ばれる
- リセットベクタはフラッシュROMの0x000000に格納されている

## コードの説明
- 割り込みベクタ(vector.c)一部抜粋
    - フラッシュROMの先頭（H8の割り込みベクタの場所）に書き込まれる
    - リセットベクタの割り込みハンドラとしてstart関数を登録する
    - 起動するとstart関数に処理が渡される
    - H8の割り込みベクタの数である64個の要素

```
void (*vectors[])(void) = {
  start, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
```

- リンカスクリプト(ld.scr)
    - 上記の配列をフラッシュROMに配置するスクリプト

- スタートアップ(startup.s)一部抜粋
    - start関数の定義
    - start関数の中でmain()を呼び出す

```
_start:
	mov.l	#0xffff00,sp
	jsr	@_main
```

- main()関数の定義(main.c)一部抜粋

```
int main(void)
{
////略
  return 0;
}
```


## 元の本

<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4877832394/kuredev-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51HYm-LUi3L._SL160_.jpg" alt="12ステップで作る組込みOS自作入門" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4877832394/kuredev-22/ref=nosim/" name="amazletlink" target="_blank">12ステップで作る組込みOS自作入門</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 16.08.21</div></div><div class="amazlet-detail">坂井 弘亮 <br />カットシステム <br />売り上げランキング: 38,961<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4877832394/kuredev-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>
Lua のインストールとAtomエディタの設定【Windows】


## 要点
この手順は大きく分けて二つです．
1. Luaのインストール
2. Atomエディタの実行環境の設定

まとめた理由
* WindowsでのLuaの実行環境についてあまりまとまったものがないこと．

## Luaのインストール
下記のリンクを基にLuaのインストールを行った．
http://yohshiy.blog.fc2.com/blog-entry-291.html

1. 下記のリンクから実行ファイルをdownload．
http://joedf.ahkscript.org/LuaBuilds/

1. 展開物を「C:¥Lua」に保存．

1. パスを通す．
 * 「コントロールパネル」=>「システムとセキュリティ」=>「システム」へ
 * 「システムの詳細設定」をクリック．
 * 「詳細設定」の「環境変数（N）」をクリック．
 * ユーザー環境変数（U）側の「path」に「C:¥Lua」を追加．


## Atomエディタの実行環境の設定
プログラムの作成後にコンパイル&実行がスムーズにできるようにAtomエディタのプラグを導入した．

* Atomのインストール
https://atom.io/

* 日本語など初期設定．
http://www.kotalog.net/archives/6038

* atom-terminalのインストール
コマンドプロンプトから以下のコマンドを打ち込む．　

```
apm install atom-terminal
```

Windowsの場合，Term3やterminal-plusを入れても入らなかったり，またインストールできても上手く動かなかったり．今回はこの環境設定で落ち着いてます．
paratestを使ってみた

phpunitの実行に時間がかかるので速くするための施策として、phpunitの並列実行ができる[paratest](https://github.com/brianium/paratest)を使ってみました。

## 実行環境その1

開発環境でまず実験

* CPU : 1.80GHz * 2
* Memory : 4GB
* PHP 5.6
* phpunit 4.4.2
* paratest 0.13.3

## 実行

以下のようなテスト数のアプリケーションを対象にparatestを実行

```zsh
7260 tests, 15736 assertions
```

コマンド

```zsh
$ vendor/bin/paratest -c phpunit.xml.dist --phpunit vendor/bin/phpunit -p 5
```

paratestはプロセス数指定のオプション-pを動かして変化があるか確かめる。

|方法|プロセス数|Time(sec)|Memory(Mb)|
|---|---|---|---|
|phpunit単体|1|328|299.00|
|paratest|5|627|70.25|
| |10|601|70.50|

今回の環境ではプロセス数は10まで。それを超えるとエラーになりphpunitが途中終了してしまいました。

```zsh
PHP Warning:  proc_open(): fork failed - Cannot allocate memory in /xxx/src/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php on line 943
```

## 結果
phpunit単体実行時よりもparatestのほうが遅くなってしまいました。
--functionalや--bootstrapのオプションなどを試してみるもあまり効果は得られず。

サーバのスペックが低くメモリが足りていない感があるので別の環境で再度試してみることにしました。

## 実行環境その2

CIをまわしているスペックの高めなサーバ

* CPU : 2.13GHz * 2
* Memory : 24GB
* PHP 5.6
* phpunit 4.4.2
* paratest 0.13.3

## 実行

対象のアプリケーションはその1と同じ。メモリ使用量はおおよそ同じなので省略します。
CIのジョブとしてphpunit, paratestを実行しその時間を計測します。

|方法|プロセス数|Time(sec)|
|---|---|---|
|phpunit単体|1|585|
|paratest|5|568|
| |10|234|
| |15|209|
| |20|192|
| |25|164|
| |30|200|
| |35|216|
| |40|261|
| |45|171|
| |50|162|
| |60|228|
| |70|232|
| |80|168|
| |90|167|
| |100|170|

## 結果

今度はプロセス数を増やすと実行時間も短縮され最大で約1/3程度になりました。
ただしプロセス数を増やしすぎてもあまり効果はないようです。50でも100でもあまり変わらない。

## おまけ

上記の結果はphpunitのカバレッジなしの場合でした。
カバレッジありの場合は時間がかかるので下記1パターンだけ実施してみました。

|方法|プロセス数|Time(sec)|
|---|---|---|
|phpunit単体|1|18150|
|paratest|30|3060|

5時間→50分

となりました。（短縮されても時間かかりすぎですね…）

## まとめ
* paratestを使うと実行時間を1/3程度に短縮できた
* プロセス数は増やしすぎてもあまり効果がない。サーバの負荷も考慮して20～50程度で設定するとよいと考えられる
* スペックが低い（メモリが少ない）環境だと逆に遅くなるのである程度のスペックが必要
【SSH】ssh-agentの使い方を整理する

ssh-agentの使い方の備忘録メモ

# ssh-add

| コマンド                    |                                       |
|:-------------------------|:--------------------------------------|
| ssh-add [秘密鍵へのパス] | 秘密鍵を登録する                  |
| ssh-add -l               | 登録されている鍵のFingerprints一覧を表示する |
| ssh-add -L               | 登録されている鍵の公開鍵一覧を表示する   |
| ssh-add -d [秘密鍵へのパス] | 登録されている鍵を削除する                  |
| ssh-add -D               | 登録されている全ての鍵を削除する           　　　　|

# ssh-agent

起動するときは

```
$ ssh-agent bash
```

または

```
$ eval `ssh-agent`
```

で起動する。

| コマンド                    |                                       |
|:-------------------------|:--------------------------------------|
| ssh-agent -k             | ssh-agentを停止する |

# ssh-agentの転送機能を使う

```
ssh -A ホスト名
```

とするとログイン先のホストでも登録しておいた鍵が使えるようになる。

# .ssh/config

`~/.ssh/config`ファイルで`ForwardAgent yes`をつけておくと、`ssh -A`にしなくても鍵を持っていってくれる。

```
Host sample
  HostName sample.host
  IdentityFile ~/.ssh/sample_id_rsa
  User hoge
  ForwardAgent yes
```


# 参考

http://man.openbsd.org/ssh-add.1

http://man.openbsd.org/ssh-agent

http://qiita.com/isaoshimizu/items/84ac5a0b1d42b9d355cf

http://qiita.com/naoki_mochizuki/items/93ee2643a4c6ab0a20f5

http://qiita.com/yudoufu/items/82f752807893c63f06db

http://blog.manaten.net/entry/ssh-agent-forward

http://techblog.clara.jp/2014/07/ssh-agent/

http://inaz2.hatenablog.com/entry/2013/06/09/224556

http://webos-goodies.jp/archives/50672669.html

http://inaz2.hatenablog.com/entry/2013/06/09/224556

http://ie.u-ryukyu.ac.jp/e095708/archives/194

http://www.unixwiz.net/techtips/ssh-agent-forwarding.html
見出しタイトルや文章をスマホで見た時に無様に中折れさせないための方法

見出しのタイトルや文章が横幅の狭いブラウザで見た場合に変な位置で改行されてしまい、見栄えを損なっているのをたまに見かけます。
そういったことを防止するための方法として改行タグも`display:none`が使用できるのでそれを利用します。

```html
<h1>例えばこんな見出し。<br class="show_sp">スマホで見た時<br class="show_sp">ちょうどよく改行したい。</h1>
```

```css
h1 {
  text-align: center;
}

.show_sp {
  display: none;
}

@media only screen and (max-width: 680px) {

.show_sp {
  display: block;
}

}
```

## 動作イメージ

### 横幅が十分なブラウザ
<img width="1049" alt="スクリーンショット 2016-08-24 1.01.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/7193/75ecb50f-38b4-311f-925f-cb52ce6b8953.png">

### 横幅が狭いブラウザ
<img width="517" alt="スクリーンショット 2016-08-24 1.01.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/7193/0d9829ea-c053-0bfe-a16a-d278170d7544.png">


### 動作サンプル
https://maiko-ando.github.io/wordbreak_example/
IntelliJ系で git push ができないのを解消


せっかくIntelliJ系のIDE使ってるんだからちゃちゃっとしたGitの操作はIDE内で出来たら楽だなーと思ってはいたんだけどずっと`git push`ができなくて調べるのも面倒で放置してたんだけどちょっと調べたら解決した。ダメ、横着、ゼッタイ。

## エラー内容

`git push`したら毎回こんなんが出てた

`Push failed: Failed with error: fatal: Could not read from remote repository.`


## 解消方法
Preferences > Git > SSH executable
ここを`Native`にする。

![Preferences 2016-08-18 11-43-53.jpg](https://qiita-image-store.s3.amazonaws.com/0/6586/e9683c40-8104-8cc6-23ac-800a52d28645.jpeg "Preferences 2016-08-18 11-43-53.jpg")

デフォルトだとビルトインのSSHを使ってるから`~/.ssh/config`を読まないってことかな
archlinux ctrl加空格 无法呼出sogoupinyin

fcitx-diagnose 诊断问题

https://wiki.archlinux.org/index.php/Fcitx_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#KDE

尝试安装fcitx-gtk2或者fcitx-gtk3
archlinux 乱码 方块

我刚装的是archlinux-2008.03-i686版本。现在补充下安装指南。

关于字体安装。
我现在没有装xorg里面的75和100两个字体，装了wqy-zenhei（文泉驿正黑）和wqy-bitmapfont（文泉驿宋体），理论上，宋体的可以不用装，正黑的显示效果已经非常不错了。安装方法是pacman -S wqy-zenhei，这个包现在收录于community里面。
安装完之后，会有英语提示，是否打开bitmap（点阵字体？）的功能，然后就打开/etc/fonts/conf.d/44-wqy-zenhei.conf，对这句
<edit name="embeddedbitmap"><bool>false</bool></edit>
里面的false改成true

然后，再输入
fc-cache -fv

我是先这样装上字体包之后再装的kdebase，理论上，反过来也是可以的。接着，我上douban.com，已经有中文可以显示了。不再是之前的方块了。。。

https://www.douban.com/group/topic/2259557/

https://wiki.archlinux.org/index.php/Arch_Linux_Localization_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#ftp.E4.B9.B1.E7.A0.81
ボーイスカウト・ルールってご存じですか？

# はじめに
プログラマ向けの格言っていっぱいありますよね。
その中でも好きな格言の一つである「ボーイスカウト・ルール」をご紹介したいと思います。

とてもよい考え方なので、普及すると嬉しいです。

# ボーイスカウト・ルールとは？
ボーイスカウトのルールには、大切なことがあります。
それは、「来た時よりも美しく」です。

たとえ自分が来た時にキャンプ場が汚くなっていたとしても、
そしてたとえ汚したのが自分でなかったとしても、綺麗にしてからその場を去る、というルールです。

そうやって、次にキャンプに来る人達が気持ちよく過ごせるようにするのです。
（プログラマが知るべき97のことより抜粋）

同じことがプログラマの世界でも言えるのではないでしょうか。

# プログラムの世界では？
新規開発もありますが、エンハンス等で他のエンジニアが作成したソースコードに
機能拡張したり、修正したりすることも多いのではないでしょうか。

ソースコードをCloneしてきた時に、愕然とすることもあるでしょう。
ツッコミたくなることもあるでしょう。

気づいても、見てみないフリをして、
既存のソースコードに極力影響がないように修正するエンジニアが多いのではないでしょうか。

そこで登場するのが、「ボーイスカウト・ルール」です。

何も大掛かりにリファクターしろとは言いません。
変数名を適切に変えたり、長いメソッドを2つに分割したり、
そんな些細な配慮で「来た時よりも美しく」なります。

自分も含め、チームメンバー全員がそのようなマインドで取り組むことにより
より品質の高いソースコードができるのではないでしょうか。

# まとめ
日本人の「おもてなし」の精神をもってプログラミングをすれば、
将来の自分にも、他のエンジニアのためにもなるのではないでしょうか。

## 参考
プログラマが知るべき97のこと
備忘録：コマンドプロンプトでパス設定

毎回ググっている気がするので記す。
`setx` を用いて行うことができる。
`setx SCALA_HOME "C:\Program Files (x86)\scala"`
`setx PATH "%PATH%;%SCALA_HOME%\bin"`
(setx PATH ～は動作確認できなかったがこれであっているはず)

2つ目のsetx PATH～を行おうとしたら
「警告: 保存されたデータは 1024 文字に切り捨てられました。」
が出て、いろいろ試してみたものの、結局GUIから設定することとなった。
しかし、
http://qiita.com/rohinomiya/items/cf5236678b3459da9017
をみるに上のでできるはず。
9/12　今日の学習内容〜Railsのビューの機能について学習！〜

###今日の学習内容
***
昨日は、テンプレート（ビュー）の基礎を学習しました。
なので、今日はテンプレートについて、少し掘り下げて学習していきました( ´ ▽ ` )ﾉ

###sprintfメソッド
***
文字列や数字の格式をそろえる際にはRubyの``sprintf``メソッドを利用するそうです。

まず、新しく練習用のアクション``practice8``を作成していきます。
内容は以下の画像を参考にしてください↓

![スクリーンショット 2016-09-12 23.31.27.png](https://qiita-image-store.s3.amazonaws.com/0/137880/85d9f6c9-4722-5dfe-c0be-a36d203e59c9.png)

次にテンプレートを作成していきましょう。
``lesson``フォルダに``practice8.html.erb``というファイルを作ってください。

![スクリーンショット 2016-09-12 23.48.11.png](https://qiita-image-store.s3.amazonaws.com/0/137880/e20df2b6-e8b1-2a0f-6b92-a7e742e3ed32.png)



↑``sprintf``メソッドは、第一引数に格式を指定し、第二引数以降に指定した引数（今回なら``@popuration``のように）が埋め込まれます。

よく使われるものでは、整数``%d``、浮動小数点数``%f``、文字``%c``ですね。
ここら辺はC言語をやったことがあったのですんなりと使えましたが、これまで使ったことのない人は、覚えておいたほうがいいかもしれませんね( ´ ▽ ` )ﾉ

以下、実行画面です↓
数値については適当なので、気にしないでくださいね（笑）

![スクリーンショット 2016-09-12 23.48.52.png](https://qiita-image-store.s3.amazonaws.com/0/137880/dc16cb87-a0f7-e6ae-b3a4-34b722715a21.png)



###あとがき
***
今日は、書く時間が取れなかったので、ここまでにさせていただきますm(__)m

学習自体は、もう少し進めたんですけどね〜（笑）
こんな駄文ですが、読んでくださり、ありがとうございました。

###参考にさせていただいたサイト・参考文献
***
- [改定3版基礎RubyOnrails](https://www.amazon.co.jp/dp/4844338153)
- [cloud9](https://ide.c9.io/)
Powerlineは導入が面倒だからlightline.vim使うといいよ

Powerlineのインストールが面倒すぎたので、代替物を探していたらこいつに出会いました。

itchyny/lightline.vim: A light and configurable statusline/tabline for Vim
https://github.com/itchyny/lightline.vim

作者はitchynyさん（日本人）。ミニマルさを意識して作られているようで好感が持てます。

作者が教える！ lightline.vimの導入・設定方法！ 〜 初級編 - インストールしよう - プログラムモグモグ
http://itchyny.hatenablog.com/entry/20130828/1377653592

## インストール



```.vimrc
NeoBundle 'itchyny/lightline.vim'
```

これだけでMacVim(Kaoriya)で動く！！

![ 2016-09-12 at 22.38.46.png](https://qiita-image-store.s3.amazonaws.com/0/28666/89041fc6-f009-91a0-ed6a-8d69015f329a.png)

## homebrewでいれたvimで動かなかったけど治った

```
NeoBundle 'itchyny/lightline.vim'
set laststatus=2 "ステータスラインを常時表示させる
set t_Co=256
```

これもドキュメントに書いてありますね。

![ 2016-09-12 at 22.51.50.png](https://qiita-image-store.s3.amazonaws.com/0/28666/6eab523d-ee89-6d6c-dda9-6aa3c2434f81.png)
HSTS によって開発サーバーにアクセスできなくなった

# オレオレ証明書を開発サーバーで発行

良い子は「[オレオレ証明書は外部アクセスがありうる場所では使うなよ](http://qiita.com/Sheile/items/dc91128e8918fc823562)」との事なのでマネしないように

# オレオレだから怒られる。しかも例外に追加できない
まぁ、オレオレなのでブラウザから怒られるのはしゃーないとして、例外に追加できない。  
メッセージには

> このサイトでは、暗号化された通信のみで接続するよう Firefox に指定する HTTP Strict Transport Security (HSTS) が使われています。そのため、この証明書を例外に追加することはできません。

と出てきている

もうマルッとそのまま検索バーに突っ込んで調べたら、俺と同じくドハマりした方がいらっしゃったので拝見
[HSTSによる強制HTTPS無間地獄にどハマりした件](https://nakayan.jp/18000.html)

おかげさまで助かりました。
Nginxではデフォルトでこの設定になっていたと思うので、使う人は要注意。

リンクを張り付けただけになるけど、備忘録として。
素人の言語処理100本ノック:04


[言語処理100本ノック 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)の挑戦記録です。環境はUbuntu 16.04 LTS ＋ Python 3.5.2 \:\: Anaconda 4.1.1 (64-bit)です。過去のノックの一覧は[こちら](http://qiita.com/segavvy/items/fb50ba8097d59475f760)からどうぞ。

## 第1章: 準備運動

###04.元素記号
>"Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."という文を単語に分解し，1, 5, 6, 7, 8, 9, 15, 16, 19番目の単語は先頭の1文字，それ以外の単語は先頭に2文字を取り出し，取り出した文字列から単語の位置（先頭から何番目の単語か）への連想配列（辞書型もしくはマップ型）を作成せよ．

出来上がったコード：

```python:main.py
# coding: utf-8
num_first_only = (1, 5, 6, 7, 8, 9, 15, 16, 19)
target = 'Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.'
result = {}

words = target.split(' ')
for (num, word) in enumerate(words, 1):
	if num in num_first_only:
		result[word[0:1]] = num
	else:
		result[word[0:2]] = num

print(result)
```

実行結果：

```python:端末
{'K': 19, 'S': 16, 'He': 2, 'Al': 13, 'B': 5, 'Mi': 12, 'C': 6, 'O': 8, 'Li': 3, 'N': 7, 'Na': 11, 'H': 1, 'Si': 14, 'P': 15, 'Ne': 10, 'Ca': 20, 'Ar': 18, 'F': 9, 'Be': 4, 'Cl': 17}
```

あれ？原子番号12のMg（マグネシウム）だけおかしいですね。Miになっています。でも、該当する位置の単語はMightなので、プログラムは正しそう。

[`enumerate()`](http://docs.python.jp/3/library/functions.html#enumerate)が開始番号を指定できるのは便利。進んでしまったイテラブルの途中から列挙したい場合などに、コードがシンプルになりそうです。

###実行する度に結果が変わる！？
このプログラム、実行する度に結果が変化することに気づきました。

```python:実行結果2
{'B': 5, 'Al': 13, 'Be': 4, 'Cl': 17, 'P': 15, 'Si': 14, 'Ca': 20, 'Ne': 10, 'O': 8, 'K': 19, 'S': 16, 'Li': 3, 'He': 2, 'Na': 11, 'C': 6, 'Ar': 18, 'Mi': 12, 'H': 1, 'F': 9, 'N': 7}
```

```python:実行結果3
{'B': 5, 'He': 2, 'H': 1, 'C': 6, 'Be': 4, 'Si': 14, 'O': 8, 'F': 9, 'P': 15, 'Ca': 20, 'Al': 13, 'Ne': 10, 'Li': 3, 'K': 19, 'S': 16, 'Ar': 18, 'Cl': 17, 'Mi': 12, 'Na': 11, 'N': 7}
```

```python:実行結果4
{'Cl': 17, 'Si': 14, 'Al': 13, 'C': 6, 'Ca': 20, 'O': 8, 'He': 2, 'N': 7, 'F': 9, 'Ar': 18, 'Na': 11, 'Mi': 12, 'H': 1, 'P': 15, 'Be': 4, 'Ne': 10, 'Li': 3, 'B': 5, 'S': 16, 'K': 19}
```

辞書への格納順序は全く同じなので、なかなか興味深い挙動です。実行の度にハッシュ関数が変化しているのでしょうか。でも何のために？あ、もしかしたら`print()`時に、使用アドレスの影響を受けて順番が変わるとか？
余談ですが、Cのプログラマ時代、辞書の実装で、衝突によるパフォーマンス悪化と、その回避によるハッシュテーブルのメモリ消費量増大のトレードオフに胃を痛めてきた経験があるので、内部実装が気になります。PythonはCで実装されていると聞いたので、時間に余裕ができたらちょっと覗いてみたいところです。
　　
5本目のノックは以上です。誤りなどありましたら、ご指摘いただけますと幸いです。
EBSのボリュームサイズを縮小する

EBSのディスクサイズを縮小するやり方はググると色々出てくるものの、なぜか現在のEBS Backedなインスタンスだと日本語の情報の手順ではできなかったのでメモ。

普通にゆっくりインスタンスを止められる状況でのやり方です。（スナップショット取って新しいVMでやることなどで停止時間は短くすることは可能）

## 1. 新規のEBSを作成

まず目的のサイズのEBSを持ったEC2インスタンスを作り、そのEBSボリュームをデタッチすることで作成する。
というのもこうしないと Partition に BIOS Boot Partition が無くて立ち上がらないため。

そしてこのボリュームのVolumeIDをメモっておく。VMはこの時点で用済みということで削除。

## 2. 作業用EC2を作成

t2.smallインスタンスで十分ぽい。
以下作業は全て root にて。

数百ギガだと rsync でのコピーが長く tmux にて作業したいのでtmuxをインストール。
AWSコマンドのjson操作でjqは必須なのでこれも入れる。

あと aws configure で cli 操作もできるようにしておく。権限はEC2周りはフルアクセスで。

```
# yum install tmux jq
# aws configure
AWS Access Key ID []: xxx
AWS Secret Access Key []: xxx
Default region name []: ap-northeast-1
Default output format [None]: json

(この後のコマンドでよく使うので)
# export INSTANCE_ID=`/opt/aws/bin/ec2-metadata  | grep instance-id | cut -d " " -f2`
# export NEW_VOLUME_ID=メモっておいたVolumeID
```

## 3. 新EBSをAttach

```
aws ec2 attach-volume --volume-id ${NEW_VOLUME_ID} --instance-id ${INSTANCE_ID} --device /dev/sdf 
lsblk #確認
```

## 4. フォーマットして余計なデータをなくす

```
mkfs.ext4 /dev/xvdf1 
```

## 5. 元となるEBSをEC2からデタッチし、作業用AWSにアタッチ

```
export TARGET_NAME=hoge
export TARGET_ID=`aws ec2 describe-instances --filters "Name=tag:Name,Values=${TARGET_NAME}" | jq -r '.Reservations[].Instances[].InstanceId'`

aws ec2 describe-instances --instance-ids ${TARGET_ID} | jq -r '.Reservations[].Instances[].BlockDeviceMappings[].Ebs.VolumeId' | xargs aws ec2 detach-volume --volume-id
aws ec2 attach-volume --volume-id {戻り値のボリューム名} --instance-id=${INSTANCE_ID} --device /dev/sdg
```



## 6. パーティションにラベルを付ける

xvdgと同じラベルをつける。（/etc/fstab や /boot/grub/grub.conf で指定されている値にしない場合に起動時にボリュームがマウントされないため。）

```
e2label /dev/xvdg1
e2label /dev/xvdf1
e2label /dev/xvdf1 /
e2label /dev/xvdf1
```


## 7. デバイスをマウント

```
mkdir -p /mnt/small /mnt/large
mount -t ext4 -r /dev/xvdg1 /mnt/large
mount -t ext4 /dev/xvdf1 /mnt/small
df -hT
```

## 8. Rsyncでコピー

```
tmux
rsync -ax /mnt/large/ /mnt/small
```

## 9. アンマウント

```
umount /mnt/large/ /mnt/small/
```

## 10. EBSをデタッチ

```
/opt/aws/bin/ec2-describe-instances --region ap-northeast-1 `/opt/aws/bin/ec2-metadata  | grep instance-id | cut -d " " -f2` | grep /dev/sd | cut -f 3 | xargs -n 1 aws ec2 detach-volume --volume-id
```

※適当なワンライナーなのでちょっと動作が変わると動かないかも

## 11. 元のEC2に新しい方のEBSをアタッチして起動後に動作確認

```
aws ec2 attach-volume --volume-id ${NEW_VOLUME_ID} --device /dev/xvda --instance-id $TARGET_ID
aws ec2 start-instances --instance-ids $TARGET_ID
```

## 12. スナップショットを取ってAMI作成

```
aws ec2 create-image --instance-id $TARGET_ID --name ${TARGET_NAME}_`date "+%Y%m%d"`
```

## 13. イメージからインスタンスを作り直す

CloudFormation使ってればImageIdを変更するだけだったり。
インスタンスが問題なく立ち上がったら不要なEBSボリュームやスナップショットを削除して完了。


# 参考

http://superuser.com/questions/332252/creating-and-formating-a-partition-using-a-bash-script
http://atodorov.org/blog/2014/02/07/aws-tip-shrinking-ebs-root-volume-size/
Googleカレンダーライクなスケジューラーを作成する手段をまとめる

# 0. 前書き
スケジュール管理をするアプリケーションを作成するときに、よく真似したいと話題に上がるのがGoogleカレンダーのようなスケジューラーアプリケーションです。下記のような特徴を持っていると思いますよね。

1. ビュー（月、週、日）の切り替えができる
2. スケジュールの作成や移動がマウス操作でできる

ゼロから機能を作成するのも大変ですので、こういったことが実現できるライブラリーを探してみたいと思います。実現手段はWebアプリケーションとします。

# 1. 見つけたライブラリー
無償・有償問わず探した結果、下記のライブラリーが使えそうです。
前述の2つの要望にも答えてくれています。

- FullCalener
- Kendo UI の Scheduler
- DHTMLX の Scheduler

各製品ホームページに記載のサンプルのスクリーンショットを添えて解説します。

## 1-1. FullCalender
jQuery Pluginとしてオープンソースで開発されているプロダクト。
https://fullcalendar.io/
機能的にも、充実しているライブラリー。更新も順調に進んでおり現在ver.3。
見た目もシンプルで、ドキュメントも充実しているため好印象です。

![image](https://qiita-image-store.s3.amazonaws.com/0/34410/50511609-7003-b2db-c7c7-7d957aed50c7.png)

## 1-2. Kendo UI の Scheduler
有償ライブラリーである[Kendo UI](http://demos.telerik.com/kendo-ui/)のコンポーネントの一つ。
http://demos.telerik.com/kendo-ui/scheduler/index/
PDFエクスポート機能などもあります。デフォルトの見た目が少し悪い（煩雑な）ので、
ここからそれっぽく組み込んでいくにはけっこうな体力がかかりそうです。
1開発者当たり999ドル（他のコンポーネントも含む）。

![image](https://qiita-image-store.s3.amazonaws.com/0/34410/c5faa7c9-7705-583a-fdff-870caba7e821.png)

## 1-3. DHTMLX の Scheduler
有償ライブラリーのDHTMLX Scheduler。
http://dhtmlx.com/docs/products/dhtmlxScheduler/
ビューに「年」があります。また、こちらもPDFエクスポートできますね。
DHXでは、このスケジューラー単体で売り物にしているため、なんとなく安心感があります。
全機能を使うことができるCommercial Licenseは、449ドル（開発者5名まで）。

![image](https://qiita-image-store.s3.amazonaws.com/0/34410/980aef71-1b37-be9b-f558-306ff0f96fd0.png)

# 2. おわりに
今回はGoogleカレンダーライクなパーツを探してみました。有償ライブラリを踏まえてもFullCalenerがシンプルでドキュメントも分かりやすく、開発も活発なためおすすめですね。
QTableWidgetでExcelとコピペできるようにする

残念ながらQTableWidgetはデフォルトでコピー、ペーストができないので実装する必要があります。また、どうせならExcelと連携できると便利です。とりあえずの実装ですがメモがてら共有しときます。

環境：Windows、Qt4.8.6、C++

```cpp
// 初期化処理時にショートカットを登録
{
        QShortcut *scCtrlC = new QShortcut(QKeySequence("Ctrl+C"), ui.tableWidget);
        connect(scCtrlC, SIGNAL(activated()), this, SLOT(copyCell()));
        QShortcut *scCtrlV = new QShortcut(QKeySequence("Ctrl+V"), ui.tableWidget);
        connect(scCtrlV, SIGNAL(activated()), this, SLOT(pasteCell()));
}
```

```cpp 
// 選択したセルをコピーする
void mainwindow::copyCell()
{
        QAbstractItemModel* model = ui.tableWidget->model();
        QItemSelectionModel* selection = ui.tableWidget->selectionModel();
        QModelIndexList indexes = selection->selectedIndexes();

        if (indexes.count() == 0) {
                return;
        }

        qSort(indexes); // デフォルトだと列ソートのため行でソートする

        QString clip;
        QModelIndex previous = indexes.first();
        indexes.removeFirst();
        clip.append(model->data(previous).toString());

        for each(QModelIndex current in indexes.toVector())
        {
                if (current.row() != previous.row())
                {
                        clip.append("\n");
                }
                else
                {
                        clip.append("\t");
                }

                clip.append(model->data(current).toString());
                previous = current;
        }

        QApplication::clipboard()->setText(clip);
}

// クリップボードの内容をセルを貼り付ける
void mainwindow::pasteCell()
{
        if (ui.tableWidget->selectedItems().size() != 1)
        {
                return;
        }
        QString clip = QApplication::clipboard()->text();
        QStringList rowList = clip.split("\n");

        QTableWidgetItem *currentItem = ui.tableWidget->selectedItems().first();
        int pasteRow = currentItem->row();
        int pasteCol = currentItem->column();
        for each(QString row in rowList.toVector())
        {
                QStringList colList = row.split("\t");
                for each (QString cell in colList.toVector())
                {
                        table->item(pasteRow, pasteCol)->setText(cell);
                        pasteCol++;
                }
                pasteCol = currentItem->column();
                pasteRow++;
        }
}
```

参考
http://stackoverflow.com/questions/1230222/selected-rows-line-in-qtableview-copy-to-qclipboard
ReactをES6で開発時のbindの問題


# 自己紹介

じゅんじゅんというニックネームで、関西を拠点に活動しているフロントエンドエンジニアです。

HAL大阪の2回生です👍 (2016.9.12現在)

よくstart up系イベントに行くので、大阪らへんの方は会いましょう！

# bind問題とは

ReactをES6で書いた場合に、イベントハンドラでthisがundefinedとなりメソッドが実行できないという問題。

これはFacebookのReact公式にも書いていて

[Reusable Components](https://facebook.github.io/react/docs/reusable-components.html)

このリンクの中盤すぎぐらいに__ES6 Classes__と書いている欄。

___No Autobinding___と書いている。明示的にthisをバインドしてね！ってことらしいぞと。

ということで、解決策を具体的に書いていきたいと思います。

## 解決策たち

解決策的には

1. constructor内に明示的にbind
2. es6のアローファンクションを使う
3. jsxコンポーネント内でbind
4. stage-0でメソッドの定義をする
5. es7のbindオペレータを使う

前半3つはすぐに導入することができますが、後半2つを使うには少しプラグインなどを入れる必要があります。

### 1. constructor内に明示的にbind

```js
constructor(){
  super()
  this._hoge = this._hoge.bind(this);
}

_hoge(){
  console.log("hoge");
}
```

この方法は、メソッドが多くなるにつれてthis祭りになるので、推奨はしないですが楽です（）

### 2. es6のアローファンクションを使う

```js
render(){
  return(
    <button onClick={(e)=>this._click(e)}>click me</button>
  )
}

_click(){
  console.log("click!")
}
```

この方法は、eventを渡す必要があるようなので`(e)=>this._click(e)`と書いています。

### 3. jsxコンポーネント内でbind

```js
render(){
  return(
    <button onClick={this._click.bind(this)}>click me</button>
  )
}

_click(){
  console.log("click!")
}
```

これは、コンストラクタでthisのbindをしていない分jsxの方で書いとくぜ！って感じなんですかね。


### 4. stage-0でメソッドの定義をする

まず、この開発環境でstage-0が使えるようにしないといけません。

`npm install babel-preset-stage-0`

`.babelrc`にも記述しましょう

```text:.babelrc
{
  "presets": ["react", "es2015","stage-0"]
}
```

メソッドの書き方を変えましょう。

```js
render(){
  return(
    <button onClick={this._click}>click me</button>
  )
}

_click = () => {
  console.log("click!")
}
```

### 5. es7のbindオペレータを使う

es7のbindオペレータを扱うためにbabelにプラグインとして

[transform function bind](http://babeljs.io/docs/plugins/transform-function-bind/)を使います。

`npm install babel-plugin-transform-function-bind`

`.babelrc`にも記述しましょう

```text:.babelrc
{
  "presets": ["react", "es2015"],
  "plugins": ["transform-function-bind"]
}
```

jsx内のthis._clickを書き換えます

```js
render(){
  return(
    <button onClick={::this._click}>click me</button>
  )
}

_click(){
  console.log("click!")
}
```

この5つの方法以外の方法に、ReactのComponentを継承して自分でMyComponent見たいなものを作り、そのMYComponentのコンストラクタで`_`から始まるメソッドは全部thisでバインドする。みたいな書き方ができそう！って感じですが、今回はこの5つの方法で記事をまとめておきます。

# 最後に

個人的にReactをとても活用していて、最近やっとReactNativeを触り始めました。。

すごいですね...w

Googleのトレンド的にはAngular2とかがトレンドらしいので、また時間があれば噛んでみようかなと思ってます！

Twitter [@konojunya](http://twitter.com/konojunya)
java8のリストソート方法

java8 のリストソートメモ

``` SampleBean.java
public class SampleBean {

    private String id;
    
    private String name;
}
```

```
List<SampleBean> sampleList;
```

をid順でソートする方法

```
sampleList.sort(Comparator.comparing(SampleBean::getId));
```

逆順ソート

```
sampleList.sort(Comparator.comparing(SampleBean::getId).reversed());
```
マルチ・プラットフォームを扱うインフラ屋さんのための連携技術: SSH編 その2

#z/OSのSSHについての補足

[マルチ・プラットフォームを扱うインフラ屋さんのための連携技術: SSH編](http://qiita.com/tomotagwork/items/b35aa09c1aa1acb3d554)の続きです。
異なるプラットフォームを扱う際は、「文字コード」の違いが問題になるケースがあります。
大体こんな感じの使い分けがされてます。

* Windows: SJIS
* Unix/Linux: UTF-8/ECU-JP/SJIS
* z/OS(USS含む): EBCDIC

z/OSのUSS(Unix System Service)は、Unixと言いながらもメインフレームなだけあってやっぱり文字コードはEBCDICで扱われます。
[z/OSのユーザー・インターフェースについて考える ～teraterm利用のすゝめ～](http://qiita.com/tomotagwork/items/5ae230c7a215f6ef4409)
こちらの記事でも書いているように、z/OSのUSS使うときも他のプラットフォームと同じようにteraterm使いましょうよ、ということを言っているのですが、teratermが普通にz/OSでも使えているのが実は不思議でした。コード変換ってどうしてるのかな～？という疑問をしばらく放置していたのですが、関連する記述見つけたので補足しておきます。

z/OS V2.2のマニュアル
[z/OS V2R2 OpenSSH User's Guide - Globalization on z/OS systems - OpenSSH and globalization](https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.2.0/com.ibm.zos.v2r2.foto100/fotz127.htm)

この記述によるとこんな感じです

* SSHクライアント(Windows) - SSHサーバー(z/OS)間の通信では、ASCII-EBCDIC変換が行われる
* ネットワーク上はISO8859-1(ASCII)でデータのやり取りが行われる
* マルチバイトのロケールはサポートされない。つまり日本語はNG。

もう1つ疑問だったのはscp(sshプロトコルを使用したファイル転送)を使う場合。scpはftpのように転送モード(binary/ascii)が無いので基本バイナリーで扱われるものだと思ってましたが、Windows-z/OS間ではコード変換されていました。これについても上のマニュアルに記載がありまして、z/OSのSSHではscpは基本的にファイルはテキストとして扱われ、なんとコード変換の対象になってしまうんですと。ということは逆に言うとバイナリのファイル(tarとか画像とか)をscpで送受信したらどうなるかと思ってやってみると、コード変換してくれちゃったらしく、案の定壊れました。
ということで、z/OSとの間でファイル転送する場合はftpとか他の仕組みを考えた方がよさそうですね(日本語含まないテキストをさくっとコピーする分には便利ですけど)。
lambdaを使ってリストをマップ化

lambdaの使い方メモ

リストに入っているデータを後の処理(for文とか)で使うために、一度マップ化しておくことがよくあります。
以前はリストをfor文で回してMapにputしていましたが、lambdaを使うと1行でかけることを知りました。

``` SampleBean.java
public class SampleBean {

    private String id;
    
    private String name;

    // getter,setter
}
```

```
List<SampleBean> sampleList;
```

を

```
// Key=ID, Value=SampleBean
Map<String, SampleBean> sampleMap;
```

のMapにする。

lambdaを使わない場合はこう

```
Map<String, SampleBean> sampleMap = new HashMap<>();
for (SampleBean bean : sampleList) {
    sampleMap.put(bean.getId(), bean);
}
```

lambdaを使った場合はこう

```
Map<String, SampleBean> sampleMap = sampleList.stream().collect(Collectors.toMap(SampleBean::getId, bean -> bean));
```

こんな風にもかける。

```
Map<String, SampleBean> sampleMap = sampleList.stream().collect(Collectors.toMap(bean -> bean.getId(), bean -> bean));
```

-> と :: の使い方になんか名前があったような気がしたけど忘れてしまいました。。
気になったことはすぐメモするべきですね
始めてのOpenCV [ Node.js ]

# 自己紹介

じゅんじゅんというニックネームで、関西を拠点に活動しているフロントエンドエンジニアです。

HAL大阪の2回生です👍 (2016.9.12現在)

よくstart up系イベントに行くので、大阪らへんの方は会いましょう！

# OpenCVとは

> OpenCVとは、Intelによって開発された、画像認識に関連する機能のライブラリのことである。 OpenCVは、コンピュータビジョンと呼ばれる、画像認識・解析に関するコンピューティング技術が主な用途として想定されている。

画像認証・解析ができるライブラリです！

まず、本体にインストールしなければいけません。

以下の記事を参考にインストールしてください。

[MacにOpenCVをインストールする方法](http://qiita.com/daisukeokaoss/items/738566e9f24d114651ab)

# Dissimilarity

今回は、OpenCVで2枚の画像がどれだけ似ているかを数値化できるものを使います。

ファイルの構成は

```
- app.js
- images/
    - image files...
- package.json
```

# 開発

先ほどのOpenCVをNode.jsから扱えるように、npmで`node-opencv`をインストールします。

[peterbraden/node-opencv](https://github.com/peterbraden/node-opencv)

`npm install opencv`

これで開発環境は整いました！

早速app.jsを書いていきましょう。

今回は`images/`に僕のアイコンを用意しました！

![スクリーンショット 2016-09-12 17.22.23.png](https://qiita-image-store.s3.amazonaws.com/0/90347/55090ae6-90e4-a56e-3fb7-270a2a0f177d.png)

この２枚はどれぐらい似ているんでしょうか！

```js:app.js
var cv = require('opencv');

if (cv.ImageSimilarity === undefined) {
  console.log('TODO: Please port Features2d.cc to OpenCV 3')
  process.exit(0);
}

cv.readImage("./images/icon.jpg",function(err,im){
  if (err) throw err;

  cv.readImage("./images/icon2.jpg",function(err,im1){
    if (err) throw err;

    cv.ImageSimilarity(im,im1,function(err,dissimilarity){
      if(err) throw err;

      console.log(`Similarity: ${100 - Math.round(dissimilarity)}`);

    })      

  });

});
```

まず、cvにopencvを読み込みます。

このcvの`readImage`メソッドを使い画像を読み込み、matrixを返します。

それを2つ用意し、`ImageSimilarity`メソッドを使い二つの画像の相違を数値化します。

その数は、callbackの`dissimilarity`に入っています。

ここで帰ってくる値は___相違の数値___なことに気をつけてください。

つまりここでかえってくる数が多い→相違点が多い→似ていない。となります。

ではこれを大雑把ですが四捨五入して100から引いてどれだけ似ているか。に変えてあげる必要があります。

(100から引いているのは、上限が100くさいぞ...ってだけなので玄人の方、間違っている場合コメント欄で指摘ください。。)

`dissimilarity`を四捨五入して100から引くので

`100 - Math.round(dissimilarity)`となります。

# 最後に

今回、初めてNodeでOpenCVを触ってみました。

いくつもメソッドがあるので、やりたいことを実現するのに方法を選定していかないとな〜と思いました。

参考にした記事

- [Node.jsとOpenCVで顔認識してみます。 by n0bisuke](http://qiita.com/n0bisuke/items/f650a876d14807b70f80)

のびすけさんの記事は、参考になるものが多いです...さすがすぎる...

Twitter是非フォローしてね！ [@konojunya](http://twitter.com/konojunya)
publicで公開してしまったgistをsecretにする方法

#はじめに
現在、gistを**publicからsecret**に変更する方法は提出されていません。
今回は、publicで作成してしまったgistを新規に作成するsecretのリポジトリに移し変えることで代用しようと思います
##1 publicで上げたgistをローカルに落とす
まず、publicで上げてしまったgistのCopy to clipboardを**Clone via HTTPS**にし、urlをコピーし、コマンドラインで　
```　$ git clone "publicの方のurl"
$ cd "cloneしたフォルダ"　```
します
##２ privateでgistを作成
誤って上げてしまったファイルと同じ名前でNew gistを**Create　secret　gist**で作成し、gistのCopy to clipboardを**Clone　via　HTTPS**にし、urlをコピーします。
##3 `git push -f`で強制的に書き換える
コマンドラインで
```$ git remote set-url origin "privateの方のURL"```
し、remote urlを切り替えます。最後に
```$ git push -f origin master```
で強制的にpushしてあげれば完了です。これでログも残ったままpublic gistをprivate gistに切り替えれます。
MVCフレームワークを作る際にドキュメントルートの設定をcloud9で行った

ドキュメントルート変更の方法やコマンドは環境によって違うらしい

・cloud9の場合
1.設定ファイルのパス

```
/etc/apache2/sites-enabled/001-cloud9.conf
```
2.編集箇所

```
DocumentRoot /home/ubuntu/workspace/public
```
3.編集コマンド

```
sudo vim /etc/apache2/sites-enabled/001-cloud9.conf
```

3.参考サイト
http://cloudfish.hatenablog.com/entry/2015/09/18/022222
[NodeJS for Android]ビルド済のバイナリはここだ

前回の[NodeJS-Android完璧なビルド方法](http://qiita.com/QianJin2013/items/2e1300f8d317b2642f12)の続きです。

いろいろ整理して、ビルド済のバイナリを[ここ](https://github.com/sjitech/nodejs-android-prebuilt-binaries)に提供しました！

コンパイルせずに、nodeバイナリをダウンロードできます。

現在はNodeJS 6.5.0-7.4.0のビルド結果をアップロードしましたが、他のバージョンや自分の修正をビルドするには、いくつか便利な方法があります：

- Docker image `osexp2000/build-nodejs-for-android`でビルド

    [NodeJS-Android完璧なビルド方法](http://qiita.com/QianJin2013/items/2e1300f8d317b2642f12)で提供したDocker image を利用して、~/nodeに入って`git checkout v6.4.0`か`git checkout master`のようにバージョンを切り替えて、あるいは直接ソースを修正して、最後に、用意済の`build-nodejs-for-android`コマンドでビルドする、例
    ```
    build-nodejs-for-android . --arch arm -o ../nodejs-6.4.0-android-arm --pre-clean
    ```
    ほとんどのソースは変更ないので、ビルドはキャッシュが利用でき、すごく早いはず。

- ローカルでビルド

    スクリプト[build-nodejs-for-android](https://github.com/sjitech/build-nodejs-for-android/blob/master/build-nodejs-for-android)を利用してローカルマシンでビルドする。

    もちろん、このスクリプトはandroid-gcc-toolchainのラッパーです。

以上です。
Windows10 に Vagrantをインストールした際、vagrant -vの時点でエラー

# はじめに

Vagrantについての詳しい内容や導入方法は他の方々がわかりやすく説明してくださっているので割愛いたします。申し訳ございません。
自分は仮想マシンの構築が面倒で、最近家では、Windows上のXamppでphpの開発を行っていたのですが、vagrantを使えば簡単に仮想サーバーを構築できると伺い、喜んでインストールしてみました。

# エラー内容
インストール後、動作の確認を行おうとコマンドプロンプ上で以下のようなコマンドを実行しました。

```コマンドプロンプト
C:\Users\[user_name]>vagrant -v
```

その結果以下のようなエラーが返ってきました。

```エラー内容
C:/HashiCorp/Vagrant/embedded/lib/ruby/2.2.0/tmpdir.rb:85:in `mkdir': Permission denied @ dir_s_mkdir - c:/Users/[user_name]/vagrant-bundle-app-configxxxxxx (Errno::EACCES)
        from C:/HashiCorp/Vagrant/embedded/lib/ruby/2.2.0/tmpdir.rb:85:in `block in mktmpdir'
        from C:/HashiCorp/Vagrant/embedded/lib/ruby/2.2.0/tmpdir.rb:129:in `create'
        from C:/HashiCorp/Vagrant/embedded/lib/ruby/2.2.0/tmpdir.rb:85:in `mktmpdir'
        from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.8.4/lib/vagrant/bundler.rb:59:in `init!'
        from C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.8.4/lib/vagrant/pre-rubygems.rb:23:in `<main>'
```

テンポラリディレクトリがうまく取得できていないようで、確認してみると、
```%USERPROFILE%\AppData\Local\Temp```
でのwritable?関数がfalseを返しているようでした。
一応Cドライブ直下にtmpというディレクトリを作成することで動作するようにはなったようだけれど、勉強不足のため、なぜ上記の一時ディレクトリが書込不可となっているのかまではわかりません。。。
権限はどのユーザーでも書き込みできるようになっていたし、他のソフトは問題なく書き込みできているっぽいんだけどなあ。。。

# 追記（9/15）
原因がわかりました。
Vagrantをインストールした`C:\HashiCorp\`以下の整合性レベルがLowとなっていたことが原因だったようです。管理者権限でコマンドプロンプトを実行し、以下のコマンドを実行し、整合性レベルをMediumにしたところ、問題なく動作するようになりました。やっぱりwindowsの権限管理は難しいですね。。。
`C:\WINDOWS\system32>icacls C:\HashiCorp\* /setintegritylevel M /T`
しとりーのRedisのSortedSetの理解の仕方


「マニュアル上で使われている"用語"に対する理解の仕方」と、「PHPで書くとこんな感じやろ」の2点を書いときます。

# 私の、用語に対する理解の仕方

マニュアル上での名前 | 私の理解の仕方 | 補足
:-- | :-- | :--
key | 変数名 | いわゆる、変数名。
member | キー名 | ハッシュとか配列とかで言う、キー名とかインデックス。
score | 値 | 配列の中身。常に整数で、SortedSetは常にこれを基に昇順に（0から始まって、大きくなってくように）ソートされた状態を保つ。

# 要するに、SortedSetってこういう感じのやつでしょ？

つまり、以下の2つを「同じようなもの」という理解の仕方をしてます。（実際は違うと思うけど。）

```bash
ZADD zset1 1 "one"
ZADD zset1 3 "three"
ZADD zset1 2 "two"
```

```php
<?php
$zset1['one'] = 1;  array_sort($zset1);
$zset1['three'] = 3;  array_sort($zset1);
$zset1['two'] = 2;  array_sort($zset1);
```

# あとがき

本当は、SortedSetの実装部分読んで、実際はどういう実装のされ方してるのかまで確認したかったけれど、まだやってないです。
WebRTCハンズオン 準備編

# はじめに

- この資料は、WebRTCハンズオン勉強会(2016.09.19/2017.04.09)用の資料です。
- 資料の全体はこちらのINDEXを参照してください。
  - [WebRTCハンズオン資料 INDEX - Qiita](http://qiita.com/yusuke84/items/de9f0f6d221acec6fc07)

### 今日のハンズオンで必要なもの

- 参考:[WebRTCを試すために必要なもの](http://qiita.com/massie_g/items/fc5e82d192f6767123bc
)


---
### ハードウェア
- ノートパソコン... Windows, Mac (, Linux)
- Webカメラ ... 内蔵、またはUSB接続のもの
    - USB接続の場合は「ドライバ不要」のもの

---
### ソフトウェア
- エディタ... お好きなもの
- ブラウザ... 今回はChromeを推奨
    -  （2016年9月現在、Chrome 53が最新）
    -  2017年4月現在、Chrome 57が最新、Firefoxは52
    -  2019年1月現在、Chrome 71が最新、Firefoxは74
    -  ※今日はChrome 71 を前提に説明します
- ローカルのWebサーバー
    - Apache, nginx, PHP/Python/Ruby付属など
    - Visual Studio Code の機能拡張がおすすめ
    - 参考：[開発用ローカルサーバを立ち上げる方法](http://qiita.com/higuma/items/b23ca9d96dac49999ab9)
    - 参考：[お手軽なWebサーバーの立て方](http://qiita.com/massie_g/items/2913066e596dae197539)
- Node.js (v4.x or v6.x or v7.x or ) v8.x v10.x
    - シグナリングサーバーで利用

※ Webサーバーの準備ができていない方は手をあげてください。サポートします
※ Node.jsの準備ができていない方は手をあげてください。サポートします

---
### ネットワーク接続

- シグナリングの過程でICE Candidateと呼ばれる通信経路情報を収集
    - PCがネットワークにつながっている必要あり
    - 完全にスタンドアローンの状態では収集できない
- 今日は会場のWiFiがある、はず

---
### 元になるソースコード

元になるソースコードをGitHubから取得

- WebRTCハンズオン 本編
    - https://github.com/yusuke84/webrtc-handson-2016
- MediaRecorder編 （録画）
    - https://github.com/mganeko/handson_201609 

git clone、またはzipをダウンロード→解凍してください

```shell-session:gitの場合
git clone https://github.com/yusuke84/webrtc-handson-2016.git
git clone https://github.com/mganeko/handson_201609.git
```

※ソースの取得方法が分からない場合は、手をあげてください。サポートします


---
## ここまで、準備はできましたか？

- 何か質問や、困っていることがある人は？

## それでは、ハンズオン本編をどうぞ！

- [WebRTCハンズオン 本編](http://qiita.com/yusuke84/items/43a20e3b6c78ae9a8f6c)
fluentdのforestプラグインで生成されるプラグインにplugin_idをつける方法

[fluent-plugin-forest](https://github.com/tagomoris/fluent-plugin-forest)によって生成されるプラグインに`plugin_id`をつけることで、エラーログの調査などがしやすくなります。

タグごとに `plugin_id` をつけるには以下のようなconfを書けばOKです。

```
<match hoge.**>
  @type forest
  subtype your_plugin
  <template>
    @id out_forest_${escaped_tag}
    ...
  </template>
</match>
```

上記の設定で、forestプラグインによって生成されるプラグインには `out_forest_<タグの.を_に置換した文字列>` という `plugin_id` が付与されます。