OmniAICreator/Qiita-1.07M huggingface dataset:
MongoDB環境構成時のポイント


- 何は無くとも公式資料をよく読み込む事、特にOperationChecklist。v3.0以降の情報は書籍でも追いついていない所があります。今回のまとめはほぼ以下の抜粋と補足です。
- シャーディングは経験がほぼ無いのでもっと知見を増やしていきたい、、、
  - https://docs.mongodb.com/manual/contents/
  - https://docs.mongodb.com/manual/administration/production-checklist-operations/


#### 用途
- MongoDBのみを稼働させ、他用途に使わない。

#### アーキテクチャ
- **64bitOS必須**
  - 32bitOSだと使用可能なメモリ容量が実質1.5G程度しかない
- リトルエンディアンのマシンにする。
  - ビッグエンディアンのMAC、SPARK、PowerPC等のアーキテクチャは避ける。

#### CPU
- CPUバウンドの負荷はほとんど無いので、あまり考慮は不要。
- 但し、オンメモリ稼動(インデックス＋ワーキングセット＞RAMの状態)でも高負荷であればCPUバウンドの場合も有り、スケールアップを後から検討する。

#### メモリ
- **MongoDBパフォーマンスの一番の肝**
- **オンメモリ稼動(インデックス＋ワーキングセット＞RAMの状態)になるように出来るだけ多く積む。**
- オンメモリ稼働できない場合はページフォルトとしてディスク側へのデータ読み込みを行う。当然速度は低下するので極力避ける。

#### ディスク
- **SSD推奨**
- **xfs推奨(ext4だとパフォーマンス上の懸念有)**
- RAID10推奨
- dbPathにNFSを使用しない

#### ジャーナル
- **基本的に有効にする。メモリ書込み～ディスク書込みまでに予期せぬ停止が起きた場合の障害を最小限に抑えられる。**

#### ストレージエンジン
- **V3デフォルトのWiredTigerを使う。（MongoV3～）**  
http://qiita.com/fetaro/items/050a20f695652c6acc94  
http://qiita.com/fetaro/items/cd570d70623b58b5deef#_reference-820e25a3d04877ff37e7
  - 従来のエンジン「MMAP」と比べて以下のメリットがある。
    - **ロックがのDB単位からドキュメント(レコード)単位に変わり、ロック待ちが減った。**
    - **メモリ使用量の制限が可能になった(cacheSizeGB)**
      - 従来はシステムメモリを青天井で使い切ってしまう
    - データ圧縮（CollectionBlockCompressor）、インデックス圧縮（PrefixCompression）が出来るようになった。
    - データのフラグメンテーションが発生しない。  
データ挿入時にフラグ部分のコンパクションが行われる。
    - インデックス、データそれぞれ保管場所を指定可能。
    - ジャーナルの仕様が変更された（従来と異なり、ジャーナル無効でドキュメント更新中にMongoがクラッシュしてもレコードが壊れることはない。古いデータを残して新しいデータを追記するから。）
  - **(必須)CachSizeGBは搭載メモリ容量の5割程度におさえる。**

#### OS
- **THP(Transparent Huge Page)をオフにする**
  - Linuxでメモリ効率化のための仕組みだが、Mongoと相性が悪いので起動時にオフにするオプションを指定する。
  - https://docs.mongodb.com/v3.0/tutorial/transparent-huge-pages/
- NUMAアーキテクチャをオフにする
  - パフォーマンス低下につながる可能性有り
  - http://rdma.hatenablog.com/entry/2014/05/26/010641
- TCP keepaliveを調整
  - https://docs.mongodb.com/v3.0/faq/diagnostics/#faq-keepalive

#### レプリケーション
- **最低3台で構成されるレプリカセットを1セット以上構成する**
  - 2台以下だと自動フェールオーバ出来ない。  
    - 自動フェールオーバ時のプライマリ再選出の基準になる「過半数以上の投票」という条件を満たせない。
- レプリカセット内のメンバーは同一のntpサーバを使い時刻同期をさせる
- レプリカセットメンバー内で3つ以上の奇数投票権がある事を確認する。
- **更新記録用のoplogsizeは必ず大きめのサイズに変更する。**
  - **MySQLで言うバイナリログのようなもの。大きな違いとして保管サイズが決まっており超過分は古いデータから押し出しで自動削除されるので要注意。**
  - **扱うデータ量によっては、「デフォルトのoplogSizeだとロールフォワード可能な期間が極端に短かった。短期間止めただけなのにロールフォワードNGで結局対象サーバ全復旧するしかねえ！」なんてことになりかねない。**
  - まずは5%を目安とし、最終バックアップからの更新をカバーできるように設計を行うと良いかも。
- レプリケーションメンバーのストレージサーバはスペックを統一させる。
- レプリカセットのメンバー登録はホスト名ベースで行う。hosts登録済である事も要確認

#### シャーディング
- 水平スケーリング（シャーディングしているか）
  - インデックスサイズ＋ワーキングセットサイズ ＞ RAMサイズを大きく超えていないか
  - 書込み負荷が高くないか

#### インデックス
- インデックスはあるか、適切か
  - -->getIndexes()でインデックス一覧確認、explain()で実行時間、対象数、検索キー数、検索ドキュメント数、適用インデックス名は要確認。
  - 作りすぎても更新負荷やサイズ増につながるのでインデックスの乱用は避ける。
