OmniAICreator/Qiita-1.07M huggingface dataset:
丸の内 MongoDB 勉強会 #22 に行ってきた


丸の内 MongoDB 勉強会 #22 に行ってきましたので，内容メモ書き．
個人的な興味の濃淡で記載の厚さも変えていますがご容赦ください．

---

# 勉強会詳細
https://mongonouchi.doorkeeper.jp/events/26940
ハンズオンと最近開催された MongoDB World のサマリーについて．特に MongoDB の特長の話やハンズオンについては，最新の v3.0 についての話あり．

# Part1: MongoDB とは & MongoDB Hands-on
今回の勉強会主催の渡部徹太郎さん (@fetarodc) による　MongoDB の概要説明と，各自の持参したノートブックを通じてのハンズオン．

## MongoDB のキホン
以下のスライドを元に渡部さんがトーク．
http://www.slideshare.net/tetsutarowatanabe/mongo-db-32210761

ほとんどスライドに書いてある通りだが，気になったのは以下．
* NoSQL と一口に言っても KVS, カラムナー，グラフなど様々あるが，最近になって多くのデータストアプロダクトがドキュメント型なテイストを取り入れている．(ex. DynamoDB, MySQL, PostgreSQL)
* ドキュメント DB の中でも，MongoDB は動的にクエリを打てる (SQL のように，その場で書いて実行できる)．しかし CouchDB などは静的なデータ問い合わせしかできない．(予め MapReduce ロジックを準備しておく必要がある．起動する前にデプロイが必要になるようなイメージ？)
* ドキュメント型 DB だと KVS と違って階層構造を持った表現力もあり，なおかつスキーマレス．例えば病院の統合で病院ごとにカルテのスキーマが違っても，共通するキーは共通させ，統合元の病院ごとに固有の列はそのままにする，みたいなことができる．
* ドキュメント DB はその取っ付き易さ故，最近アメリカでは「SQL は出来ないけど MongoDB は触れる」っていう若者が出てき始めているらしい．

## MongoDB ハンズオン (と，実務でのつまりどころなどの Q&A)
以下のスライドのコマンドを打ちながら渡部さんがレクチャー．その後 Q&A が 20 分ほど．(渡部さんいわく，Q&A がここまで盛り上がったのは初めてだったらしい)
https://github.com/syokenz/marunouchi-mongodb/blob/master/20150716/fetarodc/README.md

気になった点をいくつか．

### WiredTiger を使うには？
3.0 から WiredTiger ストレージエンジンが利用可能になった．MongoDB 3.0 で WiredTiger を使うには，`mongod` の初回起動時にオプションを付せば良い．

### WiredTiger とドキュメントのリロケーション
MongoDB 2.6 までは，一度挿入されたドキュメントが update されてデータ量が肥大化して当初確保した領域に入りきらなくなった場合にリロケーションが起きる．
WiredTiger を使うと，このリロケーションが起きなくなるらしい．(ここの仕組みの詳細は渡部さんも知らないみたいだった)
今回の勉強会の参加者の中には，MongoDB 2.6 以前で `db.myCollection.find()` でカーソルを取得した後にリロケーションが起きて，カーソルを進めていくと同じドキュメントが2回登場する，という事故に遭遇した人がいたようだが，2.6 のリロケーションが原因の可能性が高い様子．

