OmniAICreator/Qiita-1.07M huggingface dataset:
UIWebViewのUserAgentを独自のものに変更する

## サンプル

```swift:AppDelegate.swift
・・・
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    UserDefaults.standard.register(defaults: ["UserAgent": "Custom user-agent"])
    return true
}
・・・
```

ソースコードだけですみません...
管理者権限のないサーバでローカルに色々（zshやvim、mecab等）入れる方法

管理者権限がない（一般ユーザのアカウントを作ってもらった）サーバで自分が好き勝手にインストールしようとすると、/usr/local/binなどにインストールしようとして権限がないと怒られます。
管理者にお願いして入れてもらうのも方法の一つですが、手間がかかるのと、何か理由があって入れてもらえない場合があります。そこで、自分が欲しいものは自分のホームに入れて、そこにパスを通して見るようにしようということです。
またインストールやアンインストールの方法も書いておきます。

今回zshの例を取り上げましたが、vimやmecabでも基本は一緒で、./configureに渡すオプションはそれぞれ確認すればできます。

## 基本
ホーム（~/）に以下の2つのディレクトリを作っておく。

- **src/**
	- ソースをダウンロードしてくるディレクトリ
- **local/**
	- インストール先
	- 上記の~/src/にダウンロードしたディレクトリ内で大体 ./configure --prefix=$HOME/local を叩く

## インストール
zshでシステムに入っているのより高いバージョンをインストールする例。
まずデフォルトでどこを見てるか確認。

```
$ which zsh
/bin/zsh
$ zsh --version
zsh 4.2.6 
```

欲しいバージョンのソースを取得して解凍。
最新版はここから確認 -> [Download Page](http://zsh.sourceforge.net/Arc/source.html)

```
$ cd ~/src
$ wget https://sourceforge.net/projects/zsh/files/zsh/5.3.1/zsh-5.3.1.tar.gz/download -O zsh-5.3.1.tar.gz
# ↑ ただwgetするだけだと、download というファイル名になってしまったので-Oオプションで名前を指定してあげた
$ tar zxvf zsh-5.3.1.tar.gz
```
インストール

```
$ cd zsh-5.3.1
$ ./configure --prefix=$HOME/local --enable-multibyte
$ make
$ make install
```

パスを通しておく。
~/.bashrcなどに以下を追記

```:.bashrc
export PATH=$HOME/local/bin:$PATH
```
そして反映させて確認してみる

```
$ source ~/.bashrc
$ which zsh
~/local/bin/zsh
$ zsh --version
zsh 5.3.1
```
うまくいった

## アンインストール
```
$ cd ~/src/zsh-5.3.1
$ make uninstall
$ cd ../
$ rm -rf ./zsh-5.3.1/
```

## ソースを消してしまった場合のアンインストール
```
$ cd ~/src
$ wget https://sourceforge.net/projects/zsh/files/zsh/5.3.1/zsh-5.3.1.tar.gz/download -O zsh-5.3.1.tar.gz
$ tar zxvf zsh-5.3.1.tar.gz
$ cd zsh-5.3.1
$ ./configure --prefix=$HOME/local --enable-multibyte
$ make
$ make uninstall
```

## 参考文献
- [一般ユーザだけどzshとvimを入れたい](http://qiita.com/xeno1991/items/5db7b851d40b0787379e)
- [ソースからインストール,アンインストールのメモ](http://qiita.com/srea/items/9ebb55c4e3531c9c0b22)
AkkaのActorを増やす話

※rpscalaの発表用に作った資料です。

## はじめに
AkkaのActor使ってますか。Futureだと不足するような高度な並行並列処理をするのに便利でちょいちょい使います。

今回は同じ処理をするActorを簡単に増やすRoutingを紹介します。

## サンプル
Actorを使うときはこんな感じですね。

```scala
import akka.actor._
val system = ActorSystem()
val actor = system.actorOf(Props(new HogeActor(fuga)))
actor ! value
```

## Routing
Actorを増やして並列に処理させたいときはRoutingを使います。

```scala
import akka.actor._
val system = ActorSystem()
val actor = system.actorOf(Props(new HogeActor(fuga)).withRouter(SmallestMailboxPool(4)))
actor ! value
```

滅茶苦茶簡単ですね。

## Routingアルゴリズム
複数のActorに処理を分散するということは、割り当てのアルゴリズムを指定する必要があります。

### RoundRobin
順番に割り当て

### Random
ランダムに割り当て

### SmallestMailbox
メールボックスが一番小さいものに割り当て。ネットワーク越しのActorに対してはレイテンシが厳しいので特にそういうことはしなくて別の優先順位で決定するようだ。

### Broadcast
全体に配信

### ScatterGatherFirstCompleted
全体に配信して一番早く処理が終わったものを返す

### TailChopping
ランダムに順序を決めて、最初のActorから応答が無かったら次のActorへ処理を移す。

### ConsistentHashing
Hash関数を使って、同じValueは同じActorで処理するように分配する

## 公式
詳しくは公式を見ましょう。

http://doc.akka.io/docs/akka/2.4/scala/routing.html
最後に実行したコマンドを繰り返す

読み取り専用レジスタ `@:` を使う．

```
@:
```

直前のコマンドを100回実行したい時は

```
100@:
```

で良い．普段のマクロ実行と同様，一度 `@:` で実行するとその後は `@@` で繰り返せる

```
@@
```
UETorchをWindowsで動かしてみる

ディープラーニングのフレームワークであるTorchをゲームエンジンのUE4から扱うためのプラグインにUETorchというものがあります。ディープラーニング界隈はLinuxが標準なのですが、今回はゲーム開発者が普段使用しているWindowsでUETorchを動かしてみようと思います。

# 必要なもの
- **Visual Studio**    
無料版のVisual Studio Communityで大丈夫です。
- **Git**
- **Conda**    
パッケージ管理システムです。CondaにはAnacondaとMinicondaがあります。全部入りのAnacondaを入れておけば問題ないですが、結構時間がかかるので時間がない人はMinicondaでも大丈夫です。

# Torch
以下のリポジトリをクローンしてください。
https://github.com/torch/distro.git

面倒くさいからと言ってZIPでダウンロードしてはいけません。このリポジトリはTorch本体を含む関連パッケージをGitのサブモジュールの形で保持しているので、ZIPではこれらがダウンロードされずインストールに失敗します。

クローンが完了したら、コマンドプロンプトでそのフォルダまで移動して以下のコマンドを実行します。

```bat
set TORCH_LUA_VERSION=LUA52
install.bat
```

```Installation succeed!```
の表示が出ればインストール完了です。

インストールが失敗するときの原因で一番多い（かつ厄介）のがコンパイルエラーだと思います。masterブランチは絶えず更新がされているので一部の環境でコンパイルが通らないコードが存在することがあります。さらに、Windowsにインストールしようという人は稀有な存在なのでこのような問題があっても放置されがちです。かといって、エラーが出ないことが保証されたリリース版のようなブランチやタグもなさそうなので、エラーが出たらそれより前のリビジョンにしてみたりコードを読んで自分で直したりしなければなりません。私は71219a0043ff8d902888f089d57123cf1f1e9d0aのリビジョンをクローンして、pkg\torch\lib\TH\vector\AVX.c の \_\_AVX\_\_ を USE_AVX に変えることでコンパイルできました。

インストールが完了したらテストを実行して正常にインストールできているか確かめましょう。

```bat
install\torch-activate
test.bat
```

# Unreal Engine 4
言わずと知れたゲームエンジンです。環境構築に関してはいろいろな記事がありますので、ここでは割愛します。注意点としては、バイナリをダウンロードするのではなく、GitHubからソースコードをクローンしてこないといけないということです。2017年4月現在でUETorchが公式にサポートしているのはUE4.13です。

# UETorch
リポジトリは以下になります。
https://github.com/facebook/UETorch.git

UETorchはLinuxをターゲットとして開発されているため、Windowsから使うには少し変更が必要です。ですが、私がWindowsにインストールしたときに対応したものが、ありがたいことに公式のリポジトリにマージされたので、現在はLinuxと同様の手順でインストールできるようになっています。

1. 上記リポジトリをUE4のプラグインフォルダにクローンします。    
    - 例：```git clone https://github.com/facebook/UETorch.git Engine/Plugins/UETorch```
    - 後述するプロジェクトのプラグインフォルダに置くことも可能ですが、その場合は手順２のバッチファイルは使えないので、バッチファイルの内容を手でやってください。
2. ```UETorch/Setup.bat```を実行してください。バッチファイルではパッチの適用とジャンクションの作成をしているだけです。バッチファイルの実行前に、Torchのインストールフォルダにあるtorch-activate.cmdを実行しておく必要があります。

# チュートリアル
ここまででインストールは完了したので、簡単なサンプルを動かしてみましょう。まずは、GenerateProjectFiles.batでソリューションを作成し、Visual Studioを使ってビルドしておいてください。

エンジンを起動する前に、Torchのインストールフォルダにある**torch-activate.cmd**とUETorchのインストールフォルダにある**uetorch_activate.bat**を実行しておく必要があります。これらで環境変数の設定をしているので、実行しておかないとスクリプトが見つからないなど正常に動かない原因になります。

あとは公式リポジトリのREADMEを参照してプロジェクトの作成、コンポーネントの追加と進めてください。

すべてが完了したら「新規エディタウィンドウ」で開始してみましょう。以下のような画面が出て、キャラクターがブロックのほうへ移動すれば成功です。
![uetorch_example.png](https://qiita-image-store.s3.amazonaws.com/0/173259/a73f14c7-58db-4787-d888-1712b9f2bdfa.png)
‪データの集計ではsort | uniq -c をシェル芸で良く使うけど大量データには向かないのでawkでもっと高速な処理を書く‬

```sort | uniq -c``` という操作は、データの集合から件数を数えるのによく使いますね。

uniq はデータから重複データを取り除いたり、重複したデータだけを取り出したり、あるいは件数を数える、という処理ができるコマンドですが、実行時の前提条件として予めソートされたデータが必要です。だから先に sort しています。

しかしデータの母集団が大きいと sort の処理時間がボトルネックとなって、数分単位のオーダーで処理待ちが起きることがあります。そのような場合に ```sort | uniq -c``` とは違う方法で集計を行えば、処理速度を大幅に改善できる可能性があります。

## 例：1から1000までのランダムな値の集合1億件について、値ごとの件数を集計してみる

例えば1から1000までのランダムな値の集合1億件のデータを以下のように作成したとして……

```bash
# 試験データの作成（1～1000のランダムな数値の集合を１億件作る）
kinoue@ubuntu1604LTS:~$ seq 100000000 | awk 'BEGIN{ srand('"$RANDOM"')  } { printf "%d\n", rand() * 1000 }' > randomvalue.txt
```

これを単にsortしてuniqすると、手元の環境では1分20秒台で処理が完了しました。


```bash
# sort | uniq -c は速くない
kinoue@ubuntu1604LTS:~$ time cat randomvalue.txt | sort | uniq -c > /dev/null

real    1m25.391s
user    1m22.904s
sys     0m1.188s
```

ただし今回は数値の集合なので、sortの条件を変えたら約20秒の短縮ができました。

```bash
# 今回の試験データは数値だけの集合なので、sort -n | uniq -c で速度改善可能
kinoue@ubuntu1604LTS:~$ time cat randomvalue.txt | sort -n | uniq -c > /dev/null

real    1m3.361s
user    0m54.528s
sys     0m1.248s
```

## 事前にsortするのがボトルネックなので、それを止める方法を考える

結局、sort の方法を変えれば時間短縮できるということは、これがボトルネックであることを意味します。しかしそもそも sort と uniq を組み合わせるのではなく、連想配列やハッシュ配列、ディクショナリ型などを用いた実装で代替すれば、より高速に処理できる余地があります。

今回の例はawkのスクリプトで```sort | uniq -c```の処理を置き換えてみましたが、これだと約20秒で処理が完了しました。1分以上の時間が掛かっていたようにくらべると、とても高速になりました。

```bash
# 今回作成したスクリプトを使えば、sort | uniq -c よりも高速に処理が行える
kinoue@ubuntu1604LTS:~$ time cat randomvalue.txt | ./uniqc.awk > /dev/null

real    0m20.089s
user    0m19.692s
sys     0m0.348s
```

## ２種類の実行結果が合致することを確かめる

このように時間は短縮できましたけど、２つの方法の実行結果が本当に一致するかどうかを検証してみましょう。

1-1000のランダムデータ１億件の結果をここで引用するのは無理なので、別の母集団として1-6の値のランダムデータ100万件を作成してみます。この実行結果を２つの方法で比較すると集計結果は全く同じであることがわかります。

```bash
# 試験データの作成（1～6の値をランダムに100万件作る）
seq 1000000 | awk 'BEGIN{ srand('"$RANDOM"')  } { printf "%d\n", 1 + rand() * 6 }' > dicevalue.txt

# sort | uniq -c の実行結果
kinoue@ubuntu1604LTS:~$ cat dicevalue.txt | sort | uniq -c
 167433 1
 166536 2
 166209 3
 166335 4
 166403 5
 167084 6

# 今回作成したスクリプトでの実行結果
kinoue@ubuntu1604LTS:~$ cat dicevalue.txt | ./uniqc.awk
167433  1
166536  2
166209  3
166335  4
166403  5
167084  6
```

# 実装例

スクリプトをファイルにするならこんな感じです。

```awk:uniqc.awk
#!/usr/bin/awk -f

{
	# 入力行を添字とする連想配列をキーバリューストアのように使ってキーの出現数を管理する
	key=$0
	value[key]++
}

END {
	# value と key をタブ区切りで全件出力する
	for ( key in value ) print value[key] "\t" key
}
```

ワンライナーならこんなふうに書けます。スマホのメモアプリとかに転記しておけば、自分の管理下にない環境のようにスクリプトファイルをインストールしづらい状況でも使えます。

```bash
kinoue@ubuntu1604LTS:~$ cat dicevalue.txt | awk '{ v[$0]++ } END { for ( k in v ) print v[k] "\t" k }'
167433  1
166536  2
166209  3
166335  4
166403  5
167084  6
```
「キャッシュのせいです」とは言わせない！更新されたファイルだけ確実にキャッシュを無効化させる方法

「キャッシュのせいです。」「スーパリロードお願いします。」だなんて二度と言わない、言わせないために。

### 条件
- 基本はキャッシュを有効にしたい
- ファイル更新があった場合、そのファイルだけキャッシュを無視したい

### 前提知識
リクエストするファイルが同じでも、パラメータが異なると、違うファイルと認識されてキャッシュは無効化されます。

```
// 下記二つは別ファイルとして認識される
style.css?20170403
style.css?20170404
```

このパラメータを、ファイル更新があったときに、どうにかして自動更新したいわけです。


# 方法1：ファイルの最終更新日をパラメータに

PHP関数「[filemtime()](http://php.net/manual/ja/function.filemtime.php)」を使い、そのファイルの最終更新日を取得してパラメータとします。

```html:index.php
<link rel="stylesheet" href="/css/style.css?<?= filemtime('css/style.css'); ?>">
```

まさにタイトル通りのことが実現できていそうなものの、この関数には注意点があります。

> 注意: この関数の結果は キャッシュされます。

またもやキャッシュ。。

つまり、実際にはファイルが更新がされていても、この関数で返される結果にすぐに反映されない可能性があるようです。

実際に試しみてます。

### 実験1

下記スクリプトを実行→ファイルを編集→もう一度実行、してみる。

```php
<?php 
echo filemtime('ファイル名');
```

すると、特にキャッシュされている様子はなく、filemtime()の結果がファイル編集前後で正常に変化しました。

### 実験2
次に下記スクリプトを実行。
一度のスクリプト内で実験1と同様のことを行い、最後の行で結果が変わったかどうかを比較しています。

```php
<?php 
$old = filemtime('ファイル名');
file_put_contents('ファイル名', 'hoge');
$new = filemtime('ファイル名');
var_dump($old == $new);
```

するとtrueが返ってきてしまいました。
（＝ファイルを変更したにもかかわらずfilemtime()の結果に反映されない！）

実験1と実験2の結果から、**一度のスクリプト内の実行に関してのみ**filemtime()の結果がキャッシュされてしまい、ファイルに更新があってもfilemtime()の結果が古いままになるようです。

### 実験3（おまけ）
下記のように、全然関係ない別のファイルに対するfilemtime()の実行をはさんでみると、、

```php
<?php 
$old = filemtime('ファイル名');
filemtime('別のファイル名'); // ←追加
file_put_contents('ファイル名', 'hoge');
$new = filemtime('ファイル名');
var_dump($old == $new);
```

結果はfalse。
最後に実行したfilemtime()の結果だけがキャッシュされるみたいです。

### 結論
filemtime()の結果はキャッシュされると言っても、一度のスクリプト内に限った話なので、

```html:index.php
<link rel="stylesheet" href="/css/style.css?<?= filemtime('css/style.css'); ?>">
```

のような使い方をする分には特に問題なさそうです。

# 方法2：gitのコミットハッシュをパラメータに

最初にfilemtime以外でなんとかしようと考えた末の苦肉の策。
gitのコミットハッシュをパラメータにつけてみました。

```php:どっか
<?php 
function getCommitHash($file) {
	return exec('git rev-parse --short :'.$file);
}
// ↑ユーザー入力を引数に渡したらダメゼッタイ
```

```html:index.php
<link rel="stylesheet" href="/css/style.css?<?= getCommitHash('css/style.css'); ?>">
```

exec関数使いたくないし、gitに依存するのも気持ち悪いです。
方法1が問題ないとわかった以上、こっちを選ぶ理由はありません。
Scala勉強始めました。５

##前回までの知識（プラスα）で、カレンダーを作って行こうと思います。

参考サイト様
カレンダー関係

- http://qiita.com/f81@github/items/1e72244cdac7ea512bbb
- http://www.geekpage.jp/programming/c/leap-year.php
- http://d.hatena.ne.jp/gallu/20090112/p2
- http://www.ne.jp/asahi/hishidama/home/tech/scala/def.html#h_return

Android Studio関係

- https://www.slideshare.net/saturday06/abc20141221


##難しい。
何が一番難しいかというと、環境構築でした。
環境構築に時間がかかりすぎて、まだまともにカレンダーのコードなんてかけてない・・・

とりあえず手順を。

試した環境

- MAC Sierra

1,Android Studioの用意
・https://developer.android.com/studio/index.html?hl=ja
ここを参考にインストールまでこぎつけてください。
開発するandroid端末によってSDKのバージョンが変わってくるみたいです

2,Scalaの用意
・https://www.scala-lang.org/download/
ダウンロードして、任意（でいいんでしょうか）の位置に解凍してください。

3,AndroidStudioとScalaを合体（？）させる

- Android Studioを開いて、上部にあるPreferenceからPluginsを探し当てる。
![Screen Shot 0029-04-05 at 0.06.19.png](https://qiita-image-store.s3.amazonaws.com/0/172678/d7869a04-375d-df7c-31bf-3d06fa480131.png)
![Screen Shot 0029-04-05 at 0.06.35.png](https://qiita-image-store.s3.amazonaws.com/0/172678/c990dff8-e24c-6711-005c-37e7075cda81.png)

- Scalaを入れた記憶のない人はプラグインをインストールする
![Screen Shot 0029-04-05 at 0.06.49.png](https://qiita-image-store.s3.amazonaws.com/0/172678/652afe39-2051-8bbf-d2cf-679d236f06c2.png)
真ん中のBrowse repositoriesボタンから・・・
![Screen Shot 0029-04-05 at 0.07.10.png](https://qiita-image-store.s3.amazonaws.com/0/172678/842d692e-c6ba-4f1f-58bf-a003525ad382.png)
上部の検索ボックスに"Scala"って入れて写真のプラグインを探す。（写真はインストール済み）
![Screen Shot 0029-04-05 at 0.10.41.png](https://qiita-image-store.s3.amazonaws.com/0/172678/09355bef-9a2e-3f5f-a628-9ef9bdd95ed4.png)
上の写真は全く関係のないプラグインですが、写真のような緑のボタンが"Scala"のところにもあるので、これをクリックしてインストールします

- Scalaを有効にする

![Screen Shot 0029-04-05 at 0.14.12.png](https://qiita-image-store.s3.amazonaws.com/0/172678/3a13d7c7-4244-d46c-db3f-bd46b7e559a2.png)
Android Studioから、新しいプロジェクトを作成したら、早速.scalaファイルを作成していきます。
これで準備ができた。かと思いきや、おそらくファイルのエディター画面上部にエラー的なものが表示されると思います。
焦らず右上ったへんにあるsetup Scala SDKを探しましょう
![Screen Shot 0029-04-05 at 0.18.08.png](https://qiita-image-store.s3.amazonaws.com/0/172678/d0c5bb47-40b7-a6f0-95bd-e339dc7cf0de.png)
右上の青文字。
これをクリック
![Screen Shot 0029-04-05 at 0.19.22.png](https://qiita-image-store.s3.amazonaws.com/0/172678/82cbdeba-efdf-e3b1-34b6-c1428c45ec97.png)
Use libraryにエラーが出てるかと思うので、横のCreateボタンを押して、さっきダウンロードと解凍したScalaのファイルを探します![Screen Shot 0029-04-05 at 0.19.56.png](https://qiita-image-store.s3.amazonaws.com/0/172678/7a89e6ce-a214-990f-b42e-8543c071548d.png)
名前が入ってる部分を消してあります。
.jarファイルが詰まってるファイルを選択してOKを押すと、
![Screen Shot 0029-04-05 at 0.19.22.png](https://qiita-image-store.s3.amazonaws.com/0/172678/cb6b5a37-fd36-6b4f-dbec-b9e656232c51.png)
こうなります。
もう一回OKを押してこれでAndroidStudioでScalaのコードを書くことができるようになりました。

##まとめ
大変でした。
次回から、コードを書いてければいいな・・・。
ほとんど参考サイト様に書いてあるけど、自分でやってみました。
お手軽Firebase Codelab を Google Cloud Shell で試す時のメリット・落とし穴と解決策

https://codelabs.developers.google.com/codelabs/firebase-web/
今回のネタはこちら

[Firebase](https://firebase.google.com/)はお手軽で素晴らしいんだけど，買収先である[Google Cloud Platform](https://cloud.google.com/)との連携がまだ不十分な部分もある（現在急速に強化中．parse.comのように潰されることもなさそうな印象）
[Google Cloud Shell](https://cloud.google.com/shell/)（ブラウザ上で手軽に叩けるコマンドライン）で上記コードラボを試すと，そのままではつまづく場所がいくつかあったのでメモ
~~（まぁ連携云々ほどの話でもないし，Cloud Shellを理解しているなら問題ない内容）~~

#メリット
環境構築不要
ログインも不要かも？
　初期状態でどうかは確認しそこねた

#落とし穴と解決策
## [#4](https://codelabs.developers.google.com/codelabs/firebase-web/#3) `firebase login`
そのまま実行すると，指示されたURLをブラウザで開いてauthした後にlocalhostに誘導されて死ぬ
`firebase login --no-localhost`
と入力すること

## [#5](https://codelabs.developers.google.com/codelabs/firebase-web/#4) `firebase serve`
デフォルトのポート5000はファイアウォールで塞がれている（多分）
`firebase serve -p 8080`
と入力し，Cloud Shell左上の一番左のアイコン ＞ ポート上でプレビュー 8080 を選択

## [#6-](https://codelabs.developers.google.com/codelabs/firebase-web/#5) `firebase serve`再び
（Cloud Shellに限った話ではない）
`scripts/main.js`をいじる時に
`cd scripts`
とかしていると，あとで
`firebase serve`
した時にブラウザで`Cannot GET /`とだけ出て死ぬ
カレントが`web-start`ディレクトリであることを確認すること
どこのディレクトリであっても↓のように言ってくるので，ぱっと見ややこしい

```shell-session:stdout
Starting Firebase development server...

Project Directory: /home/<project_no_namae>/friendlychat/web-start
Public Directory: ./

Server listening at: http://localhost:8080
```

## [#6](https://codelabs.developers.google.com/codelabs/firebase-web/#5) Authリダイレクトドメイン
このページを最後まで進めると，Authを試した時に一瞬窓が開くがすぐ閉じて使えない
Cloud Shellの提供するURL`8080-dot-XXXXXXX-dot-devshell.appspot.com`が登録されていないのが問題
Firebaseのウェブコンソール ＞ Authentication ＞ ログイン方法 ＞ OAuthリダイレクトドメイン から登録する

## [#11](https://codelabs.developers.google.com/codelabs/firebase-web/#10) database-rules.json
（Cloud Shellに限った話ではない）
全部書き換えよう
よく見ると3行目にも追加されてる
~~つまりちゃんと読め~~

　

一部飛ばしたので，まだあるかもしれない
他にもつまづいたかたいたら報告お願いします
あるいはわかりづらかったら言ってください
　
　
　
###ついでに補足
[#4](https://codelabs.developers.google.com/codelabs/firebase-web/#3) の`firebase use --add`内でalias設定がある
プロジェクトを簡単に切り替えられるようになるステキ機能
（でも開発・本番環境をプロジェクトで分ける場合，Realtime DatabaseとかStorageとかは一工夫要る）
（参考：[FirebaseをStaging環境とかDebug環境とかRelease環境で切り替えをする(Webアプリ編)](http://qiita.com/fullkawa/items/dee3754ba243970c37c7)）
GitLabのメジャーバージョンアップグレード方法（8~11対応）


[インストール記事はこちら](http://qiita.com/boiyaa/items/20a4fd0cc79f7d3b4a56)

本記事はOmnibus GitLab Community EditionをDocker Composeでインストールしている場合のアップグレード手順です。
それ以外の方法でインストールしている場合は[From 8.17 to 9.0](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/8.17-to-9.0.md)、[From 9.5 to 10.0](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/9.5-to-10.0.md)、[From 10.8 to 11.0](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/10.8-to-11.0.md)をご覧ください。


## Step 1. コンテナを停止する
```sh
$ docker-compose stop
```

※ バックアップしたい場合はコンテナ停止前にしてください。

```sh
$ docker exec -t <container name> gitlab-rake gitlab:backup:create
```

バックアップ対象をスキップすることもできます

```sh
$ docker exec -t <container name> gitlab-rake gitlab:backup:create SKIP=db,uploads,repositories ,builds,artifacts,lfs,registry,pages
```
参考: [Creating backups for GitLab instances in Docker containers](https://docs.gitlab.com/omnibus/settings/backups.html#creating-backups-for-gitlab-instances-in-docker-containers)

さらにバックアップファイルをホスト側にコピーしたい場合は以下を実行してください。

```shell-session
user@host ~ $ docker exec -t <container name> ls /var/opt/gitlab/backups
1491273987_gitlab_backup.tar
user@host ~ $ docker cp <container name>:/var/opt/gitlab/backups/1491273987_gitlab_backup.tar .
```


## Step 2. イメージをpullする
```sh
$ docker-compose pull
```

※ バージョン固定している場合はpullする前にdocker-compose.ymlのイメージタグを編集してください。
メジャーバージョンをまたぐ時は1.x.xずつ増やした方がよさそうです。
最新のタグ名を[こちら](https://hub.docker.com/r/gitlab/gitlab-ce/tags/)で確認してください。

```yml:docker-compose.yml
-    image: gitlab/gitlab-ce:8.17.0-ce.0
+    image: gitlab/gitlab-ce:9.0.0-ce.0

-    image: gitlab/gitlab-ce:9.5.0-ce.0
+    image: gitlab/gitlab-ce:10.0.0-ce.0

-    image: gitlab/gitlab-ce:10.8.0-ce.0
+    image: gitlab/gitlab-ce:11.0.0-ce.0
```

## Step 3. コンテナを再生成して起動する
```sh
$ docker-compose up -d
```

## 以上

※ 8.xから9.0でCI変数名が変わっているのでご確認ください。

| 8.x                | 9.0+                  |
| ------------------ | --------------------- |
| CI_BUILD_ID        | CI_JOB_ID             |
| CI_BUILD_REF       | CI_COMMIT_SHA         |
| CI_BUILD_TAG       | CI_COMMIT_TAG         |
| CI_BUILD_REF_NAME  | CI_COMMIT_REF_NAME    |
| CI_BUILD_REF_SLUG  | CI_COMMIT_REF_SLUG    |
| CI_BUILD_NAME      | CI_JOB_NAME           |
| CI_BUILD_STAGE     | CI_JOB_STAGE          |
| CI_BUILD_REPO      | CI_REPOSITORY_URL     |
| CI_BUILD_TRIGGERED | CI_PIPELINE_TRIGGERED |
| CI_BUILD_MANUAL    | CI_JOB_MANUAL         |
| CI_BUILD_TOKEN     | CI_JOB_TOKEN          |

https://docs.gitlab.com/ce/ci/variables/#9-0-renaming
ES2015で追加された分割代入

##分割代入の一例


```js

let data = [1, 2, 3, 4, 5, 6, 7];

let [num1, num2, num3, num4, num5, num6, num7] = data;

console.log(num1); //1
console.log(num2); //2
console.log(num7); //7

let data = [1, 2, 3, 4, 5, 6, 7];

```

「...」演算子を利用した例

```js
let data = [1, 2, 3, 4, 5, 6, 7];

let [num1, num2, num3, ...rest_num] = data;
console.log(num1); //1
console.log(num2); //2
console.log(rest_num); //[4, 5, 6, 7];
console.log(rest_num[0]); //4

```
便利なオプション忘れていませんか？なにかと忘れがちな検索系シェルスクリプト覚え書き【find x grep】


## 前置き

ファイル内を文字列で検索かけたいときに毎回毎回微妙に間違えるので書き留めておく

## 【grep】特定の文字列を含んだファイルの検索

シンプルに grep を使った検索

-e: パターン
-n: 行番号出力
-r: 再帰処理
-w: 文字列全体でのマッチ

```bash
$ grep -nrw ./* -e 'pattern'
```

## 【find】特定の文字列を含んだファイルの検索

find の結果を標準出力で受け取って、grep に噛ませて検索

-type: 検索対象のタイプを指定
-print: 検索結果を標準出力

```bash
$ find ./ -type f -print | xargs grep 'pattern'
```

## さいごに

find コマンドの使い方すら忘れがちで、ググるたびにエンジニアやめたほうがいいと思ってる

```bash
$ find  ./* -name 'pattern'
```
[LT] 画像のぼかし処理

> チーム全体、毎週金曜日の朝、一人３分 LT をやっています。忘れないように、また日本語の勉強もしたいと思います、記事として記録します。

日本にとって、卒業の季節がもう終わった。だが、中国にとって、そろそろ卒業季節に入るようです。自分の卒業を思い出した、、、卒業論文についての記憶もよみがえている。そして、先週金曜日は卒業時の作り物の話をしました。

matlab と C++ をよく使って画像処理系のアルゴリズムを実現する。あの時、画像分析と画像処理の知識はそもそも少ないので、勉強しながら、JavaScript を使って、こういうものを作った --> [LightImage](https://lightimage.herokuapp.com/) 、ブラウザは進化したが、ツールはぜんぜん更新されない、バグがどんどん増えていくようです。。。ぼかし処理はまだ使えるのは幸いです。日常生活の中、ぼかし処理はよく見える。PhotoShop などのツールも簡単に画像をぼかせる。

しかし、画像ぼかしの目的は何ですか？ぼかし処理のキーは何ですか？目的の一つは、画像のノイズを軽減、もう一つは、コントラストを下げること。

これから、ピクセル単位でぼかし処理を説明したい、例えば、下に行列があり、テンプレートとして画像をぼかす：

```
[1 / 9, 1 / 9, 1 / 9,
 1 / 9, 1 / 9, 1 / 9,
 1 / 9, 1 / 9, 1 / 9];
```

RGBa は別で計算することを前提として、ある写真の一部ピクセルの R 値は以下のような：

```
[1, 2, 3,
 7, 8, 9,
 4, 5, 6];
```

上のテンプレート行列に基づいて、真ん中のピクセルのぼかし R 値を計算。テンプレートの半径は 1、各位位置の重み係数は 1、それで、8 から 5 ((1 * 1 / 9 + 2 * 1 / 9 + .. + 9 * 1 / 9) / (1 / 9 * 9)) になる。

```
[1, 2, 3,
 7, 5, 9,
 4, 5, 6];
```

でも、中心ピクセルとの距離を問わず、重み係数区別無し全部同じ、そうしたら、ぼかし効果があんまりよくないです。そして、中心との距離より重み係数も違うの**ガウシアンぼかし**を説明したい。なぜかガウシアンを付いている？実は**正規分布**と関係ある、別称は**ガウス分布**です。

![Standard_deviation_diagram.svg.png](https://qiita-image-store.s3.amazonaws.com/0/140059/7e7a61f2-eaef-a35a-c929-ad1352a671c1.png)


> Wiki: 平均値の付近に集積するようなデータの分布を表した連続的な変数に関する確率分布である。中心極限定理により、独立な多数の因子の和として表される確率変数は正規分布に従う。このことにより正規分布は統計学や自然科学、社会科学の様々な場面で複雑な現象を簡単に表すモデルとして用いられている。

Wiki より、普通な確率密度関数は：
<img width="356" alt="p0.png" src="https://qiita-image-store.s3.amazonaws.com/0/140059/46d398d0-191f-099d-b260-08f92407a5ab.png">

画像は二次元ですが、二次元確率密度関数が必要。

<img width="575" alt="p2.png" src="https://qiita-image-store.s3.amazonaws.com/0/140059/81ed3278-130a-df9b-5204-a47efbd8f7db.png">

こちらの σ は[標準偏差](https://ja.wikipedia.org/wiki/%E6%A8%99%E6%BA%96%E5%81%8F%E5%B7%AE)。

ここから、計算できました！ σ = 1 の場合、テンプレートは：

```
[0.058549833, 0.09653235, 0.058549833,
 0.09653235, 0.15915494, 0.09653235,
 0.058549833, 0.09653235, 0.058549833];
```

重み係数の合計は 1 ではないので、1 / 合計 = 1.28290053、そして、テンプレートは下のようななります：

```
[0.075113612, 0.1238414, 0.075113612,
 0.1238414, 0.20417996, 0.1238414,
 0.075113612, 0.1238414, 0.075113612];
```

最後、どうやってテンプレートを画像に適用しますか？LightImage なら、[畳み込み](https://ja.wikipedia.org/wiki/%E7%95%B3%E3%81%BF%E8%BE%BC%E3%81%BF)を使っています。:shamrock:
【初心者投稿-17】HTML&CSS初級道場コース完了！

#昨日までのおさらい
まだ何もしていないのに**伸び悩んでいる気に**なっていた笑

まずは調べながらでもいいから形にしよう！
やっぱり社会人になって勉強しても思うけど、子供の時の保護者とか学校の友達みたいな、**競えるライバル的**な人か**見守ってくれる系**の人が欲しい。

この初心者投稿ご覧頂いている方、よければ声かけてください笑
必ず返信します笑

学習においても双方向コミュニケーションは大事ですね。(甘えである、と言われたらそれまでですが)

#HTML&CSS初級道場コース完了！
昨日Progateを使った勉強は一旦お休みと言った最中。笑

やっぱり成果物を目指して作る方が気持ち的に楽ですよね笑
進んでいる気になるし、いざとなれば答え見れるし笑

#学習の記録
* サイト作り：2日目
* Progate:14日目
* 今日の勉強時間：40分
* 総学習時間：16時間55分
* 今日学んだこと：やっぱりお問い合わせフォームを作るのが好き笑　自分には独創性というか、良きUIとは何かを判断できるだけのインプットが足りないですね笑　どんなページを作れば良いのか全然わからないので
LDAP初心者の備忘録


## 前置き

なにかと認証周りで利用されているLDAP。
自分も仕事で使っているが「ユーザー情報が格納されてるんでしょ？」ぐらいの理解しかないので、
この機会に理解を深めるべく、つらつら調べたことをまとめてみる( ･`д･´)
※コマンドやファイルのパスなどは基本的に OpenLDAP で利用

## LDAPとは？

Lightweight Directory Access Protocol の略で LDAP。
名前の通りで、ディレクトリサービスにアクセスするためのプロトコル。

## ディレクトリサービスとは？

ネットワークを利用するユーザー名やマシン名など様々な情報を管理するためのサービス。
分散型のディレクトリサービスとして DNS が有名。

## ディレクトリサービスの特徴

- 読み取りが高速
- 分散型の情報格納モデル
- 高度な検索機能を持つ
- テーブル構造ではなく木構造
- 主にテキストベースの情報を扱う
- 基本的な設定項目が最初から定義されている（氏名・電話番号など）

## 代表的なディレクトリサービス

- OpenLDAP（OSS）
- NIS（Sun Microsystems = Oracle?）
- NDS（NetIQ）
- Open Directory（Apple）
- Active Directory（Microsoft）

## 用語

### LDBM
ツリー状にデータを管理するデータベース

### ベースDN
ディレクトリサービスの起点となるディレクトリ

### エントリ
ツリー状に構成される要素（データ）
実世界のオブジェクトを反映したもの

### DN (= Distinguished Name)
各エントリを一意に識別する識別名  

### 属性
エントリの関連情報

### オブジェクトクラス
属性の集合体でエントリにオブジェクトクラスを指定すると、
そのオブジェクトクラスで定義されている属性をエントリで使用できるようになる。
ユーザーが自由に作成することが可能だが、一般的に OpenLDAP に含まれる標準的なオブジェクトクラスを使用する。

### スキーマファイル
オブジェクトクラスを定義したファイル
/etc/openldap/schema に格納されている。

### LDIF (= LDAP Data Interchange Format)
LDAPのデータをまとめて処理するためのファイルフォーマット。
簡単にデータの操作が可能になる。

## LDAPサービスの代表的な属性
|属性名|定義|
|:---:|:-:|
|dc   |ドメイン名の要素（Domain Component）|
|c    |国名（Country）|
|o    |会社名・組織名（Organization）|
|ou   |部署名（Organization Unit）|
|uid  |ユーザーID（UserID）|
|cn   |氏名（Common Name）|
|sn   |姓（Surname）|
|gn   |名（Givenname）|
|mail |メールアドレス|
|loginshell|ログインシェル|
|uidNumber|ユーザーID|
|gidNumber|グループID|
|homeDirectory|ユーザーのホームディレクトリ|
|userPassword|ユーザーのパスワード|

## 参考資料
- [LDAPとは何をするもの？](https://thinkit.co.jp/free/tech/18/1/1.html)
- [ディレクトリ・サービス - Wikipedia](https://www.wikiwand.com/ja/%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%83%BB%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9)
- [LDAP の関連用語とデータ格納方式](http://www.turbolinux.co.jp/products/server/11s/user_guide/openldapdirtree.html)
- [No. 4 コマンドを使ってみる。](http://kuwalab.hatenablog.jp/entry/20080814/1218722605)
画像ファイルのmimetypeを取得する


`Photo`フレームワークを使用する。


```swift
import Photos

let photo = PHAsset.fetchAssets(withALAssetURLs: [imageURL], options: nil).firstObject

PHImageManager.default().requestImageData(for: photo!, options: nil){ data,string,orientation,hash in

        // mimetype 取得
        let mimeType: String = UTTypeCopyPreferredTagWithClass(string as! CFString, kUTTagClassMIMEType)!.takeRetainedValue() as String
}
```
GoogleOptimizeを試してみる

GoogleAnalyticsと連携し、A/Bテストや多変量テストができるという噂のGoogleOptimizeが無料で使えるらしいので試してみました。

# 前提
- テストしたいサイトに既にGoogleAnalytics（以下GA）が入っている
- GAの管理者権限を持っている

GAの権限は [こちら](https://support.google.com/360suite/optimize/answer/6376029?hl=ja#linking-to-analytics-360) にあるように、プロパティに対する編集以上の権限があればよいとのことですが、今回は管理者権限で試しました。

# セットアップ

https://optimize.google.com にアクセスすると親切にもやるべきことが右ナビに出ているのでそれを設定する。

全部完了した状態
![スクリーンショット 2017-04-04 13.31.59.png](https://qiita-image-store.s3.amazonaws.com/0/9186/ed969282-46e1-40fa-8670-c086e5a4a1f8.png)

詳細は割愛しますが、GAのプロパティとアプリに対応する概念としてコンテナがあり、コンテナ毎にIDが発行されます。
発行されたIDを

```
ga('require', '発行されたID');
```

の形式で埋め込めばよいです。
どのみちanalytics.jsを入れることになるので、GAが入っていない場合は先に導入しておくと良いかと。

# できること

ヘルプが充実しているのでそちらを参照すればだいたい雰囲気がつかめるかと思いますが、エディタで画面を弄れるのが便利だったのでそれだけ紹介します。

## Google Optimize （Chrome拡張）
<img width="1011" alt="スクリーンショット 2017-04-04 13.45.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/9186/369c353c-fbab-444d-e6a1-52a846f8ca04.png">

実際にテストを作成しようとすると、これをインストールさせられます。
このエディタを用いて、テストしたい対象をchrome dev toolの要素の検証と同じ要領で選択し、htmlの追加削除が行えます。また、htmlのidやclassによる指定もできます。

文言変更、文字サイズ調整くらいはこのツールですぐできますね。

# まとめ
簡素で恐縮なのですが、Optimizeについて紹介しました。
既にGAタグが入っているサイトであれば、テストをするまで30分もかからないと思いますので、一度触ってみると良いかもしれません。

また、A/Bテストの本質はデータによる分析なので、そこに関しても知見が溜まったらまたまとめてみようと思います。
コンパイルエラーをテストする

個人的に、TypeScriptでVueコンポーネントを(なるべく型安全に)書くためのライブラリを作っている。
という話を [この辺](http://qiita.com/wonderful_panda/items/2e4f2b12d1802144f38b) に書いた。

「型安全」というのはつまり「正しくないコードを書いたらコンパイルエラーになる」ということなので、「与えられたコードをコンパイルしたら期待通りのコンパイルエラーが発生する」というテストが必要になる。
で、そういうテストを書いてたんだけど、他所でも同じようなことをしたいケースが出てきたのでそこのところをライブラリ化した。

ソースは [こちら](https://github.com/wonderful-panda/tsc-test)

## 使い方

1. テスト用の `tsconfig.json` を作成する。コンパイル結果を出力する必要はないので、`noEmit` を指定しておくといいと思う。

    ```json:test/tsconrfig.json
    {
      "compilerOptions": {
        "target": "es6",
        "module": "commonjs",
        "noEmit": true,
        "strictNullChecks": true
      },
      "filesGlob": [
        "*.ts"
      ],
      "exclude": [
        "node_modules"
      ]
    }
    ```

2. テスト用のソースファイルを作成する。

    ```ts:test/common.ts
    export interface Payload {
        foo: string;
        bar: number;
    }

    export function dispatch<K extends keyof Payload>(name: K, payload: Payload[K]): void {
        // Do something
    }
    ```

    これは普通にコンパイルが通るはずのコード。

    ```ts:test/should-succeed.ts
    import { dispatch } from "./common";

    dispatch("foo", "value");
    dispatch("bar", 1);
    ```

    コンパイルエラーを期待するコードの場合、エラーがおきるはずの行に `////` に続けてエラーコードを記述する。`:` に続けて、期待するエラーメッセージの一部(または正規表現)を書くこともできる

    ```ts:test/should-fail-1.ts
    import { dispatch } from "./common";

    dispatch("foo", 1);            //// TS2345
    dispatch("fooo", "value");     //// TS2345: type '"fooo"' is not assignable
    dispatch("foo", 3);            //// TS2345: /'3' is not assignable .* 'string'/
    ```

    これはFailするサンプル

    ```ts:test/should-fail-2-wrong.ts
    import { dispatch } from "./common";

    dispatch("foo", 1);
    dispatch("foo", 2);     //// TS2345: type '1' is not assignable
    ```

3. `tsc-test` コマンドを実行する

    ```
    $ tsc-test -p test/tsconfig.json
    ```

    で、こんな感じに結果が出力される

    ![tsc-test.png](https://qiita-image-store.s3.amazonaws.com/0/11109/bca4235f-b1ca-1c82-7fcc-eb1c07790855.png)

## 制限事項とか
### １行に複数のコンパイルエラーが発生するケースに対応できない

想定されるエラーをインラインで書くので、１行に２つ以上エラーが出てくるとだめ。
これはまあ別にいいかなと思っている。

### `node_modules/@types` を自動で読んでくれない￥

`tsc` でコンパイルする場合は `node_modules/@types` の下にある `d.ts` を自動で読みにいってくれるのだけど、LanguageService APIでコンパイルする場合はそこまではやってくれないっぽくて、どうすればいいか調査中。
知っている方がいたら教えてください。

とりあえずは、`tsconfig.json` で明示的に `lib` を指定するとか、`lib.d.ts` に書いておくとかすれば回避できるはず。

```ts:lib.d.ts
/// <reference types="node" />
```

## TODO
- 上の `@types` の問題をなんとかする
- `--watch` の対応とインクリメンタルビルドとかやりたい
CSSで写真コントロールUIを作る

##はじめに
React+Reduxで写真コントロールUIを作成しました。
具体的には、

- マウスホイールを使ってズーム
- マウスでスクロールして見る位置を変更

できる機能を目指した。

Reactでこういう機能を実現したライブラリでは、[react-image-lightbox](https://github.com/fritz-c/react-image-lightbox)があったのですが、既存のライブラリを使うとなかなか思い通りにカスタマイズできないという悩みにぶつかり、これを参考にしつつ実装してみることに。

今回、特にこのマウスホイールのズーム操作に苦戦したので、そのとき気づいたことをまとめます。

##transformプロパティで画像をコントロール
画像を拡大、縮小させることでズームイン、ズームアウトを実現しました。
これだけなら、スタイルのwidthプロパティを変更すればできるが、マウスコントロールで画像の位置を変えられるようにするために、transformプロパティを使用。

```
transform: `translate3d(${offset.x}px,${offset.y}px,0) scale3d(${zoomRatio},${zoomRatio},1)`
```

上記のように、translate3dとscale3dをスペース区切りで指定すれば、ズームと移動を同時にできる。

##はまったポイント
- **translate()では動かない**

最初、画像を移動させる際には、translate()関数を指定したが、機能せず。
translate3d()を使ったら上手く動作しました。

- **transformOriginを使ってはいけない！！**

マウスポインタの位置を中心としてズームさせるために、transformOriginプロパティを使って、ズームの中心をマウスのホイールイベントごとに設定するようにしました。

```
transformOrigin: `${event.clientX}px ${event.clientY}px`
```

しかし、この時ズームの中心となるのは、画像の最初の位置に対するマウスポインタの座標。
一度、マウスホイールでズームした後、マウスを動かして別の位置でズームしようとすると、当然マウスポインタが指す画像上の画素は、元のサイズの時とは位置がずれているので、画像が大きくずれる羽目に！

- **transitionで指定した変化時間でパラメータが上書きされる**

先に書いたように、ズームの倍率が変わると、ズームの中心以外の位置の画素は、最初の位置からズレてしまう。
そのため、ズームと同時にズームによって生じたズレ分だけ反対方向に画像をずらして、見かけ上ズレが起きてないように見せなければならない。
しかし、transitionでアニメーションの変化時間を持たせると、その間にパラメータは更新されたが、画像のレンダリングの更新が終わらないという状態ができてしまった。
結果、連続的にマウスホイールを回すと、画像のレンダリングがパラメータの更新に追いつかず、画像が徐々にずれるようになった。

##解決策
解決策は
**ズームの中心は変えずに、ズームに合わせて画像を動かして、マウスポインタの位置が動いていないように見せる。**
transformOriginを使わなければ、常に対象レイヤーの中心を軸にしたズームになります。
対象レイヤーの中心はgetBoundingClientRect()を使えば求められるので、あとはズームの際の、マウスポインタが指す画素の移動距離を計算して補正をかければいい。


##課題
これで一通り期待通りのUIを作成できたが、やはりズームやスクロールに伴うアニメーションをスムーズにしたい。
今のところ、一回のズームの倍率を適当な値に設定してごまかしていますが、良い方法を模索したいと思います。
Capistrano3でhttps経由でソースコードをcloneする


gitのソースコードをhttpsプロトコル経由でcloneする場合には、git_http_usernameとgit_http_passwordを指定する必要があります。

**deploy.rb**

```ruby
set :repo_url, "https://my_repo.git"
set :git_http_username, "my_name"
set :git_http_password, "my_password"
```


方法はStackOverflowに記載されていました
(http://stackoverflow.com/questions/14253913/capistrano-deploy-from-git-http-repo)

が、↑の内容のままではエラーになり、ソースコードを調べたところCapistrano3では微妙にパラメータ名が変更されたようでした。

**capistrano-3.8.0/lib/capistrano/scm/git.rb**

```ruby
  def git_repo_url
	if fetch(:git_http_username) && fetch(:git_http_password)
	  URI.parse(repo_url).tap do |repo_uri|
	    repo_uri.user     = fetch(:git_http_username)
	    repo_uri.password = CGI.escape(fetch(:git_http_password))
	  end.to_s
	elsif fetch(:git_http_username)
	  URI.parse(repo_url).tap do |repo_uri|
	    repo_uri.user = fetch(:git_http_username)
	  end.to_s
	else
	  repo_url
	end
  end
```
Raspberry Piでソケット通信

#Raspberry Piでソケット通信する
　Raspberry Piでソケット通信をするためのプログラムです。サーバ側のプログラムです。

##環境
ハードウェア:Raspberry Pi 2
OS:Debian GNU/Linux 8
言語:C

##ソースコード
```C++

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>


//転送用構造体
typedef struct {
    float prm_pc_to_soc[20];		//PC→SoCへの転送パラメータ
    float prm_soc_to_pc[20];		//SoC→PChへの転送パラメータ
} Transfer_data;


int
main()
{
	int sock0;
	struct sockaddr_in addr;
	struct sockaddr_in client;
	int len;
	int sock;
	int yes = 1;

	
	//パラメータ転送構造体
	Transfer_data td_recv;
	Transfer_data td_send;
	
	//転送テスト用データ
	float send0 = 30;
	float send1 = 444;

	//ソケット作成
	sock0 = socket(AF_INET, SOCK_STREAM, 0);
	
	//ソケット作成エラーチェック
	if(sock0 < 0) {
		perror("socket");
		return -1;
	}
	
	//接続先情報設定
	addr.sin_family = AF_INET;
	addr.sin_port = htons(12345);
	addr.sin_addr.s_addr = INADDR_ANY;
	
	//ソケットのオプション設定
	setsockopt(sock0, SOL_SOCKET, SO_REUSEADDR, (const char *)&yes,  sizeof(yes));
	
	//アドレスとソケットディスクリプタを関連付け
	if (bind(sock0, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
		perror("bind");
		return -1;
	}
	
	//接続待ちに設定（acceptにて接続要求を受ける）
	if(listen(sock0, 5) != 0) {
		perror("listen");
		return -1;
	}
	
	
	//接続要求待ちループ
	while (1) {
		len = sizeof(client);
		sock = accept(sock0, (struct sockaddr *)&client, &len);
		
		//接続エラー判定
		if (sock < 0) {
			//エラー時はループを抜けて処理を終了
			perror("accept");
			break;
		}
		
		//受信用バッファ用意
		memset(td_recv, 0, sizeof(td_recv));
		
		//データ受信
		recv(sock, (void *)&td_recv, sizeof(td_recv), 0);
		
		//受信したデータを表示
		printf("recv0 = %f\n", td_recv.prm_pc_to_soc[0]);
		printf("recv1 = %f\n", td_recv.prm_pc_to_soc[1]);
		printf("recv2 = %f\n", td_recv.prm_pc_to_soc[2]);
		
		//送信データをセット
		memcpy(&td_send.prm_soc_to_pc[0], &send0, sizeof(float));
		memcpy(&td_send.prm_soc_to_pc[1], &send1, sizeof(float));
		
		//データ送信送信
		send(sock, (char *)&td_send, sizeof(td_send), 0);
		
	}
	
	//ソケットクローズ
	close(sock0);
	
	printf( "Close socket...\n" );
	
	return 0;
}
```
Raspberry PiでSPI通信

#Raspberry PiでSPI通信する
　Raspberry Piで「wiringPiSPI」ライブラリを使ってSPI通信をするためのプログラムです。8bitのデータを4回送信するサンプルプログラムです。

##環境
ハードウェア:Raspberry Pi 2
OS:Debian GNU/Linux 8
言語:C

##ソースコード
```C++
//スレッド2 SPI通信処理
#include <wiringPiSPI.h>
#include <wiringPi.h>
#include <stdio.h>

//定数定義
#define SS_PORT 22					//GPIO 22
#define SPI_CHANNEL 0					//SPIチャンネル
#define MILLI_SEC 1000000				//ms

int main(void)
{
	int i;
	int buffSize = 4;
	int speed;                                      //通信速度(Hz)
	unsigned char spi_buff[buffSize];                      //送受信用バッファ
	struct timespec req;
	
	//sleep設定
	req.tv_sec = 0;
	req.tv_nsec = 1000 * MILLI_SEC;				//sleep時間msで設定
	
	//バッファ初期化
	for(i = 0; i < buffSize; i++){
		spi_buff[i] = 0x0;
	}
	
	//SPI通信速度設定
	speed = 10000000;                               //通信速度100kHz
	
	//SPIチャンネル初期化
	if((wiringPiSPISetup (SPI_CHANNEL, speed)) < 0){
		printf("wiringPiSPISetup error \n");
		return -1 ;
	}
	
	printf("Setup SPI...\n");
	
	//GPIO初期化
	if(wiringPiSetupGpio() == -1){
		printf("wiringPiSetupGpio error\n");
		return -1;
	}
	pinMode(SS_PORT, OUTPUT);                       //22pinを出力に設定
	digitalWrite(SS_PORT, 1);                       //SS信号初期化
	
	printf("Start SPI...\n");
	
	//通信処理
	while(1){
		//送信用データをバッファにセット
		spi_buff[0] = 0x01;		//送信テスト用データ
		spi_buff[1] = 0x02;		//送信テスト用データ
		spi_buff[2] = 0x03;		//送信テスト用データ
		spi_buff[3] = 0x04;		//送信テスト用データ
		
		//SPI通信実行
		digitalWrite(SS_PORT, 0);                   //SS信号をLOW出力にして通信開始
		wiringPiSPIDataRW(SPI_CHANNEL, spi_buff, 4);             //データ送受信
		digitalWrite(SS_PORT, 1);                   //SS信号をHIGH出力にして通信終了
		
		//インターバル
		nanosleep(&req, NULL);
	}
	
	return 0;
}
```
SD Card CopyerでラズパイのSDカードを複製


## 必要なもの

- Raspbianセットアップ済みMicroSDカード（複製元）
- USB型SDカードリーダー
- 複製先のMicroSDカード

## 準備
ラズパイに複製元SDカードを挿して起動
SDカードリーダーに複製先のSDカードを装着してラズパイのUSBに挿す

## SD Card Copierを開く

アクセサリ => SD Card Copier

![スクリーンショット 2016-12-30 23.31.22.png](https://qiita-image-store.s3.amazonaws.com/0/52227/e16da868-4827-9cf6-9ca5-8a02eaa38c9c.png "スクリーンショット 2016-12-30 23.31.22.png")

## コピー先を選んでStart

Copy To Deviceにコピー先を指定する。
※今回はMulti Flash Reader(/dev/sda)になっている

![スクリーンショット 2016-12-30 23.35.39.png](https://qiita-image-store.s3.amazonaws.com/0/52227/f88c407e-6334-1240-4407-4d9e13c4857e.png "スクリーンショット 2016-12-30 23.35.39.png")

## 実行前の確認

デバイスの中身が全部消えちまうけど大丈夫かい？
的なダイアログが出るので「Yes」を選択

![スクリーンショット 2016-12-30 13.31.55.png](https://qiita-image-store.s3.amazonaws.com/0/52227/4d4b6538-132a-da11-55ea-9045cd99b6db.png "スクリーンショット 2016-12-30 13.31.55.png")

## 完了
「Copy Complete」が出れば完了。
自分の場合は5分程度で出てきた。

![スクリーンショット 2016-12-30 13.52.31.png](https://qiita-image-store.s3.amazonaws.com/0/52227/292d53b9-0cdb-53d5-7598-03fcbc42d630.png "スクリーンショット 2016-12-30 13.52.31.png")

複製先のSDカードはそのままラズパイに挿せば起動する。
wifi設定やインストール済みソフトまで複製元が丸ごとコピーされていた。
いざという時のバックアップにも使えると思う。
RedHat Enterprise LinuxのIOサイズの変動についてわかったことのまとめ

# 発端
業務上の種々の都合から、IO一回あたりのスループットを明確にする必要に駆られた。

# 勘違いしてたこと
一回あたりのIOはアプリケーションごとに固定値だと考えていた。
例えばOSが行うread/writeであれば、64KB * IOPSでスループットが算出できると思っていた。
（なぜファイルシステムのブロックサイズである4KBではなく、64KBだと思っていたのかは不明）

#勘違いに気づいた理由
iostat -dx 1の出力結果を見て、rKB/sをr/sで割ったらなぜか512KB近い値が出た。
いくつかサンプルをとったところ、どうも4KB〜512KBの間で一回のIOあたりのスループットが推移しているようだった。

# 今のところわかったこと
* Linuxの一回あたりのIOは、扱うデータサイズによって変動する。（TCP/IP通信のように、継続したIOの中でサイズが上下する）
* LinuxのIOはIO Schedulerなるモジュールが管理している。
* IO Schedulerにはいくつか種類がある。
    * noop
    * deadline scheduler
    * cfq
    * その他いろいろ
* RHEL7の場合、SATA以外のデバイスに対してはdeadline schedulerがIOの管理を行う。
* 現状どのIO schedulerを使っているかは以下ファイルをcatすることで確認可能。
  `/sys/block/sd*/queue/scheduler`
* 1IOあたりの最大値である"512KB"という値は、"max_sectors_kb"というファイルで確認可能。
  `/sys/block/sd*/queue/max_sectors_kb`
* 当初はIO schedulerにnoopを選んだときのみmax_sectors_kbが設定として有効になる認識だったが、更に調べたところ、当該設定はIO schedulerに何を選んだかに依存しないっぽい？

# 参考サイト
http://tfcenturion.hatenablog.com/entry/2015/11/07/091307
http://cromwell-intl.com/linux/performance-tuning/disks.html
http://longwhiteclouds.com/2016/03/06/default-io-size-change-in-linux-kernel/
https://martincarstenbach.wordpress.com/2013/07/03/increasing-the-maximum-io-size-in-linux/
Cloud Robotics Azure Platform V1 が試せます　～その3～

思わずシリーズ化してしまったCloud Robotics Azure Platform、第3回です。

今回が最終回となります。

<前々回>

http://qiita.com/minorungj/items/09da9143dc3b43a520d7

<前回>

http://qiita.com/minorungj/items/7c45a788ce84772973c9

前回、Tutorial 08まで進みましたので、今回はTutorial 09から最後まで進めたいと思います。

Tutorial 09：Cloud Robotics FX 上で、アプリを実行

Tutorial 10：Stream Analytics の設定

##Tutorial 09

こちらは、ハンズオン通りに進めていけば特に問題ないと思います。

終わるとPepperくんが「Hello World !」と言ってくれます！

##Tutorial 10

こちらでリアルタイム分析のハンズオンができます。

Stream Analyticsの設定をするのですが、Stream AnalyticsはAzure IoT プラットフォームを構成する機能としてとても重要でかつよくできているので、ぜひ触ってみてください！

また、Power BIも企業アカウントで無料で使えますが、簡単に可視化ができますので、こちらもおすすめです！

このブログでは補足として、Power BIの設定を解説します。

T10_10でPower BIの接続確認ができている状態からスタートします。

PowerBI左下メニューにストリーミングデータという項目があると思います。こちらをクリックします。

![image](https://qiita-image-store.s3.amazonaws.com/0/167354/fd147957-b538-d692-192c-ebfcc2a47902.png)


ストリーミングデータの一覧の中から今回作成したものを選択し、アクションのグラフマークをクリックします。

![image](https://qiita-image-store.s3.amazonaws.com/0/167354/fab4aa80-41a4-3526-00af-988924a3d3c9.png)


そうするとレポート作成画面が開きます。

![image](https://qiita-image-store.s3.amazonaws.com/0/167354/7b37b841-b55b-5708-2499-2cd4a12f88db.png)


右側の「フィールド」から必要なデータを選び、「視覚化」（使用するグラフ）を選択すると、簡単にグラフやカウンターができます。

一つやってみましょう。

「フィールド」からCounter、「視覚化」は表を選びます。すると、左側に現在の集計値が出ます。

![image](https://qiita-image-store.s3.amazonaws.com/0/167354/77bab28d-4e77-b19b-22b8-81a55fe234be.png)

グラフを作ってみましょう。

「フィールド」からCounter、視覚化はグラフを選びます。すると左側にグラフが表示されます。

![image](https://qiita-image-store.s3.amazonaws.com/0/167354/07591fa9-b3a0-3329-40ec-f51b75ffac2e.png)

複数条件のグラフも簡単にできます。

例えば、性別ごとのCounterをグラフ化するには、「フィールド」のCounterとgenderにチェックし、同じようにグラフを選びます。

![image](https://qiita-image-store.s3.amazonaws.com/0/167354/5ecf89d6-3e34-2faa-b33c-355cfb6d88ca.png)


ちなみに、このデータの元は、CloudRoboticsDefToolを起動してPepperシミュレータから送るメッセージ（Pepper Detect）の中のRbBodyの値を集計しています。こちらをいろいろいじると送られるデータが変わりますので、ぜひお試しください。

![image](https://qiita-image-store.s3.amazonaws.com/0/167354/42bba045-c838-fd6d-128d-669fdbe2ab0f.png)

これらを組み合わせると、簡単な来店者情報をリアルタイムに可視化するダッシュボードが簡単に作成できます。何度もPepper Detectを送るとリアルタイムにグラフが変化する様子が分かると思います。

![image](https://qiita-image-store.s3.amazonaws.com/0/167354/addc342f-e1ca-7088-4bb0-58be0cee0753.png)

全3回に渡りお送りしましたが、いかがでしたでしょうか。

このチュートリアルでできるのはリアルタイム可視化の箇所でしたが、とても簡単にシミュレータを動かし可視化するところまでできたと思います。

![image](https://qiita-image-store.s3.amazonaws.com/0/167354/25b566e4-e834-3d22-b980-6d0f6600723c.png)

ぜひ、皆さんで使っていただいて、Pepperくんにいろいろなことをさせてみてください！

ではでは。
UQ mobileデータ高速プラン980円でSIMフリー端末テザリング

MVNO の格安 SIM は安いけど、とくに昼や夕方は遅くて、テザリングで ssh 接続するのも
ストレスになります。最近は UQ mobile の速度が安定しているらしいので、試してみました。

結論：　端末での通信速度は快適ですが、テザリングするには端末を選びます。

| 端末 | SIMロック | OS バージョン | 4G通信 | テザリング |
|---|---|---|---|---|
| iPhone 7 Plus | SIMフリー | iOS 10.2 | ◯ | × NG |
| iPhone 6 Plus | SIMフリー | iOS 9 | ☓? | × NG |
| Huawei Mate 9 | SIMフリー | Android 7 | ◯ | × NG |
| ASUS ZenFone 2 | SIMフリー | Android 6 | ◯ | ◯ |

UQ mobile の 980円のプランでは、テザリング OK で月間 3GB まで使えて、
最低利用期間はないのが安心です。
ただし、音声通話はできないので、別の手段を用意する必要があります。

<a href="http://www.uqwimax.jp/plan/"><img width="660" src="https://qiita-image-store.s3.amazonaws.com/0/12419/3971b4ee-0ee3-11f4-f094-a2bfaf9b8b09.png"></a>

### （１） iPhone 7 Plus

iPhone 7 世代は、まだ UQ の[動作確認端末リスト](http://www.uqwimax.jp/products/mobile/sim/devices/)に載っていない端末です。
[UQmobile_2.0.mobileconfig](http://www.uqwimax.jp/support/mobile/guide/apn/ios2.html) のプロファイルをインストールすれば、
端末自体は通信できるようになりました。速度も快適です。
しかし、テザリング（インターネット共有）は ON にできません。

### （２） iPhone 6 Plus

iPhone 6 世代は、UQ の[動作確認端末リスト](http://www.uqwimax.jp/products/mobile/sim/devices/)に載っているものの、
よくみると以下の注意書きがあります。使えませんでした。

> nano SIM（専用）は音声通話付きのプランしかご利用いただけません（データ専用プランのお申し込みはいただけません）

### （３） Huawei Mate 9

こちらは、APN を設定することで、端末自体は通信できるようになりました。
みんな大好き DSDS 端末なので、docomo の音声 SIM ＋ KDDI (UQ) のデータ SIM という組み合わせも可能でした。
「NTT DOCOMO」と「KDDI」の電波を両方掴んでくれる様は、素敵です！

しかし、惜しいかな、テザリングはできませんでした。
Mate 9 が KDDI の 3G 回線に対応していないためなのか、原因不詳です。
「2G/3G/4G」でなくて、「4G Only」を選べれば、使えるようになるのかなあ。

### （４） ASUS ZenFone 2

最後に！　少し古い端末ですが、ZenFone 2 では、テザリングもできました！

混雑しそうな２１時台、MacBook からの Bluetooth テザリングでの PING 結果：

```
$ ping -c 10 www.yahoo.co.jp
PING edge.g.yimg.jp (182.22.25.252): 56 data bytes
64 bytes from 182.22.25.252: icmp_seq=0 ttl=55 time=162.892 ms
64 bytes from 182.22.25.252: icmp_seq=1 ttl=55 time=133.696 ms
64 bytes from 182.22.25.252: icmp_seq=2 ttl=55 time=121.480 ms
64 bytes from 182.22.25.252: icmp_seq=3 ttl=55 time=144.337 ms
64 bytes from 182.22.25.252: icmp_seq=4 ttl=55 time=79.879 ms
64 bytes from 182.22.25.252: icmp_seq=5 ttl=55 time=124.119 ms
64 bytes from 182.22.25.252: icmp_seq=6 ttl=55 time=123.576 ms
64 bytes from 182.22.25.252: icmp_seq=7 ttl=55 time=140.747 ms
64 bytes from 182.22.25.252: icmp_seq=8 ttl=55 time=109.580 ms
64 bytes from 182.22.25.252: icmp_seq=9 ttl=55 time=97.682 ms