- インデックスサイズ＋ワーキングセットサイズ ＞ RAMサイズとなっていないか、
なっている場合はディスクパフォーマンスが悪くなっていないか（iostat)
  - -->db.statsで確認。インデックスサイズ（indexSize)＋データサイズ(dataSize）を確認。またディスク側への影響をiostatで確認。どちらも単位はbyte。
- データのコンパクト化は出来ているか
  - -->db.statsで確認。storageSize >>>> dataSizeとなっていればコンパクションを検討する。どちらも単位はbyte。
storageSize、dataSizeの仕組みは以下参照  
http://blog.mlab.com/2014/01/how-big-is-your-mongodb/
Assignment Problem

## Assignment Problem
https://en.wikipedia.org/wiki/Hungarian_algorithm

### Excel Solver
http://www.excel-easy.com/examples/assignment-problem.html


### Example

http://www.aaai.org/ocs/index.php/IAAI/IAAI15/paper/view/9899/9887


http://csclab.murraystate.edu/~bob.pilgrim/445/munkres.html

https://www.topcoder.com/community/data-science/data-science-tutorials/assignment-problem-and-hungarian-algorithm/



http://www.math.harvard.edu/archive/20_spring_05/handouts/assignment_overheads.pdf
Ubuntu 16.10でNimを公式サイトのソースからインストールする

チラシの裏的な記事「[Ubuntu 16.10でNimをaptで入れた際のハマりどころ - Qiita](http://qiita.com/manzyun/items/15f524a50ebaf8f75e9d)」の続きっぽくなってしまうが、読んでいただけると幸いである。

結論から言ってしまうと、公式ページからソースをダウンロードし、ビルドしてインストールしたほうが早かったかもしれない。以下はほとんど[download - Nim Programming Language](https://nim-lang.org/download.html)に書いていることそのままなので、分かりそうな人は公式を参照したほうがよろしいかと。

# Nim単体インストール方法

## コマンドで要約

```shell-session
$ wget https://nim-lang.org/download/nim-0.16.0.tar.xz
$ tar -Jxvf nim-0.16.0.tar.xz
$ cd nim-0.16.0
$ sh build.sh
$ sudo sh install.sh /usr/local/lib #ここの引数は/usr/binでも良いし、/optでもいい。詳しくは引数無しでinstall.shを起動。
$ nim --version
```
## コマンド解説
1. 公式ページのtar.xzファイルをwgetでダウンロード
2. tarで展開。tar.xzなのて、普段はあまり見慣れない引数だが、問題ない。
3. 展開したnimのディレクトリに入る
4. build.shを実行
5. システム領域にファイルをコピーするので、管理者権限をつけてinstall.shを実行。
6. インストール確認兼バージョン確認。Nimのバージョンなどが出れば成功。

# Nim用パッケージ管理システムNimbleのインストール

## コマンドで要約
```shell-session
$ cd /path/to/your/directory/nim-0.16.0 #Nimのソースコードを展開したディレクトリへ移動
$ nim c koch.nim && ./koch
$ ./koch tools
$ nimble --version
```
## コマンド解説
1. もしも他ディレクトリに移動していれば、もう一度展開したnimのディレクトリへ移動。
2. koch.nimをビルドし、./kochを実行
3. nimの本体以外の便利ツール（stdlibやcompilerが多い）をインストール。
4. nimbleのインストール確認兼バージョン確認。

------------------------

今回コンパイルしたkock実行ファイルだが、ヘルプを見る限りだとタイトルに「Maintenance program for Nim」と書いてあるので、捨てないでアクセスしやすいところに置くのが吉かもしれない。（自分はとりあえず/usr/local/bin下に置いた）

# Apodia IDEもインストール……と試みたが

nimbleでApodia IDEをインストールしたまでは良かったが、自分の手腕では依存しているパッケージを探しだしてインストールすることができないので（GTK周りなのはわかるのだが）、[Atom](https://atom.io/)に[nim](https://atom.io/packages/nim)パッケージをインストールしてコーディングすることにした。

あなたはもしかしたらVim使いかもしれないので、[zah/nim.vim: Nim language plugin for vim](https://github.com/zah/nim.vim)も紹介しておく。Emacsは……分からん。

以上、あなたが何らかのきっかけでNimに興味を持ったUbuntuユーザーで、参考になったら幸いである。
ViewPagerの内のFragmentが挙動不審？

# ViewPagerの内のFragmentが挙動不審？

ViewPagerの内のFragment の Lifecycle イベントの呼ばれ方がおかしいようだ…なんだかいろいろおかしいようだ…。そんなときに思い出してください。私は思い出せずに１日悩みました。

## たとえばViewPagerがネストしているとき

ViewPagerがネストしているときなどで、Fragmentを親としてViewPagerを作る場合に注意が必要です。

FragmentPagerAdapterのコンストラクタに引数として渡すFragmentManagerは **getChildFragmentManager()**で取得しなければいけません。**Child**です。

getFragmentManager()で取得したものを渡してしまうといつか不審な挙動が現れます。

## android.support.v4.app.Fragment 

なお、API16 (Android 4.1) 以下をターゲットに含めて開発している場合には、[android.app.Fragment](https://developer.android.com/reference/android/app/Fragment.html) の [getChildFragmentManager()](https://developer.android.com/reference/android/app/Fragment.html#getChildFragmentManager()) がAPI17以上にしか対応していませんので、v4サポートライブラリの[android.support.v4.app.Fragment](https://developer.android.com/reference/android/support/v4/app/Fragment.html)を使う必要があります。

同時に、FragmentPagerAdapterもv4サポートライブラリの[android.support.v4.app.FragmentPagerAdapter](https://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html)を使用する必要があります。

API17以上がターゲットならば[android.support.v13.app.FragmentPagerAdapter](https://developer.android.com/reference/android/support/v13/app/FragmentPagerAdapter.html)とandroid.app.Fragmentで良いでしょう。

## 備考

[FragmentStatePagerAdapter](https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html)を使用する場合にも同様の注意が必要でしょう。
技術英語 > slices [can step by values other than one] / and [goes right by 2]

@ Introducing Python: Modern Computing in Simple Packages by Bill Lubanovic
(No. 1211 / 12833)

> As with strings, slices **<font color=red>can step by values other than one</font>**. The next example starts at the beginning and **<font color=red>goes right by 2</font>**:

```py
>>> marxes[::2]
['Groucho', 'Harpo']
```
renameコマンドで拡張子を一括変換

コマンドラインで拡張子を一括変換しようとすると`for`を使う方法が一般的なようなのですが、めんどくさいので私はそんな物を書きたくありません。

### rename コマンド

あまり有名ではないようですが`rename`コマンドと言うものがあります。Macであれば`brew install rename`でインストールして、拡張子の一括変換を行いたいディレクトリで

```.sh
rename 's/.jpeg/.jpg/' *.jpeg
```

とすれば一括変換されます。

### 欠点

ディストリによって`rename`コマンドは全く別のものが用意されていて、上記コマンドが使えない方の環境では

```.sh
rename .jpeg .jpg *.jpeg
```

とする必要があるようです。

もっと`rename`コマンドが有名になって、どちらかが標準になってくれることを祈りながこの記事を書きました。みなさんどんどん広めていきましょう！
Hugo で JSON-LD 内の URL がなぜかエスケープされる問題

久々にブログの Hugo テンプレートをいじって JSON-LD に対応させようとして、ハマりました。バージョンは Hugo-0.18.1-windows_amd64 です。

エスケープ問題
----
`url` 属性に `.Permalink` を当てはめようとすると、普通に書けば以下のようになると思います。

```html:partials/json-ld.html
<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "Corporation",
  "url": "{{ .Permalink }}",
  "contactPoint": [{
    "@type": "ContactPoint",
    "telephone": "+1-401-555-1212",
    "contactType": "customer service"
  }]
}
</script>
```

しかし、そのレンダリング結果には余計なURLエスケープが入ってしまいます。

```html
<script type="application/ld+json">
{
  ...
  "url": "http:\/\/localhost:1313\/about\/",
</script>
```

いろいろググると、「`{{ .Permalink | safeJS }}` を使え」とか「`{{ printf "%s" .Permalink }}` ならうまくいく」とか書かれていましたが、どれも結果は同じでした。


解法
----
最終的にたどり着いた解法は、**「`{{ .Permalink}}` を `"` で囲わない」** でした。

```html:partials/json-ld.html
<script type="application/ld+json">
{
  ...
  "url": {{ .Permalink }},
  ...
}
</script>
```

これで期待通りプレーンな URL が生成されます。

```html
<script type="application/ld+json">
{
  ...
  "url": "http://localhost:1313/about/",
  ...
}
</script>
```

JSON レンダリング時に何か余計な気を使ってくれているっぽいですね。小一時間ムダにしました :disappointed:


参考になった記事
----
- [HUGOで作れるCMSっぽいパーツ:関連記事・目次・JSON-LDなど - Qiita](http://qiita.com/y_hokkey/items/f9d8b66b3770a82d4c1c)
go getでgopkg.inのパッケージが取得できないときgit configに追加すること

確認したGitのバージョンは `2.11.1` です。
環境をいじっていたら `go get` でgopkg.inのパッケージが取得できないエラーが出るようになってしまいました。

```
$ git --version
git version 2.11.1

$ go get gopkg.in/yaml.v2
# cd .; git clone https://gopkg.in/yaml.v2 /Users/jiska/go/src/gopkg.in/yaml.v2
Cloning into '/Users/jiska/go/src/gopkg.in/yaml.v2'...
error: RPC failed; HTTP 301 curl 22 The requested URL returned error: 301
fatal: The remote end hung up unexpectedly
package gopkg.in/yaml.v2: exit status 128
```

[gopkg.inのissue#50](https://github.com/niemeyer/gopkg/issues/50#issuecomment-273299592) にて同様事象のやりとりがされており、git configに設定追加でエラー解消できることがコメントされています。

`$ git config --global http.https://gopkg.in.followRedirects true`

これでgo getができるようになりました。感謝。
Mac 上の opensource COBOL で Hello World!!

[OSSコンソーシアム](https://www.osscons.jp/)の[オープンCOBOLソリューション部会](https://www.osscons.jp/osscobol/)が提供する opensource COBOL をMacにインストールして、「Hello World!!」を出力するCOBOLプログラムをコンパイル・動作させます。

# opensource COBOL のインストール

opensource COBOL の[ダウンロードサイト](https://www.osscons.jp/osscobol/download/?_restful_permalink=osscobol/download/)からUTF-8のソースパッケージ(2017年2月8日時点では[opensource-cobol-1.5.1J-utf8.tar.gz](https://www.osscons.jp/osscobol/files/?action=cabinet_action_main_download&block_id=414&room_id=21&cabinet_id=11&file_id=382&upload_id=761))をダウンロードします。

また、opensource COBOL に必要な[GMP](https://gmplib.org/)のソースパッケージ(2017年2月8日時点では[gmp-6.1.2.tar.lz](https://gmplib.org/download/gmp/gmp-6.1.2.tar.lz))もダウンロードします。

インストールはGMPから始めますが、その前にGMPのlzip圧縮されたソースパッケージを展開するためのツールをbrew経由でインストールします。

```bash
$ brew install plzip
```

GMPのソースパッケージを展開し、コンパイル、インストールします。

```bash
$ plzip -d gmp-6.1.2.tar.lz
$ tar xf gmp-6.1.2.tar
$ cd gmp-6.1.2
$ ./configure
$ make
$ sudo make install
```

次に opensource COBOL に必要な Berkeley DB をbrew経由でインストールします。

```bash
$ brew install berkeley-db
```

最後に opensource COBOL をコンパイル、インストールします。

```bash
$ cd ..
$ tar zxf opensource-cobol-1.5.1J-utf8.tar.gz
$ cd opensource-cobol-1.5.1J-utf8
$ ./configure
$ make
$ sudo make install
```

# COBOLプログラムの作成と実行

ソースファイル hello.cob に以下のとおりコーディングします。コードの各行は8桁目から始まっていることに注意してください。

```cobol
        IDENTIFICATION DIVISION.
        PROGRAM-ID. HELLOWORLD.
        PROCEDURE DIVISION.
        DISPLAY "Hello World!!".
        STOP RUN.
```

コンパイルして実行します。

```bash
$ cobc -x hello.cob
$ ./hello
Hello World!!
```
Virtualbox Host-Only Ethernet Adapter の作成

## Description

vagrant × Virtualbox on Windows10で使っていると、win10のOS更新が入ったあとにvagrantが起動できなくなることがよくある。最近結構その状態に陥るのだが、毎回毎回うろたえているので、エラーになるたびに直し方をメモしていこうと思う。

## Status

### VBoxManage.exe: error: Details: code E_FAIL (0x80004005), component ConsoleWrap, interface IConsole

`vagrant up` すると、このようなエラーが出る。

![err.PNG](https://qiita-image-store.s3.amazonaws.com/0/129740/28f8ca1d-2211-1950-fe11-742a83f12d57.png)


### VirtualBox Host-Only Adapter が無い
ネットで調べると、すぐに「VirtualBoxのHost-Only Adapterが無効化したから」という情報が手に入る。しかし、コントロールパネルからネットワークとインターネット/ネットワーク接続をたどってみたところで、そんなアダプターは表示されていない。
![nothing.PNG](https://qiita-image-store.s3.amazonaws.com/0/129740/7f56ea83-4629-8561-4768-112e0ff4197a.png)
原因はアダプターが無効になっているからではなく、アダプターそのものが無くなってしまうからである。セキュリティプログラムにでも引っかかるのだろうか？理由はよくわからない。


## Solution

### VirtualBox Host-Only Adapterを作成する

以下の手順で、VirtualBoxの操作画面からアダプターを作成できる。

1. [ファイル]->[環境設定]
![step1.PNG](https://qiita-image-store.s3.amazonaws.com/0/129740/c96347e9-a081-d70a-425c-dae60fd56290.png)
<br/>

1. [ネットワーク]->[ホストオンリーネットワーク]
![step2.PNG](https://qiita-image-store.s3.amazonaws.com/0/129740/11f182e5-1790-3cd9-1f45-4a95e32af9af.png)
<br/>

1. ＋のマークをクリックし、アダプターを作成
![final.PNG](https://qiita-image-store.s3.amazonaws.com/0/129740/7b329307-4c52-2afd-09d7-156598eb15d1.png)


### vagrantを再起動する

`vagrant reload`


## change log

更新記録

1. 2月8日：投稿
1. 2月9日：Fixed typo
pip installで「'ascii' codec can't decode」の回避

VPS上のubuntu 14.04 LTSにPython環境を整備中に、あるモジュールのpip installでハマったのでメモ。

こんなエラーが出現。

```
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 472: ordinal not in range(128)
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-lb6kda75/
```

色々試した結果、

```
sudo apt-get install language-pack-ja
```
で事なきを得た。基本的な事だけど意外と忘れる。
Dotsのイベントカレンダーで絞込ではなくて、除外指定したい場合

勉強会、イベントを探すとき、[dotsのイベントカレンダー](https://eventdots.jp/calendar)をよく使んだけれど、絞り込んで探すんじゃなくて、特定のキーワード以外で探したいときが時々ある。
例：最近、人工知能とか機械学習とか流行ってるみたいだけど、自分には難しいので行かなくていいやとか。女子会、学生限定とか除外したいとか。

そんな機能はないので、強引に、テキストボックスと、ボタンをJavascriptで埋め込んで、
テキストボックスに除外キーワードを入れて、削除ボタンを押すと、除外キーワードを含むイベントが消えるようにした。

下記のJavascriptを[dotsのイベントカレンダー](https://eventdots.jp/calendar)上で、ブラウザの[コンソール](https://developer.mozilla.org/ja/docs/Tools/Browser_Console)に打ち込む、または[ブックマークレット](http://www.lifehacker.jp/2013/04/130402bookmarklet_matome.html)で実行。

```

function xx(){$(".events li:contains('"+ $("#o").val()+"')").remove()} $('[name=event]').append('<br><input type="text" id="o" ><button class="pageheader-search-btn" type="button" onclick="xx()" >削除</button>');


```
 
やってることは、画面上部のformエリアにテキストボックスと、削除ボタンをJQueryで埋め込んで、


```
$('[name=event]').append('＜input 〜　> <button 〜 >削除</button>')

```


下記のJQueryの指定で、除外キーワードを含む行を削除しているだけ。


```
$(".events li:contains('除外キーワード')").remove()

```
備忘録: Node.js の aws-sdk での callback と Promise の違い

時間も遅いのでとりあえずは前提と備忘録だけ

## 前提
- Node.js の aws-sdk を使って簡易的なツールを作ろうとしている最中
- 今、いじろうとしているのは S3
- Node のバージョンは `v6.9.2`

## `promise()` を使うと Promise もサポートされる
aws-sdk は Promise とかができる前から作られていたらしく、基本的に [callback を前提とした作り](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#createBucket-property)になっている。
けども昨今の Promise による、管理しやすい実装も[ちゃんとサポートされていて](https://aws.amazon.com/blogs/developer/support-for-promises-in-the-sdk/)、`promise()` という関数を噛ませる事で、Promise を返すようになる

## けど、コードの違いに注意

```js
// Callback による実装
s3.createBucket({Bucket: 'mybucket'}, (err, data) => {
  if (err) {
    return console.log("Error", err);
  }
  return console.log(data);
});

// Promise
s3.createBucket({Bucket: 'mybucket'}).promise().then(data => {
  return console.log(data);
}).catch(err => {
  return console.log("Error", err);
});
```

ご覧の通り、エラーは `catch` によって検知できるので、`then` へ渡される値は1つになるのです。（というか2つの値を return できないから必然的に 1 つになるしかないんだけどさ）

最初、then の中でも `(err, data) => {}` と書いていたから、エラー吐いてるけど S3 は作られているという謎状況に陥って少しハマってました←

以上、そんな感じで。
コードを修正することなく、安心してsendmailコマンドを叩くメール送信テストをする方法（Ubuntu）

# はじめに

サテ皆さん、sendmailしてますか？
最近、とあるメール送信処理を修正をすることになったのですが、困ったことにその実装が

**sendmailコマンドを直接叩く**

というものでした。

これをローカル側でテストするときに一番やっかいです。というのも、sendmailは同時にデーモンが動いていて、こっちが「やるなよ！やるなよ！」と思っていても、賢いsendmail様はメールをちゃんと相手に届けてくれます（設定によってはアレだが）。

**ローカルでテストしてるときはメールを外に出したくない**

じゃないですか！

**デプロイする時の心配を一つでも省きたい**

じゃないですか！　ポート番号の書き換えを忘れて、会社の上長やテスト担当、客先の人々に怒られたくないですよね！　だからこそ

**コードを変えることなくテスト環境を整える**

のです。

というわけで、なんとかしてsendmailを使って外に出ないメールを出したいという悪戦苦闘の結果を共有したいと思います。

# 前提

今回おこなうのに必要な前提は以下のとおりです。少し違う環境の時は、逐次脳内変換しておいてくださいませ（全部が全部サポートできません故…）。

* 使ってるOSはUbuntu14.04だぜ！
* sendmailは普通に入ってるぜ！
 * sendmailコマンドを叩けば普通にメールが送れるぜ！
 * postfix?知らない子ですね（できればMTAとかはsendmailのみにしておきます)
* rubyも入ってるぜ！
 * 当方はrbenvで2.4.0入れた状態で解説してるぜ！
 * Pythonでもええけどそのときは逐次置き換えてね！
* sudo -s でrootになれるぜ！

# やり方

では、早速、実行方法を伝授いたします。順を追って解説していきます。

## mailcatcherを導入

ではまず、送られたメールをキャッチして外に出さないRubyのgemを導入します。

[Mailcatcherのサイト](https://mailcatcher.me/)

```
$ gem install mailcacther --no-ri --no-rdoc
```

インストールが終われば、mailcatcherコマンドを起動確認します。そのまま起動すると、デーモンとして立ち上がるので、-fオプションで楽に動作適しできるようにしておきましょう。

```
$ mailcacther -f

Starting MailCatcher
==> smtp://127.0.0.1:1025
/home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/thin-1.5.1/lib/thin/server.rb:104: warning: constant ::Fixnum is deprecated
==> http://127.0.0.1:1080
```

2.4.0で動かしているのでFixnum使うなヨーというメッセージが出ていますが、無視しましょう。
動いたのを確認したら、Ctrl-Cで停止します。

## Sendmailのデーモンを停止

先のmailcactherには、標準では1025がSMTPポートになりますが、オプションでポート番号を変えられるので、そのままオプション指定で起動…と思ったらそうは問屋が卸さない。すでにsendmailのデーモンが25番ポートを専有しています。

なので、このデーモンを切っちゃいましょう。ubuntuの場合、rootになってsystemctlコマンドを使います。

```
# systemctl stop sendmail
```

…え、sendmailコマンドはデーモン見てるんじゃないかって？　それは無いと思います。実際この状態でコマンドを叩いても影響はありませんでした。特に、sendmailのバックにpostfixが動いている場合もありますしね…ていうか、これで動かかなかったら記事にできません…

しばらくテストをするつもりでしたら、無効化するのも手です。デーモン停止後に以下のコマンドを実行します。

```
# systemctl disable sendmail
```

これで、mailcatcherを起動する準備ができました。

[参考にしたサイト](https://www.server-world.info/query?os=Ubuntu_16.04&p=initial_conf&f=4)

## Mailcatcherを起動する

では、25番ポートを指定して、mailcatcherを起動します。25番ポートはroot権限がないと開けないので、sudoでルートになっておいてから起動します

```
# sudo -s
# mailcatcher --smtp-port 25

Starting MailCatcher
==> smtp://127.0.0.1:25
/home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/thin-1.5.1/lib/thin/server.rb:104: warning: constant ::Fixnum is deprecated
==> http://127.0.0.1:1080
*** MailCatcher runs as a daemon by default. Go to the web interface to quit.
```

さあ、これでメールを送れる状態になりました。

## ブラウザを開く

お好みのブラウザを開いて、URLを指定します。

```
http://127.0.0.1:1080
```

これは、メーラーが送ってきたメールが表示され、テスト結果の確認に大いに役立ちます。

## 実際にメールを送る

あとは、メールを送って、ちゃんと結果が出るか見てみます。

```
$ echo Meaow3! | sendmail hoge@fuga.com
```

ブラウザに、hoge@fuga.comに送ったメールが表示されれば成功です！　お疲れ様でした！

# まとめと謝辞

テストする時は、デプロイする際の影響を最低限にしたいもので、だからこそ、人は試行錯誤するもんだと感慨にふけっております。もちろん、たくさんのテストのうちの氷山の一角ですが、これがデプロイミス減少に役立てられたら非常に嬉しく思います。

この問題で色々アドバイスを頂いた、shinosaka.rbの皆さんに感謝！

それではHappy Hacking!
DB2DBA: DB2 11.1新機能 - 正規表現

2016年6月にリリースされた11.1より、ようやくDB2でもSQL内で正規表現が使えるようになりましたた。

# 概要
正規表現の実装は各RDBMSでまちまちですが、DB2ではOracleと互換性のある以下の組み込み関数が提供されます（一部はDB2独自）。

| 関数名          | 機能                                                           |
|:--------------|:--------------------------------------------------------------|
|REGEXP_LIKE    |ストリング内に正規表現パターンがあるかどうかを示すブール値を戻します。|
|REGEXP_COUNT   |ストリング内で正規表現パターンが一致した回数のカウントを戻します。|
|REGEXP_MATCHCOUNT|REGEXP_COUNTと同様|
|REGEXP_SUBSTR  |正規表現パターンに一致したストリング内のサブストリングの出現箇所を 1 つ戻します。|
|REGEXP_EXTRACT |REGEXP_SUBSTRと同様|
|REGEXP_INSTR   |return_option 引数の値に応じて、一致したサブストリングの開始位置または終了位置を戻します。|
|REGEXP_REPLACE |ソース・ストリング内の正規表現パターンの出現箇所を、指定された置換ストリングに置き換えた変更バージョンのソース・ストリングを戻します。|


# 使用例
```
SELECT * FROM table WHERE REGEXP_LIKE(column, pattern)
```

上記のように検索条件に使用できるのはもちろんですが、チェック制約を柔軟に記述できるようになる点でも有用と思われます。以下は正規表現でIPアドレスとしてクラスBプライベートアドレスのみを受け付けるチェック制約を定義してみた例です。

```
db2 => create table servers(hostname char(8) not null primary key, ip varchar(15) not null)
DB20000I  SQL コマンドが正常に完了しました。
db2 => alter table servers add constraint priv_class_b check (regexp_like(ip, '^172\.(?:1[6-9]|2[0-9]|3[0-1])(?:\.(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)){2}$'))
DB20000I  SQL コマンドが正常に完了しました。
```

```
db2 => insert into servers values ('host0001', '172.16.0.1')
DB20000I  SQL コマンドが正常に完了しました。
db2 => insert into servers values ('host0002', '172.16.0.256')
DB21034E  コマンドが、有効なコマンド行プロセッサー・コマンドでないため、 SQL
ステートメントとして処理されました。  SQL 処理中に、次のエラーが返されました。
SQL0545N  行がチェック制約 "SVC34.SERVERS.PRIV_CLASS_B"
を満たしていないために、要求された処理は実行されません。  SQLSTATE=23513
db2 => insert into servers values ('host0003', '172.32.0.1')
DB21034E  コマンドが、有効なコマンド行プロセッサー・コマンドでないため、 SQL
ステートメントとして処理されました。  SQL 処理中に、次のエラーが返されました。
SQL0545N  行がチェック制約 "SVC34.SERVERS.PRIV_CLASS_B"
を満たしていないために、要求された処理は実行されません。  SQLSTATE=23513
```

# 11.1以前の場合
DB2 11.1以前でどうしても正規表現を使いたい場合は、[developerWorksで正規表現のユーザー定義関数が公開されているので](https://www.ibm.com/developerworks/jp/data/library/db2/j_d-regularexpression/)これを用いるとよいかもしれません。UTF-8環境を前提としているようです。

# 参考資料
- IBM Knowledge Center
    - DB2 for Linux UNIX and Windows 11.1.0
        - [SQL の互換性の機能拡張](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.db2.luw.wn.doc/doc/c0054107.html)
        - [正規表現の制御文字](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.db2.luw.sql.ref.doc/doc/r0061533.html)

- IBM developerWorks日本語版
    - [UDFとXQueryでSQLに正規表現パワーを！](https://www.ibm.com/developerworks/jp/data/library/db2/j_d-regularexpression/)
Ubuntu 16.10でNimをaptで入れた際のハマりどころ

有り難いことに、Ubuntuでは（2017-02-08現在）最新のNimのパッケージ（Nim compiler Version 0.16.1 (2017-02-07)）が配布されている。

しかし、ホイホイ以下のようなコマンドでインストールして[Nim Tutorial (Part I)](https://nim-lang.org/docs/tut1.html)をやると、しょっぱなからちょっと躓いたのでQiitaに書き留めておく。

```shell-session
$ sudo apt install nim
```

# 1.コンパイルしようとすると「cannot open '/usr/local/lib/nim/system.nim」と怒られる

ということで、非常に短絡的な解決方法だが、[download - Nim Programming Language](https://nim-lang.org/download.html)からソースコードをダウンロードし、その中に入っているlibディレクトリを、まるっと該当のディレクトリに移す。以下のような具合である。

```shell-session
$ wget https://nim-lang.org/download/nim-0.16.0.tar.xz
$ tar -Jxvf nim-0.16.0.tar.xz
$ sudo mv min-0.16.0/lib  /usr/local/lib/nim
```

※: もちろんコマンド操作が不安な人は、Nautilusなどのファイルマネージャーを管理者権限で立ち上げて操作しても問題ない。

```shell-session
$ sudo nautilus #後はマウスで操作
```

# "nim compile --run filename.nim" を実行しても、Cコンパイラのエラーが出て実行できない。

これはNimのバグなのか判別がつかないが、エラーログを見る限り、ビルド時に生成されるnimcache内のCのソースコードで、いくつか行末のセミコロン（;）が抜けていてビルドできないらしい。

これの回避方法は、最初からリリースバージョンでコンパイルする。すると無事実行ファイルが生成される。ちゃんと写経できていれば、実行ファイルはソースファイルの拡張子が無くなったものが、ソースファイルのあるディレクトリに生成される。

```shell-session
$ nim c -d:release filename.nim
$ ./filename #これで実行
```

以上。
また何かハマったら加筆する。

# P.S.
## 加筆予定リスト
- [ ] nimbleのコンパイルとインストール（？）
- [ ] nimbleからNimのIDE「Aporia」のインストール

## バグ報告？
- [ ] Nimをインストールしてもライブラリがないと怒られるのはあまりよろしくない気がするので、パッケージマネージャーさんに相談するべきなのでしょうか。
- [ ] Nimを普通にコンパイルしてCのエラーが出るのはいささか良くない気がするので、これは本家に相談するべきでしょうか。

## 実行環境（neofetch結果）
```shell-session
            .-/+oossssoo+/-.               
        `:+ssssssssssssssssss+:`           --------------------------- 
      -+ssssssssssssssssssyyssss+-         OS: Ubuntu 16.10 x86_64 
    .ossssssssssssssssssdMMMNysssso.       Model: Aspire 3820 V1.13 
   /ssssssssssshdmmNNmmyNMMMMhssssss/      Kernel: 4.8.0-37-lowlatency 
  +ssssssssshmydMMMMMMMNddddyssssssss+     Uptime: 2 hours, 33 mins 
 /sssssssshNMMMyhhyyyyhmNMMMNhssssssss/    Packages: 2964 
.ssssssssdMMMNhsssssssssshNMMMdssssssss.   Shell: zsh 5.2 
+sssshhhyNMMNyssssssssssssyNMMMysssssss+   Resolution: 1366x768 
ossyNMMMNyMMhsssssssssssssshmmmhssssssso   DE: Unity 
ossyNMMMNyMMhsssssssssssssshmmmhssssssso   WM: Compiz 
+sssshhhyNMMNyssssssssssssyNMMMysssssss+   WM Theme: Ambiance 
.ssssssssdMMMNhsssssssssshNMMMdssssssss.   Theme: Ambiance [GTK2/3] 
 /sssssssshNMMMyhhyyyyhdNMMMNhssssssss/    Icons: Ubuntu-mono-dark [GTK2/3] 
  +sssssssssdmydMMMMMMMMddddyssssssss+     Terminal: gnome-terminal 
   /ssssssssssshdmNNNNmyNMMMMhssssss/      CPU: Intel i5 M 450 (4) @ 2.4GHz 
    .ossssssssssssssssssdMMMNysssso.       GPU: Intel Ironlake Mobile 
      -+sssssssssssssssssyyyssss+-         Memory: 2711MiB / 7653MiB 
        `:+ssssssssssssssssss+:` 
            .-/+oossssoo+/-.                                       
```
neofetchに関してはこちら: [Neofetch 3.0 Released - OMG! Ubuntu!](http://www.omgubuntu.co.uk/2017/01/neofetch-3-0-released)
vagrant で package して box add して up すると enp0s8 が起動しない件

#前提
物理PCのOS : macOS Sierra
VirtualHostのOS : CentOS7
Vagrant : 1.9.1

#現象

nginxなどをインストールした環境を複製しようと

```
vagrant halt
vagrant package
vagrant box add test package.box
cd ../dir2/
vagrant init test
sed -i '' -e 's/# config.vm.network "private_network", ip: "192.168.33.10"/config.vm.network "private_network", ip: "192.168.33.11"/' Vagrantfile
vagrant up
```

みたいなことをしたら enp0s8 が起動しなくてハマりました。

```
3: enp0s8: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN qlen 1000
    link/ether 08:00:27:59:4d:a9 brd ff:ff:ff:ff:ff:ff
```

ググった情報を参考に `/etc/udev/rules.d/70-persistent-net.rules/` や `/etc/sysconfig/network-scripts/ifcfg-enp0s8` を削除して package してみたのですがだめでした。

#対策1 手動でネットワーク再起動

```
sudo systemctl restart network
```

したら enp0s8 が起動しました。
しかし、vagrant halt → up するとまた DOWN するようです。
reboot なら起動したままのようです。

#対策2 自動でネットワーク再起動するようにvagrantfileに設定

```:Vagrantfile
  # config.vm.provision "shell", inline: <<-SHELL
+config.vm.provision "shell", run: "always", inline: "systemctl restart network.service"
```
※ + の列は追加を示す。

```bash
vagrant reload
```

http://qiita.com/junqiq/items/a19d3ea48b072a1b28d3


#原因
~~わかりません。
知ってる方いたら教えてください。~~

vagrant1.9.1のバグらしいです。次リリースで修正される見込みとのことです。

[追記] こちらのエントリと同じ現象のようです。
http://qiita.com/junqiq/items/a19d3ea48b072a1b28d3

---
以上
Docker for Mac上のコンテナ時刻がずれていく場合の対処法

#概要
　Docker for Macをサーバ用途などで１日以上起動したままにすると徐々にコンテナ内の時刻がずれてしまいます。
　検索しても自分の環境と条件が違うものが多かったので、Docker for Macでの同期についてやってみました。

#環境
OS: Mac OS Sierra 10.12.3
Docker for Mac: 1.13.0

#手順

1 ターミナルを開いて以下を実行する

```bash
screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
```

2 空の端末が起動するので、次のコマンドを実行する

```bash
hwclock -s
```

これでコンテナ内の時刻がホストのmac OSの時刻と同期しているかと思います。

#手順の内容
##Docker for Macコンテナの階層
公式の[Docker for Mac vs. Docker Toolbox](https://docs.docker.com/docker-for-mac/docker-toolbox/)には以下のように記載されています
>Docker for Mac does not use VirtualBox, but rather HyperKit, a lightweight macOS virtualization solution built on top of Hypervisor.framework in macOS 10.10 Yosemite and higher.

　Docker for MacではMacの上にHyperKitという仮想化ソリューションを用いてAlpine Linuxベースの仮想環境を構築し、その上にDockerコンテナが乗ることになります。

##時刻がずれる要因
　本来Dockerではホストの時刻を参照するため、時刻がずれることはないのですが、上記の通りHyperKit上の仮想OSがDockerコンテナにとってのホストとなり、そのホストの時刻がずれていくことで、コンテナ上の時刻もずれていきます。

##HyperKit上の時刻をハードウェアクロックと同期させる
　手順1.で実行しているのは、HyperKit上のLinuxへのアクセスで、手順2.では、ハードウェアクロックをシステムクロックに同期させています。
　ハードウェアクロックは文字通りmacのハードで刻んでいるクロックで、ホストはNTPで適宜正しい時刻をハードウェアクロックに反映していますので、ハードウェアクロックをHyperKit上のLinuxに反映させることで、それを参照するコンテナの時刻同期を図っています。

(2017/05/28追記)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/136146/861f9c41-ac88-3886-fe08-e71af464f012.png)

　HyperKit上のLinuxにはcronが入っていたので、

```bash
crontab -e
```

でスケジューリングしてやれば、定期的にハードウェアクロックと同期させることもできます。

#参照
[How to access the VM created by docker's HyperKit?](http://stackoverflow.com/questions/39739560/how-to-access-the-vm-created-by-dockers-hyperkit)
[Docker for Mac vs. Docker Toolbox](https://docs.docker.com/docker-for-mac/docker-toolbox/)
【AWS】DBパラメータグループの内容をBacklogのWikiにはっつけるメモ

# 概要
- RDSの特定のDBパラメータグループをBacklogのWikiにはっつける
- 前提
    - AWS CLIが使えること
    - WikiはBacklog形式

# メモ

## 1. データをテーブル形式でひっぱってくる

MySQL 5.7のデフォルトパラメータグループの場合

```
$ aws rds describe-db-parameters --db-parameter-group-name default.mysql5.7 --query "Parameters[*].[ParameterName, ParameterValue, AllowedValues, ApplyType, Description]" --output table > hoge.txt
```

## 2.スペースを削除

vim とかで頑張る

## 3.Backlogにはっつける
コピペして、ヘッダ行をつける（以下例）
|パラメータ名|デフォルト値|許容される値|適用タイプ|説明|h
[Unity]ZTestやBlend等をシェーダー外から設定する

サンプルとして単純なSprite用のシェーダーっぽいの

```
Shader "Custom/Sprite" {
	Properties {
		// TIPS: モバイル環境でScaleとOffsetは使えないのでNoScaleOffsetで封印する
		[NoScaleOffset] _MainTex ("Base (RGB), Alpha (A)", 2D) = "white" {}

		[Enum(UnityEngine.Rendering.CullMode)]
		_Cull("Cull", Float) = 0				// Off

		[Enum(UnityEngine.Rendering.CompareFunction)]
		_ZTest("ZTest", Float) = 4				// LEqual

		[Enum(Off, 0, On, 1)]
		_ZWrite("ZWrite", Float) = 0			// Off

		[Enum(UnityEngine.Rendering.BlendMode)]
		_SrcFactor("Src Factor", Float) = 5		// SrcAlpha

		[Enum(UnityEngine.Rendering.BlendMode)]
		_DstFactor("Dst Factor", Float) = 10	// OneMinusSrcAlpha
	}

	SubShader {
		Tags {
			"Queue" = "Transparent"
			"IgnoreProjector" = "True"
			"RenderType" = "Transparent"
			"PreviewType" = "Plane"
		}
		
		Cull [_Cull]
		ZTest [_ZTest]
		ZWrite [_ZWrite]
		Blend [_SrcFactor][_DstFactor]

		Pass {
			CGPROGRAM
			#include "UnityCG.cginc"

			#pragma vertex vert
			#pragma fragment frag

			struct appdata_t {
				float4 vertex : POSITION;
				half2 texcoord : TEXCOORD0;
				fixed4 color : COLOR;
			};

			struct v2f {
				float4 pos : SV_POSITION;
				half2 uv : TEXCOORD0;
				fixed4 color : COLOR;
			};

			sampler2D _MainTex;

			v2f vert(appdata_t v) {
				v2f o;
				o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = v.texcoord;
				o.color = v.color;
				return o;
			}

			fixed4 frag(v2f i) : SV_Target {
				return tex2D(_MainTex, i.uv) * i.color;
			}
			ENDCG
		}
	}
}
```

これでシェーダーファイルを増やさずにInspector上からMaterialでの設定ができる
メリットとしてはShaderVariantが減るのでシェーダーコンパイル時のスパイクが減らせる
あとコピペシェーダー作る必要がないのでコピペ漏れみたいなミスが減る
デメリットはマテリアルの生成難度が上がるので、
エンジニアでない人が「加算にしたいんだけどどうしたら･･･」となってしまいがち
（プリセット設定が選択出来ればいいのだけれど･･･MaterialPropertyDrawerは拡張できるのだろうか･･･）
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/105136/0807fa5c-cc09-0d12-b0d1-7b89f3f76a17.png)


スクリプトからも変更できる･･･が、**MaterialPropertyBlockでは値を変えても変化がなかった**
renderer.materialを呼び出すとMaterialが複製される･･･
sharedMaterialを使うとなると参照しているRenderer全てに影響が出る･･･
動的に変更することが有用な場面は非常に限定的かなと

```
// Materialを直接変更すると変わる
Material mat = new Material(Shader.Find("Custom/Sprite"));
mat.SetFloat("_Cull", (float)UnityEngine.Rendering.CullMode.Off);
mat.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
mat.SetFloat("_ZWrite", 0f);
mat.SetFloat("_SrcFactor", (float)UnityEngine.Rendering.BlendMode.SrcAlpha);
mat.SetFloat("_DstFactor", (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);

// MaterialPropertyBlockでは無効（SpriteRendererはそもそも無理）
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
mpb.SetFloat("_Cull", (float)UnityEngine.Rendering.CullMode.Off);
mpb.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
mpb.SetFloat("_ZWrite", 0f);
mpb.SetFloat("_SrcFactor", (float)UnityEngine.Rendering.BlendMode.One);
mpb.SetFloat("_DstFactor", (float)UnityEngine.Rendering.BlendMode.One);
MeshRenderer render = this.GetComponent<MeshRenderer>();
renderer.SetPropertyBlock(mpb);
```

【公式リファレンス】
https://docs.unity3d.com/jp/current/Manual/SL-Properties.html
https://docs.unity3d.com/jp/current/ScriptReference/MaterialPropertyDrawer.html
RoR｜カスタムバリデータを使いまわす


## やりたいこと
カスタムバリデータを作ったはいいが、まったく関係ないAPIでも同じバリデーションを実行したい。

## 試してみたこと
APIが呼び出されたらActiveModelを利用して、カスタムバリデータを利用するようにしてみた。

```ruby
class GreatApiController < ApplicationController
  class FruitApi
    include ActiveModel::Model
    attr_accessor :search_key

    validates :search_key, tel_number: true
  end

  def index
    respond_to do |format|
      fruit_api = FruitApi.new(search_key: params[:search_key])

      if fruit_api.valid?
        format.json { render json: {title: "GreatAPI Response"}, status: 200 }
      else
        format.json { render json: {title: "Error Response"}, status: 500 }
      end
    end
  end
end
```

`TelNumberValidator`が今回の主役です。
本来（？）の用途としては、`Book`にあるタイトルには絶対に電話番号（ぽい）ものを入れたいというものです。

```ruby
class Book < ActiveRecord::Base
  validates :title, tel_number: true
end
```

```ruby
class TelNumberValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless value =~ /^\d{2,4}-\d{2,4}-\d{3,4}$/
      record.errors[attribute] << "wrong tel number"
    end
  end
end

```

## やってみて思うこと
カスタムバリデータを利用することでコードがシンプルになっているのはグッド。
ただ、他にももっといい方法があるきがする。。
Botkitを使って定期的にメッセージを送るBotを作ってみた

社内でスタンドアップミーティングをSlackで初めて定刻になるとメッセージを送ってくれるBotを作ろうと思ってやってみました。

## Bot作成

Botを作るために予め登録しておく必要があります。
https://my.slack.com/services/new/bot

URLを開くと下のような画面が開くのでBot名を入力します。

![create.png](https://qiita-image-store.s3.amazonaws.com/0/119043/b6753feb-ec80-1346-fa64-d54467a29142.png "create.png")

Bot名を入力後、APIトークンが表示されますのでこれをメモしておきます。

![token.png](https://qiita-image-store.s3.amazonaws.com/0/119043/e3e00612-9383-f09a-165d-7b37aa56e8f4.png "token.png")

前準備はこれで終わりです。

## Botkitのインストール

https://github.com/howdyai/botkit

まずはBotを作る環境を整えます。

```bash
$ mkdir samplebot && cd samplebot
$ npm init
$ npm install --save botkit cron
```

単にメッセージやメンションに反応するBotであれば`botkit`だけで良いですが今回は定期的にメッセージを送るBotを作りたかったので`cron`も合わせてインストールしておきます。

## Botアプリの基本と起動

それではアプリを作っていきます。

```bash
$ touch index.js
```

BotkitのサンプルをほとんどそのままですがおまじのようなものですがこれでほぼBotは動作させることはできます。

```js:index.js
if (!process.env.token) {
	console.log('Error: Specify token in environment.');
	process.exit(1);
}

var Botkit = require('botkit');
var controller = Botkit.slackbot({
	debug: false
});

var bot = controller.spawn({
	token: process.env.token
}).startRTM(function(err, bot, payload) {
	if (err) {
		console.log('Error: Cannot to Slack');
		process.exit(1);
	}
});
```

試しにこれを起動してみます。

```bash
$ token=<APIトークン> node index.js
```

Slackの画面を見るとBotがオンラインになることがわかると思います。
起動する度に毎回APIトークンを入れるのも面倒なのでスクリプトに登録しておくと便利かもしれません。

## 定期的にメッセージを送る

インストールの際に`cron`を使って定期的にメッセージを送るように修正します。

```js:index.js
var Botkit = require('botkit');
// Add --
var CronJob = require('cron').CronJob;
// --
var controller = Botkit.slackbot({
	debug: false
});

var bot = controller.spawn({
	token: process.env.token
}).startRTM(function(err, bot, payload) {
	if (err) {
		console.log('Error: Cannot to Slack');
		process.exit(1);
	}
	// Add --
	new CronJob({
		cronTime: '30 16 * * 1-5',
		onTick: function() {
			bot.say({
				channel: 'standup',
				text: '進捗はどうですか',
				username: 'standupbot'
			});
		},
		start: true,
		timeZone: 'Asia/Tokyo'
	});
	// --
});
```

なんとなく察しはつくと思いますがCentOSとかでよく見るCronと同じような書き方で日時を指定してメッセージを送信します。
上記の例では平日（月-金）の16時30分にメッセージを送信します。

これで起動しておくと定期的にメッセージを送信することができます。
案外あっさりできたので他にも色々と作ってみようかなと思います。

## おまけ

各自が状況を報告して確認するだけも物足りないのでちょっとリアクションするように処理を加えてみました。

```js:index.js
controller.hears(['バグが', '不具合を発見', 'エラーが'], ['ambient'], function(bot, message) {
	bot.reply(message, 'なに？:fearful:');
});
```

`message_received`を書けばいいという記事をいくつか見かけましたがうまく動作させることができませんでしたが`ambient`でいけました。
あとはchannelにこのBotを参加させてやると反応します。

上の例ではだれかが「バグが・・・」と書くと反応します。
キーワードはいくつもできるのでけっこう面白いです。
が、やりすぎると結構面倒臭いBotになるのでご注意を...
過去に実行したコマンドを蘇生する

# 概要
過去に実行したコマンドを検索して、実行する手順

# 手順

```
history 100 #100行の過去を表示
```
↓こんなん表示されます。

```
   99  bundle install --without production
  100  cd sample_app/
  101  bundle install --without production
  102  git init
  103  git add .
  104  git commit -m "Initialize REPO"
  105  git mv README.rdoc README.md
  106  git commit -am "Improve the README"
  107  git remote add origin git@github.com:ksyunnnn/RailsTutorial_SampleApp.git
  108  git push -u origin -all
  109  git push -u origin --all
  110  git add .
  111  git commit
  112  cd sample_app_/
  113  ll
  114  view config/routes.rb 
  115  vi app/views/static_pages/home.html.erb 
  116  history 100
```

```
![番号] # 指定した番号のコマンドを実行
```

なんて簡単。素晴らC :clap:

## 追記：`Ctrl + r`を使用する方法

`Ctrl + r` を押した後に、文字列を入力すると、過去実行したコマンドが検索＆実行できるみたいです！すごい！:clap:

 @7of9 さん教えてくれてありがとうございます！
リダイレクトでアンドマーク'&'がやっていること

# 概要
LPIC Lv.1の勉強をしていて、のっけからリダイレクトで詰まったから。

```bash
ls > hoge.txt 2>&1
```

の＆が分からんかった。

ググったら書いてあったので、メモ。


# 前提
## リダイレクトとは、的なことから
### 標準出力
linuxではコマンドなどの入出力は主に次の３つに分類することができる。

+ 標準入力
+ 標準出力
+ 標準エラー出力

それぞれ見たとおりで、順にコマンドに渡す入力、コマンド成功時の出力、エラー時の出力となる。
デフォルトでは、標準入力はキーボードから入力した文字が指定されている。
標準出力は画面に表示される。標準エラー出力も画面だ。

なにげなくコマンドを実行したら普通に画面に結果が表示されるのは、標準出力や標準エラー出力が画面に対して結果を渡していたからのようだ。

### リダイレクト

だけれども、時には入力や出力先を変えたくなる。
コマンドでなんやらした結果をファイルに書き込みたいとか、そんな時だ。

で、登場するのが「<」や「>」といった記号を使ったリダイレクト。

こいつを使えば、出力先や入力元を指定することができる。

### 例

```bash
ls / > root.txt 
```

こうすれば、root.txtにルートディレクトリの中身の一覧が格納される。


エラーをファイルに書き込むこともできる。

```bash
cat / 2> err.txt
```

err.txtには、たぶんこんな内容がかかれている。

```text
cat: /: Is a directory
```

### なんで？
実は、コマンドの入出力にはファイル記述子と呼ばれる番号が振られている。
これを利用して、入出力の指定をできるのだ。

|input / output|file descriptor|
|:-:|:-:|
|標準入力|0|
|標準出力|1|
|標準エラー出力|2|


# &マークの仕事


ここで、冒頭のコマンドを見てみる。

```bash
ls > hoge.txt 2>&1
```

コマンドは、基本的に左から実行されるから、とりあえずlsの標準出力をhoge.txtにリダイレクトして書き込んでいるのはわかる。

だが、そのあとが謎だ。

いろいろ調べた結果、こういうことらしい。

https://oshiete.goo.ne.jp/qa/2257403.html

>これで出力ファイル・ディスクリプタ（記述子）の複製を行います。
したがって、
2>&1
この場合、ファイル・ディスクリプタ2に、ファイル・ディスクリプタ1の複製を使用するという意味になります。

なんのこっちゃ。

上記のエントリの助言に従って、bashのマニュアルを見てみた。

```bash
man bash
```

の中に次の記述を発見。

> Note  that  the order of redirections is significant.  For example, the
       command
              ls > dirlist 2>&1
       directs both standard output and standard error to  the  file  dirlist,
       while the command
              ls 2>&1 > dirlist
       directs  only the standard output to file dirlist, because the standard error was duplicated from the standard output before the standard  output was redirected to dirlist.


ざくっと内容を抽出すると、「&１」は　lsの標準出力先をコピーしているという意味らしい。今回の場合

```bash
ls > dirlist 2>&1
```

lsコマンドの標準出力がdirlistというファイルに向いているので、2>&1は、ファイル記述子の２番、つまりlsの標準エラー出力を、標準出力の向き先であるdirlistにリダイレクトするということらしい。

一方で、

```bash
ls 2>&1 > dirlist
```

はうまく動かない。なぜなら、コマンドは左から順に解釈されるので、ls 2>&1はもとのlsコマンドの出力先にしかならない。　ファイル記述子を指定しない「>」記号が定義するのは標準出力なので、結果としてこのコマンドは、うまく言った結果はファイルに記録され、エラーの場合は画面に表示するというコマンドになっている。


# 感想

linuxコマンドは、むずかしいけどたのしいです。
文字の書式

# 目的
C#とpython3での文字書式を入れる方法

# 参考にしたサイト
ありがとうございました。
## Csharp
- http://ufcpp.net/study/dotnet/bcl_format.html
- http://dobon.net/vb/dotnet/string/inttostring.html
  
## python3
- http://qiita.com/kAhn/items/2a7b4201beb0d467e5b8
- http://qiita.com/mas9612/items/af6a3030f9ef19feae22

# 0詰め,ゼロパディング(zero padding),リーディングゼロパディング
123=>「0123」
↑のような感じにするやつ
色々見つかった。

C#版
   
``` csharp
var num1 = 123;
//ToString 
num1.ToString("D4");
num1.ToString("0000");
num1.ToString(new string('0', 4));
//string.Format
string.Format("{0:0000}", num1);
string.Format("{0,04:D}", num1);
//$""
$"{num1:d4}";
$"{num1:0000}";
```

python3版

``` python3
'{:04}'.format(123)
'{:0>4}'.format(123)
str(123).zfill(4)
```

# ゼロサプレス(zero suppress) ,リーディングゼロサプレス
123=>「 123」(先頭にスペースで4文字)
↑のような感じにするやつ
C#

``` csharp
var num1 = 123;
string.Format("{0,4}", num1);// 123
string.Format("{0,4:D}", num1);//
$"{num1,4}";
$"{num1,4}";
```

python3

``` python3
'{:4}'.format(123)
'{:>4}'.format(123)
```

# 小数点
123.456 => 「123.5」(小数点一桁かつ四捨五入)
↑のような感じにするやつ
がメインだけどそうでないものも
C#

``` csharp
var d = 123.456;
d.ToString("#.#");//123.5
d.ToString("0.0");//123.5
d.ToString("0000.0");//0123.5
d.ToString("0.00");//123.46
d.ToString("N1");//123.5
d.ToString("F1");//123.5
string.Format("{0:F1}",d);//123.5
string.Format("{0:N1}", d);//123.5
string.Format("{0:0.0}", d);//123.5
string.Format("{0:#.#}", d);//123.5
$"{d:0.0}"; //123.5
$"{d:#.#}"; //123.5
$"{d:f1}"; //123.5
$"{d:n1}"; //123.5
```

python3

``` python3
'{:.1f}'.format(d)//123.5
```
Objective-Cにてtry-catchした時に変数がmutableになってしまう問題の解決方法

# 困ったこと

こんなコードがあるときに`try-catch`を入れたくなりますよね。

```objc
NSString *const name = [self getNameMethodMayCauseException];    // 例外が発生するかもしれないメソッドや処理
[self otherMethodWithName:name];
```

するとこんな感じに`name`が意味もなくmutableになってしまいます。

```objc
NSString *name = nil; // immutableでありたい:(
@try {
    name = [self getNameMethodMayCauseException];    // 例外が発生するかもしれないメソッドや処理
} @catch (NSException *exception) {
    name = nil;
}
[self otherMethodWithName:name];
```

# 解決法

どうにかimmutableにしたいと考えた結果、**blocks**を利用することでそれっぽくなりました。

```objc
// immutable :)
NSString *const name = ^NSString*(){
    @try {
        return [self getNameMethodMayCauseException];    // 例外が発生するかもしれないメソッドや処理
    } @catch (NSException *exception) {
        return nil;
    }
}();
[self otherMethodWithName:name];
```
POSIX shの変数展開による文字列置換の限界を探る

シェルスクリプト中で文字列置換をしたくなったら普通はsedやawkを呼び出すのが正解でしょう。ただ、世の中にはプロセスのforkが異常に遅い環境というのがあるので（CygwinとかMSYSとか）、シェルスクリプト内で頑張りたくなることがあります。

そんなときに使えるのがシェルの変数展開の機能です。特に下記の4つの書き方はPOSIX shがサポートしているのでポータビリティの観点でも安心して使うことができます。

| 表現 | 説明 |
|:--|:--|
| `${parameter%パターン}` | `$parameter`の末尾からパターンにマッチする文字列を取り除いた値を返す<br>（最短一致） |
| `${parameter%%パターン}` | `$parameter`の末尾からパターンにマッチする文字列を取り除いた値を返す<br>（最長一致） |
| `${parameter#パターン}` | `$parameter`の先頭からパターンにマッチする文字列を取り除いた値を返す<br>（最短一致） |
| `${parameter##パターン}` | `$parameter`の先頭からパターンにマッチする文字列を取り除いた値を返す<br>（最長一致） |

これらを使ってどこまで頑張れるのかについて調べてみました。

## パターンの書き方

上記のパターンの部分はいわゆるワイルドカードマッチで、次のような表現が使えます。


| 表現 | 説明 |
|:--|:--|
| `?` | 任意の1文字にマッチ |
| `*` | 任意の0文字以上にマッチ |
| `[abc]` | 文字a,b,cいずれか1文字にマッチ |
| `[!abc]` | 文字a,b,c以外の1文字にマッチ |
| `[a-z]` | aからzまでの1文字にマッチ |
| `[!a-z]` | aからz以外の1文字にマッチ |

上の表を見てわかる通り、パターンマッチの能力はかなり貧弱です。特に、直前の表現のn回繰り返し（正規表現で言う`*`）が使えないのは非常に痛いですね。

## POSIX shでできること一覧

わかりやすさのため、変数展開で出来ることを正規表現と並べて記述してみました。

### 先頭または末尾の固定文字列の削除

| 正規表現 | POSIX shで対応する変数展開 | `README.md`に対して適用した結果 |
|:--|:--|:--|
| `s/\.md$//` | `${str%.md}` | `README` |
| `s/^README//` | `${str#README}` | `.md` |

元の文字列と比較することでマッチングの成功失敗も判定できますから、次のように`if`で分岐すれば文字列置換を行うことも可能です（もちろん、こんな書き方をするくらいならsedなどを使うべきだと思いますが）。

```bash
tmp=${path%.gif}
if [ "$path" != "$tmp" ]; then
  tmp="${tmp}.jpg"
fi
```

### 先頭から特定の文字列までの削除・特定の文字列から末尾までの削除

`abc=123=foo=bar`から`=`より前（`abc`）や`=`より後（`bar`）を取り出したいような場合も簡単に記述可能です。

| 正規表現 | POSIX shで対応する変数展開 | `abc=123=foo=bar`に対して適用した結果 |
|:--|:--|:--|
| `s/=.*$//` | `${str%%=*}` | `abc` |
| `s/=[^=]*$//` | `${str%=*}` | `abc=123=foo` |
| `s/^.*=//` | `${str##*=}` | `bar` |
| `s/^[^=]*=//` | `${str#*=}` | `123=foo=bar` |

これと同じ書き方で、`basename`コマンドを`${path##*/}`で、`dirname`コマンドを`${path%/*}`で代用する、などというのが定番の使い方だと言えます。

### 文字列先頭から特定の文字群が連続する限り取り出す

`Abc123-foo:bar`から、先頭や最後でアルファベットが連続している部分（`Abc`や`bar`）を取り出したいような場合もPOSIX shで記述可能です。

| 正規表現 | POSIX shで対応する変数展開 | `Abc123-foo:bar`に対して適用した結果 |
|:--|:--|:--|
| `s/^([A-Za-z]*).*$/$1/` | `${str%%[!A-Za-z]*}` | `Abc` |
| `s/^.*?([A-Za-z]*)$/$1/` | `${str##*[!A-Za-z]}` | `bar` |

逆にアルファベット連続だけを削除する方法はありません。不便ですね。

## まとめ

今回調べてみて、POSIX shでもそれなりに文字列操作ができるんだな、という感想を持ちました。一方で、このような記法は保守性が非常に低いと個人的には感じます。実際に利用する際は補足コメントを書いておいた方が良いでしょう。

これより複雑な処理を書きたい場合はsedなどの外部コマンドを呼び出すか、ポータビリティはあきらめてbashやzshに依存したスクリプトを書くのが良さそうです。bash/zshならPOSIX正規表現（zshならPCREも使える）によるマッチングおよびキャプチャができるので、もう少し頑張れるはずです。

## 参考URL

- [Pattern Matching Notation](http://pubs.opengroup.org/onlinepubs/007908799/xcu/chap2.html#tag_001_013) POSIX shのパターンマッチの解説
- [shとbashでの変数内の文字列置換など \- ろば電子が詰まっている](http://d.hatena.ne.jp/ozuma/20130928/1380380390)
【macOS】Chromeアプリの終了ショートカットキーによる悲劇

#この記事の概要
クラウドコンピューティングが盛んな今日、Macbookで起動中のブラウザで作業をしていたら悲劇が起こりました。
テキストエリア内の全文字列を選択しようと、キーボードのショートカット「コマンド⌘ + Aキー」を押そうとしたら、誤って斜め上の「Qキー」を押してしまったのです。
「⌘ + Q」といえば、アプリ終了のショートカットですね。
高性能な我がMacbookは、有無を言わせずに業務作業中のChromeを一瞬で終了。
それまでの作業は、雲の彼方へ。

これが原因
<img width="653" alt="スクリーンショット 2017-02-07 22.47.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/70476/4287ae9a-ee82-939b-0040-a4a15f2f6c9a.png">

どうしよう。
こうしよう。
Chromeの「Google Chrome を終了」ショートカットキーを変更しよう。
「コマンド + オプション + Qキー」にしよう。
以下、手順です。

#手順
##1. システム環境設定アプリを開いて、キーボードを選択する
<img width="668" alt="スクリーンショット 2017-02-07 22.33.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/70476/9c22fd37-c094-c4af-71c8-af117cead1f0.png">

##2. 【ショートカット】タブを選択する
<img width="780" alt="スクリーンショット 2017-02-07 22.33.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/70476/a3021800-102a-72ed-92a4-813feacfb7a9.png">

##3. アプリケーションを選択して、【＋】をクリックする
<img width="780" alt="スクリーンショット 2017-02-07 22.57.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/70476/a6146256-e33b-4aec-7e0d-ec58e6d73e41.png">

##4. アプリケーションの挙動にショートカットを設定する
<img width="752" alt="スクリーンショット 2017-02-07 22.45.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/70476/10402a16-1f86-72d4-31fd-52a150e27723.png">

##5. ショートカットキーが設定される
 <img width="668" alt="スクリーンショット 2017-02-07 22.44.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/70476/028053ac-cafb-34f7-e9b7-ce35469a32a0.png">

#確認
Chromeを起動して、アプリケーションメニューを確認します。
<img width="548" alt="スクリーンショット 2017-02-07 22.48.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/70476/b5fbf82a-5b0c-e626-7e02-17f9d8d5c049.png">

このようになっていれば、全範囲選択（⌘A）しようとした瞬間にアプリ終了という悲劇は無くなります。（Chromeに限っては...。）
vscodeでtslintを使ったときのメモ

# tslintの導入

## 必要なnpmパッケージのインストール

```
npm install -g --save-dev gulp typescript
npm install --save-dev tslint gulp gulp-tslint
```

## tslint設定ファイルの用意

```
project
 - .vscode
   - tasks.json # vscodeからgulpを実行する設定
 - tslint.json  # チェックする項目のルール
 - gulpfile.js  # tslintを実行するタスク
 - package.json
 + node_modules
```

tasks.json

```json
{
	"version": "0.1.0",
	"command": "gulp",
	"isShellCommand": true,
	"args": [
		"--no-color"
	],
	"tasks": [
		{
			"taskName": "tslint",
			"args": [],
			"problemMatcher": {
				"owner": "tslint",
				"fileLocation": [
					"relative",
					"${workspaceRoot}"
				],
				"severity": "warning",
				"pattern": {
					"regexp": "^(\\S.*)\\[(\\d+), (\\d+)\\]:\\s+(.*)$",
					"file": 1,
					"line": 2,
					"column": 3,
					"message": 4
				}
			}
		}
	]
}
```

gulpfile.js

```js
'use strict';

const gulp = require('gulp');
const gulp_tslint = require('gulp-tslint');

gulp.task('default', ['tslint']);

gulp.task('tslint', () => {
    return gulp.src(['**/*.ts', '!**/*.d.ts', '!node_modules/**'])
      .pipe(gulp_tslint())
      .pipe(gulp_tslint.report());
});
```

tslint.json

``` json
{
	"rules": {
		"no-unused-expression": true,
		"no-duplicate-variable": true,
		"no-duplicate-key": true,
		"no-unused-variable": true,
		"curly": true,
		"class-name": true,
		"semicolon": ["always"],
		"triple-equals": true
	}
}
```

## 実行

[ctrl] + [shift] + [p] でコマンドパレットを開く。

run taskと入力して[enter] → tslintを選択して[enter]

## 参考

[tslint][*1]
[vscode-tslint][*2]
[Visual Studio Codeの使い勝手をよくするツール (1/5)][*3]
[qiita vscode moca][*4]
[Visual Studio Code を使う上で良くわかっていなかった(基本的な)用語とか][*5]
[tslint-json][*7]
[tslint-cli][*8]

[*1]:https://marketplace.visualstudio.com/items?itemName=eg2.tslint
[*2]:https://github.com/Microsoft/vscode-tslint
[*3]:http://www.atmarkit.co.jp/ait/articles/1509/08/news019.html
[*4]:http://qiita.com/xingyanhuan/items/46ab06dc6ad9ffaec4f2
[*5]:http://qiita.com/satokaz/items/dd2f16fc953e7bdb6d2f
[*6]:https://github.com/yannickcr/eslint-plugin-react#list-of-supported-rules
[*7]:https://palantir.github.io/tslint/usage/tslint-json/
[*8]:https://palantir.github.io/tslint/usage/cli/
Jupyter Notebook を Proxy サーバ配下で使う場合の設定

設定に手こずったのでメモ。


Jupyter Notebook を Proxy サーバ配下で使う場合には設定が必要。

まずプロファイルを作成：

```
$ ipython profile create
```

ファイルを修正。proxy.example.com:80, proxy.example.com:443 の部分には Proxy サーバを記載する。

```
$ vi ~/.ipython/profile_default/startup/00-startup.py
---
import sys,os,os.path
os.environ['HTTP_PROXY']="http://proxy.example.com:80"
os.environ['HTTPS_PROXY']="http://proxy.example.com:443"
```

Jupyter Notebook のセルで設定が反映されたことを確認する

```
%env
```

```
{
...
'HTTP_PROXY': 'http://proxy.example.com:80',
...
```
自分で作ったNSViewをConstraintsでAutoLayoutしたかったけど、NSViewに直接はできなかった。

Swift × macOS です！ iphoneじゃないよ。

自作のNSViewにAutoLayoutさせるために、Constraintsを使おうとしたけどできなかった。

やろうとしていたのは、
Storyboardを使わずに、addsubviewしたitemにaddConstraintsをすること。

結果としてやったのは、以下。

1. Storyboard上で、CustomViewを作成して、IBoutletでviewControllerに繋ぐ。
2. storyboard上で、CustomViewにConstraintsを設定する。
2. 繋いだCustomViewに`addSubview`をする。

----

storyboardにcustomviewを置く前は、画面サイズを縦に小さくすると上にmenuが消えちゃってたんですよ。
![customView.gif](https://qiita-image-store.s3.amazonaws.com/0/129283/dc90d612-df3d-5b2b-2816-b1952360ea7e.gif)

----
> 曖昧なことは書かない方が良いと思うんですが...試行錯誤はこれらを参考にしてしました。
これとかでできると思ったんですけどねぇ。。。自分の環境では、NSViewの値とかを外部から変更しているし、NSrectとかのサイズ指定もコード上でしてたので多分使えなかったのかなぁ。

- http://stackoverflow.com/questions/31224953/how-to-add-constraints-after-an-addsubview-so-the-subview-resizes-with-the-super
- http://stackoverflow.com/questions/8156799/how-to-make-a-custom-view-resize-with-the-window-with-cocoa-auto-layout
Perlでmkpathをするときの恐怖

Perlで階層を一気にパーミッションを指定してmkdirするとき、インターネットではFile::Pathを使って以下のような書き方を見かける。
```mkpath( "/hoge/moge/hoge", 0, 0775);```
しかし、この書き方は誤動作することがある。

[インターネットでドキュメント](http://perldoc.perl.org/File/Path.html)を確認してみますと、以下の4つの書き方がある。
```
mkpath( $dir )
mkpath( $dir, $verbose, $mode )
mkpath( [$dir1, $dir2,...], $verbose, $mode )
mkpath( $dir1, $dir2,..., \%opt )
```
この4つの書き方で、2番目と4番目が非常に似ているので、2番目で書いたつもりが、4番目で動作することが有り得る、verboseのつもりで書いていても、それをdir2と認識しゴミディレクトリーを作成してしまう恐れがある。
実行したディレレクトリーに「0」という謎のディレクトリーが作られていたら、間違い無く、解釈ミスが起きている。
回避方法は、以下のように、最初から4番目の書き方で記載するのが良い。

```mkpath( "/hoge/moge/hoge", {chmod => 0775});```