OmniAICreator/Qiita-1.07M huggingface dataset:
共用環境向けのChainerMNのインストール

共用環境でCUDAやOpenMPIが標準的なパスにインストールされていない場合のChainerMNのインストール手順．

# ChainerMNのダウンロード
今回はCUDAやOpenMPIのインストールパスを指定するためソースからインストールする．

```
$ git clone https://github.com/pfnet/chainermn.git
```

ソースからインストールしなくて良い場合は以下のようにするとchainerやmpi4pyのインストールなどをよしなにやってくれる．

```
$ pip install chainermn
```


# Chainerのインストール
CUDAが標準的なパス(/usr/local/cudaとか?)にインストールされていない場合，以下のようにする．

```
$ CUDA_PATH=/path/to/cuda pip install chainer
```

詳細は以下を参照．
http://docs.chainer.org/en/stable/install.html

# mpi4pyのインストール
OpenMPIが標準的なパス(/usrとか？）にインストールされていない場合，以下のようにする．

```
$ env MPICC=/path/to/mpicc pip install mpi4py
```

詳細は以下を参照．
https://pythonhosted.org/mpi4py/usrman/install.html

# ChainerMNのインストール

基本的には以下のようにすればよい．

```
python setup.py install
```

ただし，CUDA(やNCCL)やOpenMPIが標準的なパスにインストールされていないときはライブラリをみつけてくれないのでsetup.pyを以下のように編集する．（もっとナイスなやり方があるかも．．）

```
<         include_dirs=['/path/to/cuda/include', '/path/to/openmpi/include'],
<         libraries=['nccl'],
<         library_dirs=['/path/to/cuda/lib', '/path/to/openmpi/lib'])
---
>         libraries=['nccl'])
```

# 簡単なテスト

```
$ mpiexec -n 4 python examples/mnist/train_mnist.py

```
OSX El Capitanにopenssl-1.0.2lをインストールしてPythonの_ssl.soも更新する

OSX El Capitan に openssl-1.0.2l をインストールした記録。

内容は [OSX Yosemite に openssl-1.0.2f をインストールしてPythonの_ssl.soも更新する](http://qiita.com/drafts/0a2363f905a4478bad0b)と同じ。

OSX El Capitan の OpenSSL は 0.9.8 系なのだが、2015年12月31日でサポートが終了している。
OS X El Capitan のリリースが2015年9月30日で、その年の末にはEOLになる OpenSSL 0.9.8zh をバンドルしてくるのはどうなんだろう。

ちなみに、OS X El Capitan の openssl は version コマンドに対して

~~~
$ /usr/bin/openssl version
OpenSSL 0.9.8zh 14 Jan 2016
~~~

という出力を返す。配布されている OpenSSL 0.9.8zh は `OpenSSL 0.9.8zh 14 Jan 2016` という出力を返すので、なにか手はいれてあるらしい。




openssl-1.0.2l のビルド

32bit 版と 64bit 版を二度に分けてビルドし lipo で Univesal Binary にする。
コンパイルオプションで -arch x86_64 -xarch i386 で multilib にできるかと思ったら、コンパイルでラーがでるためこのような方法をとっている。

~~~
$ ./Configure shared darwin64-x86_64-cc
$ make
~~~

テスト

~~~
$ make test
~~~

エラーがでていなければOK

インストール
デフォルトの /usr/local/ssl にインストールされる。

~~~
$ sudo make install
~~~


~~~
$ cd /usr/local/ssl
$ sudo mkdir bin64
$ sudo sh -c 'cd bin && find . -print | cpio -pdmu ../bin64'
$ sudo mkdir lib64
$ sudo sh -c 'cd lib && find . -print | cpio -pdmu ../lib64'
~~~

ソースツリーに戻って 32bit 版をビルド

~~~
$ make clean
$ ./Configure shared darwin-i386-cc
$ make
~~~

インストール
ドキュメントは不要なので make install_sw を実行する。

~~~
$ sudo make install_sw
~~~

~~~
$ cd /usr/local/ssl
$ sudo mkdir bin32
$ sudo sh -c 'cd bin && find . -print | cpio -pdmu ../bin32'
$ sudo mkdir lib32
$ sudo sh -c 'cd lib && find . -print | cpio -pdmu ../lib32'
~~~

lipo で Univesal Binary を作成する。

~~~
$ cd /usr/local/ssl
$ sudo lipo -create bin{32,64}/openssl -output bin/openssl
$ sudo lipo -create lib{32,64}/libcrypto.a -output lib/libcrypto.a
$ sudo lipo -create lib{32,64}/libssl.a -output lib/libssl.a
$ find lib64 -type f -name '*.dylib' | while read file ; do echo lipo -create $(echo "$file" | sed 's/64/{32,64}/') -output $(echo "$file" | sed 's/64//'); done | sudo sh
$ sudo rm -r bin{32,64} lib{32,64}
~~~


今後プログラムをビルドするときに/usr/local/ssl にある openssl を使うようにすれば、1.0.2 系の openssl がリンクされる。




python の SSL ライブラリを更新しておく。
開発環境が `xcode-select --install` されていないと、`configure` でヘッダが見つからずエラーになるので注意。

~~~
$ sudo xcode-select --install
Password:
xcode-select: note: install requested for command line developer tools
~~~


https://www.python.org/downloads/release/python-2710/ からソースファイルを取得する。

~~~
tar xfz Python-2.7.10.tgz
cd Python-2.7.10
~~~

~~~
CC=cc \
CPPFLAGS=-I/usr/local/ssl/include \
LDFLAGS='-L/usr/local/ssl/lib -Wl,-rpath,/usr/local/ssl/lib' \
./configure --enable-framework --enable-universalsdk --with-universal-archs=intel
~~~

~~~
$ make
~~~

じつは、欲しいのは `_ssl.so` だけ。

~~~
$ find . -name _ssl.so
./build/lib.macosx-10.5-intel-2.7/_ssl.so
~~~

python で `import ssl` したときに、この `_ssl.so` がロードされるようすればよい。

~~~
$ sudo mkdir /Library/Python/2.7/lib-dynload
$ sudo cp build/lib.macosx-10.5-intel-2.7/_ssl.so /Library/Python/2.7/lib-dynload
~~~

このような sitecustomize.py を作成して、/Library/Python/2.7/lib-dynload を検索パスに追加する。

```/Library/Python/2.7/site-packages/sitecustomize.py 
import sys
sys.path.insert(0, '/Library/Python/2.7/lib-dynload')
```

動作確認。

~~~
$ python
>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 1.0.2l  25 May 2017'
~~~
CodePipeline, CodeCommit, CodeDeploy を使ったデプロイ

CodeCommit が東京リージョンでも使えるようになったので, Code~ 系を使ってデプロイを統合します.
※github を使っている場合は CodeDeploy で直接デプロイできます.

以前の記事 [AWS CodeDeploy 導入調査 AWS 設定編](http://qiita.com/ta_ta_ta_miya/items/7fc0e65cb89b367810dc) ではソースコードを zip 化して 
S3 にアップロードして CodeDeploy でデプロイという方法を取っていました.
この方法だとチーム運用するには CI サーバー等がないとちょっと厳しそうだったのですが, 
CodeCommit を使用することによりその辺りのハードルが少し下がります.

### CodeCommit
https://aws.amazon.com/jp/codecommit/
言うなれば AWS の git ホスティングサービスです. 
ただし現時点(2017/06月)では PullRequest 機能もありませんのでメインのソースコード管理サービスとして他から移行するのは厳しいです. 
ただ AWS 内のサービスということで他の Code~ サービスとのコラボレーションを期待できます.

#### リポジトリ作成
1. "リポジトリの作成" ボタンからリポジトリ名を入力
2. 以上

### CodePipeline
https://aws.amazon.com/jp/codepipeline/
CodeCommit を使っても直接 CodeCommit -> CodeDeploy でデプロイすることはできません.
CodePipeline を使ってデプロイワークフローに沿ってデプロイします.
単純なデプロイだけでなく, CodeBuild を使ってビルドを挟んだり, 
jenkins と連動してデプロイ前にテストをしたりとなかなか便利です.

#### パイプラインの作成
AWS コンソール上でのパイプライン作成方法の流れ
1. パイプライン名を適当に "test"
2. ソースコードプロバイダは "CodeCommit"　 
　リポジトリとブランチを指定
3. ビルドは今回スクリプト言語想定なので "なし"
4. デプロイプロバイダは "CodeDeploy" アプリケーション名等は以前の記事参照
5. サービスロールは初回なら "ロールの作成" から作成 
6. 最後に内容確認して終了

### デプロイまでの流れ
1. ソースコードコミット&プッシュ (ローカル)  
社内で使っているのは BitBucket なので普通にプッシュします
2. BitBucket と CodeCommit の同期  
   ここはどうしようか検討中
3. CodePipeline 上で "変更のリリース" を選択
4. デプロイが完了するまで待つ

### まとめ
以上 Code~ を使ったデプロイを簡単にまとめてみました.
デプロイ周りが整っているプロジェクトなら無理に移行する必要はないかと思いますが, 
こうしたサービスの機能を利用したデプロイの価値はデプロイツール自体のメンテナンスを
ある程度省けるところにあると思います. (ある程度です)

### 今後の課題
BitBucket と CodeCommit の同期部分が決まってません.
手動同期はイケてないので何か方法を考えなければなりません.
この記事の内容とか試してみようかと(BitBucket の Webhook を API GateWay で受け取って Lambda 起動)
https://aws.amazon.com/jp/blogs/devops/integrating-git-with-aws-codepipeline/
(2017/5/30追記)CodeCommitのHTTPSによる接続が普通に可能なためBitBucketならミラーフックでよい模様
Cocos2d-x の2系かつ Android だと半角スペースで改行される

取り急ぎ調べただけなのでメモ。

表題の件、原因は`Cocos2dxBitmap.java` の `divideStringWithMaxWidth` 関数と思われる。

```
if (tempWidth >= pMaxWidth) {
	final int lastIndexOfSpace = pString.substring(0, i).lastIndexOf(" ");
	
	if (lastIndexOfSpace != -1 && lastIndexOfSpace > start) {
		/* Should wrap the word. */
		strList.add(pString.substring(start, lastIndexOfSpace));
		i = lastIndexOfSpace;
	} else {
		...
	}
	...
}
```

長さがオーバーしている場合は末尾の半角スペースで区切ってそこで1行としている（っぽい）。
おそらく英文想定の実装だと思われる。

3系だとこの処理はなくなっている。
https://github.com/cocos2d/cocos2d-x/blob/v3/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxBitmap.java
PythonからリモートPCの色んな情報を抜いてみた by WMI Library

#はじめに
数百台あるクライアントPCから各種情報を採集する必要があり、Pythonコードを書いて楽をしたので、その時のメモです。
ちなみにADドメイン環境下を想定しています。

#前準備
##リモートPC
リモートPCで以下のサービスが実行されているか確認する。
もし実行されていないようであれば、グループポリシーなり力業なりで自動起動するように設定する。

- Remote Procedure Call(RPC)
- Windows Management Instrumentation

##ADグループポリシー設定
以下のページを参考に、グループポリシーを利用してリモートPCのRPC接続を有効化する。
[Windowsファイアウォールのリモート管理を有効にする](http://www.atmarkit.co.jp/fwin2k/win2ktips/570remadmin1/remadmin1.html)

グループポリシーを直ぐに反映するには、リモートPC側で強制適用する。

```dos:cmd.exe
gpupdate /force
```

##Python環境設定
リモート接続する側（Pythonコード実行環境）で、WMIに必要なモジュールをインストールする。

```bash
pip install pypiwin32
pip install wmi
```

#サンプルコード
```python:sample.py
# coding: utf-8

import wmi

NODE = "host-1.example.local"
USER = "Administrator@MYDOMAIN"
PASS = "P@ssW0rd!"

## WMIクライアントの初期化（ローカルPCへ接続する場合）
#conn = wmi.WMI()
## WMIクライアントの初期化（リモートPCへ接続する場合）
conn = wmi.WMI(NODE, user=USER, password=PASS)

# コンピュータ名の取得
# Win32_OperatingSystem => http://www.wmifun.net/library/win32_operatingsystem.html
obj = conn.Win32_OperatingSystem()[0]
print("Hostname: %s" % obj.CSName)

## Cドライブの空き容量チェック(GB単位、小数点下2桁まで)
## Win32_LogicalDisk クラス => http://www.wmifun.net/library/win32_logicaldisk.html
obj = conn.Win32_LogicalDisk(DeviceID='C:')[0]
free = float(obj.FreeSpace) / 1024 / 1024 / 1024
print('FreeSpace: {:.2f}'.format(free))

## 現在ログオン中のユーザーアカウント確認
## Win32_ComputerSystem クラス => http://www.wmifun.net/library/win32_computersystem.html
obj = conn.Win32_ComputerSystem()[0]
print("LogonUser: %s" % obj.UserName)

## PCの製造番号（シリアルNO）確認
## Win32_ComputerSystemProduct クラス => http://www.wmifun.net/library/win32_computersystemproduct.html
obj = conn.Win32_ComputerSystemProduct()[0]
print("SerialNo: %s" % obj.IdentifyingNumber)

## コマンド実行
## Win32_Process クラス => http://www.wmifun.net/library/win32_process.html
CMD = "notepad.exe"
CUD = None
## フルパスの場合、セパレータ文字(\)を更にエスケープ
#CMD = "C:\\Users\\Public\\Desktop\\example.exe"
#CUD = "C:\\Users\\Public\\Desktop"
SW_SHOWNORMAL = 1

p_startup = conn.Win32_ProcessStartup.new()
p_startup.ShowWindow = SW_SHOWNORMAL
pid, result = conn.Win32_Process.Create(
    CommandLine=CMD,
    CurrentDirectory=CUD,
    ProcessStartupInformation=p_startup
)
if result == 0:
    print "ProcessId: %d" % pid
else:
    raise RuntimeError, "Problem creating process: %d" % result
```

実行結果

```
% python sample.py
Hostname: HOST-1
FreeSpace: 18.53
LogonUser: MYDOMAIN\user001
SerialNo: JPA12345LF
ProcessId: 3784
```

#その他

- リモートPCのアプリケーションを実行する場合、対話型アプリケーション（Notepad等）は画面が表示されない。これはセキュリティ上の仕様とのこと。（>= Windows XP SP3 ?）
- WMIを利用するには、ローカル管理者アカウント、またはドメイン管理者アカウントによる接続が必要。（= Access Denied）

#参考
[wmi Tutorial](http://timgolden.me.uk/python/wmi/tutorial.html)
[WMI Library](http://www.wmifun.net/library/)
今時、bower、使ってます。

# **Bower入門**
自分の周りでは使っているのをほとんど見かけないBowerですが、個人的には十分な機能を備えているので、重宝しています。そんなBowerの超入門を記事に残しておきたいと思います。
自分のメモとしてもそうですが、誰かのためになる事を切に願ってます。

---
【コンテンツ】
1. Bowerとは
2. 初期設定
3. 何かインストールしてみる

【PC環境】
・MacOS
・Node v5.0.0

---

## 1. Bowerとは
簡単な説明。
Bowerとは、一言で言うとフロントエンド用のパッケージ管理ツールです。
npmと同じようイメージで、npmはNodeで使うモジュールを管理するのに対して、bowerはフロントエンドで使うライブラリ（パッケージ）を管理するツールです。一回設定ファイルを作っておけば、一発で自分がいつも使うライブラリが取得できますので、便利だな〜って思ってます。
それで、bowerでインストールするモノがnpmでインストールできたりしますが、そのあたりは自分の環境にあった方法でインストールするといいです。
自分は、npm→ビルド用、bower→フロントで必要なライブラリ取得、で使ってます。

## 2. 初期設定
では使ってみましょう。まず初期設定。
と、初期設定の前に、bowerを使うには、Node.jsが必要です。
`node -v`
で、バージョンが出れば大丈夫です。

そして、bower本体をインストールしましょう。

```
npm install -g bower
```
これでインストール出来ます。念のため確認してみましょう。

```
bower -v
```

バージョンが出ればOKです。
次に、bowerの初期設定です。

```
bower init
↓
↓ // 打つといろいろ聞かれる
↓
name: My site // 自分のプロダクト名
version: 0.0.1 // プロダクトのバージョン
main: index.html // エンドポイント
...
add commonly ignored files to ignore list? (y/n): y //公開時不要になるファイルをリストに追加するかどうか
```

と、いろいろ聞かれますが、ある程度で大丈夫です。
enter押下で、bower.jsonが出来上がると思います。
このbower.jsonが設定ファイルで、これからインストールするパッケージが保存されていきます。

自分は、ライブラリを取得するだけにしか使わないので、簡単に最低限の情報しか書きませんが、
もっとちゃんと使う人はしっかり書かないとダメかもしれません。（特に調べてない。。）

これで使う準備が出来ました。

## 3. インストールしてみる
せっかく準備が出来たので、何かインストールしてみます。
自分がよく使ってる、sanitize.cssというのがあるので、例としてあげておきます。
sanitize.cssは要はリセットCSSです。他にも有名なリセットCSSはあるかと思いますが、自分はよく使ってます。
良いところは特に思いつきませんが、悪いところもないので、そこが良いのかもです。。
と、まーインストールですね。

```
bower install --save sanitize-css
```

これでインストール出来ます。
--saveオプションは、bower.jsonに保存するという意味です。
--save-devオプションというのも使ったりしますが、こちらはbower.jsonには保存しないというもの。
自分は、bower.jsonを使いまわすので、保存します。
保村しておくと、

```
bower install
```

これ一発で、今まで保存してあるライブラリをインストールできるので便利です。

そして、インストールが完了すると、
bower_componentsというディレクトリが出来て、その中にsanitize-cssフォルダがあると思います。

![スクリーンショット 2017-01-27 21.05.46.png](https://qiita-image-store.s3.amazonaws.com/0/183948/7cdf9348-ff08-7a6c-ab8f-95846dfd7a5b.png)

この中にあるファイルをコピーして、自分の開発環境に取り込めば良いです。
たくさんファイルがあるのですが、そのディレクトリの中にあるbower.jsonのmain部分をみれば本体がわかります。

![スクリーンショット 2017-01-27 21.06.44.png](https://qiita-image-store.s3.amazonaws.com/0/183948/bea7ec14-e26a-3f20-c717-473e24e9a736.png)

そのファイルを読み込めば使えます。

![スクリーンショット 2017-01-27 21.10.12.png](https://qiita-image-store.s3.amazonaws.com/0/183948/c0bb63a0-6ba7-c4b3-603f-363c9291eda8.png)

もしかしたら本体だけでは使えないものもあるかもですが、基本はこれで大丈夫なはずです。


sanitize.cssに関わらず、bowerでインストールできるライブラリは、公式ドキュメントなどみるとやり方が書いてあります。どんなライブラリもほぼ同じ方法だと思うので、一回やってしまえば同じ方法でいけるはずです。
毎回使うライブラリを保存しておけば、ファイルを探す手間が減りますし、最新のバージョンを取得できるので、グッドだと思います。
エクセル日付の「数値」を python の datetime に変換する

python の xlrd などでエクセルファイルを読み込むと、エクセル上で表示されていた日付が、**41496** などの 5 桁の謎の数値に代わっている。

これは、エクセルでは日付は 1900 年 1 月 1 日を起点 (1 日目) として、そこから日数を加算した数値で日付データを保持しているためらしい。

- 例えば 2017 年 5 月 29 日では 42884 。1900 年 1 月 1 日から 42884 日経過しているらしい。
- (ちなみに 1800 年とかエクセルに入れると数値変換されない。マイナスとかにならなんだ)


この数値を python で日付形式に変換するには、timedelta を用いて次のように加算すればよい. num にはエクセルの数値を代入する

```python
def excel_date(num):
    from datetime import datetime, timedelta
    return(datetime(1899, 12, 30) + timedelta(days=num))
```

例えば、41496 を入れると、2013 年 8 月 10日の datetime が返される。

```python
excel_date(41946)

> datetime.datetime(2013, 8, 10, 0, 0)
```
Atom term3 背景いじる


##term3パッケージのインストール
` $ apm install term3 `

##背景に使用する画像の準備
背景画像
![alt](https://qiita-image-store.s3.amazonaws.com/0/181192/e568d05d-dfd9-17dd-64c7-7bb8e1479c9c.png)

##コード
~/.atom/packages/term3/stylesにあるterm3.lessを書き換える

```less:term3.less
.term3 {
  .terminal {
  background:url('https://qiita-image-store.s3.amazonaws.com/0/181192/e568d05d-dfd9-17dd-64c7-7bb8e1479c9c.png');
  background-size: 90%;
  }
}
```
##変更後
![スクリーンショット 2017-05-29 14.17.25.png](https://qiita-image-store.s3.amazonaws.com/0/181192/dcce450c-9c88-a6ad-5617-32e09f223dc9.png)
もともと真っ黒の背景のターミナルに画像を組み込んだ
画像の大きさに合わせてsizeなどいじって調節可能。
blastでヒットした配列の前後を取る

```python3
#coding: UTF-8

from Bio import SeqIO
import datetime
import subprocess
import sys
"""
使い方 
python blastget.py blastn query.fasta db.fasta num(default:0)
で走らせると以下のコマンドを実行し、ヒットした配列を取得

blastn -query query -db db.fasta -outfmt 6

numは取得する周辺配列の長さ。
num = 100 にすればヒットした配列の前後100aaを取得。
前後が100aa以下の場合は取れるだけの長さを取る
makeblastdbは入れてないので先にやっておいてください
"""

now = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")

argvs = sys.argv # コマンドライン引数を格納したリストの取得
argc = len(argvs) # 引数の個数
blast = argvs[1]
#num変数の設定
if argc > 4:
	num = int(argvs[4])	
else:
	num = 0
#blastの実行

print ("blast with following command:")
print('%s -query %s -db %s -outfmt 6 > BlastResult_%s'%(blast,argvs[2],argvs[3],now))
subprocess.call('%s -query %s -db %s -outfmt 6 > BlastResult_%s'%(blast,argvs[2],argvs[3],now), shell=True)
outputFasta = open("Output_%s.fasta"%now,"w")
#配列の取得
for line in open("BlastResult_%s"%now) :
	 #print line
	if len(line) > 2:
		ID = line.split("\t")[1]
		seqstart = min(int(line.split("\t")[8]),int(line.split("\t")[9]))
		seqend = max(int(line.split("\t")[8]),int(line.split("\t")[9]))
		index = 0
		handle = open(argvs[3], "rU")
		for record in SeqIO.parse(handle, "fasta"):
			 if record.id == ID:
				 if seqstart < num and seqend > len(record.seq)-num:
					 outputFasta.write( ">"+record.id +"\n" )
					 outputFasta.write( str(record.seq ) +"\n" )
				 elif seqstart < num:
					 outputFasta.write( ">"+record.id +"\n" )
					 outputFasta.write( str(record.seq[0:seqend + num] ) +"\n" )
				 elif seqend > len(record.seq)-num:
					 outputFasta.write( ">"+record.id +"\n" )
					 outputFasta.write( str(record.seq[seqstart-num:] ) +"\n" )
				 else:
					 outputFasta.write( ">"+record.id +"\n" )
					 outputFasta.write( str(record.seq[seqstart-num:seqend + num]) +"\n" )
		handle.close()
outputFasta.close()
 
```
サーチコンソールで構造化データエラーでたときの対処

サーチコンソールで構造化データエラーでたときの対処。
headタグ内に以下を記述する。

```php
<?php if(is_single()||is_page()) { ?>
<?php while (have_posts()) : the_post(); ?>
<script type="application/ld+json"> {
"@context": "http://schema.org",
"@type": "BlogPosting",
"mainEntityOfPage":{ "@type":"WebPage", "@id":"<?php the_permalink(); ?>" },
"headline": "<?php the_title();?>",
"image": {
"@type": "ImageObject",
"url": "ロゴのURL.jpg",
"height": 696,
"width": 696 },
"datePublished": "<?php the_time('Y/m/d') ?>",
"dateModified": "<?php the_modified_date('Y/m/d') ?>",
"author": {
"@type": "Person",
"name": "<?php the_author_meta('nickname'); ?>" },
"publisher": { "@type": "Organization",
"name": "<?php bloginfo('name'); ?>",
"logo": {
"@type": "ImageObject", "url": "ロゴのURL.jpg",
"width": 250,
"height": 60 }
},
"description": "<?php echo mb_substr(strip_tags($post-> post_content), 0, 60); ?>…" }
</script>
<?php endwhile; ?>
<?php } else { ?>
<?php } ?>
```
～ながら


**意味**　
　　　動作の並行を表わす。**vừa** làm A, **vừa** làm B
　
**接続** 　Vマス形＋ながら
        
## :anchor: **ポイント**　
* Dùng để mô tả 2 hành động diễn ra đồng thời, có cùng chủ ngữ. 
* Nhấn mạnh hành động phía sau.
 
1. 大学時代、勉強し**ながら**、アルバイトをやりました。
   Thời đại học tôi **vừa** học **vừa** làm.
   
2. 運転し**ながら**、タバコを吸うのはやめろう。
   Hãy bỏ cái vụ hút thuốc **trong khi** lái xe đi nhé.

## :briefcase: **ビジネスメモ**
　Trong văn viết hay văn business, người ta dùng dạng formal hơn của `～ながら` là `～つつ`
 
```ex:ex 
　森林は現在破壊されつつある
　Cây rừng đang bị phá hoại dần.
```

## :white_flower:  練習

①　体に悪いと知りながら、酒を（　　　）人が多い。	
>:one: やめたい　　　:two: やめている 　
>:three: やめられる　　:four: やめられない 

②　有能なA君のこと（　　　　）、きっといい仕事をするだろう。
>:one: ながら　　　:two: にして 　
>:three:だから 　　　:four: にせよ

②　今日は時間がありません。あいさつは（　　　　　　）さっそく会議を始めましょう。
>:one: 抜きにして　　:two:抜きながら 　
>:three:抜いても 　　　:four:抜きつつ
xargsコマンドの備忘録

# はじめに

基本的にManを読めばいいのですが、Linux(GNU)とmacOS(BSD系)で微妙にオプションが違ってハマったり、実際どうなるの？ という用例が有ると嬉しいことがあるので、このページにまとめることにしました。

随時、加筆予定。

# 動作環境について

- macOS ... 2020年5月現在はMojaveを使ってます。
- Linux ... 同Ubuntu 18.04LTSを使うことが多いです。

# オプション

Linux, macOSどちらでも使えるもの:

 オプション | 効果
----------|-----
 `-L {number}` | 引数を最大何行ずつ処理するか。後述
 `-n {number}` | 引数を最大何個処理するか指定する
 `-t` | 実行するコマンドを出力する

## `-L {number}`

- 何行ずつ処理するか
- `-n {number}` だとスペースで分かれている単語も別と換算するけど、 `-L` だと引数が行単位になる。N行ずつ処理したい、という場合に使う

LinuxとmacOSで微妙にManの説明が違うのですが、同じ挙動のようで、よく読むとまあ同じことを書いているような気もします。
macOSのManだと `-n` と同時に指定はできないとあるのですが、LinuxのManでは書いてない。

```bash:使用例
# Linux & macOS
% seq 1 5 | xargs -L2 echo
1 2
3 4
5
% seq 1 5 | xargs -L2 echo | xargs -L2 echo
1 2 3 4
5
```

# 参考

- [Man page of XARGS - GNU](https://linuxjm.osdn.jp/html/GNU_findutils/man1/xargs.1.html "Man page of XARGS")
- [xargs - FreeBSD Manual Pages](https://www.freebsd.org/cgi/man.cgi?query=xargs&amp;apropos=0&amp;sektion=0&amp;manpath=FreeBSD+8.0-RELEASE&amp;format=html "xargs")
OSS時代の学び方とお金

研修などを考えるときに，ずっと感じていたことを書き出してみた．
何か特別新しいことを書いている訳ではないけど，何かしらコンテンツを投下しようとしている人やこれから何か学び始めようとしている方の参考になると，良いように思っている．

なお，自身でフリーソフトウェアやOSSを開発した人の学び方ではなく，誰かが作ったフリーソフトウェアやOSSを学ぶ人のお話なので留意ください．

## OSS時代の学び方とは

* もうン十年も前からフリーソフトウェアやOSSを組み合わせた開発になっている
* フリーソフトウェアやOSSは "**しょっちゅうリリース**" される
* どこでその "しょっちゅう" に自身の知識やスキルをアプデするかで，コストの種類や金額も変わるよね，というお話
    * 書いているうちに，OSS時代だろうが何だろうが一緒に思えてきた

## 学びはじめるタイミングで学習者をタイプ分け

イノベーター理論で学習を例えると，スッとまとまったので，これで学習者をタイプする．

1. イノベーター
    * これ便利だから使ってこうぜ，と初めて言う人
1. アーリーアダプター
    * イノベーターに触発されて趣味開発を始めたり，一部プロダクションで使ってみる人
    * ↑ で培った知見を広める人
1. アーリーマジョリティ
    * 社内のプロダクトやシステムで本採用になったので，身につける必要が出てきた人
1. レイトマジョリティ
    * 業界(??)標準となったので，身につける必要が出てきた人
1. ラガード
    * アプデしないで，いまの自身の知識とスキルに固執する人

## 学習者が "何で" 学ぶのかで傾向分け

学習者のタイプと同じように，イノベーター理論に沿って，学習者が "何で" 学ぶのかをまとめると，コストの内容がスッとまとまった．

1. イノベーター
    * 論文，その分野のトップカンファやGitHub，OSS等のML，その分野のAuthorのブログなど一次発信で知る
    * 情報が全くない(ほとんどない)中で学習するので，無駄や地雷を沢山踏んで，無限に時間が溶ける．道なき道を走っている気分で学習する (強い。。)
    * 実質的なお金は掛からないことが多い (とはいえ渡航費とか発生。。)
    * 学習したことが無駄になることも多い
    * その分野でAuthorとなることが多い
1. アーリーアダプター
    * イノベーターの発信(ブログ，Twitter，国内カンファ，勉強会など)で知る
    * 引き続き，情報がほとんど無い中で学習するので，地雷を踏んで無限に時間が掛かるときもあるが，ある程度，無駄はなくなり，一般道(途中で曲がると，そこは未整備)を走っている気分で学習する
    * 実質的なお金はかからないことが多い (とはいえ出張費とか発生。。)
    * 学習したことが無駄になることもある
    * その分野でAuthorとなることがある
1. アーリーマジョリティ
    * イノベーターやアーリーアダプターが体系的にまとめたもの(Webメディアや雑誌の連載記事，ワークショップ，書籍など)で学ぶ
    * 情報が溢れている中で，学ぶ時間を実質的なお金で買うようになり，よく整備された一般道で走っている気分で学習する
        * 一部の学習者はなぜ学ぶのかわかっていて，整備されていることに感謝する
    * 有料で学習することが多いので，実質的なお金が掛かる
    * 学習したことが無駄になることは，ほとんど無い
1. レイトマジョリティ
    * つまづきポイントを丁寧に解説した書籍群や，スクールや会社指定の集中的な研修講座(2~3日間)などで学ぶ
    * 高速道路で学んでいるのだが，ほとんどの学習者にそんな気分はなく(先達の苦労は知らない)，やらされ感がある
    * なぜ学んでいるかは分からないケースが多いが，一部興味を持って，掘り下げる人もいる
    * 相応のお金も時間も掛かる
    * 学ぶものが枯れきっていて，generalな知識になっていればよいが，そうでなく，すでに新しい技術が出てきていることもある (本人は気にしないことが多い)
1. ラガード
    * 会社の上司や先輩，研修部門から命じられて，ある程度，中長期(1週間～1ヶ月)の研修講座で学ぶ
    * 学生時代，新人研修など以来，これまでに登場した技術に，興味をもって学習したことが無いため，アプデするのに膨大な時間がかかる
    * 相対的にべらぼうにお金と時間が掛かる
    * 学習することに無駄はなく，学習し始めたことに価値がある
    * やれされ感しか無く，講座期間中は苦痛の連続で，出席したことに価値を見出すことが多い
 
## まとめ

時間とお金は払うコストなので，意識すると，自分がどう取り組むかが分けられそうだなぁ，ということと，何らかコンテンツを企画するとき，対象となる技術がどのフェーズにあるのかで取り組み方やアウトプットも変わるなぁと思っている．

なお今，私自身はアーリーマジョリティの情報をもとにプロダクト開発にまつわるものを学習していて，巨人の肩に上に乗っている．感謝しかない．
RaspberryPi Zero Wのワイヤレスセットアップ


Pi Zero W を手に入れたのでセットアップしました.
USBキーボードを持っていないのでSSH経由でセットアップしました.

環境は以下の感じです.

- macOS
- Raspberry PI Zero Wireless
- Micro SDカード
- SDカードが読み書きできるもの(自分の場合Mac Book自体にあった)
- 無線LAN

## TL;DR

ブート用のSDカードに以下を書き込む(`/Volumes/boot`にマウント済み)

```bash
touch /Volumes/boot/ssh
cat > /Volumes/boot/wpa_supplicant.conf <<EOF
network={
  ssid="xxxxxx"
  psk=xxxxxxxxxxxxx
}
```

## Boot用のMicro SDカード作成

RASPBIAN JESSIE LITEのイメージをSDカードに書き込みます.

- [Raspberry PiにRaspbianをインストールする for Mac OSX - Qiita](http://qiita.com/ttyokoyama/items/7afe6404fd8d3e910d09)

その後、macOSにSDカードを抜き差しすると
`/Volumes/boot`にマウントされます.
以降の操作はmacOS上でマウント済みとして説明します.

## SSHの有効化

RaspbianはデフォルトではSSHは無効化されています.
とは言っても有効にするとは簡単で`ssh`ファイルを置くだけです.
このファイルの有無で起動時にSSHが有効になります.

```shell
touch /Volumes/boot/ssh

```

- [SSH (Secure Shell) - Raspberry Pi Documentation](https://www.raspberrypi.org/documentation/remote-access/ssh/README.md)

## Wi-Fiの有効化

SSHを有効にしてもPi Zero Wでは有線LANがないため無線LANの設定をする必要があります.

[Raspberry PIの公式サイト](https://www.raspberrypi.org)では`wpa_supplicant.conf`を用意する必要がるのですが、`wpa_passphrase`コマンドを使った方法がりますがmacOSでは入っていないため自分で作成する必要があります.

必要なものは接続する無線LANのSSIDとパスフレーズをメモして以下のサイトでPSKのハッシュ値を計算します.

- [WPA key calculation: From passphrase to hex](http://jorisvr.nl/wpapsk.html)

あとはSSHの用に特定の場所に`wpa_supplicant.conf`ファイルを作成します.

以下のコマンドを実行します.
`ssid`と`spk`は適宜埋めてください.

```shell
cat > /Volumes/boot/wpa_supplicant.conf <<EOF
network={
  ssid="xxxxxx"
  psk=xxxxxxxxxxxxx
}

```

- [Setting WiFi up via the command line - Raspberry Pi Documentation](https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md)
- [The latest update to Raspbian - Raspberry Pi](https://www.raspberrypi.org/blog/another-update-raspbian/)

## 起動

ここまでで起動に関する準備は完了しました.
あとはPi Zero WにSDカードをさして起動します.
miniHDMIをモニタに繋げられれば起動時にDHCPにより割り振られたIPが表示されます.ない場合はarpとかでIPを探して繋いでみましょう.

仮にIPに`192.168.1.10`が振られたとしてSSHで接続できることを確認します.
この時、デフォルトのユーザとパスワードは`pi`, `raspberry`になります.

```shell
ssh pi@192.168.1.10
```


## 起動後

とりあえずアップデートしておきます.

```shell
sudo apt-get update
sudo apt-get upgrade

```

セットアップは以上ですがSSHの接続ユーザを変えたりパスワードログインを無効にしたりとLinuxの最低限のセキュリティ周りは設定しておきましょう.
rmagickを使って画像をリサイズする


画像の大きさを設定したい、リサイズする時に使えます。
まずはGemfileにインストール。

```Gemfile
gem 'carrierwave'
gem 'rmagick'
```


```
bundle install
```
忘れないように。

## アップローダーを作成

```
rails g uploader image
```

作成されたファイルに設定を記述していきます。

```app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base 

# 保存形式をjpgに設定
process :convert => 'jpg'

#　画像の大きさを設定する
process :resize_to_limit => [300, 200]

# jpg,jpeg,gif,pngのみ設定
def extension_whitelist
    %w(jpg jpeg gif png)
  end
```

これで画像をリサイズできるようになりました。
RailsとReactをJWTで繋ぐ

# 結果
ログイン処理部分だけは作れたけど、サインアップまでは作れなかった。

# 動機

Rails と React 使って何か作りたい。React使うんだったらRailsはAPIサーバーとして動作させて、シングルページアプリケーション(SPA)としてReactを使うのがよさそう？
後々はAPIサーバーとAndroidやiPhoneのネイティブアプリのバックエンドサーバーとしても使えて、開発スピードアップを図れるやもしれない。そういう思惑がありました。

# てさぐり期

レイルズチョットデキル程度の人間なので、Reactの仕組みも良くわからないし、その周りのエコシステムも全然門外漢。そういう状態でのスタート。

どういう経緯で見つけたかは忘れたが、[Ruby on Rails on React on SSR on SPA](http://r7kamura.hatenablog.com/entry/2016/10/10/173610)というサイトに出会う。
これをまねして実行しようと試みるも、私のRailsの技術不足(?)により動かすに至らなかった。

次にルーティングはRails側とReact側でそれぞれで持ったほうがいいよねというオレオレ理論により、[react-router](https://github.com/ReactTraining/react-router) に手を出す。ルーティングはできるようになったが、肝心のログイン認証とかが良くわからない。色々調べて[ここのページ](https://gist.github.com/fdidron/ebcf52dc1ed62ff7d80725854d631a9e)に出会うも、APIサーバー側への通知処理が無かった。どうすれば。。。

# サンプル実行期

最終的に [JSON Web Tokenを使ってReactとReduxのSPAでログイン認証をする](http://qiita.com/nabeliwo/items/ac4b77324a9989e8e6bb)のページを参考に作ってみることにする。[サンプル](https://github.com/nabeliwo/jwt-react-redux-auth-example)がgithubにあがっていたので、それをまずは動かしてみる。README.mdの通りにすれば動く。Windows 上では動かなかったので、Bash on Windows 上で実行した。動いた。`server.js`がサーバーの役割をしているようだった。クライアント側は`src/sagas/auth.js`あたりかな？何しか同じホスト上でしかアクセスできないようだったので、rails側のルーティングに引っ掛けるにはリバースプロキシの力を借りる必要がありそうだった。

## nginx導入

nginx をフロントにおいて、ルートディレクトリにアクセスされたときはjs側に流し、/api/* にアクセスされたときはrails 側に流すという設定だけをしてデーモン起動。

## Rails サイドの JWT

Rails サイドでJWTを作成するには、[nsarno/knock](https://github.com/nsarno/knock)がよさそうだった。README.md と [KnockでRails APIモードでJWT認証してみる](http://qiita.com/kiyodori/items/3b7817af7d16bcc8f7dd) を参考に設定した。

## サンプルを修正

`knock`がJWTを作成するのに必要なJSONの形式が`jwt-react-redux-auth-example`で生成するJSONの形式と異なっていたので、生成するJSONの形式を修正。といってもauth{}でラップして、emailとpasswordに直すだけだけど。修正したコードは[こちら](https://github.com/bamchoh/jwt-react-redux-auth-example)
フォークして作っちゃってるから、もやもやしてる。オリジナルの作者がわかるような形でフォークじゃなく、新しくgitリポジトリを作成したほうがいいかも。

## Docker compose でまとめる。

サーバーが3台立ち上がってるので、Docker compose でまとめる。結果は[こちら](https://github.com/bamchoh/dockerfiles/tree/master/fbook)
これもgitリポジトリのまとめ方が下手なので、ちゃんとしたい。

# 今後の課題

Signupフォームからユーザーを登録して、自動ログインできるような仕組みがほしい。React力が足りず、そこまではできてない。
Ruboty を slack の Reminder: に反応させる

slack には cron のようなリマインダー機能がある。こいつを登録しておく事で、定期的に slackbot が

```
Reminder: @name 登録メッセージ...
```

といった発言をさせることが出来る。

## Ruboty に反応させたい

Ruboty は標準の正規表現では、上記メッセージに反応しない。

- https://github.com/r7kamura/ruboty/blob/master/lib/ruboty/action.rb#L4

実装は固定で

```
module Ruboty
  class Action
    def self.prefix_pattern(robot_name)
      /\A@?#{Regexp.escape(robot_name)}:?\s+/
    end
```

となっているので、それらを変えてしまう。(-l でロード時のスクリプトに追加等々)

```
require 'ruboty/action'

module Ruboty
  class Action
    def self.prefix_pattern(robot_name)
      /(?:\A|\s)@?#{Regexp.escape(robot_name)}:?\s+/
    end
  end
end
```

これで `Reminder: @name xxx` に反応する。

## 綺麗なやり方

場当たり的な方法じゃ無く、ちゃんとしたAPIを作ってPRを送ろう！
Alibaba Cloud RAMでサポート問い合わせのポリシーを作る

## はじめに
[Alibaba Cloudの日本サイト](https://jp.aliyun.com)ではテクニカルサポートが回数制限なく利用できるのは魅力的なポイントの１つです。
デフォルトで用意されているRAMのポリシーセットでは、テクニカルサポートに問い合わせをするにはアドミン権限をつける必要があります。
しかし、実際の運用現場では、RAMのサブユーザにアドミン権限は与えたくないが、サポートの問い合わせは行ってほしいケースはよくあると思います。

本記事では、アドミン権限を付与することなく、テクニカルサポートを行う権限を付与する方法を紹介します。

## そもそもRAMとは
RAMとはAlibaba Cloud上のユーザとそのアクセス権限を管理するサービスです。AWSでいうとIAMと似たようなサービスといえます。
RAMを利用することで１つのアカウントを複数人チームで利用することができるようになります。
また、Webサーバ運用チームはECSサービスだけ、DBサーバチームはRDSサービスだけ操作できるする、などのユーザやグループごとの操作できる権限を管理できるサービスです。

### 参考
- [RAM(Alibaba Cloud 公式プロダクトページ)](https://jp.aliyun.com/product/ram)
- [[Alibaba Cloud] RAMによる権限管理とAutoScalingによるサービス継続性の実現](https://www.slideshare.net/sbcloud/alibaba-cloud-ramautoscaling)

## カスタムポリシーの作成
まず、テクニカルサポートを行うことのできるポリシーを作成します。
RAMではJSONフォーマットでポリシーを作成することができます。

下記から作成画面にいくことができます。
<img width="600" alt="スクリーンショット 2017-05-29 9.54.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/259/036788a7-a1f4-d392-3c00-873b6b2af61e.png">

作成画面にて「空白テンプレート」を選択し、ポリシー内容に下記の内容を記述します。
これで準備は完了です。
<img width="600" alt="スクリーンショット 2017-05-29 9.56.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/259/fdc583fd-3a1a-b90e-5886-febd804a5227.png">

```
{
  "Version": "1",
  "Statement": [
    {
      "Action": "support:*",
      "Resource": "*",
      "Effect": "Allow"
    }
  ]
}
```

## ポリシーの付与
上でポリシーの作成が完了したら、そのポリシーを適応したいユーザあるいはグループに付与するだけです。
わたしの場合は、権限は基本的にグループで管理しているので、対象のグループに対してポリシーを付与します。

<img width="600" alt="スクリーンショット 2017-05-29 9.59.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/259/116c9253-364c-4f0f-aafe-bda212f235a2.png">
<img width="600" alt="スクリーンショット 2017-05-29 9.59.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/259/c4567090-b7db-0791-48d7-74ca05c267fd.png">
Bluemix PaaSのサービスで ベアメタル他を一元監視する方法のメモ

Bluemix のサービスを利用して、Bluemix Infrastructure の ベアメタルや他のサーバーを一元監視する方法についてのメモです。　実施したい事のイメージは次の様なものです。

![スクリーンショット 2017-05-29 11.31.42.png](https://qiita-image-store.s3.amazonaws.com/0/42829/febb6238-e5d8-2229-eae5-1c88fe856aa6.png)


# New Relic のサービス利用
New Relic は Bluemix のカタログに登録されている サードパーティのサービスです。これは、Bluemix のアカウントがあれば、Bluemix からオーダーして利用資格を取得し、請求関係はIBMから一括で実施されるというビジネスモデルのサービスです。 New Relic とは？ という部分は [New RelicでBluemixをモニタリングしてみた](http://qiita.com/asasaki/items/e327634df62e79667a98) を参照してください。

Bluemix のポータル https://console.ng.bluemix.net/ にログインして、カタログの中から、New Relic を探してクリックすると、次の様な画面が表示されます。 このサービスの説明だけを見ると、違うと思って、次へっとなるのですが、なんか大人の事情もあるかもしれません。このサービスで、他社も含めてサーバーの監視を実現する事ができます。 しかも、無料から始められるので、すぐに評価を開始できます。

![スクリーンショット 2017-05-29 9.49.08.png](https://qiita-image-store.s3.amazonaws.com/0/42829/df8d0ef2-367e-4e52-00c6-b399da97a3e5.png)

# サービスの選択

サービス利用のための一連の画面を進んだ後に、次の様な画面が表示されます。 ここで次の画面が出るので **INFRASTRUCTURE** を選択して、次の画面に進みます。 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/42829/c5496952-9a4f-ddf5-41cb-d959846f4b8a.png)

そして、次の画面の一番上のラインのメニューで、**SERVERS** を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/42829/88832862-8e6b-e391-8aca-21419b2cae22.png)

Linux と Windows が選択でき、Linux のディストリビューションごとに、インストール方法が案内されているので、Bluemix Infrastructure のベアメタル・サーバーにログインして、エージェントをイントールします。

以下に、CentOS6.9 ベアメタルでの導入例を紹介します。

1. New Relic のリポジトリを追加します。

~~~
[root@server1 ~]# rpm -Uvh https://download.newrelic.com/pub/newrelic/el5/i386/newrelic-repo-5-3.noarch.rpm
~~~
2. 監視のエージェントをインストールします。

~~~
[root@server1 ~]# yum install newrelic-sysmond
~~~
3. ライセンスキーをインストールします。 このラインセンスキーは、Bluemix からログインしていくことで、ウェブ画面に表示されます。

~~~
[root@server1 ~]# nrsysmond-config --set license_key=****************************************
~~~
4. エージェントを起動します。

~~~
[root@server1 ~]# /etc/init.d/newrelic-sysmond start
Starting newrelic-sysmond:                                 [  OK  ]
~~~


5. インストールが完了すると、５分程度経過すると次第に測定結果が表示される様になります。
![スクリーンショット 2017-05-29 10.57.59.png](https://qiita-image-store.s3.amazonaws.com/0/42829/2c97b4c4-bb59-57f6-4764-6ce7bd2d785c.png)


# タイムゾーンの設定
グラフの時間軸の表示が、US時刻になっているので、日本時間に変更します。 画面右上のアイコンをクリックしてメニューを表示します。 ここで、Account Settings にタイムゾーンの機能があります。

![スクリーンショット 2017-05-29 11.01.45.png](https://qiita-image-store.s3.amazonaws.com/0/42829/a91f6698-6a8e-010d-f71d-800901abf0d9.png)

アカウント設定画面の下の方で、Host Usage Report の部分で、Tokyo を指定することで、グラフやイベントの時間が日本時間表示に切り替われいます。
![スクリーンショット 2017-05-29 12.01.53.png](https://qiita-image-store.s3.amazonaws.com/0/42829/d7ed19ab-4f90-39b5-8544-d8fa4ff58eeb.png)


# アラート通知設定
次のスクリーンショットのAlertから、閾値超え時のアラート設定ができる様になっています。 

![スクリーンショット 2017-05-29 10.24.48.png](https://qiita-image-store.s3.amazonaws.com/0/42829/238525a4-bea4-047d-0d6e-0a477f0dd78f.png)


# まとめ
簡単に使い始められて、Bluemix だけでなく、他社クラウドを含めて利用できる点で、表示便利と思います。



# 参考資料
* [New RelicでBluemixをモニタリングしてみた（インフラ編）](http://qiita.com/asasaki/items/e327634df62e79667a98)
* [New Relic Documentation](https://docs.newrelic.com/)![uploading-0]()
Nginx の limit_req/limit_conn を特定の条件でのみ適用する/しない

# limit_req の使い方 (基本)

```
http {

  ...

  limit_req_zone $binary_remote_addr zone=zone1:1m rate=5r/s;

  server {

    ...

    location = /some/application/path {
      limit_req zone=zone1 burst=5;

      ...

    }
  }
}
```

上記の例では、/some/application/path へのリクエストについて、毎秒5リクエストの割合に制限している。

`limit_req_zone` は http ブロックにしか記述できない点に注意が必要。

# limit_req の適用を特定の条件に絞る

## 以下は間違い

```
http {

  ...

  limit_req_zone $binary_remote_addr zone=zone1:1m rate=5r/s;

  server {

    ...

    location = /some/application/path {
      if ($http_user_agent ~* "android.*mobile") {
        limit_req zone=zone1 burst=5;
      }

      ...

    }
  }
}
```

[ngx_http_limit_req_module#limit_req](http://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req) に書かれているとおり、`limit_req` ディレクティブは if ブロックに書けない。

## 正しい例

```
http {

  ...

  limit_req_zone $limit_req_key zone=zone1:1m rate=5r/s;

  server {

    ...

    location = /some/application/path {
      limit_req zone=zone1 burst=5;
      if ($http_user_agent ~* "android.*mobile") {
        set $limit_req_key $binary_remote_addr;
      }

      ...

    }
  }
}
```

http ブロックに記述した `limit_req_zone` の第一引数 (key) を、`$binary_remote_addr` から `$limit_req_key` に変更している。そして、`$limit_req_key` を if ブロックの中で set している。ここがミソで、`limit_req_zone` で指定する **key が空 (値なし) の場合は、制限がかからない**のである。[ngx_http_limit_req_module#limit_req_zone](http://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_zone) に書かれている。

> The *key* can contain text, variables, and their combination. Requests with an empty key value are not accounted.

Requests with an empty key value **are not accounted**. とは英語のネイティブでない私には意味がわかりにくかったのだが、要するに「...の場合は制限が適用されない」と解釈した。

逆に特定の条件で制限を適用**しない**場合は、以下のようにすれば良いだろう。

```
    location = /some/application/path {
      limit_req zone=zone1 burst=5;
      set $limit_req_key $binary_remote_addr;
      if ($http_user_agent ~* "android.*mobile") {
        set $limit_req_key "";
      }
```

なお、本項では limit_req で説明したが、[limit_conn](http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html) でも全く同様のはずである。
raspberry pi で、MCP23017 の入力ポートを使う smbus版

```py3:mcp23017_smbus.py
#! /usr/bin/python3
# -*- coding: utf-8 -*-
#
#	mcp23017_smbus.py
#
#					May/29/2017
#
# ----------------------------------------------------------------
import sys
import smbus
#
# ----------------------------------------------------------------
sys.stderr.write("*** start ***\n")
CHANNEL   = 1
ICADDR    = 0x20
REG_IODIR = 0x00
REG_GPIOB = 0x13
#
bus = smbus.SMBus(CHANNEL)
bus.write_byte_data(ICADDR, REG_IODIR, 0xff)
#
bus.write_byte_data(ICADDR, 0x0d, 0xff)
#
value = bus.read_byte_data (ICADDR,REG_GPIOB)
sys.stderr.write("value = %x\n" % value)
#
sys.stderr.write("*** end ***\n")
# ----------------------------------------------------------------
```
LoopBackフレームワークでCSV出力API実装

モデルにCSV出力のremote methodを付けてみた。

- Streamな感じに出力したい
- シフトJISな文字コードで出力したい

という点はおおむね達成できたが、[csv](https://www.npmjs.com/package/csv)と組み合わせるとうまく動作しなかったのが心残りだ。
StreamとシフトJIS変換はiconv-liteさまさま。さらにcsvなモジュールでstreamにpipeでうまく処理できるとパーフェクトなのだが。

```js:common/models/note.js
'use strict';
const iconv = require('iconv-lite');
module.exports = function(Note) {
  // サンプル用にModelのfindの代わり
  function find(filter, cb) {
    cb(null, [
      {id: 1, date: new Date(2017, 4, 26), name: 'ラーメン', price: 600},
      {id: 2, date: new Date(2017, 4, 27), name: 'カツ丼', price: 700},
      {id: 3, date: new Date(2017, 4, 28), name: '唐揚げ定食', price: 800},
    ]);
  }

  Note.csv = function(filter, cb) {
    find(filter, function(err, list) {
      if (err) return cb(err);

      const stream = iconv.encodeStream('Shift_JIS');
      cb(null,
        stream,
        'text/csv; charset=shift_jis',
        'attachment; filename=note.csv'
        );

      for (const item of list) {
        const line = ['id', 'date', 'name', 'price'].map(function(key) {
          return item[key];
        }).join(',') + '\n';
        stream.write(line);
      }
      stream.end();
    });
  };

  Note.remoteMethod('csv', {
    accepts: {arg: 'filter', type: 'string', http: {source: 'query'}},
    returns: [
      {arg: 'body', type: 'file', root: true},
      {arg: 'Content-Type', type: 'string', http: {target: 'header'}},
      {arg: 'Content-Disposition', type: 'string', http: {target: 'header'}},
    ],
  });
};
```

remote methodをLoopBack API Explorerからたたくと、charset付けていてもutf-8に変換されるのは仕様なのだろうか？
HTMLファイルにform作ってpostしてみると、こちらからはちゃんとシフトJISでダウンロード出来るので良しとする。

## 日本語のファイル名でダウンロードさせたい場合

「日本語.csv」のようなファイル名は、レスポンスヘッダを少し変えて、次のようにする。

> Content-Disposition: attachment; filename*=utf-8''%E6%97%A5%E6%9C%AC%E8%AA%9E.csv

filename=ファイル名はブラウザによって対応方法が異なるため、
`"attachment; filename*=utf-8''" + encodeURIComponent('日本語.csv')`
と、filename*=utf-8''URLエンコードしたファイル名を付けると良さそうです。

## モデルのリレーション先も含める場合

findメソッドで、filter引数のincludeプロパティを使うとリレーションも含めた結果がもらえる。
※ただし、結果のリレーション部分のプロパティはFunctionで、もうひと手間toJSON()をかけてやらないとアクセスできないので注意。
参考：[https://loopback.io/doc/en/lb3/Include-filter.html#access-included-objects](https://loopback.io/doc/en/lb3/Include-filter.html#access-included-objects)

## より汎用的に

モデルのdefinition.rawPropertiesを参照すると、汎用的な処理にできそうです。
mixinにしてしまえば、他のモデルへのCSV出力API追加もさくっと対応できますね。
Delphi の疑似フレンド

# 疑似フレンド化

[Unit Friend](http://qiita.com/pik/items/9eaab2395a276fb9035f) の続きです。

# クラスの継承
当然ながら Delphi はクラスを継承できます。

```delphi
type
  TFoo = class
  protected
    FBar: String;
  end;

  // Foo を継承
  // Protected メンバーの FBar にアクセス出来る
  TBaz = class(TFoo)
  end;
```

## Unit Friend を悪用？しよう
前の記事で Unit Friend で、private / protected なメンバーは同一ユニット内からアクセス出来ると紹介しました。
ここで、クラスの継承と組み合わせると…

protected メンバを持つ TFoo クラスを定義して

```delphi:unit1.pas
type
  TFoo = class
  protected
    FBar: String;
  end;
```

TFoo を継承したクラスを定義すると

```delphi:unit2.pas
uses
  unit1;

type
  TOpenFoo = class(TFoo) 
  end;

var
  Foo: TFoo;
begin
  Foo := TFoo.Create;

  // キャストするとアクセスできちゃう！
  Writeln(TOpenFoo(Foo).FBar);
end.
```

Unit Friend の機能があるため、**キャストしただけで protected メンバーにアクセス出来ちゃう！！**


## 疑似フレンド

```delphi
type 
  TOpenXXX = class(XXX) end;
```

として定義されたクラスを用いて protected メンバーにアクセスする技を「疑似フレンド化」というみたいです。
偽物の友情っぽくていいですね！！

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/pik">@pik</a> <a href="https://twitter.com/ktz_alias">@ktz_alias</a> メーリングリストの過去ログを読んでいたら「擬似 friend 化」という言い回しがあって、わりとしっくりきました。</p>&mdash; suno (すの) (@suno88) <a href="https://twitter.com/suno88/status/867273072386101248">2017年5月24日</a></blockquote>

なお、通例として疑似フレンド化させるクラスは Open を頭に付けるようです。
VCL 等のライブラリ内部でもよく使われるテクニックなので、ドッタンバッタン大騒ぎしなくても安心して使えます。

# まとめ
電車の中とかで、Delphi の話をしているときに「疑似フレンド化」なんて言葉が出てきたら、一般的な用語である「親が子を殺す」等と相まって、大変殺伐とした印象を与えられてグッドだと思いました。
Error (use-package): exec-path-from-shell :init: Expected printf output from shell, but got: "" に遭遇したら...


# 6/10 追記

6/10 現在、 homebrew でインストールされる fish のバージョンが 2.6.0 になったので、この問題は発生しなくなりました。
よかった、よかった :smile:

```console
$ brew info fish
fish: stable 2.6.0 (bottled), HEAD
User-friendly command-line shell for UNIX-like operating systems
https://fishshell.com
/usr/local/Cellar/fish/2.5.0 (864 files, 6.4MB)
  Poured from bottle on 2017-05-28 at 00:02:45
/usr/local/Cellar/fish/2.6.0 (886 files, 6.7MB) *
  Poured from bottle on 2017-06-06 at 11:57:13
/usr/local/Cellar/fish/HEAD-352cea1 (878 files, 6.9MB)
  Built from source on 2017-06-06 at 11:55:48
/usr/local/Cellar/fish/HEAD-9236e27 (878 files, 6.9MB)
  Built from source on 2017-05-29 at 11:09:18
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/fish.rb
==> Dependencies
Required: pcre2 ✔
==> Caveats
You will need to add:
  /usr/local/bin/fish
to /etc/shells.

Then run:
  chsh -s /usr/local/bin/fish
to make fish your default shell.
```

---

macOS 上の windowed Emacs で exec-path-from-shell を使っていたら表題のエラーに遭遇。

https://github.com/syl20bnr/spacemacs/issues/4755
https://github.com/purcell/exec-path-from-shell/issues/43

を見て、config.fish 上の `eval xxxx` を `xxx | source` に変更してみたり、 exec-path-from-shell のコードをデバッグしてみたが解決せずに困っていた 😰

# エラー時の環境

| tool                 | version              | 備考                                                     |
| -------------------- | -------------------- | -------------------------------------------------------- |
| emacs-mac            | emacs-25.2-z-mac-6.4 | `$ brew install emacs-mac` でインストールしたもの        |
| fish                 | 2.5.0                | `$ brew install fish` でインストールした stable なもの   |
| exec-path-from-shell | 1.11                 | use-package 経由で melpa-stable からインストールしたもの |

# 解決方法

fish の HEAD をインストールするとあっけなく解決...

fish-shell リポジトリ上では解決したみたいだけど release 版には取り込まれてなかったみたい :cry:

```console
$ brew install fish --HEAD
```

# 情報参照元

- https://github.com/oh-my-fish/plugin-virtualfish/issues/3#issuecomment-293818951
- https://github.com/fish-shell/fish-shell/issues/3809

# 今回の教訓

本家の Issue はちゃんと隅々まで読みませう。
raspberry pi で、MCP23017 の入力ポートを使う popen版

```py3:mcp23017_input.py
#! /usr/bin/python3
# -*- coding: utf-8 -*-
#
#	mcp23017_input.py
#
#					May/29/2017
#
# ----------------------------------------------------------------
import sys
import time
#
from subprocess import Popen,PIPE
#
# ----------------------------------------------------------------
# [4]:
def i2c_set_proc (command):
	try:
		p1 = Popen(command,shell=True,stdout=PIPE,stderr=PIPE)
		stdout_data, stderr_data = p1.communicate()
	except Exception as ee:
		sys.stderr.write("*** error *** in i2c_set_proc ***\n")
		sys.stderr.write(str (ee) + '\n')
#
# ----------------------------------------------------------------
# [6]:
def i2c_get_proc (command):
	rvalue = ""
	try:
		p1 = Popen(command,shell=True,stdout=PIPE,stderr=PIPE)
		stdout_data, stderr_data = p1.communicate()
		rvalue = stdout_data.decode('utf-8')
	except Exception as ee:
		sys.stderr.write("*** error *** in i2c_get_proc ***\n")
		sys.stderr.write(str (ee) + '\n')
#
	return	rvalue
# ----------------------------------------------------------------
sys.stderr.write("*** start ***\n")
command = "i2cset -y 1 0x20 0x01 0xFF"
i2c_set_proc(command)
#
command = "i2cset -y 1 0x20 0x0D 0xFF"
i2c_set_proc(command)
#
command = "i2cget -y 1 0x20 0x13"
value=i2c_get_proc(command)
sys.stderr.write("value = " + value + "\n")
#
sys.stderr.write("*** end ***\n")
# ----------------------------------------------------------------
```
Fluent Designメモ、まとめ

# Fluent Design
複雑な世界を、わかりやすく、かつユニバーサルに表現することを目指しているのがFluent Design
## 概要
主要項目や何を目指しているかはここに書いてある
http://fluent.microsoft.com/
chromeで見るとなんか崩れるので、それ以外のブラウザ推奨
## 詳細
簡単にまとめる
実際のコーディング例、グラフィックなどは各ページにある
### Acrylic material
https://docs.microsoft.com/ja-jp/windows/uwp/style/acrylic  
depthの概念をapp内に持ってくるときに使う
ページの頭にも書いてあるが、大きく変更される可能性があるので注意

利用用途はapp内のNavigtationやメニューなど背景と溶け込ませたいものに使う
詳細画面とかには使わない

### Connected animation
https://docs.microsoft.com/ja-jp/windows/uwp/style/connected-animation
Scene切り替えをスムーズに行うanimationの考え方
Scene間,View間に同じAnimationを適用することでリッチでかつ同じコンテキストに則ったユーター体験を提供できる

### Parallax
https://docs.microsoft.com/ja-jp/windows/uwp/style/parallax
ご存知Parallax
Parallaxを使うことによりDepth, 遠近感, 動きなどを感じることができる
ページの頭にも書いてあるが、大きく変更される可能性があるので注意

### Reveal
https://docs.microsoft.com/ja-jp/windows/uwp/style/reveal
Revealはアプリのインタラクションに使う照明効果（ポインタがあった場所にエフェクトつけるとか）
ページの頭にも書いてあるが、大きく変更される可能性があるので注意

オブジェクトの周囲に隠れた境界線を表示することにより、ユーザー操作に対する応答、何を操作できるのかを理解する上で役に立つ

### Design toolkit
https://docs.microsoft.com/ja-jp/windows/uwp/design-downloads/index
Fluent Designデザインテンプレート作成ツール、プラグイン
- PowerPoint
- Adobe Illustrator
- Adobe Photoshop
raspberry pi で、IOエクスパンダ　MCP23017 の入力ポートを使う

```bash
#
# Define complete Port B as IN-Port:
i2cset -y 1 0x20 0x01 0xFF
# Activate all internal pullup resistors at Port B:
i2cset -y 1 0x20 0x0D 0xFF
i2cget -y 1 0x20 0x13
#
```
参考としたページ
http://raspberrypi.link-tech.de/doku.php?id=mcp23017
pythonのunittestでExceptionがraiseされることをテストする方法


こんにちはsekitakaです。
いつまでたってもpythonビギナー感が抜けません。

今日はpythonのunittestでExceptionがraise「される」ことをテストする方法を紹介します。

```python
def test_raise_exception(self):
    with self.assertRaises(Exception):
        raise Exception('hogehoge error') # ExceptionのRaiseを期待するテストコード
```

はじめは`try`ないで`self.fail()`して、failが実行される前に`except`に飛ばなければ、テスト成功と判断しようとしたのですが、try内のfailもexceptにキャッチされてしまって、意図したテストになりませんでした。

```python:ダメコード
def test_raise_exception(self):
    try:
        raise Exception('hogehoge error') # ExceptionのRaiseを期待するテストコード
        self.fail("exceptされなかったから失敗")
    except Exception as e:
        pass
```
CSSだけでスワイプを実現する自分用メモ

# CSSだけでスワイプを実現したい

```
/*CSSで、スワイプのティップス start*/
.parentDiv {
  display: block;
  width: 100%; /*親要素は幅100%とする*/
  overflow-x: scroll;
  overflow-y: hidden;
}
.childDiv {
  display: table;
  width: 1200px; /*子要素は要素の幅合計プラスマージンプラスぐらいなので要計算*/
  border-spacing: 10px 0px;
}
.child {
  display: table-cell;
  width: 150px; /*子供は幅を指定する*/
}
/*CSSで、スワイプのティップス end*/
```

以上！
自分用メモ。
keyが存在しない場合はデフォルト値を返すDictionaryの拡張

## keyが存在しない場合はデフォルト値を返すDictionaryのメソッド
ってなんで無いんでしょうかね。

普通に、アクセスしようとすると

```csharp
var dict = new Dictionary<string,string>();
var t = dict["test"];//↑で作ったばかりなので入ってるはずもなく、KeyNotFoundException
```

この時点でnull返してくれたりすればいいのになぁ。と思わなくもないんですが。

まぁ、想像するとまだnullableが無かったころの名残なのかな。と。
stringみたいな参照型ならいいけれど、`Dictionary<string,int>`みたいに、Valueがプリミティブ型だった場合に0返したとしてそれが本当のValueの0なのか、Keyが無かったからデフォルト値の0なのかが判別つかないからかな。
いや、そもそも、参照型だとしても明示的にvalueにnull入れる場合もあるので・・・？
そう考えると無いのもしょうがないな。とは思います。が、不便なものは不便。

一応、先に`ContainsKey`でKeyの存在チェックをしたり、`TryGetValue`する。という手もあるんですが、無駄に行数はかさむし、直感的じゃなかったりするので、**ここは拡張メソッドの出番**でしょう。

## こんな拡張クラスを作っておくと便利

```csharp
public static class DictionaryExtensions {
    /// <summary>
    /// 値を取得、keyがなければデフォルト値を設定し、デフォルト値を取得
    /// </summary>
    public static TV GetOrDefault<TK, TV>(this Dictionary<TK, TV> dic, TK key,TV defaultValue = default(TV))
    {
        TV result;
        return dic.TryGetValue(key, out result) ? result : defaultValue;
    }
}
```

Dictionaryに`GetOrDefault`という名前のメソッドを拡張メソッドとして生やします。

これで、

```csharp
var dict = new Dictionary<string,string>();
//var t = dict["test"];//↑で作ったばかりなので入ってるはずもなく、KeyNotFoundException
var t = dict.GetOrDefault("test");  //default値を指定しない場合はdefault(KV),KV=stringなので、stringのデフォ値のnullがtに入る

var t2 = dict.GetOrDefault("test2","入ってなかったよ");  //default値を明示的に指定した場合は、keyが存在しない場合にそれが使用される。
```

と、なり、みんなハッピーです。


###2020/01/27追記
C#7.0 から `out var(out変数宣言)` が使えるので、上記 `TryGetValue` はさらに簡略化して書けるようになります。
(詳しくは→ [TryGetComponentとout、out var のお話](https://qiita.com/divideby_zero/items/c976160a7457a2b0f1e6) などをどうぞ（ダイマ

```cs
public static class DictionaryExtensions {
    /// <summary>
    /// 値を取得、keyがなければデフォルト値を設定し、デフォルト値を取得
    /// </summary>
    public static TV GetOrDefault<TK, TV>(this Dictionary<TK, TV> dic, TK key,TV defaultValue = default(TV))
    {
        return dic.TryGetValue(key, out var result) ? result : defaultValue;
    }
}
```

単行になりました。　なら、こうも書けますね。(ついでにdefaultの書き方も変更)

```cs
public static class DictionaryExtensions {
    /// <summary>
    /// 値を取得、keyがなければデフォルト値を設定し、デフォルト値を取得
    /// </summary>
    public static TV GetOrDefault<TK, TV>(this Dictionary<TK, TV> dic, TK key,TV defaultValue = default) => dic.TryGetValue(key, out var result) ? result : defaultValue;
}
```

まぁ、（多分）速度に違いはないのであとは見やすさ、わかりやすさ。そして場合によってはチームの規約に従うしかないのでTPOに応じて適切なものを使いましょう。
ではでは。
SQLServer: 動的管理ビュー同士の関係を把握する

SQLServerで、動的管理ビュー(DMV)を使って情報を取得するとき、それぞれのDMVをどうやってJOINしたら良いか分からず、ググッて見つけたクエリをそのまま流す日々でした。
もちろんググッて見つけたクエリも正しい事がほとんどですが、中には結果が明らかにおかしいことも。。。

DMV同士の関係性を知ることができれば、
・ググッて見つけてきたクエリの妥当性の検証や修正、拡張
・ゼロベースでのDMV使用クエリの構築
等に使えそうです。探したところ、2008, 2012でそれらしきものが見つかりました。

SQLServer 2008 System Views Map
https://www.microsoft.com/en-us/download/details.aspx?id=9301

SQLServe 2012 System Views Map
https://www.microsoft.com/en-us/download/details.aspx?id=39083

早速、前から使っていたけど、結果が怪しいクエリを検証してみました。

下記のクエリは、現在実行中のクエリを、実行時間が長い順に100件取得するクエリです。
強力だな～とよく使っているのですが、結果が怪しいときがありました。
（出典：http://www.carehart.org/blog/client/index.cfm/2015/2/10/show_running_sql_server_queries）

```sql
--修正前
select top 100
   dest.text as [Command text]
  ,der.total_elapsed_time / 1000.0 / 60 as 'total_elapsed_time' --min
  ,DB_NAME(der.database_id) as DatabaseName
  ,der.command
  ,des.login_time
  ,des.[host_name]
  ,des.[program_name]
  ,der.session_id
  ,SUBSTRING(dest.TEXT, der.statement_start_offset / 2, (
      CASE 
        WHEN der.statement_end_offset = - 1
          THEN LEN(CONVERT(NVARCHAR(MAX), dest.TEXT)) * 2
        ELSE der.statement_end_offset
      END - der.statement_start_offset
      ) / 2) as current_running_stmt
--  ,qp.* -- プランもみたいときはコメント外す
from sys.dm_exec_requests der
inner join sys.dm_exec_connections dec on der.session_id = dec.session_id
inner join sys.dm_exec_sessions des on des.session_id = der.session_id
cross apply sys.dm_exec_sql_text(sql_handle) as dest
--cross apply sys.dm_exec_query_plan(plan_handle) as qp -- プランもみたいときはコメント外す
where des.is_user_process = 1
--  and　dest.text like '%*****%'
order by [total_elapsed_time] desc
```

図を参照したところ、dm_exec_requestsとdm_exec_connectionsのJOINにはsession_idではなくconnection_idを使うべきであることが分かり、修正したところ、正しそうな結果が得られるようになりました。
↓こんな感じの図です。かなり情報がギュッと詰まってますが、文字列検索できるので、目的のDMVにすぐたどり着けます。

![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/148310/8be990dc-8595-50cb-5b6d-838933b0428a.jpeg)


```sql
--修正後
select top 100
   dest.text as [Command text]
  ,der.total_elapsed_time / 1000.0 / 60 as 'total_elapsed_time' --min
  ,DB_NAME(der.database_id) as DatabaseName
  ,der.command
  ,des.login_time
  ,des.[host_name]
  ,des.[program_name]
  ,der.session_id
  ,SUBSTRING(dest.TEXT, der.statement_start_offset / 2, (
      CASE 
        WHEN der.statement_end_offset = - 1
          THEN LEN(CONVERT(NVARCHAR(MAX), dest.TEXT)) * 2
        ELSE der.statement_end_offset
      END - der.statement_start_offset
      ) / 2) as current_running_stmt
--  ,qp.* -- プランもみたいときはコメント外す
from sys.dm_exec_requests der
inner join sys.dm_exec_connections dec on der.connection_id = dec.connection_id -- ←ここを修正!!
inner join sys.dm_exec_sessions des on des.session_id = der.session_id
cross apply sys.dm_exec_sql_text(sql_handle) as dest
--cross apply sys.dm_exec_query_plan(plan_handle) as qp -- プランもみたいときはコメント外す
where des.is_user_process = 1
--  and　dest.text like '%*****%'
order by [total_elapsed_time] desc
```


この図を使えば、今までよりDMVへの理解が深まると思います。