--- edge.g.yimg.jp ping statistics ---
10 packets transmitted, 10 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 79.879/123.799/162.892/22.702 ms
```

手元では、Wi-Fi テザリングよりも、Bluetooth テザリングの方が安定しているようでした。

端末上の RBB TODAY SPEED TEST では、下りが 20Mbps くらい出ます。
ちゃんと端末が用意できれば、他の遅い MVNO と比べると、全然速いです。

しかし、PC テザリング時の PC 側では、下りが 1〜2Mbps くらいに落ち込みます。
家の固定回線を無くして、テザリング１本にできるような速度ではないです。（遅い）
なんでこんなに差が出るのかは不詳です。

----

（4/24追記）
省エネな Bluetooth テザリングを使っていたので、それが遅さの原因かも。
Wi-Fi テザリングを使っていれば、この数倍〜10倍くらい速かったかもしれません。
UQ mobile は既に解約してしまったので、もう再検証できません。。。
[html] inputが１つだけのフォームで入力後Enterを押すと勝手にリロードされる場合の対策

趣味でVue.jsを使ったページを作っていたら、inputをEnterすると勝手にリロードされる現象にハマったので原因と対策をメモ


# 原因

Vue.jsが原因かとおもってだいぶ調べたんですが、どうも`form`の中に`input`が１つだけだと勝手にsubmitされる仕様があるらしいです。

[【HTML】入力欄が1つだけのフォームはEnterキー押下でsubmitされる。submitボタンがなくても。 at softelメモ](https://www.softel.co.jp/blogs/tech/archives/3614?)

まったく知らなかったんですがWeb屋さんでは常識なんですかね・・・？（どういった場面で便利なのか・・・）

# 対策

以下の方法で対策できました。

対策１：formのonsubmitを無効化する
対策２：formの中の入力欄を必ず２つ以上にする（１つだけにしたい場合はダミーのinputを追加する）

```html:index.html
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>

