OmniAICreator/Qiita-1.07M huggingface dataset:
3分でできるMautic公式ドキュメントの誤訳を直す方法

MauticというPHP製のOSSなMAツールのドキュメントでやってみました。

### 参考（リスペクト）
[3分でできるCakePHP公式ドキュメントの誤訳を直す方法](http://qiita.com/ishizuki/items/f0b6846ff2a9498dcad3)
[誰でも出来る有名OSSへのコントリビュート](http://qiita.com/iKenji/items/7c54461af68d3d29d7f2)

# 必要なもの
Githubアカウント
ブラウザ


# やってみる

## 事前準備
Mauticのドキュメントリポジトリの確認
https://github.com/mautic/documentation

READMEが日本語化されてるので確認
https://github.com/mautic/documentation/tree/master/jp

※GitHubの一般的な使い方が書いてあるだけで、特別なルールは無さそうです。念のため、過去のPRもいくつか見てみましたが、ノールールのゆるい感じのようです。
ただし、commitコメント等は英語で統一されていました。



### 1. 対象を探す
README上でtypoを見つけたので、まずはこれを対象にしてみます。

### 2. Forkする

<img width="1025" alt="スクリーンショット 2017-09-04 0.35.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/32169/0ec759b1-50d9-2f84-f015-f9ec241a6b96.png">

### 3. 修正する
Forkした自分のリポジトリ内で編集したいファイル（今回はREADME）を開いて、鉛筆のボタンを押します
<img width="1041" alt="スクリーンショット 2017-09-04 0.46.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/32169/b4fd9823-490e-d1c0-3713-319e0635183b.png">





もりもり編集します。
<img width="1039" alt="スクリーンショット 2017-09-04 0.51.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/32169/faf4b9a3-f814-aa7d-aacf-3d4e5f4bf418.png">
<img width="1055" alt="スクリーンショット 2017-09-04 0.51.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/32169/924bd345-5251-390d-938e-457ba6d1cb24.png">


コミットします。今回はこのままブランチを作ります。頑張って英語で書きます。
<img width="1103" alt="スクリーンショット 2017-09-04 0.53.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/32169/d7bd4ffe-36fa-fbb8-2d03-32e30f755427.png">


で、このままPR送る画面になるのですが、なぜか自分のリポジトリに対してのPRしか送れない画面になっているので、ここは一旦閉じます。

### 4. Pull Requestする
Pull Request タブから作ります
<img width="1114" alt="スクリーンショット 2017-09-04 1.05.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/32169/0cd174a6-5e62-8303-e5af-eff944413e1e.png">
<img width="1103" alt="スクリーンショット 2017-09-04 1.05.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/32169/84458ccf-ea08-62ab-04e6-89ae1418e63f.png">
<img width="988" alt="スクリーンショット 2017-09-04 1.05.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/32169/34294e40-e597-da46-48b6-f60b5c1191f4.png">



できました。
<img width="1148" alt="スクリーンショット 2017-09-04 1.05.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/32169/6f46c990-3ac0-b8bf-a00c-39c58c18e3d2.png">

### 5. マージされるのを待つ
現在待ち状態:flushed:

### おまけ

> Commits made with the web interface may expose your email address. If you'd like to keep your email private upgarade you email settings

と言われた場合は、「このままWeb上でコード編集するとメールアドレスが公開されちゃうよ」、との事なので嫌な方はリンク先から設定すると、Web上で編集しても公開されないようになるようです。
<img width="1034" alt="スクリーンショット 2017-09-04 0.47.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/32169/de447c65-306a-d828-b65c-7c5d090bf33c.png">
<img width="790" alt="スクリーンショット 2017-09-04 0.47.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/32169/8f59ac74-4e6f-e9e2-6100-f98ba2359498.png">


# まとめ
一番最初はお作法調べたりでちょっと大変ですが、実作業としては簡単でした。
気なる方は是非挑戦してみてください。
CentOS設定記録3 apacheサーバー設定編

#はじめに
[設定記録1](http://qiita.com/ka_iwashita/items/aff837a2155a47416844)：IDCFクラウド登録～ssh接続
[設定記録2](http://qiita.com/ka_iwashita/items/6c625d7d57f1323a7c8c)：ログインユーザー作成～rootのSSH接続禁止
の続き
##今回の目的
apacheでwebサーバーを建てる
独自ドメインを紐づける

##環境
- IDCFクラウドで仮想マシン作成
- お名前.comでドメイン取得
- 権威DNSはIDCFクラウドのDNSで設定

#apacheサーバー設定
```
vim /etc/httpd/conf/httpd.conf
```
```
<Directory "/var/www">
    #.htaccess無効
    AllowOverride None
    #全ユーザーアクセス許可
    Require all granted
    #index.htmlなどがない場合のドキュメント一覧表示禁止(-で禁止、+で許可）
    Options -Indexes
    #シンボリックリンクをそのままアクセス先へするのを許可するか
    Options -FollowSymLinks
</Directory>

<Directory "/var/www/html">
    #キャッシュ無効
    Header set Cache-Control no-store
</Directory>
```
```
vim /var/www/html/index.html
```
```html
<html>
<head><title>hello</title></head>
<body>
Hello world!
</body>
</html>
```


#FW設定
[コンソール](https://console.idcfcloud.com/) → コンピューティング → IPアドレスメニュー → ファイアウォール

##HTTP接続
- コメント：HTTP接続
- ソースCIDR：Any
- タイプ：HTTP

##ポートフォワード設定
[コンソール](https://console.idcfcloud.com/) → コンピューティング → IPアドレスメニュー → ポートフォワード

- コメント：HTTPポートフォワード
- パブリックポート：HTTP
- プライベートポート：80
- 仮想マシン：作ったマシン

#表示確認
http://仮想マシンに紐づけたIPアドレス へとアクセス
『Hello world!』と表示されるか確認



#ドメインの取得
1. お名前.comアカウント作成
2. 適当なドメインを取得（example.com）
 - [IDCFクラウドDNSを使用する場合は登録可能なTLDを選択](https://www.idcf.jp/cloud/pdf/dns/dns_domain.pdf)

#IDCFクラウドDNSの設定
1. IDCFクラウドへログイン
2. [DNSメニュー](https://console.idcfcloud.com/dns/)へアクセス
3. 画面右上のDNSゾーンを作成を選択
 - ゾーン名：取得したドメイン名
 - メールアドレス：SOAレコードにて公開されるメールアドレス
 - TTL初期値：リゾルバにキャッシュされる時間
4. example.comを選択
5. 画面上部の『認証する』を選択
6. 新しいDNSゾーンの場合を確認し、記載のあるネームサーバー情報をメモ帳などに控える

#DNS認証
1. お名前.comの[ドメインNavi](https://www.onamae.com/navi/domain.html)へログイン
2. [ネームサーバー設定](https://www.onamae.com/domain/navi/ns_update/input)へアクセス
3. 『他のネームサーバーを使用』ボタンを選択
4. example.comを選択
5. IDCFクラウドDNSの設定にて控えたネームサーバー情報を記入し確認画面 → 設定する
6. IDCFクラウド[DNSメニュー](https://console.idcfcloud.com/dns/)へアクセス
7. example.comを選択
8. 画面上部の『認証する』を選択
9. ポップアップ右下の認証するを選択
 - 反映に時間がかかることがあるらしいので、ダメだったら時間をおいて再実施
10. 認証出来たら1～4を再度行い、ns**.idcfcloud.comではない、認証用レコードを削除

#DNSレコード登録
1. IDCFクラウド[DNSメニュー](https://console.idcfcloud.com/dns/)へアクセス
2. example.comを選択
3. 画面右上のレコード登録を選択
4. 以下記入して登録
 - タイプ：A
 - レコード名：@  ※『@』でサブドメイン無しを指定できる
 - GSLB：無効
 - 値：仮想マシンに紐づけたIPアドレス ※入力欄を選択でIPアドレス表示
5. 登録するを選択

#アクセス確認
http://example.com へアクセスできるか確認する。

#ssh設定
~/.ssh/configの設定をドメインへ変更

```bash
vim ~/.ssh/config
```
```
        HostName example.com
```

#あとがき
つまりポイントは特になし
http.confの意味とかで単純に知識不足
Slackにすべてのジョブの完了通知を投稿するJenkinsプラグイン書いてみた

# プラグイン書いてみた #

とりあえずものはこれ使い方は[README-JP](https://github.com/Marimoiro/GlobalSlackNotifierPlugin/blob/master/README-JP.md)に書いてみてる

https://github.com/Marimoiro/GlobalSlackNotifierPlugin

この記事では詰まったところを書いてみる。
迷い方も書いてみる

# だいたいの経緯 #

1. ジョブを全部スクリプトにしよう
2. Slackへの通知もスクリプトにしたぞ！
3. あれ？Slack飛ばないことあるやん…
4. あ…gitのサーバー死んでるスクリプトまで到達してない…
5. 全部のジョブに設定するのミスもありそうだしつらいな…
6. じゃあプラグイン書くか…

ほかにglobal post script pluginなんかwindowsだと動かないとかありました。

# テンプレート作るのは簡単だった #

http://qiita.com/kazuqqfp/items/ded99eb8d7bd967b9d2a

# 問題はどうやって書くか… #

今回のゴールは**全てのジョブが終わったということを知る**ことができれば大隊解決しそうでした。
その場所を探すために[Extensions Index](https://jenkins.io/doc/developer/extensions/)からそれっぽいものを探しました。
ええ、探しました！（ドキュメントが多分少なくてもはや探すしかねぇ…）

で、GlobalPostScriptのコードを読んでRunListenerのOnCompletedメソッドがそれにあたりそうだと思いました。

なのでログにHelloとか出すプラグイン書いてみて実験したら確かにそういう風に動くことがわかりました。
（pipelineとフリースタイルのみが今回は対象なのでそれだけテストしました。）


じゃあ後は書くだけだ！Slackへのポストや設定はとりあえず[Slack Plugin](https://github.com/jenkinsci/slack-plugin)に任せるとして。
かきかきしました。(詳細はコードよめば大体わかると思います。)

次にぶつかったのは…どうやってこれ設定画面作るん・・・あとどうやってそのパラメータ受け取るん・・・という部分だったのでそれを次に説明します。

# 設定画面の作り方 #

なんかjellyとかいうの使って作るらしい…ほかのプラグインからディレクトリ構造はわかりました。
多分resources以下にそれっぽいファイルを作ればいいはずです！

で、それを受け取る方法はいくつかあるようですがとりあえず以下のような形でDescribable<クラス名>形式をほかのプラグインからパクって採用しました。

public class GlobalSlackNotifier extends RunListener<Run<?, ?>> implements Describable<GlobalSlackNotifier>

そうすると内部にDescriptorImplというDescriptor<クラス名>を継承したクラスを作りそこで設定を読み込む感じになるみたいです。

で・・・多分ここにメンバ変数いれれば自動でなんかいい感じで変数入れてくれるのかなーと思った
思ったけどだめだった…

このconfigureというメソッドで読み込みを定義しないといけなかった

```java

        @Override
        public boolean configure(StaplerRequest req, JSONObject formData) throws Descriptor.FormException {
            
            configure(formData);
            
            save();
            return super.configure(req, formData);
        }
```

これで無事設定できる！！と思ったら…今度は設定が保存されない…なんで…と思ったら**get設定名**というメソッドを定義しないとだめらしかった…
だからいっぱいgetXXX書いたVisual Studio Codeさん有能すぎる

これでなんとかプラグインが書けたのでとりあえずgithubに公開した次第。
ドキュメント書いてプラグイン乗っけてほしいなって思ってるけどどうやって公開申請するんだろう…。

# おまけ #

ちなみに依存関係は多分この辺に書くといいっぽい
よくわかってないけど
https://github.com/Marimoiro/GlobalSlackNotifierPlugin/blob/master/pom.xml#L19
https://github.com/Marimoiro/GlobalSlackNotifierPlugin/blob/master/pom.xml#L70-L76
Let's Encript の証明書更新

certbotを使えば自動的に更新されることになっているらしいが、Apacheが起動したままだとファイルの書き換えが出来ずに更新できない。
権限をどうにかすれば出来そうな気はするがとりあえずはApache止めて更新してる。

```
$ sudo systemctl stop apache2
$ sudo certbot renew
$ sudo systemctl start apache2
```
【Android】KotlinでRealm利用時の"Cannot inherit from final class"エラー対処法

## 結論
RealmObjectを継承したクラスに`open`修飾子をつける。

## 環境
Kotlin: 1.1.4-3
Realm: 3.5.0

## エラー内容
```
Error:(33, 85) error: cannot inherit from final Foo
```

## サンプルコード
:no_good: コンパイルエラー

```kotlin
class Foo: RealmObject() {
    var id: Long = 0
}
```

:ok_woman: OK

```kotlin
open class Foo: RealmObject() {
    var id: Long = 0
}
```

## 原因
Realmがコンパイル時に生成するProxyクラスがRealmObjectを継承したFooクラスを継承するため。
`/app/build/generated/source/kapt/debug/io/realm/FooRealmProxy.java`のクラス宣言部分

```java
public class FooRealmProxy extends rkowase.sample.Foo
    implements RealmObjectProxy, FooRealmProxyInterface {
```

## 参考
Realm Java 3.5.0
https://realm.io/jp/docs/java/latest/
[Pythonによる科学・技術計算]ヌメロフ法による2階常微分方程式の解法，数値計算

#はじめに

科学・技術計算では， 一階微分を含まない二階の常微分方程式，

$ \frac{d^2 y}{d x^2} + k^2(x)y=S(x) {\tag 1} $

がしばしば出てくる(一次元シュレディンガー方程式など)。


**この方程式の解法として，**ヌメロフ法**と呼ばれる非常に簡単かつ効率的な陽解法のアルゴリズがある。この方法は4次のルンゲ・クッタ法[1]よりも1次だけ精度が高い[2]。**

本稿ではPythonを用いて簡単な例題を解く。

***

# ヌメロフ法

一様な格子間隔 を

$h = x_{n}-x_{n+1} {\tag 2}$

として，ヌメロフ法による解法は

$y_{n+1}=    \frac{(1-5bh^2)y_n-(1+\frac{1}{2}k^2_{n-1} h^2)y_{n-1}+b(S_{n+1}+10S_n+S_{n-1})}{1+bk^2_{n+1}h^2}  + \mathcal{O(h^6)}{\tag 3} $

となる[1]。特に，$S(x)=0$のときは，1次元の[ヘルムホルツ方程式](https://ja.wikipedia.org/wiki/%E3%83%98%E3%83%AB%E3%83%A0%E3%83%9B%E3%83%AB%E3%83%84%E6%96%B9%E7%A8%8B%E5%BC%8F)となり，ヌメロフ法による解は

$y_{n+1}=    \frac{(1-5bh^2)y_n-(1+\frac{1}{2}k^2_{n-1} h^2)y_{n-1}}{1+bk^2_{n+1}h^2}  + \mathcal{O(h^6)}{\tag 4} $

となる。

***
# 例題
$ \frac{d^2 y}{d x^2} = -4 \pi y, y(0)=1, y'(0)=0 {\tag 5} $

をx=0から1まで解く。

厳密解は

$ y = cos(2\sqrt \pi x){\tag 6} $
である。

**ヌメロフ法では，$y[0]$に加えて$y[1]$の値が必要となる。**
ここでは$y'(0)$の前進差分表現から，
$y'(0) = (y[1]-y[0])/h = 0 $として， $y[1] =1$とする。 

また，$h = x_{n}-x_{n+1} = 0.005$とする

***

#コード
```py3

"""
ヌメロフ法による2階常微分方程式の解法

"""
import numpy as np
import matplotlib.pyplot as plt

delta_x=0.005
xL0, xR0  =0, 1
Nx =  int((xR0-xL0)/delta_x)

k2=np.zeros([Nx+1])
k2[:] = 4*np.pi

y=np.zeros([Nx])

#初期条件
y[0] = 1
y[1]=1  # y'(0) = (y[1]-y[0])/delta_xと前進差分して評価

def Numerov (N,delta_x,k2,u):  # ヌメロフ法による発展
    b = (delta_x**2)/12.0
    for i in range(1,N-1):
        u[i+1] = (2*u[i]*(1-5*b*k2[i])-(1+b*k2[i-1])*u[i-1])/(1+b*k2[i+1]) 

                

Numerov(Nx, delta_x, k2, y) # ヌメロフ法による解

# for plot
X= np.linspace(xL0,xR0, Nx)
y_exact = np.cos(2*np.sqrt(np.pi)*X)
plt.plot(X, y,'o',markersize=2,label='Numerov')
plt.plot(X, y_exact,'-',color='red',markersize=0.5,label='Exact')
plt.legend(loc='upper right')
plt.xlabel('X') # ｘ軸のラベル
plt.ylabel('Y') # y軸のラベル

plt.show()
```

***
#結果

![t.png](https://qiita-image-store.s3.amazonaws.com/0/192457/2b7d0197-43c8-79b4-aca0-82320430b10e.png)

点がヌメロフ法による数値解，赤線が厳密解をあらわす。

***



#参考文献

[1] Qiita記事[[Pythonによる科学・技術計算]4次のルンゲ-クッタ法による1次元ニュートン方程式の解法](http://qiita.com/sci_Haru/items/b8d5c9cfe64c4366630a)

[2] 阿部正典　ほか(訳)，[『クーニン 計算機物理学』](https://www.amazon.co.jp/%E8%A8%88%E7%AE%97%E6%A9%9F%E7%89%A9%E7%90%86%E5%AD%A6-Steven-Koonin/dp/4320032918)
sklearnの欠損値補間(Imputer)でハマったのでメモ

#はじめに
文字列データの列を含むDataFrameで、欠損値補完を行おうとしてハマったのでメモします。

#欠損値補完とは
存在しないデータを周囲のデータを利用して、補完すること。

#欠損値の例
例えば、以下のようなデータがあったとしよう。gender列の5行目がunknownとなっている。補完の方法は平均値、中央値を使うなどいろいろあるが、今回は単純に多い方の性別であるmaleで補完したい。
![sample.png](https://qiita-image-store.s3.amazonaws.com/0/136340/1242dc07-7cb3-a71a-8ac8-a9c2190bf5de.png)


#やったこと
学習器にデータを入力するためには、文字列データを数値データに変換する必要がある。そこで、maleを0、femaleを1に変換したのち、欠損値補完を行うコードを書いた。つまりunknownを0(male)に置き換える。

```python
import pandas as pd
from sklearn.preprocessing import Imputer 

df_sample = pd.read_csv('sample.csv')
gender_map = {'male':0, 'female':1}
df_sample['gender'] = df_sample['gender'].map(gender_map) # male を 0　に female　を 1　に置き換え
imr = Imputer(missing_values='unknown', strategy='most_frequent', axis=0)#補完器オブジェクト作成
imputed_data = imr.fit_transform(df_sample) #補完を適用
```
missing_values に欠損値、 strategyに補完方法(平均なら mean, 中央値なら median)を指定する。

ここで、以下のようなエラーに遭遇。

`TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''`

文字列を数値に置き換えた後のDataFrameを見てみると以下のようになっていた。
![sample2.png](https://qiita-image-store.s3.amazonaws.com/0/136340/043a682e-07b0-33c3-9d09-102fb2ef2209.png)

これは、DataFrameの各列はSeriesオブジェクトとなっていて、全ての値が同じ型となっていることが原因だった。
つまり、文字列の　unknown　と数値の 　0,1　は共存できない。




#解決法

コードの'unknown'の部分を'NaN'に変えてみると上手く行った。

```python
import pandas as pd
from sklearn.preprocessing import Imputer 

df_sample = pd.read_csv('sample.csv')
gender_map = {'male':0, 'female':1}
df_sample['gender'] = df_sample['gender'].map(gender_map) # male を 0　に female　を 1　に置き換え
imr = Imputer(missing_values='NaN', strategy='most_frequent', axis=0)#補完器オブジェクト作成
imputed_data = imr.fit_transform(df_sample) #補完を適用
```

#参考文献

Python 機械学習プログラミング　達人データサイエンティストによる理論と実装 (インプレス社)
OpenCVでSplatoonのイカ分類器を作ってみた

#前回までのOpenCV
さて、[前回](http://qiita.com/haseshin42/items/4d5c7717e89c446b21ce)はサンプル10枚でイカ検出器を作成してみたところ見事に検出に失敗しました。
というわけで、今回はサンプルを数を増やしたり、パラメータを変更しながらいろいろ試してみたいと思います。
#opencv_createsamplesによるサンプルの生成
createsamplesコマンドを使用することで、1枚の画像から角度やサイズを変更した大量のサンプルを自動生成することが出来ます。

opencv_createsamples.exe -img face.jpg -num 1000 -vec test.vec

-img :元になる画像を指定します。
-num :生成する画像の数を指定します。
-vec :生成した画像から作られるvectorファイルの名前

その他のオプションは何もオプションを付けないでコマンドを実行して確認してください。
デフォルトでは生成する画像のサイズは24x24のものになります。
サイズを変更するには、 -h -w で高さと幅を指定します。
24だと少し小さすぎな気がしています。
#traincascadeによる学習
次にtraincascadeコマンドを使用して学習を行います。

opencv_traincascade.exe  -data 50 -vec test.vec -bg list.txt -numPos 50 -numNeg 10

-data:生成した分類器を出力するフォルダ。事前に作成しておく必要があります。
-vec :ソースとなるvectorファイル。createsamplesで生成したもの
-bg :ネガティブ画像のリストが記述されたテキストファイル
-numPos:使用するポジティブ画像の数。生成した数を同じ数を指定するとエラーになる場合があります。
-numNeg:使用するネガティブ画像の数
#結果
いろいろ試行錯誤して、出来上がった分類器の認識結果がこちら。顔以外にも判定がでる場合がありますが、それなりに上手く認識します。ちなみに、本当は動画でやりたいのですがキャプチャ環境が無いので、スクリーンショットをTwitterで送信してからPCに保存しています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/117736/295501a9-88d2-b0f6-883e-46054b41f27d.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117736/7ee7c06d-3395-afbc-1ba1-4816da2e885c.png)
参考までに各コマンドのパラメータです。

```
opencv_createsamples.exe -bgcolor 250 -img posi.jpg -vec 4000.vec -num 4000 -bg nega.txt -h 40 -w 40
```

```
opencv_traincascade.exe -data 4000 -v
ec 4000.vec -numPos 3500 -numNeg 1200 -bg list.txt -featureType LBP -h 40 -w 40
```
#分類器作成のコツ
さて、実際にやってみると分かるのですが、精度の高い分類機を作成するのはなかなか難しいです。というかそもそも認識するようにするだけでも試行錯誤が必要です。上手く作成するコツをまとめておきたいと思います。
##LBPを使用する
試行錯誤が必要なので、分類器の学習速度が重要です。デフォルトのHaarに比べてLBPは大幅に学習速度が速いため、数多く試行が可能です。traincascade実行時に-featureType LBP を指定すればOKです。
##createsamplesの生成結果を確認する
createsamples実行時には-bgcolorと-bgを指定して実行しないと上手く認識しませんでした。-showを指定することで生成された画像を確認することができますので、学習に適した画像が生成されていることを確認しましょう。今回のケースですと、最初はキャラクターの髪の毛が入った状態でデフォルトのパラメータで画像を生成していたところ、ほとんど認識することが出来ませんでした。そこで、目の周りの部分だけを切り取り、様々な背景に目の部分が浮き出るような画像が生成される様に-bgcolorを調整し、-bg　パラメータを指定したところ認識率が上がりました。画像を確認する際には、-h -w でサイズを少し大きめにすると確認しやすいです。ただし、大きくすると学習時間が長くなりますので、最終的には小さなサイズでvecファイルを生成します。
##まず過剰に認識する状態にしてからネガティブ画像を増やす
まず、対象を正しく認識できるようにしてから、ネガティブ画像を徐々に追加し、誤認識を減らしていきましょう。今回はポジティブ画像を1000枚、ネガティブ画像100枚程度から開始しました。この程度ですと、学習は数分で終わります。その後、ネガティブ画像を追加していったところ認識精度が悪くなったので、ポジティブ画像を3500枚に変更しました。最終的にはネガティブ画像を1200枚まで増やしています。ネガティブ画像を集めるには、Google等からキーワードで画像を一括ダウンロードするツールが沢山ありますのでそれを利用しましょう。ちなみに、最終的なパラメータでの学習時間はThinkpadT530で35分でした。

以下の写真は調整途中の結果です。こんな感じで誤認識が沢山ある状態にしてからチューニングしましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117736/f78d60a3-17c1-9e2e-388b-e8fc802f4bf4.png)

#まとめ
今回は、createsamplesコマンドを使用して大量の画像を生成し、イカを正しく認識できるうに分類器を作成しました。createsamplesコマンドを使用して分類器を作成するにはコツが必要ですので、まずは時間がかからない枚数で試行錯誤して方向性を定めてからサンプル数を増やすことをオススメします。
[C#]属性を使って項目チェック

C#の属性を使ってオブジェクトのプロパティの単項目チェックを行います。
こういうのは多分フレームワークにあるとは思いますが、C#初級者なので記事にしておきます。
コードは「.Net Fiddle」というWeb IDEで確認しました。

基本はJavaのアノテーションとほぼ同じですが、C#はチェックされる例外がないのでリフレクションで取得してもコードはすっきりします。
DisplayNameとStringLength、Requiredという既存の属性を使用しています。
Attribute.GetCustomAttributメソッドで対象（今回はプロパティ）から属性を取得できます。

```csharp
using System;
using System.Reflection;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
					
public class Program
{
	public static void Main()
	{
		Entity entity = new Entity(){Id = "123456", Name = ""};
		
		validate(entity);
	}
	
	private static void validate(object obj)
	{
		foreach(PropertyInfo prop in obj.GetType().GetProperties())
		{
			// 値
			string val = prop.GetValue(obj).ToString();
			// DisplayName属性取得
			DisplayNameAttribute dispNameAttr = Attribute.GetCustomAttribute(prop, typeof(DisplayNameAttribute)) as DisplayNameAttribute;
			// StringLength属性取得
			StringLengthAttribute lenAttr = Attribute.GetCustomAttribute(prop, typeof(StringLengthAttribute)) as StringLengthAttribute;
			// Required属性取得
			RequiredAttribute reqAttr = Attribute.GetCustomAttribute(prop, typeof(RequiredAttribute)) as RequiredAttribute;

			// ↓チェック処理
			if (lenAttr != null && val.Length > lenAttr.MaximumLength)
			{
				Console.WriteLine(string.Format("{0}({1})は最大桁数{2}桁を超えています。", dispNameAttr.DisplayName, val, lenAttr.MaximumLength));
			}
			if (reqAttr != null && string.IsNullOrEmpty(val))
			{
				Console.WriteLine(string.Format("{0}は必須項目です。", dispNameAttr.DisplayName));
			}
		}
	}

	private class Entity
	{
		[DisplayName("ID")]
		[StringLength(5)]
		[Required]
		public string Id {get;set;}

		[DisplayName("なまえ")]
		[StringLength(20)]
		[Required]
		public string Name {get;set;}
	} 
}

//ID(123456)は最大桁数5桁を超えています。
//なまえは必須項目です。
```
Githubpagesでgoogle fontsが使えない問題

# about
githubpagesに静的サイトを公開したら表示が崩れる。
**ローカル環境での表示**
![スクリーンショット 2017-09-03 23.23.45.png](https://qiita-image-store.s3.amazonaws.com/0/114861/d4cb384c-8aa1-2e9e-bc25-c25c39e8e402.png)

**githubpagesでの表示**
![スクリーンショット 2017-09-03 23.23.42.png](https://qiita-image-store.s3.amazonaws.com/0/114861/32d7f277-7f70-a61d-6856-a244b8d0294d.png)


どうやらgoogle fontsが読み込めていないっぽい。

# 原因
githubpagesはデフォルトでhttpsでの通信を行うので、http経由でコンテンツを取ってくる指定をしていたのが悪かった。

# 対応
httpをhttpsと変えるだけ(google fontsの場合は、他はコンテンツをダウンロードして直置きとか？)

```diff:index.html
-<link href='http://fonts.googleapis.com/css?family=Titillium+Web:400,600,300,200&subset=latin,latin-ext' rel='stylesheet' type='text/css'>

+<link href='https://fonts.googleapis.com/css?family=Titillium+Web:400,600,300,200&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
```

**解決:)**
<img width="600" alt="スクリーンショット 2017-09-04 0.19.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/114861/e69c6bc6-7a3f-515e-19fd-10f3efc02893.png">
Macbook歴そういえば5年目が使うキーボードショートカット

## 読者の対象
- Mac ユーザ
- USキーボーダー
- 自分

## 想定される成果
- 知らないキーボードショートカットが見つかる
- 忘れていた便利なキーボードショートカットを思い出す

## 私
- Webプログラミング初心者
- タイピングスピード 5.5 key/sec（Ghost Typing）
- キーボードは一切見ない（汚れに気付かない）
- vimは使うが、極めてはいない

## 大事にしている考え方
- 汎用性（他人のPCでも使えるか）
- 必要十分か
- 環境構築スピード

## 環境
- macOS Sierra (version 10.12.6)
- MacBook (Retina, 12-inch, Early 2016)
- US keyboard

## 初期設定
- キーバインドをcapslockからcontrolに変更（System Preference / Keyboard / Modified Keysより）
- 文字入力とSpotlight検索のショートカットを入れ替える
- Shiftitのダウンロード

## Keyboard Shortcuts
初歩的な`command + c`のようなものは除く

key|操作|備考
:--|:--|:--
command + w|ウインドウを閉じる
command + q|アプリを終了
command + tab|アプリの切り替え
command + `|ウインドウの切り替え
command + o <br> command + ↑|ファイルを開く
Enter|ファイル名変更
control + space|Spotlight検索|↓と入れ替え
command + space|入力切り替え|↑と入れ替え
command + d|保存せずに終了
command + shift + 3|スクリーンショット（全画面）
command + shift + 4|スクリーンショット（選択部分）
command + shift + F3|デスクトップを表示|F11は指が届かない
control + a|文頭へ移動
control + e|文末へ移動|(end)
control + f|一文字前へ|(forward)
control + b|一文字後ろへ|(back)
control + h|一文字前を削除|deleteと同じ
control + d|一文字後ろを削除
control + k|後ろを全削除
control + n|下に移動
control + p|上に移動
option + ←↑→|windows + ←↑→を模擬|Shiftit
command + ←→|chromeの戻る進む
command + +-|拡大縮小
command + shift + z|戻るの取り消し|command + yより好き
command + l|chromeのURLバーにフォーカス
command + shift + option + v|text styleを解除して貼り付け
command + shift + n|Private Browsing

### 基本的に使わないキーボード、機能
- fn
- f1~12
- 右のcommand, option
- 左のcontrol（capslockの位置が好き）
- 矢印
- mission control
RaspberryPi3 Model BでWiFi設定

# 目的

自宅のプランターで野菜を育てることになったので、
せっかくだしIoTの勉強をしてみるか、ということでRaspberryPiを購入。

他の記事を漁りながら諸々設定を行ったが、
WiFiの設定で少し詰まったのでまとめておく。

# interfacesの設定

```
$ sudo vi /etc/network/interfaces
```

ネットワークインターフェースの設定をつらつらと。
wlan0がWiFi用のインターフェースで、
`wpa-conf`はWiFiの接続情報をまとめるファイルで、
後ほど作成する。

```
auto lo
iface lo inet loopback

auto eth0
allow-hotplug eth0
iface eth0 inet manual
 
auto wlan0
allow-hotplug wlan0
iface wlan0 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
```

# 接続情報の作成

## 接続情報の暗号化

```
$ sudo wpa_passphrase [SSID] [PASS]
network={
	ssid="[SSID]"
	#psk="[PASS]"
	psk=563706f9bae5f492117ec13fb31d5cecafbf1e9566571f5627c18bebf9716ee4
}
```

## 接続情報の作成

`/etc/wpa_supplicant/wpa_supplicant.conf`を編集する。
先程得られた暗号化された接続情報をコピーして貼り付けるだけ。
ただし、`#psk="[PASS]"`の行が残っていると暗号化した意味がないので削除。

```
network={
	ssid="[SSID]"
	psk=563706f9bae5f492117ec13fb31d5cecafbf1e9566571f5627c18bebf9716ee4
	key_mgmt=WPA-PSK
}
```

# 固定IP設定

`/etc/dhcpcd.conf`の末尾に以下を追加。

```
interface wlan0
static ip_address=192.168.0.20/24
static routers=192.168.0.1
static domain_name_servers=8.8.8.8
```

# 再起動

全て終わったら再起動する。

```
$ sudo reboot
```

# 確認

起動後に以下のコマンドを実行する。

```
$ sudo ifconfig
eth0      Link encap:Ethernet  HWaddr b8:27:eb:b4:d3:38  
          inet6 addr: fe80::31e0:3a3b:20ed:4167/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:72 errors:0 dropped:0 overruns:0 frame:0
          TX packets:72 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:6288 (6.1 KiB)  TX bytes:6288 (6.1 KiB)

wlan0     Link encap:Ethernet  HWaddr b8:27:eb:e1:86:6d  
          inet addr:192.168.0.20  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::72d2:9d40:5d1b:e75e/64 Scope:Link
          inet6 addr: fe80::ba27:ebff:fee1:866d/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:444 errors:0 dropped:0 overruns:0 frame:0
          TX packets:326 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:35832 (34.9 KiB)  TX bytes:50856 (49.6 KiB)
```

`wlan0`に`dhcpcd.conf`で設定した`192.168.0.20`が表示されていたらOK。
git bisect run をコマンドプロンプトで実行する方法

`git bisect run` をコマンドプロンプトで実行するのにはまったのでメモ。

テスト用のバッチファイルは以下のような感じ。

```bat:test.cmd
@ECHO OFF
REM Some Test
REM Return Test Result
EXIT /B 0
REM 0 -> Success
REM 1 -> Failed
```


`git bisect run` は終了コードを受け取って自動で、問題のあるコミットを探索できる。
バッチファイルで終了コードを戻すためには `exit /b 0` のように記述すればOK。

実際に実行するときのコマンド列は、以下みたいなかんじ。
HEAD が 問題のあるコミットで、 Success が問題のないコミットのタグ。

```ba
$ git bisect start
$ git bisect bad HEAD
$ git bisect good Success
$ git bisect run cmd //C test.bat
```

bat ファイルの実行方法で結構はまってしまった。
//c で書かないと、終了コードを git bisect が解釈してくれなかった。

## 参考サイト
[dalpert-korewireless gist](https://gist.github.com/dalpert-korewireless/98196a2f51b2bcfafb61)
【Python】 pandas DataFrameの操作メモ

## はじめに
初心者ながらデータ分析をする機会を得たため、
そこで新しく得たPythonのDataFrameの文法的要素をまとめる。

## 前提
*product.csv*


| id | name   | price | category  | isPopular|
|:---|:-------|:------|:----------|:---------|
| 1  | eraser | 100   | stationary| 1        |
| 2  | pencil | 200   | stationary| 0        |
| 3  | socks  | 400   | clothes   | 1        |
| 4  | pants  | 1000  | clothes   | 0        |
| 5  | apple  | 100   | food      | 0        |


```python:analyze.py
import pandas as pd
```

## あるカラムの値の種類を抽出する
```python
df['category'].value_counts().index
```

実行結果

```
Index(['stationery', 'clothes', 'food'], dtype='object')
```


## 条件を指定して、DataFrameの値を変更・追加する
```python
df.loc[df.name == 'socks', 'price'] = 500
df.loc[df.category == 'stationery', 'category_id'] = 0
df.loc[df.category == 'clothes', 'category_id'] = 1
df.loc[df.category == 'food', 'category_id'] = 2
df
```

実行結果

| id | name   | price | category  | isPopular| category_id|
|:---|:-------|:------|:----------|:---------|:-----------|
| 1  | eraser | 100   | stationary| 1        | 0.0        |
| 2  | pencil | 200   | stationary| 0        | 0.0        |
| 3  | socks  | 500   | clothes   | 1        | 1.0        |
| 4  | pants  | 1000  | clothes   | 0        | 1.0        |
| 5  | apple  | 100   | food      | 0        | 2.0        |

## one-hot表現に変更
```python
# columnのisPopularとcategory_idのみを抽出（整数値でないとうまくいかない）
df_X = df.drop(['id','name','price','category'], axis=1)

from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder()
enc.fit(df_X)
onehot_array = enc.transform(df_X).toarray()
onehot_df = pd.DataFrame(onehot_array)
df = pd.concat([df_id, onehot_df], axis=1)
df
```

実行結果

| id | 0   | 1   | 2   | 3   | 4   |
|:---|:-------|:------|:----------|:---------|:-----------|
| 1  | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 |
| 2  | 1.0 | 0.0   | 1.0| 0.0        | 0.0        |
| 3  | 0.0  | 1.0   | 0.0   | 1.0        | 0.0        |
| 4  | 1.0  | 0.0  | 0.0   | 1.0       | 0.0        |
| 5  | 1.0  | 0.0   | 0.0      | 0.0        | 1.0        |
SparkアプリケーションのデバッグTIPS

## Spark UIでスレッドダンプを見る

どこかで詰まってる/デッドロックしているなどを調べたい場合、スレッドダンプを見るのが有効ですが、それだけならSpark UI上でできます。

![Screen Shot 2017-09-03 at 10.43.47 PM.png](https://qiita-image-store.s3.amazonaws.com/0/38151/a92010d1-c62a-99f6-8e6d-fb119be6a895.png)

![Screen Shot 2017-09-03 at 10.44.12 PM.png](https://qiita-image-store.s3.amazonaws.com/0/38151/9777d52d-366a-196f-6069-854f1ca9333b.png)


## EMR上でJMXリモートデバッグ

ここではjvisualvmを使うことにします。

### jvisualvmの準備

jvisualvmにプラグインを入れておくと捗ります。

`Tools > Plugins`からプラグイン管理画面を開き、Threads Inspectorあたりは入れておくと便利です。

### ステップを追加する

#### 前提

- アプリケーションはjarに固めて`s3://path/to/app.jar`に置いてあるとします
- `command-runner.jar`で`spark-submit`する方法でステップを実行します
- EMRクラスタのmasterおよび各ノードは、22番が空いてるものとします

#### EMRにステップの追加

以下のようなコマンドラインオプションをつけてステップを追加します。

```bash
spark-submit --deploy-mode cluster --class com.example.Main --master yarn-cluster \
  --conf "spark.executor.extraJavaOptions=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8002 -Dcom.sun.management.jmxremote.rmi.port=8002 -Djava.rmi.server.hostname=127.0.0.1" \
  --conf "spark.driver.extraJavaOptions=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8003 -Dcom.sun.management.jmxremote.rmi.port=8003 -Djava.rmi.server.hostname=127.0.0.1" \
  --num-executors 3 --driver-memory 2g --executor-memory 5g --executor-cores 2 \ # このへんはお好みで
  s3://path/to/app.jar
```

これで、driverプロセスに対しては`8003`、executorプロセスに対しては`8002`でjmx接続できるようになります。

今回は、executorプロセスに接続してみます。

##### ※注意

一つのノードで複数のexecutorが割り当てられうる設定で実行した場合、これだと8002がバッティングする可能性があります。

そういった場合は`com.sun.management.jmxremote.port=0`として、動的にポートを取得するなどの手段をとる必要があります。

#### executorプロセスの実行されているノードの特定

YARNクラスタ上のどのノードでexecutorが実行されるかは動的に決まるため、各ノードにSSHで入って`lsof`などで`8002`番が使われているかどうか確認し、つなぐ先のノードを特定します。

ここでは、`ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com`だったとします。

#### SSHトンネルを開く

手元のマシンで以下のコマンドを実行し、8002番のSSHトンネルを開きます。

```bash
$ ssh -i key.pem -NL 8002:ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com:8002 hadoop@ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com
```

#### jvisualvmから接続

あとは`127.0.0.1:8002`に対してjvisualvmから接続すればOKです。

## IntelliJでステップ実行する（localモード）

IntelliJのリモートデバッグを使えば、Sparkアプリケーションをステップ実行などできます。

ここではlocalモードで行います。（EMR上でもできるはずだけど）

### 前提

- sparkバイナリを落として`/path/to/spark_home`に解凍しておきます
- アプリケーションはjarに固めて`/path/to/app.jar`に置いておきます

### IntelliJの前準備

IntelliJを起動し、Run > Edit Configurationsから、リモートデバッグ用のconfigurationを追加しておきます。

![Screen Shot 2017-09-03 at 11.23.02 PM.png](https://qiita-image-store.s3.amazonaws.com/0/38151/7d09cb42-0608-a46c-d611-1ed834b57108.png)

`+`から`Remote`を選択すれば勝手にこれが入力されています。

### spark-submit

リモートデバッグ用のオプションをつけて、spark-submitします。

```bash
$ cd /path/to/spark_home
$ ./bin/spark-submit --master local \
    --driver-java-options "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005" \
    /path/to/app.jar
```

### IntelliJでリモートデバッグを開始

少し経ってSparkアプリケーションが起動したら、さきほど作成したconfigurationを実行すれば、いつものようにブレークポイントを貼ったりスレッドの状態を見たりwatchを仕込んだりできます。
手軽にcanvasをキャプチャする。CCapture.js

まずは [ccapture.js](https://github.com/spite/ccapture.js/) からDownload ZIPしてください。

今回は、CCapture.all.min.jsを使用します。

htmlに追加します。

```html

<script src="CCapture.all.min.js"></script>

```

jsに追加します。

```js

// formatは、WebM, gif, png, jpgがあります。
// framerateは、そのまま記録したいフレームレートです。
// verboseは、コンソールに情報を出してくれます。
// nameは、出力するファイルの名前です。
// timeLimitは、記録が開始されて止まるまでの時間(秒)です。
var capturer = new CCapture({
  format: 'webm',
  framerate: 60,
  verbose: true,
  name: 01,
  timeLimit: 20
});

var canvas = document.getElementById("element").appendChild( renderer.domElement );

// キャプチャ開始。
capturer.start();

// レンダー内に記述。
function render() {
  requestAnimationFrame(render);
  renderer.render( scene, camera );
  capturer.capture(canvas);
}

```

後は実行するとキャプチャされます。

macのsafariでエラーが出る場合があるようです。chrome等で試してみてください。
three.js用に書いてあります。メモに近いので短い記事でした。
[C#][MVVM Light Toolkit] ViewModelBaseを継承したBindableBase実装を行なう

MVVM Light Toolkit のViewModelBaseの書き方がそのままだと冗長なので、よくあるBindableBaseで使えるようにする。

MVVM Light Toolkitについては以下

+ [MVVM Light Toolkit](http://www.mvvmlight.net/)
+ [ViewModelBase Class](http://www.mvvmlight.net/help/SL5/html/e1c28204-2508-66c2-f984-25ba65c04a30.htm)

BindableBaseについては以下などを参照

+ [WPFでもBindableBaseを使ってINotifyPropertyChangedを実装する - SourceChord](http://sourcechord.hatenablog.com/entry/20130303/1362315081)
+ [[MVVM]　便利で間違えのないプロパティ変更通知を行うBindableBaseの実装 – Tech.D-ITlab | Denso IT Laboratory researcher's blog sites](https://tech.d-itlab.co.jp/programming/340/)

# 実装例

とはいってもViewModelBaseを継承してBindableBaseの実装をしているだけですが・・・。
ViewModelBaseの拡張メソッドでもいいですが、いちいち `using` つけたり `SetProperty` の全部に `this.` をつけないといけなかったりと、主にIDE的な都合で面倒だったので特に理由がなければ継承のほうが楽そうです。

```csharp:BindableBase.cs
    public class BindableBase : ViewModelBase
    {
        protected BindableBase()
        {
        }

        protected BindableBase(IMessenger messenger) : base(messenger)
        {
        }

        protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (Equals(storage, value)) return false;
            storage = value;
            RaisePropertyChanged(propertyName);
            return true;
        }
    }
```

使い方もよくあるものと変わりません。違う点は MVVM Light Toolkit 向けの Messanger の実装がそのままというところだけです。

```csharp:使用例
    public class BindableBaseImplSample : BindableBase
    {
        public BindableBaseImplSample(Model model)
            : base(Messenger.Default)
        {
        }
        
        private string _name;
        public string Name
        {
            get => _name;
            set => SetProperty(ref _name, value);
        }
    }
```

# 参考
+ [WPFでもBindableBaseを使ってINotifyPropertyChangedを実装する - SourceChord](http://sourcechord.hatenablog.com/entry/20130303/1362315081)
+ [[MVVM]　便利で間違えのないプロパティ変更通知を行うBindableBaseの実装 – Tech.D-ITlab | Denso IT Laboratory researcher's blog sites](https://tech.d-itlab.co.jp/programming/340/)
ちょっとずつ読むドメイン駆動設計 第一部 ドメインモデルを機能させる 第ニ章 コミニュケーションと言語の使い方4

# どのようにユビキタス言語を構築するか
- モデルに基づく言語に対してチームが献身的になる。
- 実験する。用語や用語の組み合わせがぎこちない場合に、代わりの表現を探す
- 言語に対する変更は、ドメインモデルに対する変更。クラス図を更新して、コード・振る舞いも変更する
- 不完全な場合、誤ってると思われる場合は懸念を表明する。


用語だけでなく、用語の組み合わせがぎこちない場合も対応が必要というところがちょっとした気づきがありました。

確かに用語単体で見た場合自然なのに、用語の組み合わせ、例えば、上位のカテゴリや下位のカテゴリを合わせて見た場合とか、似た用語とくらべて見た場合に自然でなくなることがありました。

似た用語も連携しているシステムではその用語で問題ないけど、該当のドメインでは不自然になることも。。。

そういう用語ってドメインエキスパート同士でも曖昧に使っていたり、サイト上でもバラバラの用語で使われていたりするので本当に困ります。

その時は、全体的に自然になるような代わりの表現を探していきます。そして、徹底してその用語で会話したり実装したりして実験した上で、やはりそれでも不自然であれば、また別の用語を探したりします。

実験大事！！
SQL*Loaderで指定フォルダ配下のSQLを全て実行

# SQL*Loaderで指定フォルダ配下のSQLを全て実行
特定のフォルダ配下の*.sqlファイルを全て実行するwindowsバッチです。
移送ツールが何も無い現場で利用していました。

```SqlExecute.bat
@echo off
title 【SQL自動実行ツール】
echo 【SQL自動実行ツール】

REM 実行フォルダに移動
pushd %~dp0

REM 実行予定SQL表示
echo.
echo 「実行予定SQL（実行順）」
dir /s /b | findstr -i -e "\.sql" | sort

REM Oracle接続情報入力
echo Oracle接続を入力してください。例）user/pass@service
set /p i=Oracle接続先：
set connectPass=%i%

REM エラー処理確認
echo.
echo エラー発生時に処理を終了しますか？
echo y:はい n:いいえ

set /p j=入力：
if %k% == y goto run
goto end

REM SQL実行ダイアログ表示
echo.
echo SQLを実行しますか？
echo y:はい n:いいえ

set /p j=入力：
if %j% == y goto run
goto end


REM ////////////////////////////////////////////////////////////////////////////////////////
:run

REM 変数宣言
set flowLog=実行フロー.log
set sqlLog=実行SQL.log
set tempFile=temp_file.txt
set tempExeSql=temp_sql.txt

REM 空ファイルの生成
type nul > %flowLog%
type nul > %sqlLog%
type nul > %tempFile%
type nul > %tempExeSql%

REM 処理開始時間の表示
echo.
echo 【処理開始時間】%date% %time%                   >> %flowLog%
echo 【Oracle接続先】%connectPass%                   >> %flowLog%
echo 【実行内容】                                    >> %flowLog%

REM SQL実行ファイルリストの取得
dir /s /b | findstr -i -e "\.sql" | sort             >> %tempFile%

REM SQL実行ファイルの生成
echo whenever sqlerror exit failure rollback         >> %tempExeSql%
echo whenever oserror exit failure rollback          >> %tempExeSql%
echo set autocommit off                              >> %tempExeSql%
echo spool %sqlLog%                                  >> %tempExeSql%
echo set echo on                                     >> %tempExeSql%
for /F "delims=" %%a in (%tempFile%) do (
    echo @"%%a"                                      >> %tempExeSql%
    echo pause                                       >> %tempExeSql%
)
echo set echo off                                    >> %tempExeSql%
echo prompt ◆[Enter]３回押下でコミットします。      >> %tempExeSql%
echo prompt ◆×ボタン押下でロールバックします。     >> %tempExeSql%
echo prompt ※[ctrl + c]はコミットされるので注意！!  >> %tempExeSql%
echo pause                                           >> %tempExeSql%
echo pause                                           >> %tempExeSql%
echo pause                                           >> %tempExeSql%
echo commit;                                         >> %tempExeSql%
echo spool off                                       >> %tempExeSql%
echo exit;                                           >> %tempExeSql%

REM 実行予定内容の表示
echo ----------------------------------------------- >> %flowLog%
type %tempExeSql%                                    >> %flowLog%
echo ----------------------------------------------- >> %flowLog%

REM SQLの実行
sqlplus %connectPass% @%tempExeSql%

REM 処理終了時間の表示
echo 【処理終了時間】%date% %time%                   >> %flowLog%

REM 一時ファイルの削除
del %tempFile%
del %tempExeSql%

REM ////////////////////////////////////////////////////////////////////////////////////////

:end
pause
```
XAMPP複数Versionを共存させる

PHPのバージョンが違ったりするので（5.xと7）それぞれ必要なケースで。

zip解凍版を別フォルダに分けて使い分ければOKです。

[パソコンにWebサーバを作る XAMPP の最新版を入れる](https://usortblog.com/xampp0227/)

こんなバッチつくって切り替えたりしてます。

```
@echo off
cls
:TOP
set /p version="PHP version?(5,7):"
if %version%==5 ( 
  set xampp="C:\path\to\xampp5\xampp-control.exe"
) else if %version%==7 ( 
  set xampp="C:\path\to\xampp7\xampp-control.exe"
) else (
  echo %version% is unsupported version.
  goto :TOP
)
call %xampp%
```
Vagrantfileで設定値をyamlファイルで管理する

Vagrantfileを作成する際に、ディレクトリのパスや設定値等で同じ値を複数箇所で記述する場合に
外部ファイル（ここではyaml形式）で管理する様に設定します。
※やり過ぎるとVagrantfie単体での可読性は低下します。。。普通の変数の方が手軽かもです。

#環境
Vagrant 1.9.7

#下準備
当然Vagrantが必要なので、インストールをしていない場合（でMacの方）は下記ページの下準備を行います。
[MacでVagrant上にdocker環境を構築](http://qiita.com/Manjiii/items/5546cde1ecf532cf2082)

#設定用のyamlファイルを用意する
yaml形式で設定値を記述します。
以下はサンプルです。

```
############
# host
############
vm:
 os: "centos/7"
 ip: "192.168.33.10"

############
# nginx
############
nginx:
 conf:
  host: "dockers/nginx/conf.d"
  guest: "/var/dockers/nginx/conf.d"
  docker: "/etc/nginx/conf.d"
 www:
  host: "dockers/nginx/www"
  guest: "/var/dockers/nginx/www"
  docker: "/var/nginx/www"
```
#Vagrantfileにyamlファイルを読み込む設定をする
VagrantfileはRubyなので以下の様にVagrantfileに追記します。
ここではsettings/localsetting.yamlを読み込みsettings変数に入れています。

```
require 'yaml'
settings = YAML.load_file 'settings/localsetting.yaml' #<- 読み込むyamlファイルのパス

```
localsetting.yamlの場所

```
.
├── Vagrantfile
└── settings
     └── localsetting.yaml
```

#Vagrantfileに設定値を記述する
Rubyのハッシュ形式で取得できるので
ハッシュオブジェクト[キー][キー]...
の様に取得できます。

例）

```
config.vm.box = settings['vm']['os'] 

```
上記の様に記述して変数に設定します。


#サンプル
実際に使用しているサンプルは以下にあります。
https://github.com/manjiii/Vagrant-samples/tree/master/Skeleton-nginx-nodejs-mongodb
Git初心者がGit使ったりGitサーバー建てたりする

とりあえずさわりのメモ・・・
いずれは開発/本番環境切替とか自動デプロイとか環境構築してコードレビューとかするチーム体制にしたい。

★2020/10/13追記
全然更新できておらずすみません…
その後SVNからGitに移行して運用していますが、自分でGitサーバー建てたりとかする時代ではないですね…
リンク集として残しておきつつ、さらにいくつか参考サイトを追加しておきます（★印）

### Git x Subversion
- [SubversionユーザがGitを使った時に勘違いした5つのこと](http://qiita.com/pink/items/30b3ca57ad6f6ac3979b)
- [gitとsubversionのコマンド対応表](http://blog.cyclogy.com/2011/05/05/git_subversion/)
- [Git-Subversion比較](https://www.backlog.jp/git-guide/reference/git-svn.html)

### ローカルツール
- [Windowsで使う(msysgit・TortoiseGit)](http://moondoldo.com/DoldoWorkz/?Git%2FWindows%E3%81%A7%E4%BD%BF%E3%81%86(msysgit%E3%83%BBTortoiseGit))
- [SourceTreeとGithubでGitの練習環境をつくる](http://qiita.com/naoki85/items/4f44601f1365c18035f4)
  - 同じTortoiseSvnからの移行はしやすいが、SourceTreeの方がツリーとか見やすくて使いやすかった

### サーバー構築
- [Git サーバー - サーバーのセットアップ](https://git-scm.com/book/ja/v1/Git-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97)
- [Gitリモートリポジトリ構築](http://capm-network.com/?tag=Git%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E6%A7%8B%E7%AF%89)
- [gitでシンプルなデプロイ環境を作る](http://qiita.com/zaburo/items/8886be1a733aaf581045)

### デプロイ
- [git hookでサイトを更新、やってみた](http://qiita.com/fnobi/items/98bd5d1c83c010842733)
- [Gitのフック（hook）を使って自動的にデプロイする](http://rfs.jp/server/git/gite-lab/git-hook-post-receive.html)

### プラットフォーム ★
- [GitLabに触ってみて、GitHubと比較した](https://qiita.com/developer-kikikaikai/items/3fd1277a9a5778000638)
- [GitとGitプラットフォームについてと、GitHubかGitLabかBitBucketの3大Gitプラットフォーム紹介](https://developerex.jp/3-major-git-platforms/)

### ブランチ管理 ★
- [Gitにおけるブランチ戦略について調べてみた](https://qiita.com/trsn_si/items/cfecbf7dff20c64628ea)
- [GitHub-Flow,GitLab-Flowの図など](https://qrunch.net/@yaya/entries/ml7DLDPFLsv5AsUW)
- [GitFlowは使わない！シンプルな「GitFeatureFlow」を紹介します](https://developers.gnavi.co.jp/entry/GitFeatureFlow/koyama)
  - プロジェクトの性格によりけりですが、自分が携わっているものでは GitFeatureFlow パターンが多いです

### マージ・リベースとファストフォワード ★
- [ブランチの統合](https://backlog.com/ja/git-tutorial/stepup/04/)
- [よく分かる！git rebaseとmergeの違いと使い分け](https://www-creators.com/archives/1943)
- [gitのmerge --no-ff のススメ](https://qiita.com/nog/items/c79469afbf3e632f10a1)

### AWSマネージドサービス ★
- [AWS CodeCommit](https://aws.amazon.com/jp/codecommit/)
- [AWS CodeBuild](https://aws.amazon.com/jp/codebuild/)
- [AWS CodeDeploy](https://aws.amazon.com/jp/codedeploy/)
- [AWS CodePipeline](https://aws.amazon.com/jp/codepipeline/)
  - 全然触ってもないけど取り入れてみたい…

<br> 
~~随時、更新予定・・・~~
【selenium】Firefox/Chrome/SafariのWebDriverインストール - Python 編 -

今までFirefoxのプラグイン、selenium IDEでテストスクリプトの作成をしてきましたが、
Firefox55からは、selenium IDE が動かなくなってしまいました。
もしかしたらと思い、selenium Builderも試してみましたが、同様に動きませんでした。
※ちなみに古いバージョンのFirefoxを使えば、動作できるようです。

一旦、IDEを使わずに、Firefox、chromeやSafariでもseleniumのテストをしていくために、Pythonでもseleniumを動かせるようにしたので、webdriverのインストール方法をブラウザ別に紹介します。

#今回実行した環境
MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)
プロセッサ：3.5 GHz Intel Core i7
メモリ： 16 GB 2133 MHz LPDDR3
OSバージョン： 10.12.6
Python：3.6.2


#seleniumのインストール

```shell-session
$ sudo pip3 install selenium
```
seleniumのインストールはこれだけで完了です

しかし、seleniumでブラウザを起動するには、各ブラウザのドライバが必要となります。
ここからは、ドライバーを設定していきます。

##Firefox
Mozillaのgeckodriverをダウンロードします。
以下のページから自分のOSに合わせて最新版を選択してください。

https://github.com/mozilla/geckodriver/releases

ダウンロードしたファイルを解凍したら、geckodriverを

```
/usr/local/bin/
```
にコピーします。

コピーが完了したら、以下のコードを実行して、Firefoxが立ち上がって東洋経済のサイトが表示されれば、インストール成功です！

```py3:SampleFirefox.py
from selenium import webdriver
 
# Firefoxを指定して起動
browser = webdriver.Firefox()
browser.get('http://toyokeizai.net/')
```
 

##Google Chrome
こちらも手順としてはFirefoxのときとほぼ同様です。
以下のページから自分のOSに合わせて最新版のドライバーをダウンロードします。

https://sites.google.com/chromium.org/driver/

ダウンロードしたファイルを解凍したら、chromedriverを

```
/usr/local/bin/
```

にコピーします。

コピーが完了したら、以下のコードを実行して、chromeが立ち上がって毎日新聞のサイトが表示されれば、インストール成功です！
2行目のFirefoxをChromeに書き換えるだけ！

```py3:SampleChrome.py
from selenium import webdriver

# GoogleChromeを指定して起動
browser = webdriver.Chrome()
browser.get('https://mainichi.jp/')
```

##Safari
Firefoxとchromeとは違い、
開発の設定から”リモートオートメーションを許可”にチェックを入れるだけです。

開発メニューを表示させるために、設定の詳細の一番下にある、
「メニューバーに”開発”メニューを表示」にチェックを入れます。

<img width="823" alt="スクリーンショット 2017-09-12 18.57.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/8222/478e83eb-b674-bee1-b1eb-82e6c8cc1ab8.png">

これで、メニューバーに開発メニューが表示されたら、
そこをクリックして、表示されたメニューから”リモートオートメーションを許可”を
探し出して、クリックします。
これで設定は完了です。

それではSafariを起動するコードですが、
これまでブラウザの名前を入れてきた箇所を”Safari”に変えるだけです。
簡単！

```py3:SampleSafari.py
from selenium import webdriver
 
# Safariを指定して起動
browser = webdriver.Safari()
browser.get('https://mainichi.jp/')
```
一度、ドライバーを設定してしまえば、
コードを一行変えるだけでブラウザを切り替えることが可能となります。

このように、ブラウザを変えるのは簡単なのですが、
コードはそのままで別のブラウザでも動くのかと言うとそういうわけにはいかないようです。

例えば要素を見つけることが出来なかったり、
読み込みを待たずにエラーを返してしまうことがあったりするため、
ブラウザごとに微妙な最適化は必要となるかと思います。

軽く触った感じですが、Safariはtime.sleep()などで、
ちゃんと待ち時間をとってあげないとエラーが返ってきやすい感じがしました。
こんにちは！　世界！ ➕「.」の意味

さて、jsを勉強していく上で、常に出てくる

「.」
（メンバー演算子と言われるらしい。へー）

曖昧だったので、言葉で表現してみると

意味＝どうする！何をどうする！！！！

っていう意味らしい。
で、何をというのを「.」の前に入れるらしい。

という事で、webページ上に記載するために
documentを使って記載したいと思います。


最初は、何も記述しなければwebページ上に何も記載されてないです。

それを、document.とする事で記載されるという事は

document=白紙の原稿用紙という事ですね。

では、白紙の原稿用紙＝
document.

それに何か書きたい＝英語のwriteを使って

document.write

で、何を書きたいねん。


Hello World！！

だと、外国人になっちゃうので


```
document.write("こんにちは！世界！");
```


上記を訳すと
「俺は、白紙の原稿用紙に書きたいねん。こんにちは！世界！を。」

っていう感じですね。
現に、HTMLに書かれますし。

そして、何気に重要なのが「;」ですね。
「;」=日本語で言う「。」の事ですね。

ちゃんと、文章の終わりに「。」をつけるように、そうしないと
先生から赤ペンがつけられて、戻ってきちゃいます。＝エラー



以上、基礎中の基礎
documentと「.」についてでした。
Webサーバー構築メモ（Apache+PHP+MySQL on CentOS）

見様見真似で構築した手順のメモ。
ただの参考リンク集になりかねない・・・

#### SSHアクセス制限
- [CentOS で公開鍵暗号方式を使用した SSH ログイン設定](http://fnya.cocolog-nifty.com/blog/2012/03/centos-ssh-8291.html)
- [Linuxのssh設定 ~ centos ~](http://akiniwa.hatenablog.jp/entry/2013/09/09/080718)
  - 鍵認証
- [SSHでログインユーザを制限](http://www.server-memo.net/server-setting/ssh/allow-users.html)
  - パスワードアクセスにする場合はAllowUserを

#### Apache,PHP,MySQLインストール
- [Webサーバー構築(Apache)](https://centossrv.com/apache.shtml)
  - CGI,SSIはとりあえずやらない
- [apache php mysqlをインストール(yum)](http://qiita.com/abgata20000/items/12d60b2696278cf92d5a)
- [CentOS6／CentOS7にPHP5.6／PHP7をyumでインストール](http://qiita.com/ozawan/items/caf6e7ddec7c6b31f01e)
- [CentOS6にMySQL5.7をyumでインストール](http://qiita.com/ozawan/items/648bdc146041ceb2e390)
  - デフォルトのVersionだと古いかな？

#### セキュリティ的に最低限
- [MySQLのrootパスワードを設定](https://webkaru.net/mysql/mysql-root-password/)

#### SELinux忘れがち
- [SELinuxを無効にするには](http://park1.wakwak.com/~ima/centos4_selinux0001.html)

#### 自動起動もね
- [chkconfigまとめ](http://qiita.com/shell/items/30031862d91cedf9ceef)

#### DBバックアップとか
- [mysqldumpとcronでMySQLを自動バックアップする](http://linuxserver.jp/%E3%82%B5%E3%83%BC%E3%83%90%E6%A7%8B%E7%AF%89/db/mysql/mysqldump%E3%81%A8cron%E3%81%A7%E3%81%AE%E8%87%AA%E5%8B%95%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97)
- [rsync でディレクトリの同期（バックアップ）](http://www.maruko2.com/mw/rsync_%E3%81%A7%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AE%E5%90%8C%E6%9C%9F%EF%BC%88%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97%EF%BC%89)
  - 別サーバーがあればバックアップdumpを同期しておく

#### SSL対応
- [Let's Encrypt 総合ポータル](https://letsencrypt.jp/)
- [無償SSL/TLS証明書の Let's Encrypt の設定が劇的に簡単になっていた](https://www.websec-room.com/2016/10/01/2698)
  - 無料SSL証明書
- [Webページパスワード制限(htpasswd)](https://centossrv.com/apache-htpasswd.shtml)
  - Basic認証かけるなら

#### 必要に応じてスワップ領域
- [linux スワップ（swap）領域の作成](http://kazmax.zpp.jp/linux_beginner/mkswap.html)
Node.js とは何か？

## はじめに

[Node.js](https://nodejs.org/) の登場から8年たちますが、未だに「Node.jsとは一体何か？」という疑問を持つ人は多いと思います。[Wikipediaによれば](https://ja.wikipedia.org/wiki/Node.js)
> Node.jsとはイベント化された入出力を扱うUnix系プラットホーム上のサーバサイドJavaScript環境である(V8 JavaScriptエンジンで動作する)。

だそうです。また[別の説明](https://www.ibm.com/developerworks/jp/opensource/library/os-nodejs/)では
> Node.jsの第1の目標は「スケーラブルなネットワーク・プログラムを作成するための簡単な方法を提供すること」

となっています。
こんな言い方をするから混乱するのだと*私は*思います。私の理解はこうです。
> Node.jsとは、Google Chromeに搭載されている高速なJavaScriptエンジンV8をコマンドラインから使えるようにしたJavaScript言語処理系。付属ライブラリはノンブロッキングI/Oを特徴とし、そのライブラリを使うにはブラウザ上のJavaScriptとは異なる構文を用いる。

これは3つのことを言っています。
 1. Node.jsとはJavaScript処理系である
 2. 付属ライブラリはノンブロッキングI/Oが特徴である
 3. ライブラリの参照方法が異なるため、ブラウザ上のJavaScriptと互換性がない

## Node.js とは何か

1はNode.jsの「定義」ですが、これをはっきり言わないから混乱するのだと思います[^1]。要はjavaコマンドやperlコマンドと同じです。`node hoge.js` で hoge.js に書かれたJavaScriptのプログラムを実行します。`node` とだけタイプすると対話モードに入るので、インタフェースはshに近いといえるかもしれません。

２はNode.jsが作られた本来の目的です。コールバックを用いてI/Oを非同期で処理するプログラミング・スタイル(Ajaxのスタイル)をディスクI/Oにまで適用しました。これにより、I/Oがブロックしてもプログラム自体はブロックせず、単一のスレッドでも並列して処理できるようになりました。新たにプロセスやスレッドを起こさないので計算機資源が節約できるというわけです。思うに「ノンブロッキングI/O」という用語が誤解を生む元です。**I/Oはブロックしますがプログラムはブロックしない**のです。

3は大きな問題です。Node.jsは他のプログラミング言語と同じく「プログラムから必要なモジュールを指定」できるようになりました[^2]が、ブラウザ上のJavaScriptで問題となっていた名前の衝突を避けるために、大域変数を全く使わない方法を採用しました。逆にブラウザ上のJavaScriptではグローバル変数以外にファイルをまたがったコードを参照する方法がないので、両者は互換性がない状態となってしまいました。

## フロントエンド開発とNode.js

現在Node.jsは、本来の目的であったサーバサイドの処理よりも、むしろクライアントサイドで使われる傾向にあります。モジュール管理ツール [npm](https://www.npmjs.com/) のリポジトリが活況を呈しているため、開発者はクライアントサイドのモジュールであってもnpm向けに提供することを選択するようになっています。このためクライアントサイドでもNode.jsを使う必要が出てきました。この事情を知らないと「Node.jsって何？何が嬉しいの？」ということになるのではないでしょうか。クライアントサイドではI/Oのブロックの問題はAjaxによりとっくに解決済みでしたから。

しかしながらNode.jsの利用を前提としたフロントエンド開発には未だスタンダードになる組み合わせがなく、大変混乱しているように見えます。これがまたNode.jsの分かりにくさに拍車をかけています。少し整理してみます。

#### トランスパイラ
ライブラリ参照方法の非互換により、Node.jsスタイルで書かれたプログラムをブラウザ上で動作させるには変換が必要になります。これを行うプログラムをトランスパイラと呼んでいます。この本来の意味で現在主流なのは [webpack](https://webpack.js.org/) だと思います。
どうせ変換が必要なら、ということでJavaScriptの最新仕様を多くの処理系上でも動作するよう変換する [Babel](https://babeljs.io/) や、さらに先を行って別言語からJavaScriptに変換する [CoffeeScript](http://coffeescript.org/)、[TypeScript](http://www.typescriptlang.org/)といったトランスパイラもあります。

#### タスクランナー
変換という一処理が入ったため、makeのような依存性を意識した作業自動化のツールが欲しくなります。これを行うプログラムをタスクランナーと呼んでいます。少し前までは [gulp](https://gulpjs.com/)、[Grunt](https://gruntjs.com/) といったタスクランナーが流行ったようですが、機能が豊富で設定が複雑になりすぎたため、今では npm の提供する npm-scripts と呼ばれる機能に原点回帰しているようです。[^3]

#### テスティング・フレームワーク
今までフロントエンド開発では試験の自動化がしにくかったため、テスティング・フレームワークが採用されることはまれでした。ですがNode.jsによりバッチ処理ができるようになったため、自動テストが行われるようになってきているようです。テスティング・フレームワークでは [Mocha](https://mochajs.org/) が人気です。

Web上の記事を見ていると、むやみに開発環境を複雑にしているように感じます。何のためにNode.jsを利用するのか考え、環境をシンプルにすべきと思います。[^4]

[^1]: 人によってはApacheやnginxのライバルとなるWebサーバと思っているかもしれません
[^2]: 一方、ブラウザ上のJavaScriptではHTMLがモジュールを指定します。各モジュール内には依存するモジュールを指定する記述がありません
[^3]: npm-scriptsは依存関係すら処理できないのですが…
[^4]: 私は、webpack、Babel、Mochaで充分と思います。
CentOS6にNode.jsの導入[パッケージver]

# はじめに

開発環境を構築する程度であれば，[nvm](https://github.com/creationix/nvm) や [ndenv](https://github.com/riywo/ndenv) を使って好きなバージョンを入れられるようにしておくと良いでしょう．

ちなみに私は，[anyenv](https://github.com/riywo/anyenv)を使って 〇〇env 系を全て管理するのが一番良いのではないかと思います．
そちらの手順は割愛（[参考](http://qiita.com/luckypool/items/f1e756e9d3e9786ad9ea)）

# 本題

CentOS6.x系は `yum install nodejs npm` とやっても古いバージョンのものしかインストールされません．

そのため，[本家](https://nodejs.org/dist/)からパッケージをダウンロードする必要があります．

```sh
# Download
$ cd /usr/local/src
$ wget https://nodejs.org/dist/vX.Y.Z/node-vX.Y.Z.tar.gz
# Install
$ tar xzf node-vX.Y.Z.tar.gz
$ cd node-vX.Y.Z
$ ./configure
$ make install
```

しかし，`./configure`あたりで以下のような警告が発せられます．

```
WARNING: C++ compiler too old, need g++ 4.8 or clang++ 3.4 (CXX=g++)
```

これはCentOS6のgccのバージョンが古いために発生します．
この状態で `make install`を行うとビルドエラーが置きます．

# 解決策

そこで，まずは　gccのバージョンをアップデートしましょう.
今回は必要最低限の構成にするため，devtoolset-2を用いてgccのバージョンを4.8までアップデートします．

その後改めてnode.jsをインストールしましょう．

# 手順

## devtoolset-2のインストール

```sh
# Register Repo
$ cd /etc/yum.repos.d/
$ wget http://people.centos.org/tru/devtools-2/devtools-2.repo 
# Install devtoolset-2
$ yum install -y devtoolset-2-gcc devtoolset-2-gcc-c++ devtoolset-2-binutils
# enable devtoolset-2
$ scl enable devtoolset-2 bash
```

## node.js のインストール


```sh
$ cd /usr/local/src/node-vX.Y.Z
$ ./configure
$ make install
```

ここで`make install`が完了すればインストール完了です．

```sh
# Node version
$ node -v
# npm version
$ npm -v
```

`wget`が使えなかったら，wgetで指定したURLにアクセスして，ソースコードをダウンロードして同じ場所に配置しましょう．

以上！