OmniAICreator/Qiita-1.07M huggingface dataset:
Factorization Machines

スパースなデータに有効な予測，分類アルゴリズム

元論文：http://www.csie.ntu.edu.tw/~b97053/paper/Rendle2010FM.pdf
Steffen Rendle, 2010

FMの論文、主にSVMとの比較が述べられている。FMとSVMを比較した際、FMのいいところはスパース性に強いところである。さらにSVD++やPITFやEPMCなどを一般化して説明することができる点もFMの利点である。
 
SVMは協調フィルタリングには適さない、なぜなら協調フィルタリングにはスパースなデータが含まれていることが多く、カーネルではスパース性はうまく表現することができないから。
FMは線形時間で線形個のパラメータの推定を行う。

<img width="388" alt="20160525_1.png" src="https://qiita-image-store.s3.amazonaws.com/0/155619/d90db38e-2282-fb10-5cce-5fe6c6bf88b4.png">

学習データのサンプル、どのユーザーがどの映画に対してどのスコアをつけたのかのデータになっている。黄色は他のユーザーが過去にどの映画に対してつけたレビューの点数、合計が１になるように正規化をしている。

<img width="403" alt="20160525_2.png" src="https://qiita-image-store.s3.amazonaws.com/0/155619/71de8629-7031-5a1f-6c4c-a275d766015b.png">

FMの予測式、(1)を満たすような、w、vを学習させていく。(1)の3項目がポイント、交差項のパラメーターを(n*(n-1)/2)個のパラメーターにするのではなく、(n)個の次元削減されたベクトルの内積としてあげることで、学習しなければいけない変数の数を減らしている。さらに、一見関係ないようなベクトル間の距離を測ることで、関係性を他の関係性から表現することができる。
 
適用可能なタスクと損失関数の作り方
・線形予測：二乗誤差
・２値分類：ヒンジ関数 or ロジット関数
・ランキング：pairwise分類損失
どのタスクの場合もL２ノルムを加えることで、正則化を測る
 
どのタスクの場合も勾配法（SGD）で解く、微分後の勾配
<img width="397" alt="20160525_3.png" src="https://qiita-image-store.s3.amazonaws.com/0/155619/862bac66-641e-c886-5879-3186ff7c931c.png">

交互作用を表す項を多次元化することも可能
<img width="391" alt="20160525_4.png" src="https://qiita-image-store.s3.amazonaws.com/0/155619/35187a39-324f-47e7-5ea2-5a96c623e041.png">

SVMとの式の比較：線形カーネルの場合
<img width="359" alt="20160525_5.png" src="https://qiita-image-store.s3.amazonaws.com/0/155619/f44270ff-6c6b-7c49-bc41-6f8ab1a7f6b8.png">

SVMとの式の比較：多項式カーネルの場合
<img width="384" alt="20160525_6.png" src="https://qiita-image-store.s3.amazonaws.com/0/155619/91f92703-1bbb-90e8-bed1-0b08d1616090.png">

SVMがスパース性に弱い理由
多項式カーネルを用いて、２つの目的変数にフラグがついていた場合、w_{u, i}が交互作用の項を表している。しかし、学習データの中で、w_{u, i}が出てくる回数などたかだか知れているので、うまく学習ができない。なのでこの式は多項式カーネルではなく、線形カーネルと同等の精度しか表さない。なのでSVMはスパースなデータに弱い。
<img width="362" alt="20160525_7.png" src="https://qiita-image-store.s3.amazonaws.com/0/155619/97c97e32-e6f7-7e7e-78d2-0064ee4430d3.png">
newmanのすべてのリクエストにヘッダを加える