<div id="app">
    <form>
        <!-- Enterでリロード(submit)される -->
        <input v-model="inputText" type="text">
    </form>
    <form onsubmit="return false;">
        <!-- 対策1 -->
        <input v-model="inputText" type="text">
    </form>
    <form>
        <!-- 対策2 -->
        <input v-model="inputText" type="text">
        <input type="text" style="display: none;"/>
    </form>
</div>

<script>
(function() {
'use strict';

var app = new Vue({
    el: "#app",
    data: {
        inputText: "テスト(input)"
    }
});

})();
</script>
```

# 参考
[【HTML】入力欄が1つだけのフォームはEnterキー押下でsubmitされる。submitボタンがなくても。 at softelメモ](https://www.softel.co.jp/blogs/tech/archives/3614?)
[javascript - Why does forms with single input field submit upon pressing enter key in input - Stack Overflow](http://stackoverflow.com/questions/1370021/why-does-forms-with-single-input-field-submit-upon-pressing-enter-key-in-input)
CentOS7 で仮想ネットワークを作成する

# 仮想ネットワークの作成

RDO を使用して OpenStack Ocata 版の all-in-one で構築するための仮想マシンを CentOS7 上に作成する。以下のような、仮想マシン host01 と仮想ネットワークを構成したい。まずは仮想ネットワークを設定する。

![virtualnet.png](https://qiita-image-store.s3.amazonaws.com/0/173452/1b8b248a-d39a-53f6-298b-593894006c8b.png)

'仮想化ホスト' をインストールしていなければインストールする。

```
# yum -y groupinstall "仮想化ホスト"
```


次に、パブリックネットワーク用の設定ファイルを作成する。
default の仮想ネットワークが存在しているはずなので、

```
# virsh net-list
# virsh net-dumpxml default
```

それを真似て public1.xml を適当なディレクトリ(/tmp)に作成する。
stp (スパニングツリープロトコル) は off で良いのかな？

設定ファイルは github から取得できる。
[https://github.com/syunasin/openstack/tree/master/example01](https://github.com/syunasin/openstack/tree/master/example01)

```xml:/tmp/public1.xml
<network>
  <name>public1</name>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='virbr1' stp='off' delay='0'/>
  <ip address='192.168.172.1' netmask='255.255.255.0'/>