### WiredTiger と圧縮
WiredTiger はディスクに書き込まれるデータの圧縮も行う．
ドキュメント型 DB はドキュメントごとに列情報を保存する分，従来の RDB と同じ構造のデータを保存した場合には数倍のストレージの食い方をするのがザラだとか．そのため，データ圧縮はある意味必須．渡部さんの実験では 1GB のデータが 50MB に圧縮されたらしい．(詳細は[こちら](http://qiita.com/fetaro/items/2b39a1006ceab9df7fb7) を参照．)

### MongoDB の定期保守
MongoDBの 2.6 までは，先述したリロケーションによるフラグメンテーションに対処しなければならず，オフラインのタイミングでデータのコンプレッションを行う必要があった．これは「MongoDB あるある」として有名．
WiredTiger になるとこの問題は生じないのも前述のとおりだが，その代わりに何か定期保守としてオペレーションが必要になるのかどうかは今のところ分かっていない．

いろいろあるけど WiredTiger が "Highly Recommended" っぽい．


---

長くなってしまったので，後編は別途書きます．
Pwershellで du コマンド


ディスクが圧迫してきたときとかどこが容量食ってるのか調べるのにLinuxだと`du -sh`とか使って調べていくかと思います

Windowsで調べる場合どうしようと思って調べてみました

Powershellを起動して気になるディレクトリに移動して下記

```
ls | ForEach-Object -Process { "$_"; Get-ChildItem -Path "$_" -Recurse -Force | ForEach-Object -Begin { $Len = 0 } -Process { $Len = $Len + $_.Length } -End { $Len / 1024 / 1024 / 1024 }; " " }
```

```
misc53
4.32837117649615

misc54
5.1540436539799

misc55
2.45968135166913
```

カレントディレクトリ以下のファイル、もしくはディレクトリの総容量(GB)を出してくれます

調べるにあたってちょっと時間がかかったのでメモ
Qmail 改行LFで送信出来ない問題

Qmail 改行LFで送信出来ない問題
`vi /etc/init.d/qmail
--------------------
        # SMTP
        tcpserver -qv -l0 -HR -u `id -u vpopmail` -g `id -g vpopmail` \
        -x /home/vpopmail/etc/tcp.smtp.cdb 0 smtp \
        qmail-smtpd `hostname` /home/vpopmail/bin/vchkpw /bin/true 2>&1|\
        splogger smtp &

        tcpserver -qv -l0 -HR -u `id -u vpopmail` -g `id -g vpopmail` \
        -x /home/vpopmail/etc/tcp.smtp.cdb 0 587 \
        qmail-smtpd `hostname` /home/vpopmail/bin/vchkpw /bin/true 2>&1|\
        splogger smtp &

↓ ↓ ↓ ↓ 

        # SMTP
        tcpserver -qv -l0 -HR -u `id -u vpopmail` -g `id -g vpopmail` \
        -x /home/vpopmail/etc/tcp.smtp.cdb 0 smtp \
        #Add 2015-07-17
        # qmail-smtpd `hostname` /home/vpopmail/bin/vchkpw /bin/true 2>&1|\
        fixcrio qmail-smtpd `hostname` /home/vpopmail/bin/vchkpw /bin/true 2>&1|\
        splogger smtp &

        tcpserver -qv -l0 -HR -u `id -u vpopmail` -g `id -g vpopmail` \
        -x /home/vpopmail/etc/tcp.smtp.cdb 0 587 \
        #Add 2015-07-17
        # qmail-smtpd `hostname` /home/vpopmail/bin/vchkpw /bin/true 2>&1|\
        fixcrio qmail-smtpd `hostname` /home/vpopmail/bin/vchkpw /bin/true 2>&1|\
        splogger smtp &
`


【参考】
[http://ajya.hatenablog.jp/entry/2012/03/22/223917](http://ajya.hatenablog.jp/entry/2012/03/22/223917)
[http://blog.livedoor.jp/fbikqtfm/archives/50911655.html](http://blog.livedoor.jp/fbikqtfm/archives/50911655.html)
D3.js グラフの連続描画

D3.jsを利用してグラフの連続描画を行います。

![d3](https://qiita-image-store.s3.amazonaws.com/0/3862/d608701e-b956-378e-6da5-5af8a500383f.jpeg)


定期的にタイマーを起動して配列に乱数を追加してグラフを再描画します。
配列のサイズが上限に達したとき、先頭の配列を削除します。

```html:sample.html
<html>
<head>
    <meta charset = "utf-8">
    <title>D3.js</title>
</head>

<body>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<div id="d3graph" style="border:1px solid #ccc; margin-bottom:10px"></div>

<script type="text/javascript">
var stage;
$(document).ready(function() {
    stage = d3.select("#d3graph").append("svg:svg").attr("width", $("#d3graph").width()).attr("height", 300);
    setInterval("update()",100);
});

var colors = d3.scale.category10();
var d3Line = d3.svg.line()
.x(function(d,i){return i * 10})
.y(function(d,i){return d});

var points = new Array();

function update() {
    points.push(Math.random() * 100 + 100);
    if(points.length > $("#d3graph").width()/10) {
        points.shift();
    }

    // 削除する
    stage.selectAll("path").remove();

    // 描画する
    stage.append("path")
    .attr("d", d3Line(points))
    .attr("stroke", colors(0))
    .attr("fill", "none")
    .attr("opacity", 1);

}
</script>

</body>
</html>

```


WebSocketと組み合わせると、センサ情報のリアルタイム描画が可能になります。
進捗どうですかブーム??にPythonでのりかかってみる

# はじめに

進捗どうですかがブームらしい

[「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるClojure](http://qiita.com/esehara@github/items/c57cafa57aa92dc1e3c2)
[「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるプログラム](http://elephnote.com/blog/archives/936)
[「進捗・どう・です・か」をHaskellで書いてみた](http://qiita.com/lotz/items/b47913cb27052cf9e127)
[進捗どうですかブーム?にrubyでのっかってみる](http://qiita.com/kataware/items/edc8d0f02a16a21c47dc)

# というわけで
Pythonで書いてみました．ただ書くのもアレなので，普段殆ど使わない（リスト内包表記が便利すぎて）lambda式を意味もなく使ってみました．

# コード

```py:shinchoku.py
 #coding: utf-8

import random


li =  ["進捗","どう","です","か"]
LI_RAND_LENGTH =  len(li)-1
CHECK_NUM      = -len(li)
ret = []
itr = 0

shinchokuStr    = lambda       : li[random.randint(0,LI_RAND_LENGTH)]
appendShinchoku = lambda l     : l+[shinchokuStr()]
last4Strs       = lambda l     : "".join(l[CHECK_NUM:])
loopCheck       = lambda x, y : last4Strs(x) == last4Strs(y)

while(not loopCheck(li,ret)) :
	ret = appendShinchoku(ret)
	itr += 1
	print ret[-1],	
print "\n"+str(len("".join(ret))/3)+"文字で煽られました"

```

# 実行結果

```
$ python shinchoku.py
です どう か か です 進捗 どう です どう か です です か どう か どう 進捗 です どう どう 進捗 進捗 です です 進捗 どう です どう 進捗 です か 進捗 進捗 進捗 か どう です どう か か どう 進捗 です です 進捗 どう どう 進捗 進捗 進捗 です 進捗 か どう か か か か です どう か どう です か か です です 進捗 どう 進捗 です です か どう か か 進捗 進捗 進捗 か どう か 進捗 進捗 進捗 です 進捗 です どう どう か 進捗 どう か どう 進捗 です どう どう か か 進捗 です か どう 進捗 です どう 進捗 どう どう 進捗 進捗 です 進捗 です か 進捗 です どう 進捗 どう です どう どう どう です 進捗 進捗 進捗 どう どう 進捗 進捗 どう か 進捗 どう 進捗 どう どう です です 進捗 進捗 です どう か か です どう か か 進捗 です か どう 進捗 です です か か です 進捗 です どう です 進捗 です どう どう どう か です か か です か です 進捗 か どう 進捗 進捗 か どう か 進捗 どう か どう か どう どう 進捗 進捗 どう か か どう です どう です です か か 進捗 進捗 か か 進捗 です です どう 進捗 です か か か です です 進捗 進捗 です どう 進捗 進捗 です 進捗 進捗 進捗 です どう 進捗 進捗 か か か か 進捗 です 進捗 か 進捗 か です どう 進捗 です どう か どう どう か 進捗 進捗 どう です どう です 進捗 か どう か 進捗 進捗 どう か です 進捗 か か どう 進捗 です です 進捗 か 進捗 か です です どう どう です か です です です 進捗 です どう か か どう どう 進捗 です どう どう どう です 進捗 です どう か どう か です 進捗 どう 進捗 進捗 か です か か か か か か です です 進捗 進捗 どう か です か です です です どう か 進捗 どう か 進捗 です です か です です か です です 進捗 進捗 か どう か か どう か か です です です どう 進捗 進捗 進捗 どう か 進捗 です 進捗 か か 進捗 どう どう 進捗 どう です か
656文字で煽られました
```

# 感想
lambda式楽しい．そういえば，Haskell勉強するとかどうとか言ってたので，勉強したい．あと，Pythonの文字列の長さが文字コード(?)関係で色々あるらしいbyte数とかなんとか．とりあえず，動いたのでマジックナンバー入れておきました．
[atom/git]今のブランチで変更のあったファイルを全て開く

動機
--
マージリクエストのレビュー時などに変更のあったファイルをエディタで開いて確認したいときがある.

今のブランチで変更のあったファイルのdiffを表示する
--
```sh
$ git diff $(git log --merges -1 --format=%H) @
```

今のブランチで変更のあったファイル名を表示
--
```sh
$ git diff $(git log --merges -1 --format=%H) @ --name-only
```

git aliasにする
--
```:.gitconfig
[alias]
  alias.mdiff=!git diff $(git log --merges -1 --format=%H) @
```

使用例
--
```sh
# 変更差分の表示
$ git mdiff

# tigと組み合わせる
$ git mdiff | tig

# 変更ファイルの表示
$ git mdiff --name-only

# 変更ファイルをエディタで開く
$ atom . `git mdiff --name-only`
# もしくは前回の実行コマンドを利用して
$ atom . `!!`
```

たぶんこんな感じ. 今回はatomを使ってみたけど, 他のエディタでも同じようにできると思う.
SSH接続時にmotdでメッセージを表示・非表示

先日勉強会で教えて貰った小ネタ。ちょっと調べたら非表示にも簡単にできるようだったのでやってみた。

## motdでログイン時メッセージを表示
サーバーへログインしたり、ターミナルを起動した時に表示されるメッセージは自由に変更することが可能。
`/etc`直下にmotdというファイルを作って編集すれば、固定のメッセージを表示できる。

```sh
$ sudo vi /etc/motd
```

以下の記事のように、アスキーアートやニュースヘッドライン、最近のサーバー変更点が表示できれば楽しそうだし便利そう。

[「motd」「.bashrc」…LinuxにSSH接続した時のメッセージを動的に変化させる方法](http://orebibou.com/2014/07/「motd」「-bashrc」linuxにssh接続した時のメッセージを動的/)
[ssh ログイン・メッセージをランダムに表示する motd](http://takuya-1st.hatenablog.jp/entry/2014/05/23/021213)

## ログイン時何も表示したくない場合
ユーザーのホームディレクトリに`.hushlogin`というファイルを作成すると、「Last login: 〜」のようなシステムメッセージが非表示になる。

```sh
$ touch ~/.hushlogin
```

非表示の解除はこのファイルを削除すればOK

```sh
$ rm ~/.hushlogin
```
Assembleのプラグインの作り方についてメモ

[Assemble](https://github.com/assemble/assemble/)のプラグインを作ろうとした時のメモ。
v0.6系は開発中なので、安定版のv0.4系のみに対応する。

## プラグインを利用する場合

作り方以前に、assembleのプラグインはどうやって使うのか。
[assemble-middleware-rss](https://github.com/assemble/assemble-middleware-rss)の[README](https://github.com/assemble/assemble-middleware-rss/blob/master/README.md)を参考に、プラグインを利用する際に必要なことは以下の２つだけ。

1. npm install
2. Gruntfileのassembleでプラグインの追加

プラグインをインストールして、Gruntfileにプラグインの記述を追加すれば使えるようになる。
assemble-middleware-rssの場合、npmをインストールして

```zsh
$ npm i --save-dev assemble-middleware-rss
```

Gruntfileにプラグインの設定を追加するだけ。

```js
assemble: {
  options: {
    plugins: [
      'assemble-middleware-rss'
    ],
    rss: {
      title: 'rss title',
      description: 'rss description'
    }
  }
}
```

## プラグインの作り方

一般的なnpmの作り方とほとんど一緒。[Node.js - 3分でできるnpmモジュール - Qiita](http://qiita.com/fnobi/items/f6b1574fb9f4518ed520)のような感じで、最終的に`npm publish`する。

```zsh
$ mkdir assemble-index-json
$ cd assemble-index-json
$ npm init
$ touch index.js

... # プラグインの中身作る

$ npm publish
```

index.jsでプラグインのモジュールを作る。

```js
module.exports = function (params, cb) {
  // ここにプラグインの処理を書く

  cb();// 処理の最後に第二引数のコールバック関数を呼び出す
};
```

第一引数には、`grunt`と`assemble`のオブジェクトが格納されたオブジェクトが入ってるので、`Gruntfile`で`assemble`のタスクに設定した内容は、

```
params.assemble
```

の中から取得できる。
プラグイン独自のオプションがある場合は、`params.assemble`以下に独自で定義したオプションがあるので、そこから設定されているオプションの値を取り出す。


### 実行するタイミング

プラグインの処理を`assemble`がページを生成する過程のどのタイミングで行うのか、選べるようになってる。
ドキュメントは見当たらないけど、[assembleのソースコード](https://github.com/assemble/grunt-assemble/blob/master/tasks/assemble.js)からして、以下のいずれかのタイミングでプラグインの処理を実行できるぽい。

- `options:pre:configuration` : assembleのオプション等を読み込む直前
- `options:post:configuration` : assembleのオプション等を読み込んだ直後
- `assemble:pre:layout` : layoutのhbsを読み込む直前
- `assemble:post:layout` : layoutのhbsを読み込んだ直後
- `assemble:pre:partials` : partialのhbsを読み込む直前
- `assemble:post:partials` : partialのhbsを読み込んだ直後
- `assemble:pre:data` : dataを読み込む直前
- `assemble:post:data` : dataを読み込んだ直後
- `assemble:pre:pages` : pageを読み込む直前
- `assemble:post:pages` : pageを読み込んだ直後
- `render:pre:pages` : ページを生成する直前
- `render:post:pages` : ページを生成した直後

例えば、以下のように`stage`に値を渡せば、

```js
module.exports.options = {
  stage: 'render:post:pages'
};
```

全てのページが生成された後のタイミングでプラグインの処理を実行するように制御できる。


## v0.6.0

開発中のv0.6.0は、assemble単体で動かせるようになる予定なので、gruntのプラグインが前提のv0.4.xとはだいぶ変わるようで、プラグインの書き方も違ってるので、v0.6.0が正式リリースされたらプラグインのコードをv0.6.0対応に書き換える必要がある。



## Links

- [assemble/assemble](https://github.com/assemble/assemble)
- [Overview | Assemble](http://assemble.io/plugins/)
- [assemble/grunt-assemble](https://github.com/assemble/grunt-assemble/)
- [assemble/assemble-middleware-rss](https://github.com/assemble/assemble-middleware-rss)
- [makotot/assemble-index-json](https://github.com/makotot/assemble-index-json)
HttpClient を使ってPOSTでマルチパートのファイルを送受信する

.Net でクライアントから WebAPI に対しPOSTリクエストで複数のファイルをアップロードし、サーバからのレスポンスで複数ファイルをダウンロードする必要があったのでやってみた。

クライアントからのPOSTは HttpClient を使用する想定。

サーバサイドは [ASP .Net MVC 4 WebAPI のPOSTでマルチパートのファイルを送受信する](http://qiita.com/volpe28v@github/items/fd78d70d73e5e26404eb) を参照。

## やりたいこと
**POST リクエスト**
　ローカルに保存されたファイルを MultiPart の Content にして送信する

**サーバからのレスポンス**
　MultiPart でファイルが格納された Content をローカルに保存する

## リクエストにファイルを含めて送る
送信側はネット上を調べたら比較的簡単にできた。

MultiPart の Content を作るには MultipartFormDataContent を生成し、File Content をAddしていく流れ。

```csharp
var content = new MultipartFormDataContent();
```

File Content は File.OpenRead()で開いたファイルを StreamContent に食わせて Header にファイル名を設定してあげる。

```csharp
var fileName = @"C:¥hogehoge.txt";
var fileContent = new StreamContent(File.OpenRead(fileName));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
    FileName = Path.GetFileName(fileName)
};

content.Add(fileContent); // これをファイル数分繰り返す
```

あとは HttpClient の PostAsync() で送るだけ。

```csharp
var httpClient = new HttpClient();
HttpResponseMessage response = httpClient.PostAsync(this.url, content).Result;
```

## レスポンスからファイルを読み込む
今度はサーバから返ってきたレスポンスに MultiPart のファイルが含まれている場合に読み込んでローカルに保存する。ネット上にもなかなかまとまった情報がなくて苦労した。

MultiPart の読み込みには HttpContentMultipartExtensions という拡張メソッドを使うのがミソ。(.Net4.5 以上が必要っぽい)
参照設定の[アセンブリ][拡張] から「System.Net.Http.Formatting」を追加する。

まず HttpContentMultipartExtensions.ReadAsMultipartAsync() でレスポンスに渡された Content を provider に読み込む。

```csharp
var provider = HttpContentMultipartExtensions.ReadAsMultipartAsync(response.Content).Result;
```

次に provider に読み込まれた Contents を１つずつ取り出す。
Content を取り出してしまえば、ReadAsStreamAsync() を呼び出してファイルの Stream を取得する。
保存用のファイルStreamを別途開き、CopyTo() でローカルに保存する。

```csharp
foreach (var responseContent in provider.Contents)
{
    var fileName = responseContent.Headers.ContentDisposition.FileName;
    Stream stream = responseContent.ReadAsStreamAsync().Result;
    using (var outFileStream = new FileStream(@"C:\hoge" + Path.DirectorySeparatorChar + fileName, FileMode.Create, FileAccess.Write))
    {
        stream.CopyTo(outFileStream);
    }
}
```

上記例ではファイル決め打ちで処理しているが、いろいろ混ざっている場合は ContentType などを見てよしなに判断する。
ただ、ファイルの場合は ContentType が null なのでいきなり見ないように注意する。

```csharp
if (responseContent.Headers.ContentType != null && responseContent.Headers.ContentType.ToString().Contains("text/plain"))
{
    // テキストのパラメータ
    string key = responseContent.Headers.ContentDisposition.Name;
    string value = responseContent.ReadAsStringAsync().Result;                            
}
```

書いてみるとたったこれだけの事か。。
特にクライアントサイドで MultiPart から Content を取り出す方法がなかなかわからなかったんだけど、わかってしまえば大したことはないな。
Views Moduleのページタイトルを翻訳したい



テーマファイルの中のtemplate.php編集してテーマ関数をオーバーライドする。
Wordpressでいうところのfunction.php

```template.php
// MYTHEME部分はテーマ名で置き換える
function MYTHEME_views_pre_render(&$view) {
  $view->set_title(t($view->get_title()));
}
```

Views Pageのタイトルを入力して、から`/admin/config/regional/translate/translate`に移動しタイトル文字列を検索して対応する言語の翻訳内容を追加する。

以上
gzip 圧縮したテキストファイルは cat でつなげても大丈夫だよ

# 仕様

[RFC 1952](http://www.gzip.org/zlib/rfc-gzip.html#file-format) にも書いてあるよ

> A gzip file consists of a series of "members" (compressed data sets). The format of each member is specified in the following section. The members simply appear one after another in the file, with no additional information before, between, or after them.

gzip ファイルのフォーマットは単に member の連続でしかないとのこと。
なら member の連続どうしの gzip ファイルを 2 つ以上つなげても同じだよね。

# 実際にやってみよう

```console
$ echo hello | gzip -c > hello.gz
$ echo world | gzip -c > world.gz
$ cat hello.gz world.gz > helloworld.gz
$ gzip -dc < helloworld.gz
```

```console:出力結果
hello
world
```

OK

# ところで

zcat について書かれたページ
http://itpro.nikkeibp.co.jp/article/COLUMN/20060228/231000/

> gzipやcompressで圧縮されたファイル（拡張子.gz）の内容を表示する。catコマンドとは違い，複数の.gzファイルを圧縮されたまま連結することはできない。zcatに関連するコマンドとしては，zmore，zlessがある。動作はmoreおよびlessと似ている。

この文を読むだけでは cat では繋げられないと勘違いしてしまいそう ＞＜
もちろん zcat が必要なケース・あると便利なケースがあることを筆者は否定しないよー。

# バージョン情報

念のためバージョン情報を。 ```gzip --version``` で出した。
GNU 系と BSD 系で試したかったので、
手元の OS X と Ubuntu (Linux) の gzip で試した。

## BSD GZIP

```console
Apple gzip 242
```

## GNU GZIP

```console
gzip 1.6
Copyright (C) 2007, 2010, 2011 Free Software Foundation, Inc.
Copyright (C) 1993 Jean-loup Gailly.
This is free software.  You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.

Written by Jean-loup Gailly.
```

# 免責

この情報はいかなる種類の保証も伴わずに「現状のまま」で提供するよ。
筆者はいろいろと責任を負わないし負えないよ。 (ry
ギークになるなら着ていたい、テック系Tシャツまとめ


イベントや勉強会などでもらう機会があるテック系Tシャツ。中には普段使いにも問題なく使えるオシャレなものもありますよね。珍しいTシャツを着ていると勉強会などで話題になります。


気になったのでどんなTシャツがあるのかオンラインで手に入る範囲で調べてみました。他にあったら教えてください。

# (アカウント登録+αで)無料でもらえる

サービスのアカウントを作成する、ちょっと使ってみる、などするとお礼にTシャツを送ってくれるサービスがあります。

## New Relic

去年NASDAQに上場したパフォーマンス計測サービスをやっている New Relic。

http://newrelic.com/lp/datanerd
![heroshirt-6ce239d2aa7dc50f7adca7be4bf16f79.jpg](https://qiita-image-store.s3.amazonaws.com/0/27210/2d298285-7aca-26d9-cedf-978700faf896.jpeg "heroshirt-6ce239d2aa7dc50f7adca7be4bf16f79.jpg")

## Runscope

API のヘルスチェックをするサービスです。

https://www.runscope.com/free-tshirt-offer
![tshirt-offer.png](https://qiita-image-store.s3.amazonaws.com/0/27210/59600252-97e1-dd8a-0635-8456878bdf10.png "tshirt-offer.png")

## Circle CI

http://blog.circleci.com/new-stickers-and-circleci-tee-shirts/

メールにTシャツのサイズ、住所、電話番号(日本からだと国際便になるため必要) をメールで伝えると送ってくれます。

# 販売
サービスの中にはオンラインショップを持っていてそこでTシャツやステッカーを売っていることがあります。Qiita もそうですね。だいたい3000-5000円くらいの価格帯のようです。海外のサービスの場合は送料が気になるので複数人で買うなどしたいです。

## Qiita

http://shop.qiita.com/

## Evernote

https://www.evernote.com/market/feature/tshirt-jp

## Github

昔よりTシャツのラインナップが増えた気がします。

http://github.myshopify.com/

## はてな

https://hatena.stores.jp/#!/
Elixirで進捗どうですか？

ダメです。
Elixirで遊び始めたので、やってみました。
せっかくなのでメソッドにガードつけてーとか考えてたんですけど、正規表現使えなくて諦めました。

[「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるプログラム](http://elephnote.com/blog/archives/936)
[「進捗・どう・です・か」をHaskellで書いてみた](http://qiita.com/lotz/items/b47913cb27052cf9e127)
[「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるClojure](http://qiita.com/esehara@github/items/c57cafa57aa92dc1e3c2)
[golang の進捗どうですか](http://qiita.com/mattn/items/4b4ce89396d660a155a9)

```ex:shinchoku.ex
:random.seed :os.timestamp

defmodule Shinchoku do

  @chars ["進捗", "どう", "です", "か"]
  @goal Enum.join(@chars)
  @length length(@chars)

  def doudesuka(s \\ "") do
    st = s <> Enum.at(@chars, :random.uniform(@length) - 1)
    if String.ends_with?(st, @goal), do: st <> "???", else: doudesuka(st)
  end

end

s = Shinchoku.doudesuka
IO.puts s
IO.puts Integer.to_string(String.length(s)) <> "文字で煽られました。"

```

```
かどうどうかですかかかか進捗進捗どう進捗か進捗どう進捗かどうか進捗かです進捗どう進捗かですどうどうかどうですかですですですか進捗かどうかどうです進捗どう進捗進捗です進捗進捗ですです進捗かですかかですです進捗進捗です進捗ですか進捗かかか進捗かどうですどうどうどうですかどうですですどうかですどうかか進捗どうどうですですかですどうどうどう進捗か進捗かどうかどうですどうどうかですどうですですどうどうですですかですです進捗かか進捗進捗進捗進捗どうどうどう進捗ですどうどうかかかどうどうですです進捗進捗ですどう進捗ですどう進捗進捗ですですかか進捗ですですですかかか進捗どうどう進捗かですかかかか進捗かかどう進捗どうですか???
309文字で煽られました。
```
はじめてのMongoDBメモ(Windows環境)

MongoDBについての各種コマンドメモ。MongoDBバージョンは3.0.3です。

■MongoDB
・特徴
　・NoSQL(NotOnlySQL)。RDBではない。
　・ドキュメント指向データベース
　・ライセンス	GNU AGPL v3.0（ドライバはApache License）
　・マルチプラットフォーム(Windows, Linux, OS X, Solaris)
　・各種言語サポート。(Node.jsとも相性がいい)

・公式サイト
https://www.mongodb.org/

・インストール
普通にダウンロードして、MSIインストーラーにしたがって、インストール。
環境変数のPATHにインストールフォルダ配下のbinフォルダを追加。
***
(コマンド)
以下は基本的にコマンドプロンプトから実行する。

・バージョン確認
mongo -version

・DB起動
mongod
※--dbpathオプションを指定しない場合、データ格納場所は「c:\data\db」となる。
　データ格納場所がない場合は起動エラーとなる。

・DB起動(データ格納場所指定)
mongod --dbpath D:\myproject\mongodb\data

・MongoDBのWindowsサービス登録
mongod --dbpath D:\myproject\mongodb\data --install --logpath D:\myproject\mongodb\logs\logs.txt
※コマンドプロンプトは管理者権限で実行していないと失敗する。

・DBサービス接続
mongo
※デフォルトの接続DBは「test」
***
(問い合わせコマンド)
以下は、mongoコマンドでDB接続した状態で実行する。

・DB作成・切り替え(無ければ作成)
use <ＤＢ名>
例)use sample_db

・データ登録
db.<コレクション名>.insert({登録内容});
※コレクションはRDBのテーブルのようなもの。
例) db.user.insert({ _id : 1 , name : '田中　太郎' } );

・データ更新
db.<コレクション名>.update({条件}, {更新内容});
例) db.user.update({ _id : 1 }, { $set : { name: "鈴木　太郎" } });

・データ削除
db.<コレクション名>.remove({条件});
例) db.user.remove({ _id : 1 });

・検索(全件)
db.<コレクション名>.find();
例) db.user.find();

・検索(条件指定)
db.<コレクション名>.find({条件});
例) db.user.find({ name: {$eq:"鈴木　太郎"} });
「$eq」部分は比較演算子。
$eq	等しい
$ne	等しくない
$gt	右辺より大きい
$gte	右辺以上
$lt	右辺未満
$lte	右辺以下

・コレクション削除
db.<コレクション名>.drop();
例) db.user.drop();
Active Directoryいれたらsudo権限が変更されてbrewコマンドが使えない問題の解決

## 経緯

会社PCでActive Directoryを入れられた影響でsudo権限がおかしなことになり。もろもろ影響が出ている。
特にHomebrewで`brew install`とか`brew upate`ができない。

 あれ、ちょっと前まで使えた気がしたが... :p

hubコマンド使いたくて ` $ brew install hub `したらerrorがでて萎えた。
sudoたたくとでる↓

## error文

```
$ sudo brew install

You can use brew with sudo, but only if the brew executable is owned by root.
However, this is both not recommended and completely unsupported so do so at
your own risk.

```

## 対処
#### 1. スーパユーザーにパスワードを指定

そういえばスーパユーザーのパスを設定していなかった。

```
$ sudo passwd root
Password:
Changing password for root.
New password:
Retype new password:

```

#### 2. 自分に権限の指定

/usr/local の権限がrootに変わっていたっぽいので、
homebrewを一般ユーザで実行できなくなっていた…

```

$ ls -la /usr/local/bin/brew

$ sudo chown root /usr/local/bin/brew

```
通ったっぽい。


#### 3. 満を持してぶりゅー

```
$ sudo brew install hub

==> Downloading https://homebrew.bintray.com/bottles/hub-2.2.1.mavericks.bottle.
######################################################################## 100.0%
==> Pouring hub-2.2.1.mavericks.bottle.tar.gz
==> Caveats

Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

zsh completion has been installed to:
  /usr/local/share/zsh/site-functions
==> Summary
🍺  /usr/local/Cellar/hub/2.2.1: 9 files, 9.6M

```

めでたしめでたし。🍺 見るとテンション上がる。


## まとめ

Active Directoryのクソ野郎。
kimonoの使い方 クローラーの設定編

#kimonoのサービスは終了したようです
[WebスクレイパーサービスKimono LabsがPalantirに買収され、サービスは2月末に閉鎖へ](http://jp.techcrunch.com/2016/02/16/20160215palantir-acquires-kimono-labs-for-its-web-scraping-service/)

#kimonoの仕組み？
[kimonoの使い方 基礎編](http://qiita.com/her0m31/items/b844ff74a9d488c9dc81)の続きです。

[kimono](https://www.kimonolabs.com)の動作の流れとしては、
1.スクレイピング
2.kimonolabsサーバに保存
3.kimono APIの呼び出し
4.kimonolabsからデータを取得
のようになっています。

kimono APIを呼び出した時に、対象のWebページに、直接アクセスする訳ではないようです。

なので、kimonoを使って一定時間毎にデータを取得したい時には、"kimonoがスクレイピングするタイミング"と"kimono APIを呼び出すタイミング"に気をつけなければいけないようです。


#kimono クローラーの設定
前置きが長くなりましたが、今回は、そんなkimonoのクローラーの設定についてです。

とりあえず、クローラーの設定画面を開きましょう。
CRAWL SETTINGタブです。

![ac.png](https://qiita-image-store.s3.amazonaws.com/0/31946/8527a623-c5de-07a1-0e6f-f8194efd989e.png)

今回は、クローリングのタイミングの設定と、クローリング対象ページの設定を行いたいと思います。

##クローリング頻度
[kimono](https://www.kimonolabs.com)は、どのタイミングでクローリングを行うか決めることができます。

![aa.png](https://qiita-image-store.s3.amazonaws.com/0/31946/00eb7bb0-9fb3-1df4-760e-88d231e19177.png)

2015/7/16時点では、「手動」「毎時間」「毎日」「毎週」「毎月」のタイミングから選べます。
ちなみに、手動以外は、前回のクローリング実行時を基準としているようです。
##クローリング対象URLの設定
クローリング対象は、最初に作成した時のページ以外も指定出来たりします。
左のCRAWL STRATEGYです。

![ab.png](https://qiita-image-store.s3.amazonaws.com/0/31946/10df7e8a-b6e0-dfb2-6fcd-76824bbacad9.png)

CRAWL STRATEGYのGenerated URL listを選択します。
すると下にURL GENERATERが表示されるので、これを使って設定していきます。



ページ数なんかを設定して、検索結果とか記事一覧とかが複数ページに分かれているときに使うと便利です。

#おわり
クローラーの設定をしました。上手く設定できるとアンテナサイトが作れそうな感じがしますね。

そして、実は、クローリングとスクレイピングの定義が曖昧だったりするんですが、良い資料とかあれば教えて頂きたいです。

*[kimonoの使い方 基礎編](http://qiita.com/her0m31/items/b844ff74a9d488c9dc81)の続きです。
Oracle Database 11g Release 2 Clientを間違えてインストールしてしまったときの対処方法

Oracle Database 11g Release 2 Clientを間違えてインストールしてしまった場合に、これを削除する方法についてまとめてみます。

#通常の方法
2. Windows PowerShellを管理者権限で起動します。
3. `<Oracleベース>\deinstall\deinstall`コマンドを実行します。

#うまくいかないとき
上記手順でうまく行かないときは、次の手順で行います。
1. [Oracle Database 11g ダウンロード](http://www.oracle.com/technetwork/jp/database/enterprise-edition/downloads/112010-win32soft-098788-ja.html)から、Oracle De-install Utilityをダウンロードし、適当なフォルダに解凍します。
2. Windows PowerShellを管理者権限で起動します。
3. カレントディレクトリを解凍したフォルダに移動します。
4. `.\deinstall -home {削除するOracle ClientのOracleベース}`コマンドを実行します。
5. 残ったフォルダやレジストリをお好みで削除します。
IE11におけるmain要素の扱い


html5jのMLで「IE11でmain要素にwidth,heightが効かないです」という話題で盛り上がっていたので、纏めてみた。

# IE11でmain要素を使うとどうなる？
## まずはコードを書いて試してみましょう
[サンプル](https://jsfiddle.net/1johxwzy/)
※IE11で開いてください

## 表示を確認してみましょう
IE11だと、Resultに何も表示されません。

## どうして何も表示されないのか？
IE11がmain要素に対応していないから。
IE11でmain要素を含んだHTMLをレンダリングすると、main要素でマークアップされた部分はブロックレベル要素として扱われず、widthとheightの指定が無視される。

# 対応策は？

対応策としては以下の方法が考えられる。

- main要素に「display: block」を付与する。
- 外部ライブラリを使う。

## 1. display:blockを付与する
[サンプル](https://jsfiddle.net/1johxwzy/)
上のサンプルコードにCSSを書き足してみましょう。

```css
main {
    width: 400px;
    height: 400px;
    background: red;
    display: block; /* 追記 */
}
```

これでIE11でもmain要素がブロックレベル要素として扱われるようになり、width、height指定が有効になる。

## 2.外部ライブラリに頼る
「 **html5.js** 」とか「 **html5shiv.js** 」とか。その辺を使う。
ただそれだけ。
IE8のようなレガシーブラウザ対応をしている場合、既に読み込んでいる場合が多いと思います。

しかし、下記のようにIE8にだけ適用されるようにしている場合、IE11ではmain要素がブロックレベル要素として扱われずにハマるケースが稀にあるので注意してください（体験談）。

```html
<!--[if lt IE 8]>
<script type="text/javascript" src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
```

# 余談 - floatの小噺

「 **main要素にfloatをあてる** 」
実用性はあまり無いかもしれませんが、この方法でもwidth, height指定が適用されます。

> float は暗黙的にブロックレイアウトの使用を意味していて、display の計算値を変えるケースがあります

[参考URL](https://developer.mozilla.org/ja/docs/Web/CSS/float)

floatをあてることで、mainのdisplayの値が再計算されてblockになり、width、heightの値が適用されるようになるという仕組みです。
json ファイルの不要なカンマを除去

こんにちは。
json ファイルに対して不要なカンマを除去してみました。すなわちカンマの後に括弧が閉じられていて json として不正なデータになっている場合に対する修正です。

```console
$ ruby -e 'print ARGF.read.gsub(/,(?=\s*[}\]])/, "")' bad.json > good.json
$ jsonlint -v good.json
good.json: ok
```


```console
$ cat bad.json
{
  "features": [
    "properties": {
      "level": 0,
    },
  ],
}
```

上記はコメントで頂いたものでして、推奨だと思いました。本稿内容も修正しています。標準入力渡しでも大丈夫ですね。

下記は元々の私自身のものですが、他人へは勧められないですね。

```console
$ ruby -e 'print IO.readlines(ARGV[0], nil)[0].gsub(/,(\s+[}\]])/, "\\1")' bad.json > good.json
```
ボトルネック探すコマンドまとめ

#メモリ
```bash
[suzuki_shogo ~]$ free
             total       used       free     shared    buffers     cached
Mem:       3664848    3396836     268012          0     204788    1311460
-/+ buffers/cache:    1880588    1784260
Swap:            0          0          0
```
- buffer/cacheのfreeが飽きメモリ容量
- Swapのusedが上がってきたら危険

#CPU
```bash
[suzuki_shogo ~]$ uptime
 21:18:49 up 323 days,  6:31,  1 user,  load average: 0.00, 0.00, 0.00
```
- load averageが3以上はあやしい

#ディスク
```bash
[suzuki_shogo ~]$ vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 268756 204788 1311824    0    0     0    21    0    1  2  1 97  0  0
```
- bの数が増えてきたら危険。io完了待ちの数。

#ネットワーク
```bash
[suzuki_shogo ~]$ netstat -i
Kernel Interface table
Iface       MTU Met    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0       1500   0 1257869327      0      0      0 1183733894      0      0      0 BMRU
lo        16436   0 154586757      0      0      0 154586757      0      0      0 LRU
```

- 受信パケット成功率 = RX-OK/RX-OK + RX-ERR + RX-DRP + RX-OVR が90%以下の場合は怪しい
jqGridで列に対する検索フィルターを動的に作成した選択肢のセレクトボックスにする


これも人に頼まれて実現したもの。
jqGridの検索フィルターは、デフォルトでテキストボックスとセレクトボックスをセットできる。

ただ、このセレクトボックスの項目は、静的に項目を並べた例が多くて、列の値を選択肢として動的に作った例がなかったので自作。

実現イメージは、こんな感じ。

![スクリーンショット 2015-07-16 21.20.00.png](https://qiita-image-store.s3.amazonaws.com/0/23683/0953bcb9-cf74-a763-6c4a-d41898d8a3d2.png "スクリーンショット 2015-07-16 21.20.00.png")

まずは、HTML。

```HTML
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
	<title>jqGridSample</title>
	<link type="text/css" media="screen" href="css/jquery-ui.min.css" rel="stylesheet" />
	<link type="text/css" media="screen" href="css/ui.jqgrid.css" rel="stylesheet" />
	<script type="text/javascript" src="js/jquery-1.11.0.min.js"></script>
	<script type="text/javascript" src="js/jquery.jqGrid.src.js"></script>
	<script type="text/javascript" src="js/i18n/grid.locale-ja.js"></script>
	<script type="text/javascript" src="js/underscore-min.js"></script>
</head>
<body>
  <table id="sample"></table>
</body>
</html>
```

続いてJavaScript。

まずは、列の設定で検索オプションとともに、選択肢を作成する関数（createSearchChoices）を呼び出す。
stypeをselectにして、searchoptionsで選択肢を指定。

```JavaScript
{name: "col2", index: "col2",
 stype: 'select', searchoptions: { value: createSearchChoices(displayData, "col2"), sopt: ['cn'] }}
```

検索条件は、以下のような関数で生成した。
列の値をマージするのが面倒で、underscore.jsを利用。

```JavaScript
function createSearchChoices(targetData, targetAttrName) {
  var colSelections = { "": "" };
  var cols = _.uniq(_.map(targetData, function(it) {return it[targetAttrName];}));
  cols.forEach(function(it) {colSelections[it] = it;});

  return colSelections;
}
```
【iOS】端末をアップデート後、Xcodeで実機に書き込めなくなった場合

私がこの現象に陥ったのは、Xcode7 beta3 を使っていたときに
実機をアップデートしたら、
```Could not find Developer Disk Image```とWarning がでて
書き込めなくなりました。

## Could not find Developer Disk Image

どうやら、Beta版の中にアップデート後のVersionに対応するDisk Imageが入ってないらしいです。
（その時は、iOS8.4に対応していなかった)

## 問題解決に必要なもの

- [Xcode][1]

↑ beta版ではないものからパクってきます。DLしてること前提で手順移ります。
  (たぶん、iOSアップデートくらいでXcodeもマイナーアップデートされるのでそれを使う)

## 手順

1.アプリケーションのXcodeをパッケージ内容を表示で開きます。

![スクリーンショット 2015-07-16 21.04.06.png](https://qiita-image-store.s3.amazonaws.com/0/60014/a38b89a4-ba11-af3d-9b10-892acde723dc.png)

2.下記のところまで行ってください。

```
Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/
```

![スクリーンショット 2015-07-16 21.09.12.png](https://qiita-image-store.s3.amazonaws.com/0/60014/4544da7b-e2d1-3460-33be-e69a8354b6b6.png)


3.ディレクトリ内の8.4 (12H141)をコピーする。
  今回は、iOS8.4だったためコチラをコピーしますが、実際のは見比べて、存在しないものを選べばいいかと

4.同じ手順でBeta版の方に追加する。

```
Xcode-beta/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/8.4 (12H141)
```

5.Beta版を再起動して、実機をつなぐと書き込めるようになっている。

##P.S.

Xcodeのプラグインが動かなくなった人は[コチラ][2]

[1]:https://itunes.apple.com/jp/app/xcode/id497799835?mt=12
[2]:http://qiita.com/Hakota/items/464be4576f0f244e85c1
Chinachuの導入と運用

はい、そろそろ夏休みに入るので、自由工作ということで自作pcを組み立ててpt3を買い、録画サーバーを建ててみることにしました。
録画ソフトはお金をかけるつもりはなかったのでfoltinaではなくchinachuを使うことにしました。
簡単にはまったところなどを......
#pcスペック
 - cpu: Pentium g3250
 - メモリ : 4G
 - hdd : 2TB
 - OS : Ubuntu 15.04

という感じで作りました。ぶっちゃけ録画サーバーとしては十分すぎるスペック。
エンコードとかをやるつもりないしリアルタイム視聴もする予定はないのでこれで足りると判断しました。

#Chinachuの導入
これについてはググれば大量に情報がありますのでそちらを参照してください

 < 参考にしたサイト > 

 - http://yutorm.blogspot.jp/2014/06/pt3-chinachu.html
 - https://github.com/kanreisa/Chinachu (公式）
 - [http://mimikakimemo.hatenablog.jp/entry/2014/06/08/193608](http://mimikakimemo.hatenablog.jp/entry/2014/06/08/193608) ubuntuだと `insserv` のところでハマる
 
#はまったところ（ハード編）
ハードの方ではまったところはほとんどありませんでしたが、pt3のさし方が甘かったためpcが認識せず30分くらいはまりました。

#はまったところ（ソフト編）
びっくりするくらいうまくいった。Chinachu様様ですよ本当

追記：　何故か`./chinachu updater`でエラーが止まらない。
調べてみたところどうもgitが原因っぽいのでgitを入れなおしてみたところ普通にうまくいった。私の一時間は何だったんだろう。

#はまったところ（運用編）
はまったってわけではないけれども、私が最初chinachuをインストールしたときには手動録画がすべてワンセグ録画になるというバグがあったため画質の悪さに悩まされたが、すぐに修正が入ったため特に問題はなかった。

あとは、録画したやつをそのままブラウザ上で再生しようとすると異様にcpuを食ってしまい非常にカクついた再生となってしまう。だが、録画フォルダをsambaで共有するようにしてそのファイルをメインのパソコンから再生すると何の問題もなかった。また、録画しているpcでもファイルをvlc mediaplayerのようなもので再生するとcpuの使用率がブラウザ上の再生よりも異様に抑えられる。

#使ってみた感想
導入は簡単だし今のところうまく撮れていないということもなく非常に快適。ただ、ブラウザ上からの再生でもう少しcpuの使用率を抑えられるとうれしい。


全く関係ないがQiitaの投稿は初めてでMarkdownの書き方に慣れず苦戦した orz

#追記
ある日を境に急に録画ができなくなったと思ったらpt3が認識されなくなっていた。
原因としては多分こちら
http://qiita.com/ymotongpoo/items/c31ae0fc3c7378436b27
みなさんもお気をつけ下さい。
jqGridで各行にボタンを配置する


ちょっと人に頼まれて実現してみた。
jqGrid関連の情報は、割りと古いものが多かったりするので、最新の **v4.8.2** で実現するのに、ちょっと戸惑った。

実現イメージは、こんな感じ。

![スクリーンショット 2015-07-16 20.49.29.png](https://qiita-image-store.s3.amazonaws.com/0/23683/af651122-22b2-8d19-b6d4-98ae9859b8eb.png "スクリーンショット 2015-07-16 20.49.29.png")

各行の左端にボタンを置いて、それを押した時の振る舞いをハンドリングすること。

まずは、HTML。

```HTML
<html lang="ja">
<head>
  <meta charset="UTF-8">
	<title>jqGridSample</title>
	<link type="text/css" media="screen" href="css/jquery-ui.min.css" rel="stylesheet" />
	<link type="text/css" media="screen" href="css/ui.jqgrid.css" rel="stylesheet" />
	<script type="text/javascript" src="js/jquery-1.11.0.min.js"></script>
	<script type="text/javascript" src="js/jquery.jqGrid.src.js"></script>
	<script type="text/javascript" src="js/i18n/grid.locale-ja.js"></script>
</head>
<body>
  <table id="sample"></table>
</body>
</html>
```

続いてJavaScript。
ドキュメントを見ると、列の設定でedittypeにbuttonを指定すればボタンを置けそうなんだけど、結局実現できなくて、formatterを自分で作れば実現できた。

まずは、列の設定で自作のformatterを指定する。

```JavaScript
{name: "buttonSel", index: "buttonSel", formatter: buttonFormat, search: false},
```

続いて、カスタムformatterを実装する。
と言っても、単に出力したいHTMLを文字列で返すだけ。
押したボタンの行を知りたいので、data-rowidに行番号をセットするようにしている。

```JavaScript
function buttonFormat(cellvalue, options, rowObject) {
  return '<button type="button" class="selectButton" data-rowid="' + options.rowId + '">選択</button>';
}
```

ボタンを押した時のイベントはこんな感じ。
`$(this).data('rowid')` で選択されたボタンの行数が取れる

```JavaScript
$('.selectButton').on('click', function(event) {
  console.log('button click : ' + $(this).data('rowid'));
});
```

JavaScript全体は、こんな感じ。

```JavaScript
$(function() {
  var displayData = [
    {No: 1, col1: "1", col2: "りんご", col3:5},
    {No: 2, col1: "2", col2: "バナナ", col3:10},
    {No: 3, col1: "3", col2: "バナナ", col3:2},
    {No: 4, col1: "4", col2: "りんご", col3:14},
    {No: 5, col1: "5", col2: "ミカン", col3:5},
  ];

  //列の設定
  var colModelSettings= [
  	// ボタンにする行のformatterを自作の 'buttonFormat' にマッピング
    {name: "buttonSel", index: "buttonSel", formatter: buttonFormat, search: false},
    {name: "col1", index: "col1", search: false},
    {name: "col2", index: "col2"},
    {name: "col3", index: "col3"},
  ];

  //列の表示名
  var colNames = ["", "ID", "果物の種類", "在庫"];

  //テーブルの作成
  $("#sample").jqGrid({
    data:displayData,
    datatype : "local",
    colNames : colNames,
    colModel : colModelSettings,
    rowNum : 100,
    rowList : [1, 10, 20],
    caption : "果物在庫表",
    height : 200,
    width : 600,
    pager : 'pager',
    regional : 'ja',
    viewrecords: true,
    cellEdit:true
  });

  $('.selectButton').on('click', function(event) {
    // ボタン押下時の振る舞いはここへ
    // $(this).data('rowid') で選択されたボタンの行数が取れる
    console.log('button click : ' + $(this).data('rowid'));
  });

  // ボタン生成用関数
  function buttonFormat(cellvalue, options, rowObject) {
    return '<button type="button" class="selectButton" data-rowid="' + options.rowId + '">選択</button>';
  }
});

```
シェルスクリプトのシングルクォーテーションとダブルクォーテーションの違い

シングルクォーテーションのほうが強めに特殊文字を文字化する

```bash
~ % name=shogo
~ % echo "My name is $name"
My name is shogo
~ % echo 'My name is $name'
My name is $name
```
MiddlemanにBootstrap + jQueryを導入して静的サイト制作を効率化する


[Middleman]('https://middlemanapp.com/jp/')に[Bootstrap]('http://getbootstrap.com/examples/theme/')とjQueryを導入し、静的サイト制作フローを高速化・効率化した。Bourbon RefillsのUIでは物足りないときの+αとして有効かもしれない。

# やりたかったこと
* レスポンシブなスライドショー(Carousel)を手っ取り早く実装
* タグやカウンターなど、汎用的なレスポンシブWebコンポーネントを利用
* Webフォントアイコンの利用
* Boubon Projectとの混在が可能かどうかテスト

![sample.jpg](https://qiita-image-store.s3.amazonaws.com/0/85887/dfbaebce-1255-a6f9-f96e-347d3e979d0f.jpeg)

図: [イロ得シリーズ]('http://irotoku.com/')のティザーサイト、リニューアル構想

>**イロ得シリーズ**
北陸で発行しているムック本シリーズのブランド名。「Lunch Fan!」「金沢千円で飲める店」「富山千円で飲める店」の総称。


## 導入背景

時間も人も足りないので、話題の[Bourbon]('http://bourbon.io/')を導入してみたが、先進的な普段からUIDに触れていない人から見ると、若干もの足りないっぽい... ：p　おそらく、我らが地方圏のカスタマから見ても同じ印象をもつであろう。

> *かと言って、いまさら生々しくHTML・CSSを書きなぐる気力はない*

> *Sketch.appで、専用の編集データを増やすのも気に食わない*

で、楽してそれっぽいUIを速攻で提出したい。

よくよく考えてみれば、htmlファーストにこだわる必要のない部分は、計画的にWebコンポーネントを利用すれば、場当たり的にも、それなりのものができるだろうし、下手なフレームワークを採用するより汎用的で事例も多いので、導入してみることに。


## 手順

### 1. Bootstrap + jQuery をインストール

Gemfileに BootsstrapとjQueryのgemを追加する。
※アセットパイプラインの設定が前提

```lang:Gemfile

gem 'bootstrap-sass', :require => false
gem 'jquery-middleman', :require => false

```

`:require => false` しないとerrorがでる。

### 2. BootstrapのStylesheetsの読み込み設定をする。

任意だがここでは `/stylesheets/all.css.sass` にimportの記述。

```lang:all.css.sass 

@import "bootstrap-sprockets"
@import "bootstrap"

```

### 3. JavaScriptの読み込みを設定する。

任意だがここでは `/javascripts/all.js.coffee`にrequireを記述。

```lang:all.js.coffee 
//= require jquery
//= require bootstrap-sprockets
//= require npm
//= require_tree .
```

読み込み順注意。

### 4. 動作確認 

bundleで必要なgemのインストールを終わらせる。

```
$ bundle install
```
`npm.js`が入っていなかった場合は gemでインストールする。

すんなり通れば、インストール完了。

次にbuild。

```
$ bundle exec middlemain build

```

* `/assets`以下にコンパイルされたall.cssとall.js
* `/font`以下にbootsstrapフォント
* Projectディレクトリ直下に`base`

↑できていれば成功。

あとは、[Bootstrap]('http://getbootstrap.com')から、スコスコパーツを引っ張ってきて煮るなり焼くなり。


---
## まとめ

npm.jsがgem install　されていなかったのに気づかないで、２時間くらい持って行かれた。なんだかんだProject単位でいちいち設定するのが面倒くさいから、プロジェクトのスケルトンをいい感じで準備しておきたい。と思った。

Boubonと同居させるのにはかなり違和感があるけど、「できなくはない」と気づけたのは収穫。
最近気になったGithub JavaScriptトレンド7選（2015年6月編）


##概要

先月辺りに気になった<a href="https://github.com/trending?l=javascript" target="_blank">Github JavaScriptトレンド</a>を7つ選んでみました（<a href="http://blog.mmmcorp.co.jp/blog/2015/07/16/js-trend-2015-6/" target="_blank">こちら</a>に書いたものです）。

##<a href="https://github.com/ipselon/react-ui-builder" target="_blank">React UI Builder</a>

React.jsのコンポーネントをGUI的に作成できるツール。

![ReactUiBuilder.jpg](https://qiita-image-store.s3.amazonaws.com/0/22875/ee5f1482-905d-8e54-6de9-765d34bd8d3b.jpeg)


##<a href="https://github.com/graphql/graphql-js" target="_blank">GraphQL</a>

GraphQLはデータを表記するためのクエリ言語。階層構造を備えたクエリ構造や型システム、クライアント視点でのクエリ、GraphQL言語それ自身によってクエリされるサーバの型システムといった特徴により、クライアントアプリケーションの開発に適している。

* <a href="http://codezine.jp/article/detail/8823" target="_blank">Facebook、新クエリ言語GraphQLのRFCドラフト案を公開</a>
* <a href="http://facebook.github.io/react/blog/2015/05/01/graphql-introduction.html" target="_blank">GraphQL Introduction | React</a>


##<a href="https://github.com/google/incremental-dom" target="_blank">Google incremental dom</a>

Googleが開発しているVirtual DOM。

* <a href="https://gist.github.com/azu/8f1afa948eeb2da3ad00" target="_blank">Incremental DOM ざっと見たやつ</a>
* <a href="https://medium.com/google-developers/introducing-incremental-dom-e98f79ce2c5f" target="_blank">Introducing Incremental DOM — Google Developers — Medium</a>

##<a href="https://github.com/carlosazaustre/universal-js-boilerplate" target="_blank">UniversalJS Boilerplate</a>

isomorphicなwebアプリのためのboilerplate。最近流行りの、Express、React、Babel、Browserify(Webpack)、(Flux、Jest)、な構成。

* <a href="http://qiita.com/masato/items/b4fff7e885f78cd96edb" target="_blank">ES6で書くIsomorphicアプリ入門 - Part1: リソース - Qiita</a>


##<a href="https://github.com/flyjs/fly" target="_blank">Fly</a>

Node.jsベースのビルドツール。


##<a href="https://github.com/idoco/map-chat" target="_blank">Map Chat</a>

地図上でチャットが出来るWebアプリ。

##<a href="https://github.com/gilbarbara/logos" target="_blank">gilbarbara/logos</a>

テック系のSVGロゴまとめ（サイト自体はReactでできている）。



##まとめ

* Facebookすごい
* isomorphic綺麗
* ES6こわい
* これ以上ビルドツールいるのだろうか
静的リソースをキャッシュさせない

Lightningから静的リソースファイルを読み込む場合、静的リソースに設定したJS/CSSファイルがサーバでキャッシュされて読み込まれない時がありますが、まあ単純にキャッシュを無効にするように読み込み時の静的リソースにクエリ文字列をくっつけてやるのがよいと思います。理想的には読み込むコンテンツのハッシュ値などですが、デプロイ時のタイムスタンプでもそれほど悪くないでしょう。

タイムスタンプの追加はデプロイ前にビルドプロセスでやりましょう。Gulpならpipe処理で中間ファイル作らずに可能です。

あらかじめコンポーネント定義ファイルにはタイムスタンプが置換される場所に適当な文字列（ここでは`__NOCACHE__`としている）を埋め込んでおきます。

```xml:MyComponent.cmp
<aura:component>
  <ltng:require
    scripts="/resource/MyComponent/scripts/main.js?__NOCACHE__"
    styles="/resource/MyComponent/styles/main.css?__NOCACHE__"
    afterScriptsLoaded="{!c.doInit}" />
  <div class="cmp-root"></div>
</aura:component>
```

あとは`gulp-if`と`gulp-replace`とを組み合わせ、パッケージのzip圧縮前に置換ロジックを挿入します。

```coffeescript:gulpfile.coffee
# 
gulpif = require "gulp-if"
replace = require "gulp-replace"
#

gulp.task "deploy", ->
  ts = Date.now() # Timestamp
  gulp.src "pkg/**/*", base: "."
    .pipe gulpif("**/*.cmp", replace(/__NOCACHE__/g, ts))
    .pipe zip('pkg.zip')
    .pipe forceDeploy
      username: process.env.SF_USERNAME
      password: process.env.SF_PASSWORD
    .pipe notify('Deploy Completed')
```

デプロイ後のファイルは以下のようになるはずです。

```xml:MyComponent.cmp
<aura:component>
  <ltng:require
    scripts="/resource/MyComponent/scripts/main.js?1437045298381"
    styles="/resource/MyComponent/styles/main.css?1437045298381"
    afterScriptsLoaded="{!c.doInit}" />
  <div class="cmp-root"></div>
</aura:component>
```

デプロイのたびにタイムスタンプの数値は書き換わるので、キャッシュされるのを回避できます。
UserDefaultsのラッパーのdeinitでsynchronizeを呼ぶべきではない


UesrDefaultsのラッパーを作って、deinitでsyncronizeを呼んでいた所、データがきちんと反映されない事がありました。

```swift:UserDefaultWrapper.swift
class UserDefaultWrapper {
	private var store: [String: AnyObject]

	deinit {
		userDefaults.setObject(store, forKey: "store")
		userDefaults.synchronize()
	}
}
```
的な感じです。
使うときにはオブジェクトを開放するよう気をつけていて、反映されない時もきちんとdeinitは通っていました。
ところが何故かきちんとsynchronizeされていませんでした。
根本的には原因分かっていないですが、想像ではsynchronizeが完了する前にラッパーオブジェクトが解放されてしまっていたのではないかな？と思っています。

解決方法はこんな感じ。

```swift:UserDefaultWrapper.swift
class UserDefaultWrapper {
	private var store: [String: AnyObject]

	func set(key: String, data: AnyObject) {
		store[key] = data
		userDefaults.setObject(store, forKey: "store")
		userDefaults.synchronize()
	}
}
```
もうこれだったらいったんstoreとかいう謎変数に突っ込まずに直接UserDefaultsに保存したほうが良いですね…。
画面の端点の座標を取得する【Unity, 2D】

Unity2Dで画面端のワールド座標を取得したいことがあったので、メモ。
Z座標はカメラの座標になってしまうので、注意が必要です。

```C#
private Camera _mainCamera;

void Start () {
	// カメラオブジェクトを取得します
	GameObject obj = GameObject.Find ("Main Camera");
	_mainCamera = obj.GetComponent<Camera> ();
	
	// 座標値を出力
	Debug.Log (getScreenTopLeft ().x + ", " + getScreenTopLeft ().y);
	Debug.Log (getScreenBottomRight ().x + ", " + getScreenBottomRight ().y);
}

private Vector3 getScreenTopLeft() {
	// 画面の左上を取得
	Vector3 topLeft = _mainCamera.ScreenToWorldPoint (Vector3.zero);
	// 上下反転させる
	topLeft.Scale(new Vector3(1f, -1f, 1f));
	return topLeft;
}

private Vector3 getScreenBottomRight() {
	// 画面の右下を取得
	Vector3 bottomRight = _mainCamera.ScreenToWorldPoint (new Vector3(Screen.width, Screen.height, 0.0f));
	// 上下反転させる
	bottomRight.Scale(new Vector3(1f, -1f, 1f));
	return bottomRight;
}
```
Adreno Profiler を使ってモバイルアプリを最適化


## Adreno Profiler って？
Qualcomm が提供している Adreno 搭載端末のためのプロファイラ
Android端末でのシェアが高いので有用

[Android端末一覧](https://ja.wikipedia.org/wiki/Android%E7%AB%AF%E6%9C%AB%E4%B8%80%E8%A6%A7)

ここの SoC のところに Snapdragon て書いてたらだいたいそうなんじゃないでしょうか。

## インストール
Win / Mac 対応みたいですが、
僕は Mac は諦めて Windows に入れました。
（古い記事だと Windows のみ対応と書いてあるので、最近 Mac に対応したのかも）

下記にて配布されています。（要アカウント作成）
https://developer.qualcomm.com/download/software

### Mac でのインストール
**追記
再度手順を追って試したら起動までできました。
1. Mono 2.10.5 をいれる http://download.mono-project.com/archive/2.10.5/macos-10-x86/0/
2. xQuartzの最新をいれる http://xquartz.macosforge.org/landing/
基本的にはこの2つ揃えてたら問題なさそう。
Xamarinとの併用も大丈夫そう。**

~~#### 問題1) Mono の古いバージョンが必須
Mono 2.10.5 が求められる。
Xamarin など使ってると最新の Mono が求められるので
複数バージョンの Mono が必要になる
（うまいやりかたあるのかなー）~~

~~#### 問題2) 起動しない
Mono のバージョンを揃えても、
自分の環境だと起動時にエラーが起きてダメでした。
[このへん](http://qiita.com/kramhash/items/30c41a252c24bb0967fa) にもあるけど、自分の場合は別のエラーが出ていて、
心が折れてやめました。~~

### Windows でのインストール
インストーラからインストールすれば特に問題なし

## 端末の接続
adb コマンドにパス通ってる前提で。
AndroidManifest.xml に

```
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.qti.permission.PROFILER" />
```

この2つが必要。
そして、Profiler起動前に、コマンドをうつ。

```
adb.exe shell setprop debug.egl.profiler 1
```

これが、OS起動ごとに必要らしい。

Mac だと

```
adb shell setprop debug.egl.profiler 1
```
こうかな。

## プロファイリング

ここまでの対応で connect が成功するはずなので、
そのあとは、内容見ていくだけです。
（内容多くて何書いてるかわからないとこもたくさん）

今回やってみたのは描画負荷を調べるために

* Scrubber GL 開く
* Metrics の Clocks と Pixel Writers あたりを選択して追加
* 任意の位置で、Capture Frame
* Render Calls がずらーっと出てくるので、Clocks あたりを参考に重い所を割り出し
* Texture もずらーっと出てくるので、無圧縮 Texture や、無駄に大きい Texture が潜んで居ないか確認

みたいな流れでやるとなんとなくつかめました。
このへんは探りたい対象で色々変わりそう。
最初の文字とスペースの後の文字を大文字にするjs

# jsで最初の文字とスペースの後を大文字にしたい人たちへ
## 半角英字の名前入力でチカラを発揮します

というかそれ↑用に作成したものです

```lang:name_camel.js
function strUpper(str) {
	var nameStrArray = str.split(' ');//半角スペースのみ対応。全角もいれるなら\sでもいいかもしれない
	var nameFirst = nameStrArray[0];
	var nameSecond = nameStrArray[1];
	nameFirst = nameFirst.charAt(0).toUpperCase() + nameFirst.substring(1).toLowerCase();
	nameSecond = nameSecond.charAt(0).toUpperCase() + nameSecond.substring(1).toLowerCase();
	return nameFirst + ' ' + nameSecond;
}
var name = "qiita happy";
var nameUp = strUpper(name);
console.log(nameUp)
```

* とりあえず、ファーストネームとファミリーネームだけの対応です
* ミドルネームの対応するのであれば、nameFirstあたりの変数を増やすなどして使えます。　やったね！
SpringBootテスト時に一部のプロパティだけを上書きする

SpringBootのアプリケーションをテストする際には以下のように書きますが、

```java
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringBootConfig.class)
public class HogeServiceTest {
}
```

特定のテストの時だけ、一部プロパティを上書きしたいような場合は次のように書くと便利かもしれません。

```java
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = { SpringBootConfig.class, HogeServiceTest.class })
@Configuration
@PropertySource(value = "classpath:/override.properties")
public class HogeServiceTest {
}
```
override.propertiesには、変更したいプロパティだけを書いておきます。
mapなどの配列の値を操作するメソッドまとめ


Enumerableで定義されている[配列の抽出・検索](http://qiita.com/shibukk/items/7dded3e74b0f7dbfb633)について書いたのですが、Enumerableには配列の値操作についてもいろいろ便利なものがあるので、それらをまとめてみました。

## map / collect

各要素に対して{}ブロック内の **式を実行した結果** を返します。
`collect` は `map` と同義です。

```ruby
# すべて3倍にして返す
[1, 2, 3].map { |n| n * 3 }
# => [3, 6, 9]
```

## reduce / inject

各要素に対して{}ブロック内の式を順次実行し、**最後までのブロックの実行結果** を返します。
ブロックパラメータ（||で囲まれた箇所）の1つ目には前回の実行結果が入り、2つ目のパラメータには次の要素が入ります。
`inject` は `reduce` と同義です。

```ruby
# 配列の合計を求める
[1, 2, 3, 4, 5].inject { |result, item| result + item }
# => 15
# ちなみにブロックパラメータにはこんな感じで値が設定される
# 1回目のループ … |要素1, 要素2|
# 2回目のループ … |前回の結果, 要素3|
# 3回目のループ … |前回の結果, 要素4|
# 4回目のループ … |前回の結果, 要素5|

# 最大値を求める
[1, 2, 3, 4, 5].inject { |max, item| item > max ? item : max }
# => 5
```

初期値はこう書くと設定できます。

```ruby
# 初期値を10として、配列の合計を求める
[1, 2, 3, 4, 5].inject(10) { |result, item| result + item }
# => 25
```

## group_by

{}ブロック内の式の **結果をキー、対応する要素の配列を値** とするハッシュを返します。

```ruby
#奇数と偶数でグループ分けする
[1, 2, 3, 4, 5, 6].group_by { |i| i % 2 }
# => {1 => [1, 3, 5], 0 => [2, 4, 6]}
```

なので、結果がboolになる式の場合はキーがtrue/falseになります。

## chunk

{}ブロック内の **式の結果ごとに要素をまとめた** 配列を返します。
戻り値はEnumeratorオブジェクトなので、eachなどを使うことで中身を取得できます。

```ruby
[3, 1, 4, 1, 5, 9, 2, 6].chunk { |n| n % 2 == 0 ? :even : :odd }.each { |key, value| p [key, value]}
# => [:odd, [3, 1]]
#    [:even, [4]]
#    [:odd, [1, 5, 9]]
#    [:even, [2, 6]]
```

注意が必要なのは、式の結果が変わったタイミングで要素のグルーピングが切り替わるという点です。

また、{}ブロック内でnilを返すと、その要素は含まれなくなります。

```ruby
[3, 1, 4, 1, 5, 9, 2, 6].chunk { |n| n % 2 == 0 ? :even : nil }.each { |key, value| p [key, value]}
# => [:even, [4]]
#    [:even, [2, 6]]
```

## sort_by

{}ブロック内の式の結果を **<=> 演算子で比較し、昇順にソート** します。

```ruby
# 文字を昇順にソートする
p ["foo", "bar", "Baz", "Qux"].sort_by { |v| v.downcase }
# => ["bar", "Baz", "foo", "Qux"]

# こうすれば数字を降順にソートできる
p [1, 5, 7, 2, 4, 9].sort_by { |v| v * -1 }
# => [9, 7, 5, 4, 2, 1]
```

## まとめ
[Enumerable#lazy](http://magazine.rubyist.net/?0041-200Special-lazy)など、ここでは書ききれないメソッドはまだまだあったりします。
なので[ドキュメント](http://docs.ruby-lang.org/ja/2.2.0/class/Enumerable.html)をみることをおすすめします！

Rubyってクラス探訪するだけで面白いですね。
Docker基本

## 概要

Dockerの基本を勉強しながら、実際にAWSのEC2に入れてみた。
その作業記録を以下に記載します。


## インストール

```
$ sudo yum -y install docker-io
```

## 起動

```
$ sudo service docker start
```

## 元となるイメージを取得

※Dockerの提供元が各Linuxのディストリビューションイメージを提供してくれている

以下のDocker Hubでイメージを検索できる
https://registry.hub.docker.com/

```
$ sudo docker pull centos
```

## 保存済みのイメージ一覧

```
$ sudo docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              latest              7322fbe74aa5        3 weeks ago         172.2 MB
```

## コンテナ起動

```
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
```

```
$ sudo docker run -it centos
```

```
-d：バックグラウンドで実行する。
-i：コンテナの標準入力を開く。/bin/bashなどでコンテナを操作する際に指定。
-t：tty（端末デバイス）を確保する。/bin/bashなどでコンテナを操作する際に指定。
-p [ホストのポート番号]:[コンテナのポート番号]：ホストとコンテナのポートマッピング。
-v [ホストのディレクトリ]:[コンテナのディレクトリ]：ホストとコンテナのディレクトリ共有。
```

コンテナ内で、サーバー立ち上げる際、
以下のようにポートマッピングが必要。

```
$ sudo docker run -it -p 9999:80 centos
```

## コンテナの状態確認

コンテナが停止または中断したものが一覧で確認できる

Exited：停止
Up：中断

```
$ sudo docker ps -a

CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS                      PORTS                    NAMES
3f86b314da11        centos:latest          "/bin/bash"         51 seconds ago      Exited (0) 37 seconds ago                            mad_goodall
64b2018621bb        centos/apache:latest   "/bin/bash"         24 minutes ago      Up 24 minutes               0.0.0.0:9999->9999/tcp   gloomy_wozniak
200a539beb8b        centos/apache:latest   "/bin/bash"         25 minutes ago      Exited (0) 25 minutes ago                            drunk_babbage
```

停止したコンテナに関しては、再接続できないので、またアクセスしたい場合は
コンテナのイメージ保存をする必要がある。

そうでない場合は不要なので削除しておく。

## イメージ保存

```
$ sudo docker commit [CONTAINER ID] [REPOSITORY]
```

保存完了の確認は、前述の `docker images` でやる。

## イメージ削除

```
$ sudo docker rmi [IMAGE ID]
```

## コンテナ削除

```
$ sudo docker rm [CONTAINER ID]
```

## コンテナの停止、中断

停止の場合

※コンテナ内の端末で

```
$ exit
```

中断の場合

※コンテナ内の端末で

```
$ (Ctrl + p)(Ctrl + q)
```

## コンテナへの再接続

※再接続は中断されたもののみ

```
$ sudo docker attach [CONTAINER ID]
```

## 参考

https://docs.docker.com/
http://qiita.com/zwirky/items/991f61a231f4e198a320
http://d.hatena.ne.jp/kt_hiro/20140809/1407545821
http://docker.yuichi.com/quickstart/tryit/index.html
http://qiita.com/iron-breaker/items/6b74fe9b0620b74d4281