Postmanのコマンドラインツールである『[Newman](https://github.com/postmanlabs/newman)』
サービス監視のシナリオの実行にこのNewmanを用いているのですが、ログを追うためにすべてのリクエストのヘッダにX-Request-Idをつけたくなりました。
単純にすべてのコレクション内のすべてのリクエストにヘッダをつければいいのですが、実行時に毎回違う値を送信したかったり、そもそもつけるのが面倒だったりするのでJavaScriptでヘッダを付与する方法について調べました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/154533/7d44078c-0d6c-79ea-068d-45c9fbfd5d37.png" width="500px">


# Newmanの導入

* インストール

```bash
$ npm install newman --global;
```

* 実行

```
$ newman run {collection}.json;
```

# NewmanをJavaScriptで実行

```js
var newman = require('newman');

newman.run({
  collection: require('./{collection}.json'),
  reporters: 'cli'
}, function (err) {
  if (err) { throw err; }
  console.log('collection run complete!');
});
```

# Newmanのすべてのリクエストにヘッダを加える

Newmanでは実行中の各イベントによって処理を実行することができます。([イベント一覧](https://github.com/postmanlabs/newman#newmanrunevents))
今回はすべてのアイテムが実行される前のイベントであるbeforeItemでヘッダを追加する処理を実行するようにしました。

```js
var newman = require('newman'),
    PostmanHeader = require('postman-collection').Header;

newman.run({
  collection: require('./{collection}.json'),
  reporters: 'cli'
}, function (err) {
  if (err) { throw err; }
  console.log('collection run complete!');
})
on('beforeItem', function (err, args) { // イベント登録
  var xRequestId, additionalHeader;

  xRequestId = createId(20);
  additionalHeader = new PostmanHeader({ // Postmanのヘッダ情報を作成
    key: 'X-Request-Id',
    value: xRequestId
  });
  args.item.request.headers.members.push( additionalHeader ); // ヘッダを付与
});

function createId() {
  // IDを作って返す
}
```
エンジニアによるウェブサービスのプランニングについて考える


## 所管

* 関連情報源が意外と少ない気がする

## 書籍

* 100万人から教わったウェブサービスの極意―「モバツイ」開発1268日の知恵と視点
	* 大枠でITベンチャーなことの歴史とか取り巻く状況についてわかり、そういうマクロな視点での向き合い方が参考になる
* Webサービスのつくり方　――「新しい」を生み出すための33のエッセイ Software Design plus Kindle版
	* プランニングについての言及があり、ほかにもいろいろ参考になる

## ほか

* 小さく産んで大きく育てる、ユーザーからの要望ベースで改善していく
* ユースケースじゃなくてシーケンスで整理していくパターンもある

## 設計ドキュメントについて

一人だとなんか結構大変で混乱していくわー
UWPメモ　デバッグ実行中の数値とツールバーを消す

# <i class="fa fa-cubes" style="font-size:1em;"></i> 概要
UWPアプリのデバッグ実行時に表示される、左上の数字(オーバーレイデバッグカウンター)と上部中央に表示されるツールバー(XAMLのUIデバッグツール)の消し方。

![uwp01.png](https://qiita-image-store.s3.amazonaws.com/0/142879/cfe3aa83-7243-8da9-1ad9-682d33ece644.png)

# <i class="fa fa-cubes" style="font-size:1em;"></i> 消し方

## <i class="fa fa-cube" style="font-size:1em;"></i> オーバーレイデバッグカウンター

`App.xaml.cs`を開き、
![uwp02.PNG](https://qiita-image-store.s3.amazonaws.com/0/142879/fe0d97de-3220-3805-c853-38d73b2d9604.png)

`OnLaunched`の
**`this.DebugSettings.EnableFrameRateCounter = true;`**
の行をコメントアウトするか、`false`を設定する。

![uwp03.png](https://qiita-image-store.s3.amazonaws.com/0/142879/42fd20d3-aaa1-b047-eb79-3a48bd04d1ae.png)

## <i class="fa fa-cube" style="font-size:1em;"></i> XAMLのUIデバッグツール
メニューの`デバッグ` - `オプション`を選択。
![uwp04.png](https://qiita-image-store.s3.amazonaws.com/0/142879/10475456-f7b7-a463-6635-ef6fae9982dd.png)

`デバッグ` - `全般`で**XAMLのUIデバッグツールを有効にする**のチェックを外す。
![uwp05.png](https://qiita-image-store.s3.amazonaws.com/0/142879/e10adbc9-6394-6629-184f-30da1ab5330b.png)

# <i class="fa fa-cubes" style="font-size:1em;"></i> 設定後
![uwp06.png](https://qiita-image-store.s3.amazonaws.com/0/142879/58c687ab-5b8e-f4f4-f69a-415752bcbdb8.png)

# <i class="fa fa-book" style="font-size:1em;"></i> 参考サイト

* [DebugSettings.EnableFrameRateCounter Property (Windows) - MSDN](https://msdn.microsoft.com/ja-jp/library/windows/apps/windows.ui.xaml.debugsettings.enableframeratecounter.aspx)
* [［全般］ (［オプション］ ダイアログ ボックス - ［デバッグ］) - MSDN](https://msdn.microsoft.com/ja-jp/library/85yzd16c.aspx)
* [デバッグ中に XAML のプロパティを調べます。 - MSDN](https://msdn.microsoft.com/ja-jp/library/mt270227.aspx)
POG上達のためのデータ解析４　〜Rでアソシエーション分析

# はじめに  
　しばらく間が空いたが今回も引き続きPOGに関するデータ解析を行いたい。  

　とあるきっかけでアソシエーション分析なるものが存在することを知った。アソシエーション分析とは平たく言うと「｛条件｝＝＞｛結論｝」となる因子間の組み合わせ（アソシエーションルール）をある定められた条件に基づいて抽出する分析手法である。これは競馬にも使えそうだということで試してみる。

# 使用したデータ  
　[これまで](http://qiita.com/gkmaro634/items/1a8b1d1baa8532f70d56)と同様2010-2013年までの期間に生まれた馬を解析対象とする。

　解析手法の有効性が確かめられていない状態で膨大なデータを扱うと単なる徒労で終わる可能性があるので、今回は各馬の因子を「調教師」、「馬主」、「生産者」、「POG期間賞金が700万以上か否か」に絞った。

　以下にデータの一部と全体の概要を示す。

![AnalysePOG.jpg](https://qiita-image-store.s3.amazonaws.com/0/96262/40e42e24-2d32-c4ce-ae58-b404afe571a9.jpeg)

![Association_R.jpg](https://qiita-image-store.s3.amazonaws.com/0/96262/8c32cd65-049b-91e9-2177-ae0a2eba1362.jpeg)

# 解析
## 解析の流れ  
　アソシエーション分析の解析例はRが圧倒的に多い。使い慣れたPythonでもできなくはないようだが、今回はRを使うこととした。

データの下処理：Python
↓
アソシエーション分析：R

という分業体制で臨むこととする。

## 結果
　アソシエーションルールの抽出はRのapriori関数で実行できるが、引数次第で得られる結果が左右される。今回support=0.00015としたのは全データのなかで最低でも４回(１回/年)は該当する組み合わせが出現してほしいという思いから設定した。conf=0.8の根拠はない。あえて言うならばデータを間引くためである。maxlen=5も根拠はない。defaultでmaxlen=5であることを踏襲した。
![Association_R.jpg](https://qiita-image-store.s3.amazonaws.com/0/96262/8111793b-8672-fd16-60b5-cf55a68e7718.jpeg)

　その結果6743ものアソシエーションルールが抽出された。これらのうち結論として「賞金が700万以上」であり、かつlift値が2.0より大きいものだけを抽出すると21件に絞られた。

![Association_R.jpg](https://qiita-image-store.s3.amazonaws.com/0/96262/991c6470-501d-d42f-7e0a-76a47482bcf4.jpeg)

　これらのルールを可視化すると以下のようになる。実に混沌としたグラフであるが、少なくとも私がこれまで気にもとめていなかったような単語が現れているのが興味深い。

![Association_R.jpg](https://qiita-image-store.s3.amazonaws.com/0/96262/4f71f1b2-ac62-c23a-4f38-b32004c80734.jpeg)

![assosiation_2010_2013.png](https://qiita-image-store.s3.amazonaws.com/0/96262/edfee170-61f6-57e5-cdc9-4fb683b52af4.png)

# 今後
　アソシエーション分析はルール抽出の条件設定や結果の解釈方法が難しく、私個人がその妥当性を評価できるようになるまでは時間がかかりそうであるが、質的データが大半を占める競馬においては有効な手法である感触を得た。次回は血統の解析にまで手を広げPOGに有利な組み合わせをあぶり出したい。
【Docker】cAdvisorによるDockerコンテナの監視について

# cAdvisorとは？

Googleが作成しているDockerコンテナのモニタリングツールです。

Kubernetesに組み込まれていたり、Dockerコンテナのモニタリングツールとして一般化しつつあるようなので、cAdvisorについて調査しなにが嬉しいのかについて整理してみました。

# cAdvisorの動かし方

cAdvisor自体もコンテナになっているため、`docker run`で起動することができます。

```
sudo docker run \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:rw \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  google/cadvisor:latest
```

cAdvisor 自体も Docker で起動して、同ホスト上に起動している Docker コンテナの リソースをモニタリングしてくれます。

# cAdvisorで嬉しいこと

**ホスト単位でコンテナの状態をまとめてくれる**

> cAdvisor (Container Advisor) provides container users an understanding of the resource usage and performance characteristics of their running containers. It is a running daemon that collects, aggregates, processes, and exports information about running containers.

[github](https://github.com/google/cadvisor)にあるように、cAdvisorはホスト単位で起動中のコンテナのメトリクス情報を収集＆集計しAPIとして提供してくれます。
DockerRemoteAPIを使ってごりごりと加工すれば同じようなことができるかもしれませんが、cAdvisorがそのあたりを担ってくれてるので大分楽なのではないでしょうか。

また、cAdvisorではメモリ上にデフォルトで直近60秒分の情報を保持しているので、提供しているAPIでは60秒分のメトリクス情報をとることができます。

実際にメトリクス情報を取りたい場合は、`http://<ip>:<port>/api/v2.0/stats`を叩くとホスト上で動いている起動中の全コンテナの60秒分のデータをとることができます。また、`http://<ip>:<port>/api/v2.0/stats/<container_id>?type=docker`という形でコンテナIDを指定することで各コンテナ毎のメトリクスを返してくれるようです。

**GUIを提供してくれる**

cAdvisorでは以下のようなGUIも提供してくれており、

- CPU
- Memory
- Network
- FileSystem

の情報をグラフを見ることができます。

<img width="753" alt="スクリーンショット 2016-12-18 17.32.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/32184/30a88f31-1866-b89f-596d-9cf7aec10a28.png">

**簡単に起動できる**

cAdvisorはコンテナで動かすことができるため、使いたい時にコンテナを起動してサクッと使うことができます。
とりあえずコンテナのメトリクスが見たい時に余計な手間がいらず楽なのではないでしょうか。

# おわり

cAdvisorはメモリ上にしかメトリクス情報を持たないので実際にcAdvisorでメトリクス監視をするためには、InfluxDBにデータを投げGrafanaで可視化するといったことが必要になります。
cAdvisorのコンテナ起動時のオプションで楽にInfluxDBとの連携できるようなっているようなので今度やってみようと思います。

# 参考

https://jedipunkz.github.io/blog/2015/09/12/cadvisor-influxdb-grafana-docker/
http://developer.hatenastaff.com/entry/monitoring-kubernetes
https://www.infoq.com/jp/news/2016/01/dockercon-docker-monitoring
http://blog.couchbase.com/2016/april/monitoring-docker-containers-docker-stats-cadvisor-universal-control-plane
https://www.youtube.com/watch?v=sxE1vDtkYps
https://www.youtube.com/watch?v=8RY33I_KKy4
https://www.youtube.com/watch?v=dqvaibpwAWk
https://www.youtube.com/watch?v=f3URWWSyl1U
Docker for Mac + Docker KitematicでDockerをGUI操作

Dockerの環境構築をしたときのメモ

# 今回やったこと
1. Docker for Macの導入
2. Docker Hubに登録
3. Docker Kitematicの導入

# Docker for Macの導入
## Docker for Macとは
Mac OS X向けのDockerクライアント。
従来、Mac OS X, Windows向けクライアントとして、Docker Toolboxが提供されていたが、これにはVirtual Box環境が必要であった。
それに対して、Docker for Macはxhyveを使うことで、Virtual Boxなしで簡単にDockerを利用することができる。

## Docker for Macのインストール
Dockerのインストーラを以下のURLから取得。
https://docs.docker.com/docker-for-mac/

DockerアプリケーションをApplicationsフォルダへ移動
![20160406131937.png](https://qiita-image-store.s3.amazonaws.com/0/121619/bd6d417d-f51f-08ac-fc6f-0d1043a1e35b.png)

インストールが完了すると、メニューバーに Docker のメニューが追加される
![docker7.png](https://qiita-image-store.s3.amazonaws.com/0/121619/aa4de75d-a43c-d77a-cd16-5481f3946bfd.png)

試しにDockerを動かしてみる。
ターミナルで`docker run hello-world`コマンドを打ち、hello-worldコンテナを実行。
<img width="848" alt="スクリーンショット 2016-12-18 17.27.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/121619/561a9140-9375-e9ac-0e93-5e65d989e50c.png">


# Docker Hubに登録
https://hub.docker.com/
<img width="1354" alt="スクリーンショット 2016-12-18 17.41.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/121619/245ef870-8846-505d-e1be-952d9f6aac49.png">
![Payload Too Large]()

# Docker Kitematicの導入
## Docker Kitematicとは
DockerをGUIで簡単に操作できるものであり、Docker ToolboxをインストールするとDocker Kitematicもインストールされる

## Docker Kitematicの導入
下記のURLでDocekr Toolboxをインストールし、Docker Kitematicもインストールする
https://kitematic.com/

Docker Kitematicを起動するとこのような画面が表示されるので、Docker Hubアカウントを入力し、ログインする。
<img width="1001" alt="スクリーンショット 2016-12-18 17.44.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/121619/7fea177d-5493-667d-629d-7c68a745777a.png">

ログインに成功するとダッシュボード画面が表示される。
<img width="1063" alt="スクリーンショット 2016-12-18 17.52.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/121619/e1dc0fc8-40eb-1958-bf41-28b62459962e.png">

nginxのイメージである「hello-world-nginx」を選択し、[CREATE]ボタンをクリックする。
選択したイメージがDocker Hubからダウンロードされ、以下のようなGUI画面が表示される
<img width="844" alt="スクリーンショット 2016-12-18 17.59.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/121619/37d3ac45-111e-84fd-13db-c76ad8f98fd4.png">


# 参考
- [プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化]
(http://ur0.biz/ApOy)

- [Docker for Mac プライベートベータを早速使ってみた！]
(http://paiza.hatenablog.com/entry/docker_for_mac)

- [GUIでDocker！Docker for MacとKitematicで開発環境を5分で作成](http://uxmilk.jp/33618)
Djangoの環境をDocker化する（Docker + Django + Gunicorn + nginx）その3

[前回](http://qiita.com/shinyarize/items/1d17e4fb99869d82f438)は、docker-compose.ymlを中心に記載しました。今回は、`Django`アプリケーションの設定を記載します。

下記で公開中です。記事と合わせて参考にして下さい。
[Dockerize Django Environment](https://github.com/amazipangu/docker-django)

-----

### Djangoプロジェクトの初期化

1.`Django`プロジェクトの作成

* `docker-compose.yml`があるディレクトリ下で以下のコマンドを実行します。

```sh
docker-compose run web django-admin.py startproject 任意のプロジェクト名 .
``` 

* 実行後にホスト側の`web`ディレクトリ（`Django`用ディレクトリ)内が以下のようになります。

```sh
┣web
┃  ┗任意のプロジェクト名ディレクトリ
┃  ┗Dockerfile
┃  ┗requirements.txt
┃  ┗manage.py
```

2.`PostgreSQL`へ接続

* 接続情報を手順１で作成したプロジェクトディレクトリ下にある`settings.py`ファイルに定義します。


```py:任意のプロジェクト名ディレクトリ/settings.py
# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases

DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.postgresql',
         'NAME': 'postgres',
         'USER': 'postgres',
         'HOST': 'postgres',
         'PORT': 5432,
     }
 }
```

3.`WSGI`サーバ（アプリケーションサーバ）の設定

* 今回、WSGIサーバは[Gnicorn](http://gunicorn.org/)を使用します。
 * WSGIとは、`Web Server Gateway Interface`の略です。名前の通り、webサーバとwebアプリケーションの間の汎用的なインターフェースです。

```py:任意のプロジェクト名/settings.py
WSGI_APPLICATION = '任意のプロジェクト名.wsgi.application'
```

4.コンテナを立ち上げる

ここまで、設定が出来たらコンテナを立ち上げます。
```
docker-compose up
```


-----
### アプリケーションを作成する

1. いよいよアプリケーション開発に着手します。下記のコマンドを実行してアプリケーションを作成します。

```sh
docker-compose run web python manage.py startapp 任意のアプリケーション名
``` 

* 実行後にホスト側の`web`ディレクトリ（`Django`用ディレクトリ)内が以下のようになります。

```sh
┣web
┃  ┗任意のプロジェクト名ディレクトリ/
┃  ┗Dockerfile
┃  ┗requirements.txt
┃  ┗manage.py
┃  ┗任意のアプリケーション名ディレクトリ/
┃  ┃  ┗__init__.py
┃  ┃  ┗admin.py
┃  ┃  ┗apps.py
┃  ┃  ┗migrations/
┃  ┃  ┃  ┗__init__.py
┃  ┃  ┗models.py
┃  ┃  ┗tests.py
┃  ┃  ┗views.py
```

2.admin（管理画面の有効化）と静的ファイルの読み込み


* `settings.py`の`INSTALLED_APPS`が下記のようになっているか確認します。

```py:任意の任意のプロジェクト名ディレクトリ/settings.py
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
```

* データベースにテーブルを作成します。

```shell-session
docker-compose exec web python manage.py migrate
```

* 静的ファイルディレクトリを定義します。

```py:任意の任意のプロジェクト名ディレクトリ/settings.py
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
```

* 静的ファイルを配信するディレクトリに集めます。下記のコマンドを実行します。

```sh
docker-compose run web python manage.py collectstatic --noinput
```

* 管理者ユーザーを作成します。下記のコマンドを実行し、任意のuser名とパスワードを入力します。

```sh
docker-compose exec -it web python manage.py createsuperuser
```
 
* ブラウザを開いて、[INDEX](http://localhost/)と[管理画面](http://localhost/admin)にアクセスして表示されれば成功です。

-----

### 展望

* [Django REST Framework](http://www.django-rest-framework.org/)と併用して画面とAPIを分割してマイクロサービスを構築する。

-----

### まとめ

`docker`で環境構築するのは、各フレームワーク、ミドルウェアの仕様を押さえてない嵌ることを思い知りました。今回で、`Docker` + `Django`の組合せで環境構築出来るようになったので個人プロジェクトの開発をどんどん進められそうです。展望にも書きましたが、マイクロサービス構成を容易に出来るのも`Docker`のメリットなので挑戦したいと思います。公開している情報で誤りなどがありましたらご指摘頂ければ調査して修正していきたいと考えていますので、よろしくお願いします。
QListWidgetItemにウィジェットを追加する方法

# はじめに
独自にカスタマイズしたウィジェットを、`QListWidget`に追加する方法を調べたので、まとめておきたいと思います。

# QListWidgetの使い方

まずは、以下のようにしてQListWidgetItemを追加します。

```cpp
    QListWidgetItem *item = new QListWidgetItem();
    item->setSizeHint(QSize(50, 50));
    ui->listWidget->addItem(item);
```

`setSizeHint`を忘れると、追加したアイテムの見た目が崩れるので注意してください。
つぎに、アイテムに追加したいウィジェットを用意します。

```cpp
QWidget *myWidget = new QWidget();
// 〜 あれこれ設定 〜
```

そして、`QListWidget::setItemWidget(QListWidgetItem *item, QWidget *widget)`で、アイテムにウィジェットを設定します。

```cpp
ui->listWidget->setItemWidget(item, myWidget);
```

アイテムを削除するには、`QListWidget::takeItem(int row)`で、リストからアイテムを取り除いた後、そのアイテムを`delete`してやれば削除できます。

```cpp
QListWidgetItem *item = ui->listWidget->takeItem(0);
delete item;
```

QListWidgetには、`QListWidget::removeItemWidget(QListWidgetItem *item)`というのもありますが、こちらはアイテムからウィジェットを取り除くだけで、アイテムはリストに残ったままになります。

詳しくは、公式ドキュメントを参照してください。

- [Qt Documentation - QListWidget](http://doc.qt.io/qt-5/qlistwidget.html)
- [Qt Documentation - QListWidgetItem](http://doc.qt.io/qt-5/qlistwidgetitem.html)

# サンプル

アイテムを追加・削除するサンプルをGitHubに上げておきました。
[GitHub - QListWidget_Sample](https://github.com/tatsuteb/QListWidget_Sample)


# おわりに

独自にカスタムしたウィジェットを追加できるようになったのですが、注意点があります。
中身が動的に変化するようなウィジェットを追加したい場合、`QListWidget`は使えません。
この場合は、`QListView`と`QItemDelegate`を使う必要があります。
この辺はまだ調べていないので、調べたらまとめたいと思います。
かんたんContentProviderテスト

# かんたんContentProviderテスト

## 概要
ContentProviderをRobolectric + Mockitoでテストを行う

Daoパターンの例

```
public class StorageDao {
    private final Context mContext;

    public StorageDao(Context context) {
        mContext = context;
    }

    public Book getBook(int id) {
        try (Cursor cursor = mContext.getContentResolver()
                .query(StorageContracts.URI, null , StorageContracts.Colomns._ID + "=?"
                , new String[]{String.valueOf(id)}, null)) {
            if (cursor != null && cursor.moveToFirst()) {
                String title = cursor.getString(cursor.getColumnIndex(StorageContracts.Colomns.TITLE));
                String author = cursor.getString(cursor.getColumnIndex(StorageContracts.Colomns.AUTHOR));
                return new Book(title, author);
            }
        }
        return null;
    }
}
```
一度は見たこと・書いたことがあるパターンかと思います。
では、これをMockitoとRobolectricを使ってテストを書いてみると、

```

public class StorageDaoTest {
    StorageDao sut;
    @Mock
    MockContentProvider mockContentProvider;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotation.initialize(this);
        sut = new StorageDao(RuntimeEnviroment.application);

        ShadowContentResolover.register(StorageContracts.AUTHORITY, mockContentProvider);
    }

    @Test
    public void getBook() {
        // setup
        MatrixCursor mockCursor = new MatrixCursor(new String[]{
                    StorageContracts.Colomns.TITLE,
                    StorageContracts.Colomns.AUTHOR
            });
        mockCursor.addRow(new Object[]{"白の闇", "ジョゼ・サラマーゴ"});
        when(mockContentProvider.query(xxx,xxxx,xxx)).thenReturn(mockCursor);

        // execute
        Book actual = sut.getBook(1);

        // verify
        assertThat(actual.title, is("白の闇"));
        assertThat(actual.author, is("ジョゼ・サラマーゴ"));
    }
}

```

何度か試行錯誤しテストを書いていて現状のこの書き方に落ち着きました。
肝になるのはContentProviderをモックオブジェクトにしたところです。
こうしておくことでテストごとにContentProviderを継承して作る必要もなく、
テストに応じて好きに値を返すことができるので楽です。
アーキテクチャ比較にゃ 2016 概要編

## これ何と目的

### これは？
社内勉強会で話した内容のまとめです。擬人化の部分を削除しています

### 目的
昨今のアーキテクチャ事情を簡単に確認するためのものです


## 内容

「アーキテクチャの目的」ってなんだろうを横目で見つつ
「Flux」「Clean」「Reactive Programing」をの比較をしてみたものです

---
## アーキテクチャの目的

* システム、アプリケーションの構造とデータフロー、依存関係の定義

* アーキテクチャの選択からの結果
  * 共通認識、作業イメージ
  * 作りやすい、保守しやすいの判断基準
  * 問題の切り分け "フレームワーク選択", "障害箇所判定", "スケールアウト, スケールアップ"

---
## つまるところダメなアーキテクチャとは

* 構造、データフロー、依存関係が不明
* 認識しづらい。どうやって作るの？
* これここでやるんですか？どこにあるんでしたっけ？
* 存在自体が負債

---
## 取り上げるアーキテクチャと目的視点別コメント

| Archtecture | 構造  | データフロー | 依存関係 | 作り易さ/保守性 |
|-------------|------|-----------|---------|--------------|
| Flux | action creator, dispatcher , callback/store , view の４つの要素で解決 | 一方向 | データフローで定義した順序 | フロントエンドをこれで作成することに問題はない。（これだって感じもしない。自分の場合） |
| Clean | 分類が多数あるので境界について議論が必要 | 一方向、双方向可能 | 依存関係は単一方向 | 難しくないが、冗長になる要素を含んでいるので失敗すると大変になる模様 |
| ReactivePrgraming | ストリームの定義に依存 | イベントの発生時のみ  | ストリームとイベントの関係 | 簡素になるが、知らない人が見ると訳わからない可能性がある |

---
## 取り上げるアーキテクチャとまとめ

| Archtecture | メリット | デメリット |
|-------------|---------|----------|
| Flux | 導入が楽で、高速に開発が行える | 思想とマッチしていないモジュールがあると、組み込みにくい |
| Clean | ある程度正確に分類することができる | 冗長に作り込んでしまうと保守性や生産性を落とす可能性がある |
| ReactivePrgraming | 洗練して簡素に記述できる | メンバーにスキルを要求してくるので導入する場合は民度を見る必要がある |


---
## 参考

* [FluxとDDD(レイヤードアーキテクチャ)について考えてみた](http://embryo.hatenadiary.com/entry/2016/12/16/011446)
   * 書いている内容をこれを書くのに参考にしました
* [擬人化アーキテクチャ](https://speakerdeck.com/wooyoowaan/ni-ren-hua-akitekutiya-anmarini-ren-ni-ren-sitenaikedo)
   * 勉強会資料
* [参照実装コード](https://github.com/YooWaan/KickingProgram/tree/master/web-riot-rxjs) 
   * コードの話は別のもので書きます
Windows 10でnpmのnode_modulesを削除する方法

1. Bash on Ubuntu on Windowsをインストールする
2. bashを開いて`/mnt/`以下の消したいnode_modulesがあるフォルダに移動する。コマンドプロンプトでフォルダを開いてbashを実行すると自動的に移動してくれる
3. `rm -rf node_modules`

Cygwinでも良い。

# 詳細

<a href="https://qiita-image-store.s3.amazonaws.com/0/25276/f48a5863-ded9-cbc6-e5d2-924d317c3ee4.png"><img src="https://qiita-image-store.s3.amazonaws.com/0/25276/f48a5863-ded9-cbc6-e5d2-924d317c3ee4.png" width="320"></a>

Explorerではここまでしか開けないが、最も長いパスは、`node_modules/babel-preset-es2015/node_modules/babel-plugin-transform-es2015-computed-properties/node_modules/babel-helper-define-map/node_modules/babel-helper-function-name/node_modules/babel-traverse/node_modules/babel-code-frame/node_modules/chalk/node_modules/strip-ansi/node_modules/ansi-regex/package.json`の310文字。

:innocent: :innocent: :innocent: :innocent:

npmでは依存ライブラリを`node_modules`というディレクトリの中に保存する。ライブラリ`hoge`が依存しているライブラリは`node_modules/hoge/node_modules/`の中に保存される。この方式をとることによって、使っているライブラリ`A`と`B`が、それぞれ共通のライブラリ`C`に依存している場合に、`A`と`B`が使っている`C`のバージョンが異なっていても問題が無くなる。

その代償として、ファイル数が増える。`babel-preset-es2015`内のファイルサイズの合計は94.1 MB、ファイル数は69,632個、フォルダ数は2,542個だった。また、依存関係が深ければ深いほどファイルシステム上のパスも長くなる。

LinuxやMacではパスが長くても問題無いのだが、Windowsは長いパスを扱えない。正確には、OSやファイルシステムは対応しているけれど、エクスプローラーやコマンドプロンプトが対応していない。Windows APIのドキュメントには長いパスを扱う方法の記載があるのに、なぜMicrosoft謹製のエクスプローラーやコマンドプロンプトが対応していないのか理解に苦しむ。

>
lpFileName
作成または開く対象のオブジェクトの名前を保持している、NULL で終わる文字列へのポインタを指定します。
Windows NT/2000：この関数の ANSI 版では、名前は最大 MAX_PATH 文字に制限されています。この制限をほぼ 32,000 ワイド文字へ拡張するには、この関数の Unicode 版を呼び出し、パスの前に "\\?\" という接頭辞を追加してください。詳細については、MSDN ライブラリの「」（ファイル名の規則）を参照してください。
Windows 95/98：文字列の長さは、最大 MAX_PATH 文字です。

[CreateFile 関数](https://msdn.microsoft.com/ja-jp/library/cc429198.aspx)

対処方法をググると、「パスの途中をネットワークドライブとしてマウントしろ」とか「エクスプローラーから消さずに、`npm uninstall`で消せ」とか出てくる。Deleteキー一発で消したい。

OS自体は対応しているので、削除するスクリプトでも書こうかなと思ったけど、ファイルを削除するスクリプトを書くのは怖い。自分で書いたスクリプトで消せるなら、同じような処理をするはずの`rm`コマンドで消せるんじゃないかな？と思って試したら、消せた。コマンドプロンプトの関数である`rd /s /q`や`del /s /q`ではダメだった。
MacBook Pro 事始め 2016/12/03

# はじめてのMac購入！

年単位で欲しいなーとおもっていたMacBookProをやっと購入できたので、忘れないうちに設定色々を書き残してみます。

![ファイル 2016-12-18 17 00 50.jpeg](https://qiita-image-store.s3.amazonaws.com/0/155583/bc679f2f-4c34-eef5-8b2f-431e213cc42c.jpeg)


#　MacBookProのスペック

-　2015年発売のMacBookProの13インチ
-　https://support.apple.com/kb/SP715?locale=ja_JP
--　日本語キーボード
--　CPU：2.7GHz
--　Memory：8G
--　Storage：　128GB　SSD

#　必要なアプリケーションをインストール
-　Chrome
-　Firefox
-　Palemoon
-　Skype
-　LINE
-　Dropbox
-　iTerm2
-　Sublime Text
-　xCode
-　brew
-　zsh　(標準で入ってたらしいですが知らずにいれてしまった(^^;

それぞれのアプリケーションの細かいインストールや設定については、別記事に記載しようと思います。

#　その他備品
-　![MacBookProハードケース](https://www.amazon.co.jp/gp/product/B00XEMKRWC/ref=oh_aui_detailpage_o01_s00?ie=UTF8&psc=1　"本体ケース")
-　iPhoneの充電ケーブル
付属の物を使用
-　マウス
ワイヤレスマウスはWindowsの物を流用。
帰るタイミング

下請けCOBOLERとして生きていた頃のノウハウ Advent Calendar 2016の13日目ぐらいの記事です。


##今日のタスクが終わってから帰ろう

当たり前の話ですがこの手の現場には進捗があってそれを一日でも過ぎるとエクセルを開いたタイミングで自分の名前が入ったセルが現在日時との比較の書式によって赤く表示され明確にこいつ遅れてるなってばれてしまいます。
そうなるとこんな問答が必要になります。

+ どうして遅れたのか？
+ いつまでに取り戻すのか
+ どうやって取り戻すのか←深夜残業がんばるぞいって回答はNG、やり方を変えなければいけません


今日は平日だけどアイドルのリリイベや声優さんの舞台挨拶があるので早く帰って明日頑張るぞいっていうのは通用したりしなかったりします。（基本通用しない現場での話をします）


なので、今日のタスクが終わっていることが前提となります。

終わらないときは終電になるか、優しいリーダーが遅れてもいいからもう帰れば？って言ってもらうまでやり続ける必要があります。

(タスクによりますが)だいたい終わっていたら22時を過ぎた時点で帰ろう雰囲気を読み取って帰るのがいいと思います。


##早く終わった時
奇跡的に早く終わって帰れそうなとき、そんな時は勝手に帰らずにリーダーにここまで終わったので今日はこれで帰ろうと思いますというのがいいと思います。
もしかしたら違うタスクが降ってくるかもしれませんが、それはそれで仕事として誰かがやる必要があることだと思うのでやりましょう。
そうでなければ、愛想よく「えーーそれ今日必要なんですか？？」って抵抗しましょう。
とにかく大手を振って早く帰ることが大事です。

ちなみに筆者は、6年近くひどい現場にいましたが、明るい時間に帰れることが少なく、自社に戻って会社を出た時間にまだ太陽が輝いていて、涙を流したことを覚えています。
Apache access_logログからのアクセス数集計方法


## アクセス元IP毎のアクセス数(Top30)
- **grep "日付" ログファイル名 | awk '{print $1}' | sort | uniq -c | sort -rn**
  - 例) grep "18/Dec/2016" /var/log/httpd/access_log | awk '{print $1}' | sort | uniq -c | sort -rn

## 1時間毎のアクセス数(Top30)
- **grep "日付" ログファイル名 | awk '{print $4}' | cut -b 2-15 | sort | uniq -c | sort -rn**
  - 例) grep "18/Dec/2016" /var/log/httpd/access_log | awk '{print $4}' | cut -b 2-15 | sort | uniq -c

## アクセス先URL毎のアクセス数(Top30)
- **grep "日付" ログファイル名 | awk '{print $7}' | sort | uniq -c | sort -rn**
  - 例) grep "18/Dec/2016" /var/log/httpd/access_log | awk '{print $7}' | sort | uniq -c | sort -rn

## 補足
- リアルタイムのアクセス数集計方法はこちら
  - **netstat -pantu | grep -e ':80' -e ':443' | awk '{print $6}' | sort | uniq -c**
Viewでのrenderの使い方

部分テンプレートで、`_memo.html.erb`がある前提

```ruby:_memo.html.erb:point_up:
<li>
  <%= memo.text %>
  <%= link_to '削除', memo_path(memo), method: :delete, remote: true %>
</li>
```
memo_path については、[ルーティングについて](http://qiita.com/level52/items/60991022474b01e826f4)を参照
## その1

```ruby:index.erb
<ul>
  <% @memos.each do |form| %>
    <%= render partial: "memo", locals: {memo: form} %>
  <% end %>
</ul>
```
memo は、`_memo.html.erb`で利用しているオブジェクト
memoオブジェクトにformオブジェクトを渡している
## その2

```ruby:index.erb
<ul>
  <% @memos.each do |form| %>
    <%= render "memo", memo: form %>
  <% end %>
</ul>
```
その１を簡略化したパターン
## その3
これが良いらしい

```ruby:index.erb
<ul>
  <%= render @memos %>
</ul>
```
- 呼び出し側では、renderメソッドにコレクションを渡す（例：@memos）
- 呼び出される側では、ファイル名をコレクションの単数系にする（例：_memo.html.erb）
- オブジェクトにはその単数系でアクセス可能。（例：memo.text）
Windowsのパス「ドライブレター:」、「\」のについて


Windowsで「ドライブレター:」をルートディレクトリと勘違いしている人が多いようなので、「ドライブレター:」とついでに「\」についてもまとめてみる。

|パス |意味|例 |
|:---|:---|:--|
|ドライブレター: |そのドライブのカレントディレクトリ | d:|
|\ |コマンドを実行した時カレントディレクトリが属するドライブのルートディレクトリ|\|

# ドライブレター:

コマンドプロンプトを起動すると、デフォルトの場合%USERPROFILE%がカレントディレクトリになっている。
この状態で「dir d:」や「d:」とするとDドライブのルートディレクトリが表示されるため、「d:」は「Dドライブのルートディレクトリ」のことだと勘違いしている人が多いようだ。

```text:prompt
C:\Users\UserA>dir d:
 ドライブ D のボリューム ラベルは Data です
 ボリューム シリアル番号は XXXX-XXXX です

 D:\ のディレクトリ
     ・・・
```

これは、コマンドプロンプト起動直後だと、Dドライブのカレントディレクトリは、Dドライブ直下なのでこのようになっているだけ。

Windowsでは、ドライブごとに固有のカレントディレクトリを持っている。
これについては以下のサイトの方が詳しいかもしれない。
http://www.atmarkit.co.jp/ait/articles/0006/01/news001.html

cd でDドライブのカレントディレクトリを移動してから同じ様に「dir d:」すると違う結果になることがわかる。

```text:prompt
C:\Users\UserA>cd D:\directory
C:\Users\UserA>dir d:
 ドライブ D のボリューム ラベルは Data です
 ボリューム シリアル番号は XXXX-XXXX です

 D:\directory のディレクトリ
     ・・・
```

C([fullpath.c](https://gist.github.com/re3turn/9a58f8a250485cfd4cdca9d07a4f346d))で_fullpath()とGetFullPathName()を使って「ドライブレター:」を変換してみる。

```text:prompt
C:\Users\UserA>cd D:\directory
C:\Users\UserA>fullpath.exe d:
      Source path = "d:"
      _fullpath() = "D:\directory"
GetFullPathName() = "D:\directory"
```

python([fullpath.py](https://gist.github.com/re3turn/3d55c10dae08a7c3f5972e38525cd769))でも同じ結果になった。

```text:prompt
C:\Users\UserA>cd D:\directory
C:\Users\UserA>python fullpath.py
source path = d:
fullpath    = D:\directory
```

# \

ルートディレクトリを表すのはこっち。
コマンドを実行した時のカレントディレクトリが属するドライブのルートディレクトリになる。

もしコマンド(プログラム)内でカレントディレクトリを別のドライブに変更した場合、変更したドライブのルートディレクトリになる。

```text:prompt
C:\Users\UserA>dir \
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は XXXX-XXXX です

 C:\ のディレクトリ
     ・・・
```

ちなみにUNIXと同じように「/」もルートディレクトリを表すが、Windowsのコマンドの場合、オプションスイッチとして扱われてしまう。

```text:prompt
C:\Users\UserA>dir /
無効なスイッチです - ""
```

自作コマンドでは、使用する関数にもよるが「/」もルートディレクトリとして処理される。

```text:prompt
C:\Users\UserA>fullpath.exe /
      Source path = "/"
      _fullpath() = "C:\"
GetFullPathName() = "C:\"
```
エンジニア職じゃない状態からエンジニアになる方法

この記事は新人エンジニアAdvent Calendar 2016の17日目の記事です。

今話題の<a href="http://qiita.com/advent-calendar/2016/muscle">筋肉 Advent Calendar 2016</a>の発起人の１人であるK-BOYと申します。

社会人としてまだ２年目なのですが、実は、最初に新卒入社した会社ではエンジニア職ではありませんでした。

ってことで、今回はエンジニア職じゃない状態からエンジニアになるにあたって私がどのような戦略を取ったかをお話ししたいと思います。

## 新卒でディレクターという不安
![LIG_h_officededenwatoru_TP_V.jpg](https://qiita-image-store.s3.amazonaws.com/0/111366/f28bf5e3-9335-4154-fae5-86ac48602f23.jpeg)
(画像は「ぱくたそ」)

新卒で比較的大きめの会社に総合職として入社しました。

総合職は営業になる可能性もあるし、経理とかやる可能性もあるし、IT担当になる可能性もあるって感じです。その中で私はITの事業部に配属されました。

その会社のIT事業部に配属された総合職の新入社員はそのほとんどがWEBディレクターになります。会社の持っているメディアの開発ディレクションが主な仕事です。

開発ディレクションは何をするかというと、「<strong>自分でざっくり仕様を決めて、外部のベンダーに仕事を発注してそれを管理する</strong>」って感じです。

この手の仕事をしているIT関連の人は大企業に多いように思います。

もちろん、大きい歯車を回していくにあたってこのような調整役の仕事は重要です。

しかし、<strong>あまり汎用的なスキルがつかない</strong>という問題があります。

## 自分一人でもモノをつくれるようになりたい

せっかくIT、WEBに関わっているなら、そのサービス開発に関するレベルをどんどん上げて行きたいと思うわけですが、何も考えずに開発ディレクターをやり続けると、経験値は上がるものの<strong>自分一人でモノを作れるようになりません。</strong>

今私は25歳ですが、30代になったときに自分一人でモノを作って金を稼げないっていうのはとても情けないのではないか？と思いました。

しかし、プログラマー、エンジニアになれば自分でものをつくれるようになるし、レベルの高い指示もできるようになれる！

そう考えて、新卒入社した年の夏には<strong>エンジニア職にシフトすること</strong>を目標としたのであります。

## エンジニアになるために取った戦略

私はスタートアップにエンジニアとして転職することを目標に定めました。そのために会社を利用して行ったこと、個人的に頑張ったことを紹介したいと思います。

### 会社を利用して行ったこと

幸いなことに私は新規事業開発の人数が少ない部署に配属されました。私が入社する時点で、まだ作るプロダクトが決まっておらず、その開発の進め方も決まっていないという状況。

通常であれば、子会社のベンダーに外注して、自分たちはディレクションをするというのがその会社のスタイルでしたが、人数が少なくて意見は言いやすい環境だったので、少しわがままを言いました。

「<strong>プログラミング未経験だけど自分で作りたいです。</storong>」

このようなワガママが通る会社はあまり多くないとは思いますが、いい意味で「<strong>やる気さえあれば何でもやらせてくれる</strong>」会社だったので、それを利用しました笑

結局、2015年夏の時点でプログラミング経験はほぼなし（wordpressのカスタマイズしたことあるだけ）の状態から、子会社のエンジニアの方をアサインしていただき、AndroidとiOSアプリを作りながら適宜教えてもらうという恵まれた環境でプログラミングを学ぶことができました。

### 個人でやったこと

2015年4月に新卒入社して2016年の8月には転職したのですが、エンジニアとしてスタートアップに転職するにあたって、転職活動時は明らかに経験不足でした。

なんせエンジニア歴半年くらいでしたからね。。。

これをどうカバーしたかというと、<strong>個人アプリの開発</storng>です。

【個人アプリ開発記】NCMBを使った筋トレ記録アプリの作り方
http://qiita.com/k-boy/items/90d83354b835ea415a0b

ちょっとアプリ開発して調子乗ってる奴なんか誰も採用したいと思わないと思います。だから私は本気度を伝える意味で個人アプリ開発をすることに決めました。

まあ、もちろん筋トレ記録アプリは作りたいとずっと思っていましたが、今がそのタイミングだ！と思ったわけですね。

この活動は、転職活動時にかなり高評価を受けたのではないかと思っています。特にスタートアップは主体性のあるエンジニアを採用したいと思いますので、個人アプリを作っているというのは評価になります。その完成度が低かったとしても一からリリースしたという経験は価値あるものですし！

## まとめ

新人エンジニアになってからの話ではなく、<strong>新人エンジニアになる方法</strong>を紹介させていただきました。

まとめると、

* 会社を利用して自分のキャリアにつなげる
* 個人でも活動する

この2つが新人エンジニアとしてスタートアップに転職できた理由かなと思っています。

誰かの参考になれば幸いです！

では！
お昼に行くタイミング

下請けCOBOLERとして生きていた頃のノウハウ Advent Calendar 2016の12日目ぐらいの記事です。


自分のいたところはお昼はだいたい11時半から14時の間の一時間でした。

お昼に行くタイミングとしては、12時より少し前か13時過ぎが理想です。

また筆者のいるビルは自席で飯を食ってはいけないというルールがあったので食事は会議室かランチスペースか外に出るしかありませんでした。
12時～13時というメインのお昼時間に行くとエレベーターに乗れない、コンビニで大行列、ランチスペースに座れないなどの何重もの苦痛があります。

一階当たり300人収容するビルが20階もあると、お昼のエレベータが大混雑で乗れない可能性があります、ビルにはエレベーターが6機ありましたがどれもこれもこないし、来ても満車という状態でした。
エレベーターを前に並ぶのはとてもつらいので、以下を徹底するとよいと思います。（またコンビニに行っても列があります）

* お昼はなるべく持ってくる
* 買いに行くなら早い時間
* 何をするにも混んでる12時～13時でお昼を取るな



都会の巨大ビルディングで仕事をしてるというと一見すごいって思われますが、その実態は***飯すらすら満足に食べさせてもらえない***家畜以下の待遇が待っていると思ってください。
トイレに行くタイミング

下請けCOBOLERとして生きていた頃のノウハウ Advent Calendar 2016の11日目ぐらいの記事です。

##トイレに行くタイミング

自分が出入りていたビルは、20階以上の高さを誇り、中には大量の下請けプログラマーたちが働いていました。

フロア面積も　10人掛けの島×2を一列として、少なくとも15列ぐらいあったような気がします。

####<font color="Red">一つの階に300人ぐらいのエンジニアを収容可能な計算です。</font>
それに対して、トイレの数はというと(筆者は男性です)
####<font color="Red">小が5、大が4ぐらいだったように記憶しています。</font>

大混雑するんですね。
また筆者のいたビルの会社は大変営業力を持った会社なのでフロアはあっという間に満席となり、ついにはパーティションで仕切られた狭い打ち合わせスペースにまで人を突っ込みはじめ、会議室も閉鎖され、収容スペースとなってしまいました。

本来の想定をはるかに超える数のプログラマーが押し込められるようになってしまったんですね。

####<br><font color="SaddleBrown">トイレは想定以上の大混雑を始めます。</font><br>


トイレには長時間座るな・スマホいじりするなというような張り紙がされ、外では便意を抑えながら多くの人たちが並んでいました。
水が流れた音が聞こえたにも関わらず一向に出てこない個室を前に並んでいるのはとてもストレスのたまることです。

#### <br><font color="Red">大切なことは人のいなさそうな時間を狙ってトイレに行くことです。</font>

トイレの空いてる時間としては以下になります（筆者は出勤時間が遅いことで有名だったので朝早くがどうなのかわかりません）

* 夜の8時以降などフロアが閑散とし始めたとき
* お昼休みの開始直後、みんながコンビニを目指しているとき←貴重な昼休みを失うリスクがある


混んでる時間帯は以下の感覚です。

* 終日
* 午後一


また、トイレに行くために<font color="Red">***別の階まで移動する***</font>という手段もあります。

+ フロアが比較的空いてる階を見つける(自分のいる階±1が理想)
+ ランチスペースなどがある階(お昼時以外)
+ 隠れトイレを見つける(ビルにコンビニなどが入っている場合、そこに外から普通のお客さんが入れるような別の出入り口とトイレがあったりする、という自分のいたビルにはあった)

都会の巨大ビルディングで仕事をしてるというと一見すごいって思われますが、その実態は***糞尿すら満足にさせてもらえない、畜生以下の待遇が待っていると思ってください。***



----
余談ですが、地方中小企業の弊社はフロアに20人ぐらいでトイレは大が２、小が3なので比率から行くと大企業に派遣されるよりはるかに好待遇なトイレ事情を保証します。
Gitlab CI を使用して CakePHP3のテストを実行してみた。

# はじめに
Gitlabは使っていましたがCI/CD機能は使ったことなかったので、実際初めてです。

前提

+ Gitlab gitlab.com
+ php 5.5.9
+ cakephp/cakephp 3.3.10
+ [cloud9](https://c9.io)　はオンラインIDEです。

# CakePHP3 で簡単なアプリを作成

## cloud9 ramp構成でワークスペースを作成

## プロジェクトのひな型を作成
```
 composer create-project --prefer-dist cakephp/app cakephp3gitlabci
 Set Folder Permissions ? (Default to Y) [Y,n]? Y
```
## DocumentRootの設定
``` /etc/apache2/sites-enabled/001-cloud9.conf
DocumentRoot /home/ubuntu/workspace/cakephp3gitlabci
```

## Git Init
```
git init
git add -A
git commit -m "first"
```

## インストール状況の確認
Run Project Button Click
Preview Button Click
[スクリーンショット](https://gyazo.com/988925ab13e5a96c28b0257523192017)


## Database setting 

cp config/app.php config/app.c9.php  
cloud9用のconfig/app.phpを作成してコミットしておきます。

```php:config/app.php
    'Datasources' => [
        'default' => [
            'host' => getenv('IP'),
            'username' =>  getenv('C9_USER') ,
            'password' => '',
            'database' => 'c9',
```

[スクリーンショット](https://gyazo.com/46688a2bed8123ca7b93a5d585d5278a)
```
$ cp config/app.php config/app.c9.php  
$ git add config/app.c9.php 
```

## create migrations

Migrationを作成して実行
```
$ bin/cake bake migration CreateProducts name:string description:text created modified
$ bin/cake migrations migrate 
```

## modelを作成
Bakeコマンドでモデル作成
`$ bin/cake bake model Products`

ひな形が作成されます
`src/Model/Entity/Product.php`
`src/Model/Table/ProductsTable.php`
`tests/Fixture/ProductsFixture.php`
`tests/TestCase/Model/Table/ProductsTableTest.php`

## model test

簡単なテストを一つ書きます。

```php:tests/TestCase/Model/Table/ProductsTableTest.php
    public function testFind()
    {
        /** @var App\Model\Entity\Product */
        $product = $this->Products->find()->where(['id' => 1])->first();
        $this->assertEquals("Lorem ipsum dolor sit amet",$product->name);
    }
```
composerでphpunitをインストールして実行

```
$ composer require --dev phpunit/phpunit
$ vender/bin/phpunit
```
ここまでで、ローカル環境でテストが実行できる環境になる

# GitLab CI のセットアップ

## .gitlab-ci.ymlの作成

DockerHubを検索していたら、そのまま使えそうなものがあったので、ここから、コピペします。
https://hub.docker.com/r/kaffineaddict/gitlabcakephp3/

## GitLabにpush
```
$ git remote add origin https://gitlab.com/zonoise/cakephp3_2.git                                                                
$ git push origin master 
```
最初は失敗します。
https://gyazo.com/168377d9db706c7eef079e60265c5110
## configの設定

GitLab用にconfig/app.phpを分けます。
```
$ cp config/app.default.php config/app.gitlab.php
```

gitlab-ci.ymlのデータベース情報をもとに接続情報を編集します。（Defaultとtest両方）

```php:config/app.gitlab.php
            'host' => 'mysql',
            'username' => 'root',
            'password' => 'mysql',
            'database' => 'cake_test',
```

configを分割したので、テストが走る前にcpする処理を追加

```php:gitlab-ci.yml
  - cp config/app.gitlab.php config/app.php
  - bin/cake migrations migrate
```

# 終わり
テストが通ったので今回はここまでになります。
[スクリーンショット](https://gyazo.com/5576489fec917bcf19649458ee441c82)

今回作業したプロジェクトは下記になります。
[https://gitlab.com/zonoise/cakephp3_2](https://gitlab.com/zonoise/cakephp3_2)
[Swifty]モデルもプロトコルへ

<p>モデルのHandをDataTypeプロトコル適用ということにして、項目名をCardから汎用的なItemに変更する。</p>

<pre><code>protocol DataType {
    var numberOfItems: Int {get}
    func addNewItem(at index: Int) -> Self
    func deleteItem(at index: Int) -> Self
    func moveItem(fromIndex: Int, toIndex: Int) -> Self
}
</code></pre>

<pre><code>struct Hand: DataType {
    private var deck = Deck()
    private var cards = [Card]()
    
    public init() {
    }
    
    public init(deck: Deck, cards: [Card]) {
        self.deck = deck
        self.cards = cards
    }
    
    public var numberOfItems: Int {
        return cards.count
    }
    
    public func addNewItem(at index: Int) -> Hand {
        return insertCard(card: deck.nextCard(), at: index)
    }
    
    private func insertCard(card: Card, at index: Int) -> Hand {
        var mutableCards = cards
        mutableCards.insert(card, at: index)
        return Hand(deck: deck, cards: mutableCards)
    }
    
    public func deleteItem(at index: Int) -> Hand {
        var mutableCards = cards
        mutableCards.remove(at: index)
        return Hand(deck: deck, cards: mutableCards)
    }
    
    public func moveItem(fromIndex: Int, toIndex: Int) -> Hand {
        return deleteItem(at: fromIndex).insertCard(card: cards[fromIndex], at: toIndex)
    }
    
    subscript(index: Int) -> Card {
        return cards[index]
    }
}
</code></pre>

ソースコード
GitHubからどうぞ。<br />
<a href="https://github.com/murakami/workbook/tree/master/ios/Hand">https://github.com/murakami/workbook/tree/master/ios/Hand</a> - GitHub<br />

関連情報
<a href="https://realm.io/jp/news/tryswift-daniel-steinberg-blending-cultures/">文化を調和させる</a><br />

【Cocoa練習帳】
<a href="http://www.bitz.co.jp/weblog/">http://www.bitz.co.jp/weblog/</a><br />
<a href="http://ameblo.jp/bitz/">http://ameblo.jp/bitz/</a>（ミラー・サイト）<br />
<a href="https://t.co/6P3h2jtbRk</a>note<br />
Easy-ISLispのデバッグ機能

#意図
自作ISLsip処理系、Easy-ISLispについてのデバッグ機能の覚書です。ISLisp規格にはデバッグ機能についての規定がありません。CLを参考に独自拡張したものの記録です。

#trace
ユーザ定義関数をトレース状態にします。トレース状態になると、その関数の実行時に引数とその返り値を表示するようになります。

例

```
> (trace fact)
T
> (fact 3)
ENTERING: FACT(3)
 ENTERING: FACT(2)
  ENTERING: FACT(1)
   ENTERING: FACT(0)
   EXITING: FACT 1
  EXITING: FACT 1
 EXITING: FACT 2
EXITING: FACT 6
6
> 
```

引数無しで読んだ場合には、現在トレース中の関数名を表示します。

```
> (trace)
(FACT)
> 
```


#untrace
トレース状態を解除します。

例
(untrace fact)

引数が与えられない場合には、トレース中の全関数を解除します。



#backtrace
組込み関数の実行状況を表示します。

例

```
> (fact 5)
120
> (backtrace)
(FACT (- N 1))
(- N 1)
(IF (= N 0) 1 (* N (FACT (- N 1))))
(= N 0)
(BACKTRACE)
T
```

#break
break関数を埋め込むことにより、実行を中断します。

例

```
(defun fact (n)
  (if (= n 0)
      (break)
      (* n (fact (- n 1)))))

> (fact 3)
break
> 
```



#macroexpand-1
マクロがうまく展開されているかどうかに使えます。

例

```
Easy-ISLisp Ver0.43
> (defmacro when (x y) `(if ,x ,y))
T
> (macroexpand-1 '(when (= 1 2) 3))
(IF (= 1 2) 3)
> 
```
#デバッガ
break関数あるいはエラーは実行を中断し、デバッガを起動します。デバッガに入るとプロンプトが>>に変わります。　？でヘルプ画面がでます。

```
Easy-ISLisp Ver0.63
> (break)
break
debug mode ?(help)
>> ?
?  help
:b backtrace
:d dynamic environment
:e environment
:i identify examining symbol
:q quit
:r room
:s stepper ON/OFF
other S exps eval
>> 
```

#実行ファイル
Windows及びUbuntu実行ファイルを公開しています。

http://eisl.kan-be.com/library/easyislisp.html
【GAS】QUERY関数（2時限目）

　前回
　http://qiita.com/ShishidoToru/items/d88962fd6d8606d7c4b0

　今回のテーマは条件に合致したデータの抽出ですが、式の中に直接条件を入れる場合、条件を任意のセルに入れ、そのセルを参照させる場合で記法が若干異なり、また、条件そのものが文字列か数値かでも微妙に変わってきます。つまり、4通りの組み合わせがあり、そのあたりを整理しておきます。

# 直入＋文字列

　A3に以下の式を入れます。

```
=QUERY('シート1'!A2:E,"where A is not null and D='男'")
```
　
　文字列を「'」（シングルクォーテーション）で包めばOKです。一般的に文字列は「'」か「"」で包んで、数値はそのままです。このあたりは色々なプログラミング言語で変数の定義などでお馴染みですね。ちなみこの場合、「"」（ダブルクオーテーション）だと失敗します。これは、この式をよく見ると"where・・・"と、外側がすでに「"」で包まれており、ここを、"where A is not null and D="男""などとしてしまうと、"where A is not null and D="までがひとまとまりの式なのかと誤解されてしまうからです。

　そして下のような結果になると思います。

![スクリーンショット 2016-12-18 16.14.00.png](https://qiita-image-store.s3.amazonaws.com/0/139134/49f9b762-f551-bd47-39cc-4b44684452cf.png)


# 直入＋数値

　次に年齢が26の者を抽出します。
```
=QUERY('シート1'!A2:E,"where A is not null and C=26")
```

　条件が数値であればそのままで大丈夫です。結果は下のようになります。

![スクリーンショット 2016-12-18 15.42.40.png](https://qiita-image-store.s3.amazonaws.com/0/139134/eeeffef3-0e9e-dccd-12c2-3af05aad8e10.png)

　次に任意のセルの値を参照させる場合の記法について見ていきます。

#セル参照＋文字列

　A1に「女」と入れて、QUERY式の中にA1セルを参照させてみます。

```
=QUERY('シート1'!A2:E,"where A is not null and D='"&A1&"'")
```

　直接代入＋文字列の場合は「'文字列'」でしたが、「'"&セル番地&"'」となります。ここを「'A1'」としても、純粋に文字列が「A1」のものがないかどうかを探索してしまうことになります。

　"where A is not null and D='" & A1 & "'"はよく見ると、"条件式の1部" & セル & "条件式の続き"のような形になっていることが分かると思います。このように考えられればのちのちスクリプトで式を組むときに応用が効いてきますが、いまはそうゆうもんだと思っておけばOKです。

　結果は以下のようになります。

![スクリーンショット 2016-12-18 15.45.52.png](https://qiita-image-store.s3.amazonaws.com/0/139134/488ecdea-35db-208c-a4dd-ab5193d3b540.png)

# セル参照＋数値

 セル参照＋数値の場合は「"&セル番地&"」となり、外側の「'」が不要となります。

![スクリーンショット 2016-12-18 15.50.20.png](https://qiita-image-store.s3.amazonaws.com/0/139134/00a863ee-fbc0-7ed2-07ae-d382d6165c0b.png)

# まとめ

　まとめると以下のような表になります。

<table>
<tr>
<td></td><td>文字列</td><td>数値</td>
</tr>
<tr>
<td>直入</td><td>='文字列'</td><td>=数値</td>
</tr>
<tr>
<td>セル参照</td><td>='"&セル&"'</td><td>="&セル&"</td>
</tr>
</table>

　次回はもう少しいろいろな条件抽出について見ていきたいと思います。
【備忘録】RoRで無駄な条件を書かずにステータス更新

#無駄なコードは本当にないですか...？
RoRをさわり始めて9ヶ月ほど経ちました。未だによくわからないことがいっぱいで、自分がプロダクトのあちこちに無駄なコードをばらまいてしまっていることに最近やっと気付き始めた模様です。ちょっとしたことだとすぐ忘れてまた同じことを繰り返してしまうかもしれないので、気づいたことはメモっておこうと思います。

##今回の「無駄」
controllerにてstatusを変更するとき
**「もしHogeがbarじゃなかったらbarに変更」**
の**「もしHogeがbarじゃなかったら」**が無駄！

##環境
Ruby: 2.2.3
Rails: 4.2.0
gem enum_help: 0.0.16, 0.0.15

#思うがままに書いてみる
とりあえず、何も考えずに**「もしHogeがbarじゃなかったらbarに変更」**できるように書きました。

model↓

```ruby:app/models/hoge.rb
# == Schema Information
# Table name: hoges
#  id          :integer   not null, primary key
#  status      :integer   default(0), not null
#  created_at  :datetime  not null
#  updated_at  :datetime  not null

class Hoge < ActiveRecord::Base
  enum status: %i(foo bar)
end
```
controller↓

```ruby:app/controllers/hoges_controller.rb
class HogesController < ApplicationController
 
  #patch method
  def bar
    @hoge = Hoge.find(params[:id])
    @hoge.bar! unless @hoge.bar?
  e =>
    redirect_to fugas_path, alert 'bar error'
  end
end
```

##どこが無駄？？
...冗長なのはどこかというと、まさに冒頭で書いた通りで
**unless @hoge.bar?**
の部分。自分では全く気付かずただ「動くしロジック通りに表記してるから大丈夫でしょ」っていう感覚でプルリク出したら先輩から指摘されたポイントです。
「いや、でも、これ書かないと既にbarになってるものも更新しちゃって無駄なんでないの？？」と思ったアナタ。僕と同じですね〜w(失礼)
Railsが発行したSQLを確認してみると...なんと、上の条件式を書いても書かなくても、SELECTが走って「hogeの中の、barじゃないヤツ」を取ってきてくれたのでした！ほぉ〜。なるほど〜。Rails優秀。しゅごい。

#結論
**「もしHogeがbarじゃなかったらbarに変更」**という動作を実装するとき、条件式は書かなくてもいいということがわかりました。心もコードもちょっとスッキリしましたね！d(￣ ￣)ｸﾞｯ
...まぁでも**「もしHogeがfooだったらbarに変更」**とかだとちゃんと条件書かなきゃいけないので、無駄が生じることって実はあんまりないのかもしれませんが...。
ルーティングについて

ルーティングについての備忘

以下は同じ
`memo_path(memo)`
`"/memos/#{memo.id}"`

`rake route`で実行することでPrefixを確認できる

```ruby:route
Prefix Verb   URI Pattern          Controller#Action
  root GET    /                    memos#index
 memos POST   /memos(.:format)     memos#create
  memo DELETE /memos/:id(.:format) memos#destroy
```

例えば、memos#destroyに対応するパスに「memo」というPrefixが付与されていることがわかります。
link_toの第二引数を(Prefix名)_pathとすると、そのPrefixに対応するパスをリンク先として指定することができます。

destroyのように、パラメータとしてidが必要になる場合、(Prefix名)_pathの後に括弧をつけて、そのインスタンスを渡します。
GetWildの信号強度を解析し、音の大きさをMackerelでグラフ化する

[Mackerel Advent Calendar 2016](http://qiita.com/advent-calendar/2016/mackerel)の18日目です。

# 概要
* [GetWildの信号強度を解析し、音の大きさを可視化する](http://qiita.com/sion_cojp/items/6461829cc1236b844409)
* を使ってMackerelでグラフ化しようというお話です
* ちなみに前回は[MackerelでGetWildという文字を書きました](https://speakerdeck.com/sioncojp/mackereldegetwild)

# 内容
## ①flac2floatを使って、1分間に/tmp/soud_decode.logに値を出力させるコード(flac2float.go)を書く
```go
package main

import (
  "io/ioutil"
  "log"
  "os"
  "strconv"
  "time"

  "github.com/sioncojp/flac2float"
)

const (
  filename = "/tmp/sound_decode.log"
)

func main() {
  decode := flac2float.New(os.Stdin, 1)
  values, err := decode.ReadSound()
  if err != nil {
    log.Fatalf("Error: %s", err)
  }
  for _, value := range values {
    ioutil.WriteFile(filename, []byte(strconv.FormatFloat(value, 'f', 12, 64)), 0644)
    time.Sleep(60 * time.Second)
  }
}
```

## ②Mackerel監視用スクリプトを書く
```bash
### 初期データ投入
$ echo 0 > /tmp/sound_decode.log

### 計測用スクリプトを書く
$ vim /tmp/get_wild_and_tough.sh

#!/bin/bash

name="GetWild"
monitor_time=`date +%s`
count=`cat /tmp/sound_decode.log`
echo -e "${name}\t${count}\t${monitor_time}"
```

## ③mackerel-agent.confを書いてreload。そのあとビルドしたコマンドを走らせる
```bash
### 書く
$ vim /etc/mackerel-agent/mackerel-agent.conf
[plugin.metrics.Playing_GetWild]
command = "/bin/bash /tmp/get_wild_and_tough.sh"

### reloadする
$ service mackerel-agent reload

### build後、走らせる
$ go build flac2float.go
$ nohup cat GET_WILD.flac | ./flac2float &
```

## ④結果
![スクリーンショット 2016-12-15 1.18.54.png](https://qiita-image-store.s3.amazonaws.com/0/29405/8f7ed26a-68d8-6576-d338-f72f9bb64e0e.png)
* 音楽の秒数だけ足しました

## Mackerelの良いところ
* 先ほどみたいに全体を見ることもできるし、ポイント毎に細かくチェック出来るところが良いですね
![スクリーンショット 2016-12-15 1.34.47.png](https://qiita-image-store.s3.amazonaws.com/0/29405/4d9a7d09-001b-221f-a9f4-c02df8517587.png)


## 最後に
* なんでも可視化出来るMackerelすごい！
エビデンスを残そう

下請けCOBOLERとして生きていた頃のノウハウ Advent Calendar 2016の9日目ぐらいの記事です。


##お互いのためにすべての作業はエビデンスを残せ
よく単体テストでスクショやログを熱心に撮ってエクセルにまとめる作業が馬鹿にされていますが、あれの良いところはやったこと、当時のやり方が明確になるところにあると思います。

テスト結果を残さずにやった場合、この確認はどうしたのか、やったのかやってないのか、なんで漏れたのかと原因究明ができなくなってしまいます。

しかし、もしテスト結果を残していれば、やったやらないやその正しさについて後から検証できますし、結果をレビューをしてもらっている時点で責任を最終的には上に押し付けることも可能になります。
***エビデンスというものは品質保証ではなく身を守るための最大の物証と思ってください***

##作業はすべて上の人の了解を得たうえで実施する

例えば進捗表.xlsにはあなたの作業がすべて書かれていると思います。(もし仮に一日でも風邪をひいたりインフルになったらどうするつもりの予定表なのでしょうか？)
12月1日　詳細設計
12月2日　製造　　
12月3日　単体テスト

これがあなたのやることです。諸事象で違うPGMから製造に入った方が良いというような場合は、まずはその理由を説明し、進捗表.xlsを変えてもらわなければなりません。

その場合でも、まずリーダーに説明し納得してもらい、また同じ説明を次の上の会社にする必要があります。(同じ話を何度もする手間がかかります)

```python:setumei.py
pyramids = ["一つ上の会社", "二つ上の会社", "三つ上の会社"]

for ue in pyramid:
    KEKKA = setumeisuru("説明内容！", ue)  # 上の数だけ説明する
    if KEKKA:
        continue
    else:
        return False
    if KEKKA and ue.sinchokuhyou_wo_kaeru_kenngenn:
       return True
```


また、本番障害トラブルはほかにやってほしい作業がでることもありますが、その際も電話で指示は受けた際は後からでも必ず作業指示のメールをもらうことが大切になります。
また、原則からすると、
***下請けCOBOLERは二つ以上離れた会社と直接やり取りをしてはいけません。***
上に行くにも下に行くにも必ずピラミッドを一段一段上り下りしなければなりません。

とはいえ、それはあくまで原則なので***自分がいた現場では直接三つ離れた会社さんとも直接やり取りをしていました、そうでもないと何も回りません。***

我々は支持の通りに動いた、勝手なことはしていない、やったこともすべて上の人のチェックが通ってるから見過ごし・見逃しは俺たちのせいじゃないと、正しさの証明のためにもエビデンスはしっかりとって残すようにしましょう。


補足）あくまでもこれはレガシーな現場で生き残るためのスキルになりますので、これが正しい、正しくないとか合理的だとか非合理的だとかを問うつもりはありません。
あくまでもそういう社会ではそういう社会なりの生存術があるということです。
js 配列に目的の文字が含まれているかの真偽判定

##お題
配列の第一要素に第二要素が含まれているかどうか真偽判定する。

```script.js
function mutation(arr) {
// write your code.
}
mutation(["hello", "hey"]);
```

##出力結果　例

```script.js
(["Mary", "Aarmy"]) // true
(["Alien", "line"]) // true
(["floor", "for"])  // true
(["hello", "neo"])  // false
(["voodoo", "no"])  // false
```

##使った関数
[toLowerCase()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf)
[indexOf()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf)


##一番最初に試したコード

```script.js
function mutation(arr) {
  var target = arr[1].toLowerCase();
  var item = arr[0].toLowerCase();
  for(var i= 0; i<target.length; i++){
    if(item.indexOf(target[i]) < 0) return false;
    }
    return true;  
}
mutation(["hello", "hey"]);
```

##考え方
・indexOf()の返り値をもとに真偽判定することができる。(-1が返ると誤)
・配列の第一要素と第二要素を比較するために、それぞれ小文字にして変数に入れる。
・for文でtagetの一文字目から比較して、−1になった時点でfalseを返す。
　-1が返らなかったら、真で処理終了。

##その他のコード

```script.js
function mutation(arr) {
  return arr[1].toLowerCase()
    .split('')
    .every(function(letter) {
      return arr[0].toLowerCase()
        .indexOf(letter) != -1;
    });
}
```

###他にもコードが浮かんだ方、コメントお待ちしてます。
InsertキーをPauseキーに置換する

# 概要

私の利用しているDell XPS13では、キーボードスペースの関係かPause/Breakキーが存在しない。BIOS等でもキーの入れ替えができないので、それならばという事でチャレンジしてみた。

# yamyを使う

yamyは、窓使いの憂鬱（mayu）から派生したWindows用のキーバインディング変更ソフトです。結果的にこれを使うのが最も確実でした。

mayuがドライバベースでフックするのに対して、yamyはユーザーモードでフックするする関係で署名警告やドライバ競合の悩みから解放されるのが良くWindows 10でも動作しました。

## ダウンロード

下記のダウンロードページから最新版をダウンロードして、適当なフォルダへ展開します。

- [Yet Another Mado tsukai no Yuutsu](https://ja.osdn.net/projects/yamy/releases/)

2016/12/18時点で最新版は 0.03 でした。

## 設定ファイルの作成

今回は個人的にあまり需要がないInsertキーを潰して、Pauseに仕立て上げます。

展開したyamyフォルダ内に「replace-ins-to-pause.mayu」というファイル名で下記内容のファイルを作ります。

```replace-ins-to-pause.mayu
include "109.mayu"

keymap Global

key D-Insert = &VK(D-PAUSE) &VK(U-PAUSE)
key R-Insert =
key U-Insert =
```

Pauseは単発のみでリピートしないタイプなので、Insertキーが押された(Down)時にPauseキーのDownとUpを同時に送信します。
長押し時とInsertキーが離された時は無視するようにします。

## 起動＆初期設定

先ほど作成した設定ファイルを読み込むようにyamyを設定します。

1. yamy.exe を実行します。  
システムトレイに常駐しているか確認しておきます。
この設定程度であれば管理者として実行しなくても機能しました。
1. yamyのトレイアイコンを右クリック＞設定 を選択します。
1. 追加ボタンをクリックすると、登録画面になるので下記内容を入れます。
    - 名前：InsキーをPauseにする
    - ファイル名：replace-ins-to-pause.mayu
    - シンボル：-DUSE109
1. OKボタンをクリックして追加します。
1. 先ほど追加した「InsキーをPauseにする」を選択した状態でOKボタンをクリックします。

名前は自由なので適当に決めてください。

※もし設定ミスがあれば、ログウィンドウが表示されてエラー内容が出ていると思いますので、適宜修正します。

## 確認

yamyのトレイアイコンをダブルクリック（もしくは右クリック＞調査）して、スキャンコードと仮想キーの入力欄でInsertキーを押下して動作を確認しておきます。

スキャンコードは元のInsertについて、仮想キーにD-PauseとU-Pauseが表示されてると思います。

```text:スキャンコードの調査欄でInsertキーを押下したとき
E0-0x52   D-NL-Insert
E0-0x52   U-NL-Insert
```

```text:仮想キーの調査欄でInsertキーを押下したとき
   0x13  &VK(   D-PAUSE )
   0x13  &VK(   U-PAUSE )
```

## 一時的に無効にしたい場合

yamyのトレイアイコンを右クリック＞一時停止を選択すれば、キーバインドが無効になります。

# 番外：Scancode Mapの書き換えではだめだった話

最初は、レジストリの「HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout」に「Scancode Map」を設定すればいけると思ったが、どうもPauseのような複雑なキー送信が必要なものには使えないようでした。

なので、スキャンコードを入れ替える系のソフトウェア（ChangeKey、KeySwapなど）では何かのキーをPauseに置換することはできないと思われます。

## Pauseのスキャンコード

ちなみに、Pauseキーがある機種で送出されるキャンコードはSet1の「E1 1D 45 E1 9D C5」かSet2の「E1 14 77 E1 F0 14 F0 77」どちらからしいです。

- [Key Support, Keyboard Scan Codes, and Windows](http://web.archive.org/web/20040501014944/http://www.microsoft.com/whdc/device/input/Scancode.mspx)  
に記述されているマイクロソフトのドキュメント「Keyboard Scan Code Specification」で確認しました。