</network>
```

ファイルを作成後、次のコマンドを実行する。

```
# virsh net-define /tmp/public1.xml
# virsh net-start public1
# virsh net-autostart public1
# virsh net-list
(リストに public1 が追加されている)
```

同じようにしてプライベートネットワーク用の private1.xml を作成する。

```xml:/tmp/private1.xml
<network>
  <name>private1</name>
  <bridge name='virbr2' stp='off' delay='0'/>
  <ip address='10.0.172.1' netmask='255.255.255.0'/>
</network>
```

ファイルを作成後、次のコマンドを実行する。

```
# virsh net-define /tmp/private1.xml
# virsh net-start private1
# virsh net-autostart private1
# virsh net-list
(リストに private1 が追加されている)
```

virbr1, virbr2 に IP アドレスが割り当てられていることを確認する。

```
# ip addr show virbr1
(192.168.172.1 が割り当てられている）
# ip addr show virbr2
(10.0.172.1 が割り当てられている）
```
tmuxからクリップボードにコピーする

#環境
Ubuntu 16.04.2 LTS
tmux 2.1
xsel version 1.2.0

※現行バージョンのtmuxはバージョンが2.9となります。この記事の情報は古いです。
※※令和版を書きました。→https://qiita.com/purutane/items/1d1dc4818013bbbaead4

#設定箇所
下記を~/.tmux.confに追記しました。

```~/.tmux.conf
set-window-option -g mode-keys vi

-bind-key -t vi-copy v begin-selection
-bind-key -t vi-copy C-v rectangle-toggle
-bind-key -t vi-copy y copy-pipe "xsel -bi"
-bind-key -t vi-copy Enter copy-pipe "xsel -bi"
```
※もともと"v"にはrectangle-toggleがバインドされているために、"C-v"にバインドを移動させています。


#使い方
1. "\<prefix> ["でコピーモードに入る
2. "v"で選択を開始
3. "y"もしくは"Enter"で選択を終了（コピー）、その結果がxselにパイプされクリップボードにコピー
4. ハッピー
PowerShellでパーセントエンコーディング

#パーセントエンコーディングとは
httpプロトコルでPOSTやGETするときにURIに使える文字が決まっています．
なので使えない文字は16進数に変換して，文字の前に%をつけることて，利用する必要があります．この変換を文字列に行うのがパーセントエンコーディングです．
#.NET Frameworkでのパーセントエンコーディング
Uri.EscapeDataString というメソッドでできることになっているのですが，version 4.0だと、RFC2396．version 4.5 だと RFC3986．それぞれ違う規約によってエンコーディングされるようです．私の環境のPowerShellの.NET Frameworkのversionは4.0なので，RFC2396にエンコードされます．しかし今回私はtwitterのAPIの利用がしたかったので,それに必要なRFC3986にエンコードする関数を制作しました．

```PowerShell::EncordString.ps1
function EncordString ([System.String]$inputstring) {
    #RFC3986でパーセントエンコーディング
    $inputchars=[System.Text.Encoding]::GetEncoding("utf-8").GetBytes($inputstring)
    #元の文字列のエンコードがUTF-8以外の場合はそのエンコードに書き換えてください．
    $encorded=New-Object System.Text.StringBuilder
    foreach($ch in $inputchars)
    {
        if((0x30-le$ch-and$ch-le0x39)`
        -or (0x41 -le $ch -and $ch -le 0x5A)`
        -or (0x61 -le $ch -and $ch -le 0x7A)`
        -or (0x2D -eq $ch -or 0x2E -eq $ch`
        -or 0x5F -eq $ch -or 0x7E -eq $ch))
        #'0'以上'9'未満
        #'A'以上'Z'未満
        #'a'以上'z'未満
        #その他使用できる文字(‘-‘, ‘.’, ‘_’, ‘~’)
        {
            [void]$encorded.Append([System.Convert]::ToChar($ch))
        }else {
            [void]$encorded.Append("%{0:X2}" -f [int]$ch)   
        }
    }
    $encorded.ToString()
}
```

#参考文献
Percent encoding parameters
https://dev.twitter.com/oauth/overview/percent-encoding-parameters
URLエンコード、URLデコードを行う
http://dobon.net/vb/dotnet/internet/urlencode.html
[C#] string(文字列)からバイト型配列 byte[] (バイナリ) に変換する
https://www.ipentec.com/document/document.aspx?page=csharp-string-to-bytearray&culture=ja-jp
Python 3.5 インストール(yum)(CentOS 6.8)


## インストール

```:
[root@localhost ~]# yum -y install centos-release-scl-rh
[root@localhost ~]# yum -y install rh-python35
```

## 動作確認

```:
[root@localhost ~]# python --version
Python 2.6.6
[root@localhost ~]# scl enable rh-python35 bash
[root@localhost ~]# python --version
Python 3.5.1
[root@localhost ~]# exit
```

## 自動有効設定

```:
[root@localhost ~]# python --version
Python 2.6.6
[root@localhost ~]# echo 'source /opt/rh/rh-python35/enable' > /etc/profile.d/rh-python35.sh
[root@localhost ~]# source /etc/profile
[root@localhost ~]# python --version
Python 3.5.1
```
Python 2.7 インストール(yum)(CentOS 6.8)


## インストール

```:
[root@localhost ~]# yum -y install centos-release-scl-rh
[root@localhost ~]# yum -y install python27
```

## 動作確認

```:
[root@localhost ~]# python --version
Python 2.6.6
[root@localhost ~]# scl enable python27 bash
[root@localhost ~]# python --version
Python 2.7.8
[root@localhost ~]# exit
```

## 自動有効設定

```:
[root@localhost ~]# python --version
Python 2.6.6
[root@localhost ~]# echo 'source /opt/rh/python27/enable' > /etc/profile.d/python27.sh
[root@localhost ~]# source /etc/profile
[root@localhost ~]# python --version
Python 2.7.8
```
ElasticsearchがOutOfMemoryで落ちた時のメモ

# バージョン
Elasticsearch 5.1.1

# やったこと
ヒープサイズ512mbで起動したElasticsearchに、10万件くらいのindexクエリを2000件ずつ非同期でPOSTした。

# OutOfMemoryで落ちる
<img width="1157" alt="スクリーンショット 2017-04-04 20.15.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/97287/b8857f4e-2b49-04f8-d7cf-b3f03c6c2625.png">

# 対処法
いろいろ調べたところ、ヒープサイズを増やすしかないらしい。
開発用のEC2(t2.micro)なので、アップグレードしたくないのでswaponすることにした。
公式ドキュメントにはスワップするなって書いてあるけど。。。
https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration-memory.html

# swapした結果
体感ではあまりパフォーマンスは変わらない。
ベンチマークとって比較してみたい。