OmniAICreator/Qiita-1.07M huggingface dataset:
DBバックアップ(mysqldump)の速度改善のためにやっていること

#DBバックアップがだんだん遅くなってきた！
- 運用当初は**40分**で完了していた日時DBバックアップ(全テーブルのmysqldump)
- 1年ほど運用を続けていくうちに遅くなっていき、最終的に**80分**かかるようになった

##mysqldumpはテーブル全件のselect
- selectが遅くなっている原因の一つが、テーブルの**フラグメント化**
- 主に行の削除で歯抜けが発生し、検索効率が悪くなっている

##速くするために「OPTIMIZE TABLE」を実施
```mysql
OPTIMIZE TABLE テーブル名;
```
- OPTIMIZE TABLEはinnoDBで実施すると、全件削除＋投入になる
- **delete→insertを毎日繰り返しているようなテーブルに効果が高い**

##具体的には以下のようにしてます
- ロックがかかるので、システム稼働中は流せない
- 全テーブルを5回に分け、システム停止時間帯に実施
- 01:16:28　⇒　00:51:28　　　**25分速くなった！**
- ほっておくとまた遅くなるので、**cronで月に一度実施**するように設定

※MySQLのバージョンは5.5です
ExifのOrientationを追加する


こんにちはsekitakaです。
社内の画像認識系のシステムにテスト画像をアップロードしたところ、Exifの回転情報が必須と言われました。
認識されやすい画像でテストしたいので、分かりやすい画像をPhotoshopやSketchで作ったのですが、Orientationの情報の出力ができませんでいした。
この記事は画像ファイルにサクッとExifのOrientationの情報を追加する方法について説明します。

# exiv2インストール
exiv2というコマンドラインツールを使用します。インストールは以下の通り。

```
brew install exiv2
```

# Orientationをセットする
以下のコマンドで任意のOrientationを書き込むことが出来ます。

```
# Orientation=3にするコマンド
exiv2 -M"set Exif.Image.Orientation 3" foo.jpg
```

# Orientationを確認する
以下の方法で確認することができます。
`Exif.Image.Orientation` がなかったfoo.jpgに `Exif.Image.Orientation`が追加されました。

```
# 確認コマンド
exiv2 -pt foo.jpg

# 結果
Exif.Image.Orientation                       Short       1  left, bottom #←これが追加された
Exif.Image.ExifTag                           Long        1  38
Exif.Photo.PixelXDimension                   Long        1  3609
Exif.Photo.PixelYDimension                   Long        1  3448
```

# まとめ
今回はOrientationの変更のみでしたが、exiv2を使えば色々なExif情報の書き換えができそうですね。
iScroll.js と drawer.js のハンバーガーメニューがAndroidで動かない

#概要
drawer.jsを使った、スマホ用バーガーメニュー実装で、新しいAndroidのChromeにおいて長いメニューがスクロールしない症状がありました。スクロールは、全くしない訳では無く、フリックで素早く動かすと若干スクロールするものの、通常のタップ移動では指を離したタイミングでメニューが閉じてしまいます。この不具合の修正を試みました。

#詳細
Androidでは、2016年末頃からスクロール動作を滑らかにするために、addEventListenerにイベントを登録する際、デフォルトでそのイベント内部の preventDefault を実行しないモードになりました。
jQuery の on() でイベントを登録している場合、addEventListener の第3引数に `{passive: false}` を加えられるようなオプションは無いため、drawer.js内部で on()を使用している箇所をaddEventListener を使って書き直す必要があります。加えて何かとバグの多いiscroll.js ではAndroidのタッチ動作をうまく検出出来ていない様子なので、スマホだけに表示させる画面、という前提で動作するよう修正試みました。

#修正ポイント
## drawer.js(v3.2.2)
### 19行目
iScroll.js のデフォルトオプションを定義している部分。preventDefaultが基本ONになるようにしている。
修正前

```js:drawer.js
          preventDefault: false
```
修正後

```js:drawer.js
          preventDefault: true,
```

### 107行目
修正前

```js:drawer.js
      if (touches) { 
        $this.on('touchmove.' + namespace, function disableTouch(event) { 
          event.preventDefault(); 
        }); 
      } 
```
修正後

```js:drawer.js
      if (touches) {
        document.addEventListener('touchmove.' + namespace, function disableTouch(event) {
          event.preventDefault();
        }, {passive: false});
      }
```

## iscroll.js(v5.2.0)
###42行目
内部でaddEventListnerを addEventとしてエイリアスを作っている部分があるので、ここで Android対応の書き方にする。
修正前

```iscroll.js
	me.addEvent = function (el, type, fn, capture) { 
		el.addEventListener(type, fn, !!capture); 
	}; 
```
修正後

```iscroll.js
	me.addEvent = function (el, type, fn, capture) {
		el.addEventListener(type, fn, {passive: false});
	};
```
###191行目
マウスポインタの場合の処理だが、スマホのみで使う前提なので、タッチイベントと同じものとして扱わせる。

修正前

```iscroll.js
		pointerdown: 3,
		pointermove: 3,
		pointerup: 3,
```
修正後

```iscroll.js
		pointerdown: 1,
		pointermove: 1,
		pointerup: 1,
```
###331行目
ポインター、マウスなどをdisableにする処理だが、条件分岐がAndroidの場合、望んだとおりにならないようなので、タッチデバイスしか扱わないのとChromeのデバッグ環境でも動くことを考えて修正。

修正前

```iscroll.js
		disablePointer : !utils.hasPointer,
		disableTouch : utils.hasPointer || !utils.hasTouch,
		disableMouse : utils.hasPointer || utils.hasTouch,
```
修正後

```iscroll.js
		disablePointer : false,
		disableTouch : false,
		disableMouse : false,
```

###482行目、622行目
e.preventDefault();をコメントアウト

これは
IScroll.prototype = {の中の
 _start: と
 _end: のpreventDefault を無効にしている。


以上で Android と iPhoneで正常動作するようになった。

#参考
- Android Chrome beta (v.56) でdocumentに対するtouchイベントのpreventDefaultが効かない
(http://qiita.com/ru_shalm/items/4d79e94b5d9c7c88607d)
一連の根本的な原因、ChromeのaddEventListenerについての挙動について説明があります。

- Passive Event Listeners によるスクロールの改善
(https://blog.jxck.io/entries/2016-06-09/passive-event-listeners.html)
さらに詳細な情報があって、理解が深まります。

この問題が起きているときに、Chromeブラウザのデバッグコンソールに以下のメッセージがでます。
Unable to preventDefault inside passive event listener due to target being treated as passive.
C#で静的デストラクタもどき

　C#ではstaticなデストラクタを作ることができません。そこで、静的デストラクタっぽいことを実現するコードを考えたいと思います。

#そもそも静的デストラクタって必要？

　クラスで使用するstatic変数がIDisposableなクラスの場合、

```csharp
class TestClass
{
    /// <summary>
    /// 共通のバッファみたいな
    /// </summary>
    private static DisposableClass CommonBuffer = new DisposableClass();

    /// <summary>
    /// クラスが最初に呼ばれるときにメモリ確保したい
    /// </summary>
    static TestClass()
    {
        CommonBuffer.AllocMemory();
    }

    /// <summary>
    /// 終了時にメモリを開放したい
    /// </summary>
    static ~TestClass() // ← staticなデストラクタはコンパイルエラーになる
    {
        CommonBuffer.Dispose();
    }
}
```
    
の、ようにして終了時にDisposeしてやりたいのが人情というものです。どうせ終了するんだから構わないだろうという考え方もありですが、**外部で作成されたライブラリ**を使う場合などは違ってくる場合があります。

　初期化と終了処理の機能を備えたライブラリというのは結構あるものですが、そういったライブラリは

```csharp
static void Main()
{
    // 外部ライブラリの初期化
    OuterLib.Initialize();

    // メインの処理

    // 外部ライブラリの終了処理
    OuterLib.Finalize();
}
```

このような使い方を期待されているものだと思います。ですが、**外部ライブラリを使用したクラスライブラリ**を開発する場合などは最初に示したような静的デストラクタで終了処理を行いたくなります。
　また、カメラ等の外付けデバイスの操作用ライブラリ等の場合は、正しく終了処理を行ってやらないと次回正常に起動できないケースなども稀ながら存在します（特に他の部署が作った社内向けDLLとかの場合……）。そのため、やはり終了処理を行わないというわけにはいきません。
　終了関数を新たに定義してアプリ終了時に呼ぶようにしてもらうというのも一つの手ですが、あまり親切ではありませんね。

#実装

以下のように内部Singletonクラスにデストラクタを定義してやれば、静的デストラクタのように扱うことができます。

```csharp
class TestClass
{
    /// <summary>
    /// 静的デストラクタを実現するためのSingletonパターン
    /// </summary>
    private sealed class Destructor
    {
        /// <summary>
        /// デストラクタ
        /// </summary>
        ~Destructor()
        {
            // ここに終了処理を記述！！！
            OuterLib.Finalize();
        }

        /// <summary>
        /// Singletonパターンお決まりのprivateコンストラクタ、自クラスのインスタンス、インスタンス取得関数
        /// </summary>
        private Destructor() { }
        private static Destructor instance = new Destructor();
        public static Destructor GetInstance() { return instance; }
    }
    /// <summary>
    /// 静的デストラクタ実現クラスのstaticな実体
    /// </summary>
    static private readonly Destructor destructor = Destructor.GetInstance();
}
```

　プログラムの終了時にdestructorが破棄されてDestructorクラスのデストラクタが呼ばれるので、事実上TestClassの静的デストラクタのように扱うことができます。
Prottでモバイルアプリのプロトタイピング環境を準備しよう!

※本ドキュメントは新入社員向けのトレーニング資料です。

#1.はじめに
**Prottとは**
Goodpatch社が提供しているスマホアプリ/Web向けのプロトタイピング環境の呼称です。
Prottではアプリケーションそのものの開発はできませんが、スマホアプリ/Webページのデザインやタップ時のアクション等の動作に代表されるような、設計資料上では確認できない実際のアプリの動作を作成することができます。

![alldevices.png](https://qiita-image-store.s3.amazonaws.com/0/96076/355588f3-fbec-a3ad-49f3-cc79f2d82b8b.png)


特にモバイルアプリ開発においてはデザインはもとより、UI/UXや開発スピードが重要視される傾向があります。開発を進めていく上で思い描いているアニメーション等のイメージが個々人で一致しない可能性が高く、手戻りが多く発生しているのが現状です。

これらの問題を早期に解決するためにProttを用いたプロトタイピング手法を学びます。

**プロトタイピングとは**
[「プロトタイピングは、何のため？ プロトタイピングを中心とした開発プロセスとは」](https://seleck.cc/699)が参考になります。

**Prott以外のプロトタイピングツール**
[「2017年最新版！プロトタイピングツールのまとめ」](https://www.wantedly.com/companies/Supership/post_articles/55150)が参考になります。

#2.プロトタイピング環境の準備(PC編)
**アカウントの作成**
Google Chromeにて以下のサイトにアクセスします。
https://prottapp.com/ja/

「無料ではじめる」をクリックします。
![スクリーンショット 2017-05-17 10.26.26.png](https://qiita-image-store.s3.amazonaws.com/0/96076/aa3cc8e1-3eb9-a94d-8115-47e3c44cbafb.png)


ユーザネーム、メールアドレスとパスワードを入力して「サインアップ」をクリックします。
![スクリーンショット 2017-05-17 10.27.52.png](https://qiita-image-store.s3.amazonaws.com/0/96076/7f3dbfdc-d4b6-9094-9622-c612c004791e.png)


ログイン後の画面が表示されることを確認します。
![スクリーンショット 2017-05-17 10.28.23.png](https://qiita-image-store.s3.amazonaws.com/0/96076/c6775909-6c8c-2ae8-1480-273b0c196b2b.png)

#3.プロトタイピング環境の準備(スマホアプリ編)
**Prottアプリのインストール**
実機で確認するためにiPhone/Androidのアプリをインストールします。
AppStoreもしくはGooglePlayにて「Prott」で検索します。
![IMG_0930.PNG](https://qiita-image-store.s3.amazonaws.com/0/96076/b26bcfb4-ad1e-46c8-e865-056f1d20ca63.png)

アプリの発行元が「Goodpatch inc.」であることを確認した上でインストールしてください。
![IMG_0931.PNG](https://qiita-image-store.s3.amazonaws.com/0/96076/dad43392-705e-4030-31ef-55672e010c41.png)

インストール完了後にアプリを起動します。
![IMG_0124.PNG](https://qiita-image-store.s3.amazonaws.com/0/96076/7c0c4412-91d4-defc-4473-c8f7784a8e90.png)

※iOSアプリ立ち上げ直後に通知の有無と問われるアラートが表示されることがありますが、本研修ではどちらを選択しても結構です。
<img width="414" alt="IMG_0126.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/96076/052a7806-bae3-5391-88e3-0ef5ad5e979a.png">

既にアカウントは取得しているので、「ログイン」をタップし、PCにて登録したアカウントをパスワードを用いてログインします。
![IMG_0130.PNG](https://qiita-image-store.s3.amazonaws.com/0/96076/9dd3f5bc-7402-0641-0951-37abf7357d7d.png)

ログインが完了すると以下のような画面になります。
![IMG_0167.PNG](https://qiita-image-store.s3.amazonaws.com/0/96076/e2b9d75d-401d-3788-8b8c-8f8d6a76647e.png)

プロトタイピング環境の準備は以上で終了です。お疲れさまでした。
【機械学習】パラメータの重みの初期値

今回は、さらにパラメータ更新のスタート段階の、重みの初期値に着目します。
初期値を変化させることで、交差エントロピー誤差の収束スピードがどのような変化をするのかを、プログラムで確認していきます。

```math
\def\textlarge#1{%
  {\rm\Large #1}
}
\def\textsmall#1{%
  {\rm\scriptsize #1}
}
```

# 初期値の取り方による学習推移の変化
プログラムは、現在以下のような形になっています。
![qiita_shot01.png](https://qiita-image-store.s3.amazonaws.com/0/134453/47777554-914d-13e3-50ee-8b036caf49f7.png)

隠れ層にそれぞれ、正規分布での乱数に0.01の係数で重み付けをしています。

この係数を、1.0, 0.1, 0.01, 0.001の4パターンで変化させた時の、
交差エントロピー誤差と、精度の変化をグラフで表示してみます。

OptimizerはシンプルなSGD（勾配法）を用います。

以下のような変化をします。
グラフのタイトルの「param=***」が係数に該当します。

![qiita_shot02.png](https://qiita-image-store.s3.amazonaws.com/0/134453/9b27327c-3ac2-73fc-bb58-4158301622df.png)

グラフを見ていただくと、係数が大きいほど交差エントロピー誤差の減衰スピードは
早くなっています。
一方、Accuracy（精度）を見てみると、係数が大きい1.0の場合は
精度の向上スピードは緩やかです。
また、逆に係数が小さい0.001の場合については、精度向上の立ち上がりが遅れており
こちらもあまり良い結果とは言えません。

交差エントロピー誤差の減衰、精度向上の推移でバランスが良いのは
この場合ですと、係数が0.1の場合になるでしょう。

このように、パラメータの初期値をどのように設定するかで、
学習のスピードが大きく変わってくるのが分かるかと思います。

# Xavierの初期値
上記では、係数を定数値で変化させて学習の推移を見ましたが、ロジック的には
どの層にも同じ係数を掛ける処理を行っていました。
次に紹介する、「Xavierの初期値」は層のノードの数によって、作用させる係数を
変化させます。

たとえば、前層から渡されるノード数がn個であるときには、標準偏差√nで割ってやります。
つまり以下の値を作用させます。

```math

\frac{1}{\sqrt n}

```

つまり、初期値のバラツキについては、各層ごとにノードの数で均一化しているイメージになるかと思います。

初期値の重み付けのコードは、単純に以下のように変化します。
![qiita_shot03.png](https://qiita-image-store.s3.amazonaws.com/0/134453/84ee68df-b36b-a5ee-4b6e-c06dca677bea.png)

係数として、重み付けを定数で0.1を作用させた場合と、Xavierの初期値を用いた場合を比較してグラフ化してみます。
以下のような推移となりました。
![qiita_shot04.png](https://qiita-image-store.s3.amazonaws.com/0/134453/0094ac7d-21cb-04b7-07d0-7ee94a38c44a.png)

青線が定数0.1の初期値重み、緑線がXavierの初期値です。
ほとんど推移は変わりませんが、若干Xavierの方が学習推移が早い結果となりました。

# Heの初期値
Xavierの初期値と共によく使われる初期値として「Heの初期値」があります。
作用させる値はXavierと似ていますが、標準偏差√(n/2)で割ってやります。
つまり以下の値を作用させます。

```math

\sqrt\frac{2}{n}

```


これまで、活性化関数はSigmoid関数を用いていました、Heの初期値は
活性化関数は、ReLU関数と一緒に使用します。

ReLU関数は今まで触れておりませんでしたが、以下のようなシンプルな関数です。

```math

f(x)=max(0,x)

```

つまり、xが0以下の値のときは0, xが正の値の場合はそのままxの値をとる関数です。
![qiita_shot06.png](https://qiita-image-store.s3.amazonaws.com/0/134453/8738b75c-7834-cbdc-3459-ddcfd60ccc8e.png)

Sigmoid関数の形を見ると、(x,y) = (0, 0.5)を中心に点対称のグラフです。
それに比べて、ReLu関数は負の数は0で丸められ、同時に負の領域では値のバラツキは0になります。
Heの初期値がReLU関数を採用し、値のバラツキの分散値を半分の値にしているのも、
活性化関数の形から直感的にわかるような気がします。

また、ReLU関数についての、バックプロバケーションのクラスは以下のようなコードになります。

![qiita_shot05.png](https://qiita-image-store.s3.amazonaws.com/0/134453/5057a70c-b6b4-f1e1-8acd-8476d914d04e.png)

また、ニューラルネットワークのクラスも、初期値を3パターン（定数0.01, Xavier, He）で設定できるように拡張します。
![qiita_shot07.png](https://qiita-image-store.s3.amazonaws.com/0/134453/37e156b8-c6a2-3280-f9f6-c9766597fef2.png)

それぞれの、初期値でグラフを出力すると、以下のような結果になりました。
![qiita_shot10.png](https://qiita-image-store.s3.amazonaws.com/0/134453/b196567b-120e-8531-9d2a-516a460b2b4c.png)

青線の定数0.1（Std）の重み付けの推移と、緑線のXavierの初期値での推移は
結果的に大きな差はありませんでしたが、
赤線のHeの初期値の採用したものは、交差エントロピー誤差の減衰スピードが
他のものより早い結果が得られました。
ただ、Heの場合は活性化関数でReLUを採用した影響なのか、グラフの推移の振動幅が
大きいという特徴も見られます。

以上、今回はここまで。

---
参考文献：[『ゼロから作るDeep Learning』](https://www.oreilly.co.jp/books/9784873117584/)
コードレビュー チェックリスト

*※ 本稿は元々、2016年8月頃に取引先向けに記述した文章ですが、取引先から公開について快諾頂いたため、微調整の上ここに公開しています。*

## 全般

* コードは実装が必要なものですか？
    * オープンソースライブラリなど、広く使われている、あるいは信頼性の高いコードが利用できないか検討しましょう。

* コードは動作しますか？
    * コミット、マージする前に、最低限の動作を確認しましょう。

* コードを動作させるための手順は明確ですか？
    * 最低限、コードの実行方法、依存関係を`README.md`などに書きましょう。

* コードは理解しやすいように記述されていますか？
    * 数ヶ月後の自分が読んでも理解できそうですか？
    * マジックナンバーが埋め込まれていませんか？
        * 定数化するなど、名称を与えることができないか検討しましょう。

* コードは長すぎませんか？
    * 関数（メソッド）が数十行を越える場合、分割できないかどうか検証しましょう。

* 不要なコードが残っていませんか？

## テストコード

* テストコードは記述されていますか？
    * 可能な限り記述しましょう。

* テストコードの実行結果はグリーン（正常）ですか？
    * レッド（失敗）なのであれば、その状態で本当にコミットしなければならないのかどうか再考しましょう。

## コーディングスタイル / 命名規則

* コーディングスタイルは統一されていますか？
    * コーディング標準（コーディング規約）が制定されている場合、その標準に従っていますか？
        * 例: Python - [PEP-8](https://www.python.org/dev/peps/pep-0008/)、[Google Python Style Guide](https://github.com/google/styleguide/blob/gh-pages/pyguide.md)
        * 例: C++ - [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html)

* ネストが深くなりすぎていませんか？

## 識別子

* スペルは正しいですか？

* `camelCase`、`PascalCase`、`snake_case`など、それぞれの表現と意味は統一されていますか？

    |名称|別名|代表的な用途|
    |:---|:---|:---|
    |`camelCase`|`lowerCamelCase`|Javaの変数名、仮引数名。JavaScriptのプロパティ名。|
    |`PascalCase`|`UpperCamelCase`|Java、C++、Rubyのクラス名。|
    |`snake_case`|`underline_style`、`lower_case`、`lower_case_with_underscores `|Rubyのメソッド名、変数名。|
    |`UPPER_CASE`|`UPPER_CASE_WITH_UNDERSCORES`|C言語のマクロ名。Javaの定数名。|

* 単数形、複数形は適切に使い分けられていますか？

* `tmp`、`buffer`など、汎用的過ぎる名称は使われていませんか？
    * より具体的な名称にできないかどうか検討しましょう。

* コード内で利用されている名称は統一されていますか？

* 略語を用いている場合、それは一般的な略語ですか？

* 略語を用いている場合、それは展開しても十分短い名前ではないですか？

* 対称的な処理を行っている場合、対称的な名前になっていますか？

## セキュリティ

* パスワード、秘密鍵などは埋め込まれていませんか？

## ファイル

* 絶対パスが埋め込まれていませんか？

* カレントディレクトリに依存したコードになっていませんか？
    * カレントディレクトリに依存していると、実行する環境を整えるのが大変になります。
    * スクリプトファイルからの相対パス、何らかの基準パスからの相対パスに書き換えることができないか検討しましょう。

* ファイルは適切にクローズされていますか？

## コメント

* そのコメントは必要ですか？
    * コメントで補足するより、元のコードをより分かりやすく書き換えることができないか検証しましょう。

* コードを自然言語に書き直しただけのコメントになっていませんか？
    * コメントにはコードで表現できないこと（そのアルゴリズムを採用した理由、など）を記述しましょう。

* コメントアウトされたコードは残っていませんか？

## データ型

* 配列であるべきデータですか？
    * 複数の値を渡したいという理由だけで配列が使われていませんか？
    * タプル、ハッシュ（ディクショナリ）など、他のデータ型を検討しましょう。

## コマンド / ツール

* 適切な終了コードを返していますか？
    * `Makefile`や`Dockerfile`でコマンドを呼び出す場合、終了コードが重要な意味を持ちます。
    * 異常を適切に伝えるために、`0`以外の終了コードを返すことを検討しましょう。

* 標準出力と標準エラー出力を適切に使い分けていますか？

## その他

* 乱数を使用する場合、シード（種）は適切ですか？
    * 再現性が必要な場合、シードを固定する手段を提供しましょう。

## 参考

* 書籍『[リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック](https://www.amazon.co.jp/exec/obidos/ASIN/4873115655/x7edimv35x-22/)』
* [バグを増やさないためにコードレビューのチェックリストを使う | Yakst](https://yakst.com/ja/posts/1569)
* [「リーダブルコード適用 チェックリスト」を作ってみました - Qiita](http://qiita.com/AKB428/items/574f94695de51fa1fa19)
* [IPA ISEC　セキュア・プログラミング講座：C/C++言語編　第2章 脆弱性回避策とソフトウェア開発工程：ソースコードレビュー](https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/c103.html)
NFSサーバのインストールと設定

CentOS 7にNFSサーバをインストールし、設定してみる。

```
$ cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core) 
$ df -h
$ pwd
/home/glire
$ mkdir foo
$ ls -l /home/glire/foo/
total 0
$ ls -l
total 0
drwxr-xr-x 2 glire glire 6 May 22 15:07 foo
$ ls -l /etc/exports
-rw-r--r--. 1 root root 0 Jun  7  2013 /etc/exports
$ sudo vi /etc/exports
$ ls -l /etc/exports
-rw-r--r-- 1 root root 53 May 22 15:10 /etc/exports
$ cat /etc/exports 
/home/glire/foo 192.168.119.0/24(rw,no_root_squash)
$ ps -ef | grep nfs
$ which service
/usr/sbin/service
$ sudo service nfs start
Redirecting to /bin/systemctl start  nfs.service
Failed to start nfs.service: Unit nfs.service failed to load: No such file or directory.
$ yum search nfs
$ sudo yum -y install nfs-utils
$ sudo service nfs start
Redirecting to /bin/systemctl start  nfs.service
$ ps -ef | grep nfs
root     11434     2  0 15:19 ?        00:00:00 [nfsd4]
root     11435     2  0 15:19 ?        00:00:00 [nfsd4_callbacks]
root     11449     2  0 15:19 ?        00:00:00 [nfsd]
root     11450     2  0 15:19 ?        00:00:00 [nfsd]
root     11451     2  0 15:19 ?        00:00:00 [nfsd]
root     11452     2  0 15:19 ?        00:00:00 [nfsd]
root     11453     2  0 15:19 ?        00:00:00 [nfsd]
root     11454     2  0 15:19 ?        00:00:00 [nfsd]
root     11455     2  0 15:19 ?        00:00:00 [nfsd]
root     11456     2  0 15:19 ?        00:00:00 [nfsd]
$ sudo getenforce
Disabled
$ sudo exportfs -rv
exporting 192.168.119.0/24:/home/glire/foo
```

NFSクライアントとなるホストでネットワークマウントし、試しに書き込んでみる。

```
$ sudo mkdir -p /net/bar
$ ls -ld /net/
drwxr-xr-x 3 root root 16 May 22 15:23 /net/
$ ls -ld /net/bar
drwxr-xr-x 2 root root 6 May 22 15:23 /net/bar
$ sudo mount -t nfs -o rw 192.168.119.28:/home/glire/foo /net/bar
$ df -h | grep bar
192.168.119.28:/home/glire/foo  9.4T  3.8T  5.6T  41% /net/bar
$ cp -pi /etc/hosts /net/bar/
```

NFSサーバ側のホストのファイルシステムで、問題なく書き込まれていることを確認。

```
$ ls -l /home/glire/foo/hosts
-rw-r--r-- 1 glire glire 778 Mar  8 23:01 /home/glire/foo/hosts
$ less /home/glire/foo/hosts
```
Laravelで、 `timestamp` 型はchange()できない



- Laravel 5.1 
- Doctrine 2.3

という環境。

```php
Schema::table('users', function (Blueprint $table) {
   $table->timestamp('hogehoge')->create();
});
```

の後に

```php
Schema::table('users', function (Blueprint $table) {
   $table->timestamp('hogehoge')->nullable()->change();
});
```

とすると、このような長いエラーを吐く。

```
  [Doctrine\DBAL\DBALException]                                                                             
  Unknown column type "timestamp" requested. Any Doctrine type that you use has to be registered with \Doc  
  trine\DBAL\Types\Type::addType(). You can get a list of all the known types with \Doctrine\DBAL\Types\Ty  
  pe::getTypesMap(). If this error occurs during database introspection then you might have forgot to regi  
  ster all database types for a Doctrine Type. Use AbstractPlatform#registerDoctrineTypeMapping() or have   
  your custom types implement Type#getMappedDatabaseTypes(). If the type name is empty you might have a pr  
  oblem with the cache or forgot some mapping information.                                                  
```

Doctrineのエラーだから仕方ないとのこと。

https://github.com/laravel/framework/issues/16526

DATETIME型にするしかないか。
Angular4 で Chart.js v2 を使う手順

## 雛形を作成

```
ng new practice-chart.js && cd $_
npm install --save chart.js
ng g component chart
```

## canvas で hello, world

最初に Angular4 で canvas を使う方法を確認します。まず、 描画した後にDOMに対してフォーカスを当てたいので `AfterViewInit` を使います。また、対象となる canvas 要素を `ViewChild` アノテーションを使って関連付けを行います。

edit `src/app/app.component.ts`

```typescript
import { AfterViewInit, Component, ViewChild }  from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <div style="width:800px;height:400px;">
      <canvas #myCanvas></canvas>
    </div>
  `
})

export class AppComponent implements AfterViewInit {

  ctx: CanvasRenderingContext2D

  @ViewChild('myCanvas') myCanvas

  ngAfterViewInit() {
    const canvas = this.myCanvas.nativeElement;
    this.ctx = canvas.getContext('2d')

    this.draw()
  }

  draw() {
    this.ctx.font = "30px Arial"
    this.ctx.fillText("Hello World", 10, 50)
  }
}
```

`ng serve` で動作確認を行います。

## Chart.js 

create `src/app/chart.js`

```typescript
import Chart from 'chart.ts'

export function drawBarChart(ctx) : Chart {
  return new Chart(ctx, {
    type: 'line',
    data: {
      labels: ['M', 'T', 'W', 'T', 'F', 'S', 'S'],
      datasets: [{
        label: 'apples',
        lineTension: 0,
        data: [12, 19, 3, 17, 6, 3, 7],
        borderWidth: 1,
        borderColor: "rgba(153,255,51,0.8)",
        backgroundColor: "rgba(255,255,255,0)",
      }, {
        label: 'oranges',
        lineTension: 0,
        data: [2, 29, 5, 5, 2, 3, 10],
        borderWidth: 1,
        borderColor: "rgba(255,153,0,0.8)",
        backgroundColor: "rgba(255,255,255,0)"
      }]
    },
  });
}
```

edit `src/app/app.component.ts`

```dff
 import { AfterViewInit, Component, ViewChild }  from '@angular/core';
+import { drawBarChart } from './chart'
 
 @Component({
   selector: 'app-root',
@@ -23,7 +24,8 @@ export class AppComponent implements AfterViewInit {
   }
 
   draw() {
-    this.ctx.font = "30px Arial"
-    this.ctx.fillText("Hello World", 10, 50)
+    drawBarChart(this.ctx)
   }
 }
```

## tooltip

tooltip のフォーマットを修正したい場合は以下のように options を追加します

```diff
@@ -21,6 +21,24 @@ export function drawBarChart(ctx): Chart {
         backgroundColor: "rgba(255,255,255,0)"
       }]
     },
+    options
   });
 }
 
+const options = {
+  tooltips: {
+    enabled: true,
+    mode: 'label',
+    backgroundColor: 'black',
+    caretSize: 5,
+    callbacks: {
+      beforeTitle: (tooltipItem, data) => {
+        return "========="
+      },
+      afterBody: (tooltipItem, data) => {
+        return "test test test test test test"
+      },
+    }
+  }
+}
```

## 参考URL

- http://qiita.com/clockmaker/items/c9dfe8985d35208a9cb1
- https://www.webtoolnavi.com/chart-js/
- http://www.chartjs.org/docs/#chart-configuration-tooltip-callbacks
Kotlin × DataBinding × Picasso で画像ロード

ググってでてきた方法でうまくいかなかったのでメモ。

Kotlinのバージョンは1.1.2

## うまくいかなかった箇所
KotlinでBindingAdapter使う場合は、Extension使えばいい（[参考リンク](http://jumperson.hatenablog.com/entry/2016/06/07/135256)）とあるが、Extensionだとうまくいかず。。。

http://stackoverflow.com/questions/40085724/kotlin-custom-attribute-databinding を参考にトップレベルに定義したらうまくいった。

ただ、なぜExtensionだとうまくいかないのかはわからず。ログにはこのようにでていた。`java.lang.NoSuchMethodException: com.android.ide.common.blame.Message.<init>`


## うまくいったコード
```card_view.xml
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <variable
            name="cardData"
            type="com.hoge.model.entity.CardData" />
    </data>

    ...

                <ImageView
                    android:id="@+id/card_view_user_icon"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:layout_marginEnd="8dp"
                    app:imageURL="@{cardData.userImageURL}" />
</layout>
```

```ImageViewBinder.kt
@BindingAdapter("app:imageURL")
// なぜかImageView.loadImageだとビルドとおらない・・
fun loadImage(imageView: ImageView, url: String) {
    Picasso.with(imageView.context).load(url).into(imageView)
}
```

## Tips
- ログの場所は Android Studio の Help > Show Log in Finder
- `app:imageURL` の `app` を使ってる理由は [人跡既踏: 名前空間「http://schemas\.android\.com/apk/res\-auto」の出自と意味](http://amdkkj.blogspot.jp/2016/04/http-schemas-android-com-apk-res-auto.html) にあるとおり。カスタムの属性は`app`を使う。ビルド時にアプリのURIに置き換わるらしい。
chrome58で、プライベート認証局発行のサーバ証明書が無効になる場合の対処

プライベート認証局を使って組織内だけで有効なサイトを構築しているとき、chromeブラウザが58.0以降にアップデートされると、突然、ERR_CERT_COMMON_NAME_INVALIDエラーで接続できなくなってしまう。この場合の対処法を記述する。この記事は、[このサイト](http://tech.torico-corp.com/blog/chrome58-https-ssl-cert-san-error/)の要約に加筆したようなものなので、そちらのサイトも参考にしてもらいたい。

この原因は、chromeのセキュリティー基準が変わったため、当該サーバ証明書に

<pre>X509v3 Subject Alternative Name:
        DNS:example.com, DNS:*.example.com, DNS:example.jp, DNS:*.example.jp
</pre>

のような、Subject Alternative Name (SAN)が必要になるためである。上記の例は、この認証局で2つのドメイン（example.comとexample.jp）に含まれるサーバを署名している場合である。当該サーバのドメイン名（証明書のCommon Name）は、XXX.example.com、あるいは、XXX.example.jpでなければならない。

### 設定の変更（openssl.cnf）
対処には、次の2点のみが必要である。

1. openssl.cnfの変更
2. 当該サーバ証明書の再署名、再インストール

なお、プライベートCA証明書を変更する必要はない。openssl.cnfは、例えばDebianの場合、/etc/ssl/openssl.cnfに存在する。変更および付加する部分を以下に示す。以下の項目(1)は因果関係のために示したもので、おそらく元から有効になっているだろう。

```text:openssl.cnfの変更箇所
...
[ CA_default ]
...
509_extensions = usr_cert   # (1) 元々有効なので、変更の必要はない
...
[ req ]
...
req_extensions = v3_req     # (2) アンコメント（先頭の#を除去する）
...
[ usr_cert ]
...
subjectAltName = @alt_names # (3) 追加（「usr_cert」ディレクティブの最後に）
...
[ v3_req ]
...
subjectAltName = @alt_names # (4) 追加（「v3_req」ディレクティブの最後に）

# (5) 新しいディレクティブ「alt_names」と、ドメインのリストを追加
[ alt_names ]
DNS.1  = example.com
DNS.2  = *.example.com
DNS.3  = example.jp
DNS.4  = *.example.jp
...
throwより後ろのコードへは到達しない

# <i class="fa fa-graduation-cap" aria-hidden="true"></i> 結論

* `throw`されると`catch`へ飛ぶ
* Uncaughtおよび`throw`するオブジェクトが不正な場合は、Fatal errorになる
* よって、`throw`より後のコードへは到達しない。

# <i class="fa fa-code"></i> 見かけたコード

```php:メソッド内の記述
try {
    // hogehoge
} catch (Exception $e) {
    throw new Exception(/* hugahuga */);
    return;
}
```

静的解析でもunreachableと出ていたのだが、不安になったので念のため。

# <i class="fa fa-cube"></i> どんなケースが考えられるか

`throw`したのに次の行へ行く…
ざっと考えてみて、やはりエラー関係で起きそうかなと思ったので列挙してみる。

* 例外が`catch`されない
* 不正な値が`throw`される
* 上記のエラーから意図的に復帰する

列挙と言ってもこの位しか思いつかない。

では、試す。

## <i class="fa fa-code"></i> 検証コード

```php

<?php

// http://ngyuki.hatenablog.com/entry/2013/12/24/182034 お借りしました
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
    echo "Error[$errno]: $errstr\n";
});


try {

    // 複数throwを書いているのは便宜上
    throw new aException; // PHP Fatal error:  Class 'aException' not found
    throw new StdClass;  // PHP Fatal error:  Exceptions must be valid objects derived from the Exception base class
    throw null;          // PHP Fatal error:  Can only throw objects
    throw new Exception; // PHP Fatal error:  Uncaught exception 'Exception'

    echo 'reach!';

} catch (RuntimeException $e){
}

```

以上、`E_RECOVERABLE_ERROR`でもないFatal errorでした。
なので復帰も不可。

ちなみに、
[PHP: set_exception_handler - Manual]
は
[PHP: set_error_handler - Manual]
と異なり、次の命令に継続されることはありません。
一度、`set_exception_handler`内で`trigger_error`して`set_error_handler`で継続させるというよくわからないこともしてみましたが、継続先は当然`set_error_handler`内になり意味は無いです。




# <i class="fa fa-cube"></i> おまけ

```php
<?php

set_error_handler(function ($errno, $errstr, $errfile, $errline) {
    echo "Error[$errno]: $errstr\n";
});

try {
    throw new Exception;
    hell:
    echo "Welcome to ようこそ 地ャパリパーク";
} catch (Exception $e){
   goto hell;
}
```





[PHP: set_exception_handler - Manual]:http://php.net/manual/ja/function.set-exception-handler.php
[PHP: set_error_handler - Manual]:http://php.net/manual/ja/function.set-error-handler.php
WPのページに制御文字が紛れ込んでいた話

## 概要
先日、エンジニアでは無い方がいじったWPのページに｢変なところに□□がある。絵文字など使っているのではないか。｣という報告を受けました。
確認すると、Mac環境では何も見えなかったのですがWindows環境では確かに謎の□が見えました。

## 対応したこと
最初はWPのエディタで確認していましたが、特に何も変なものは見当たらなかったので
もしかしたら見づらいせいで閉じタグが無いのを見逃してるのかもと思い
SublimeTextにコピペしてみたら変なものが見えました。

<img width="285" alt="Screen Shot 2017-05-22 at 13.05.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/147993/27852481-356b-d471-f156-47000dd05b00.png"> 
[BS]が紛れ込んでいる!

## 原因と対策
BSってなんじゃ･･･と調べてみると、**制御文字**でした。
一部のエディタでしか視認できないようです。

今回なぜ制御文字が入ってしまったのかは判明していませんが
完全に公開前のチェックを自分が怠ったのがアウトでした。
特に現場にはWindowsユーザーがほぼいないため、公開後も気付けませんでした。

コードを流用する場合でも、新規ページは公開する前にBrowserStack等で確認するのを徹底すべきですね。
確認作業がまだまだ漏れるので、きちんと習慣づけるようにしようと思ったという話でした。

## 参考記事
[するぷろで過去記事が取得できない→原因の「混入した制御文字」をSublimeTextで視認可能](http://nasimeyablog.com/slpro_control_character_sublimetext/)
[RSSフィードエラー：原因と暫定対応](http://kitamoto-nikki.keystar.jp/2015/01/31/rss-feed-error/#SublimeText)
xcodeでiOSアプリをアップロードしようとしたらエクスポートができないエラーが！！

## An error occurred during export
>  Found an unexpected Mach-O header code:0x72613c21

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37406/7082b459-d810-5038-e931-523fcfbe1fb4.png)


adhoc用エクスポートや、itunesにアップロードしようとすると、上記のようなエラーが。
「Show Logs...」ボタンがあり、、はじめてみる。
USBで端末つなげてや、シミュレータだと普通に実行できる。。。！汗

**Show Logs** ボタンを押すと対象のエラーログが見れるが、検討が付かない。。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37406/30d3e6b0-da20-1a75-d25c-27c9df1d9b3c.png)

```critical.log:
2017-05-17 09:47:32 +0000 [MT] Failed to generate distribution items with error: Error Domain=DVTMachOErrorDomain Code=0 "Found an unexpected Mach-O header code: 0x72613c21" UserInfo={NSLocalizedDescription=Found an unexpected Mach-O header code: 0x72613c21, NSLocalizedRecoverySuggestion=}
2017-05-17 09:47:32 +0000 [MT] Presenting: Error Domain=DVTMachOErrorDomain Code=0 "Found an unexpected Mach-O header code: 0x72613c21" UserInfo={NSLocalizedDescription=Found an unexpected Mach-O header code: 0x72613c21, NSLocalizedRecoverySuggestion=}
```

NSLocalizedDescription=Found an unexpected 
のNSLocalizedDescriptionあたりを疑ってgrepしてみるも、、、
わからず。

検索してみると、いくつか候補が。

* xcodeのアーカイブファイルを疑って、過去のアーカイブなど諸々削除。。駄目
* xcodeのクリーンビルド。駄目
* facebook audience network(FAN) sdk周り (OSがEl captainだったので、xcode8.21対応のFANSDKでためす。駄目。
* こんどは最新のFANSDKを入れる。そのため、別のPCで最新MacOSがはいっているxcode8.3で、、それでも駄目
* FANSDK実態をさっぱり削除(podで入れてました）....駄目
* xcodeのembedded binaryに不要ファイルがないか見る。なかった。参考：http://stackoverflow.com/questions/41786330/uploading-app-to-app-store-mach-o-header-code-0x72613c21
* NSLocalizedDescription って言っているからローアライズ周りかなとおもって、言語の切り替え設定をしている箇所をそもそも削除。。駄目
* あれ、？cocos studioのリソースファイルないに、へんなファイルが、、、plistも混じってる。。削除してみる。。。。。成功！！！！！！泣き

> * あれ、？cocos studioのリソースファイルないに、へんなファイルが、、、plistとかソースも混じってる。。削除してみる。。。。。成功！！！！！！泣き

これが原因でビルドはできるけとアップロードorエクスポートができないエラーに遭遇してしまっていたようです。。！

見つけるにとても時間がかかったので、同じ事象に遭遇した方の参考になれば嬉しいです（泣）
bash on windowsで管理しているファイルが勝手に消えてる問題

# はじめに
業務で使用している端末がWindows10のため、ansibleを叩いたりサーバにssh接続したいときのためにbash on windowsを使っています。
ついでに/home/user配下にgitディレクトリを作って、共有リポジトリの編集やらpushやらもしています。
なので形上、ローカル環境でコードの編集をしてそのまま対象サーバにコードを流したりが可能になっています。

**が！**

**「金曜日の夜にpushしたはずのファイルが消えてる！」**
という現象が、月曜日の朝にありました。
**「ansibleディレクトリ配下のhostsとserver.ymlがねえ」**みたいなことになってるわけです（それも何度も）

以前にも、[WindowsとATOMの改行コード](http://qiita.com/VTRyo/items/9f587c9d4d3ea95b3df6)が問題でサーバを停止させる事態に発展したことがあったので、「またおまえかよWindows」という感じです。

## 環境
* Windows10
* bash on windows: Ubuntu14.04
* git version 1.9.1 (Ubuntu 14.04 の公式パッケージは、1.9.1 が入ります)

bash on windows内に以下のような構成でリポジトリをpullしています。
**```/home/username/git/reponame```**

さらに、WindowsローカルのATOMで編集したいのでATOMのプロジェクトフォルダとして上記のパスをマウントさせています。
（bash on windowsの実体は/User/username/Appdata/local/lxssにある）
**```/User/username/Appdata/local/lxss/home/username/reponame/```**

これでローカルのATOMからbash on windowsにpullしたファイル等を編集できるようにしていました。

# bash on windowsの落とし穴？
結論から言うと、bash on windows内のファイルをWindowsから編集したりするとファイルがぶっ壊れるらしいのです。
> [Bash on WindowsでWindows側からUbuntu側のファイルをいじると壊れることがあるので注意](https://www.kaitoy.xyz/2016/11/19/bow-do-not-change-linux-files-from-windows/)

既知の問題だったこともあり、「本当になんだかな～だよね」って感じです。
なので、私のような使い方（bash on windows内のファイルをATOMで編集する）のはそもそも間違っていて、せめて逆にしろってことです。

* windows10内にgitリポジトリ作成する。ansibleを叩くなら/mnt/c/を使ってWindows10に入って叩く

# もっと快適な管理、編集方法はないのかよ
「vim使ってbash内で作業完結させればよくね？」と先輩はいいますが、個人的にbash on windowsで作業したくないのです。（端末Macにならないかな）

ベストプラクティス見つかったら追記します。
Unity 5.6 で SteamVR を使うとコントローラが表示されない問題の対処法

#はじめに

Unity 5.6 で SteamVR Plugin を動作させると VR 空間上にハンドコントローラが表示されないので対処方法をメモしておく。



#手順

##SteamVR Plugin を導入する
まず、ヒエラルキー上にカメラがある場合は インスペクタのチェックボックスを外してOFFっておく。
SteamVR Plugin の Prefabs から [CameraRig] をヒエラルキーにドロップする。今までならこれで実行すれば VR 空間上にコントローラが表示されていた。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/56504/90b3d518-6df8-0e07-1f87-55adb88208e2.png)

実行したところヘッドマウントディスプレイを動かすとカメラの向きは変わるものの、コントローラは表示されない。
![2.png](https://qiita-image-store.s3.amazonaws.com/0/56504/771e90a5-ba7b-e975-7d02-d99694f88424.png)


##対処方法
プロジェクトの検索窓に「Pose」と検索すると「SteamVR_UpdatePoses」というスクリプトが見つかるのでこれをヒエラルキーにある「Camera (eye)」にアタッチする。これで実行するとコントローラも表示されるようになる。
![3.png](https://qiita-image-store.s3.amazonaws.com/0/56504/9637f1d7-c4cf-e044-dbe9-9a440523c2de.png)
C#のプログラムが遅いときにもしかしたら高速化するかもしれないたった1行のおまじない [STAThread]

```Program.cs
namespace ComClientTest
{
    class Program
        static void Main(string[] args)
        {
            // COMを使った処理
        }
    }
}
```

何の変哲もないコンソールアプリケーションですが、
COMを呼び出している場合、1行のおまじないで劇的にパフォーマンスが改善することがあります。

```Program.cs
namespace ComClientTest
{
    class Program
        [STAThread]
        static void Main(string[] args)
        {
            // COMを使った処理
        }
    }
}
```

エントリポイント(この場合Main）に[STAThread]属性を付与するだけです。
あるプログラムではこれだけで速度が20倍になりました。

STAはシングルスレッドアパートメントの略で、そのほかにマルチスレッドアパートメント、中立スレッドアパートメント2つがあります。

STAを前提として実装されているCOMコンポーネントをMTAで呼び出すと余計なオーバーヘッドがかかって遅くなるらしい。
そして、C#では属性をなにもつけていないデフォルトの状態ではMTAになっているようです。

VB.NETではデフォルトがSTAであるため明示的にここを指定する必要はありません。ですので、全く同じコードを書いたのにVB.NETだと速い！　というような現象が起こりえます。

VB.NETとC#との言語の違いは.NETではILという中間言語にコンパイルされる段階で吸収されるはず。だから同じロジックなら同じように動くはず。
と高を括っていると、思わぬ罠にハマることもあるという教訓でした。

STA、MTAなどの技術的な説明はWikipediaなどにしっかりと書かれていますが、詳細はわからなくてもおまじないとしてとりあえず追加しておく、というくらいの考え方でもよいかと思います。

https://ja.wikipedia.org/wiki/Component_Object_Model

ただし、COMを使っていないプログラムではなんの効果もないと思います（未検証）。
Rubyで配列を一つずらした組み合わせが欲しい時のイディオム

Arrayクラスのeach_consメソッドを使う

```ruby
[1,2,3,4,5].each_cons(2).to_a #=> [[1, 2], [2, 3], [3, 4], [4, 5]]
[1,2,3,4,5].each_cons(2).map { |x, y| x + y } #=> [3, 5, 7, 9]
```

3つづつ欲しければeach_consに3を渡せばいい

```ruby
[1,2,3,4,5].each_cons(3).to_a # => [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
```
Pcache / APCu / APC を使えるPHPのバージョンとそれぞれの違い

## 概要
[webtools](https://webtools.yjhm214.com/text-counter)というサイトの一部ページのUIを修正した。

その時にキャッシュを導入しようかと思ったんだけど、
PHP の実行速度高速化のためにキャッシュを導入するとき、
OPcache, APCu, APC がそれぞれどの PHP のバージョンに対応しているのか、
それぞれがどういう機能なのかがいつもわからなくなるためメモ。

なお、内容は[Pcache / APCu / APC を使えるPHPのバージョンとそれぞれの違い](http://www.yjhm214.com/entry/php-cache)に書いてあることの転載。

## キャッシュエクステンションとPHPのバージョン
| PHP5.4 以前 | PHP5.5 以降 | 
|:-----------:|:--------:|
| APC       |OPcache + APCu |


## それぞれの機能
### Zend OPcache
オペコードキャッシュ（コンパイル後のコードをメモリに保存して再利用）

### APCu
ユーザーキャッシュ（オブジェクトや変数をメモリに保存して、別のリクエストからそれを再利用）

### APC
オペコードキャッシュ + ユーザーキャッシュ

## PHPのバージョンによってキャッシュが異なる理由
APC のオペコードキャッシュ機能に深刻なバグがあり、PHP5.3の時点でPHPから削除された。
↓
APC のオペコードキャシュ機能を削除し、ユーザキャッシュ機能だけを残した APCu がリリースされる。
オペコードキャッシュ機能は OPcache がカバーすることに。
↓
その後、APC の安定板がリリースされたが PHP5.5には対応していない。
↓
結果、PHP5.5以降は OPcache + APCu となった。


## 関連記事
- [Pcache / APCu / APC を使えるPHPのバージョンとそれぞれの違い(元記事)](http://www.yjhm214.com/entry/php-cache)
- [一から整理するクッキーとセッション](http://www.yjhm214.com/entry/cookie-session)
Arduino nanoでサーボモーターを動かしてみる

# はじめに

とっても安価なArduino互換機があったから、早速購入して試してみたのでレポートしてみます。

# 買ったもの

![IMG_4436.JPG](https://qiita-image-store.s3.amazonaws.com/0/114240/4fc6508d-3a0f-9d8d-d99e-dd5fbff614c0.jpeg)


[HiLetgo Mini USB Nano V3.0 ATmega328P CH340G 5V 16M マイクロコントローラーボード Arduinoと互換](http://amzn.to/2rGIZ0V)
330円

[SG90サーボ用 2軸 カメラマウント 2軸アングル FPV 空撮にも (マウント+2個SG90)](http://amzn.to/2rGtuWB)
750円

# テスト環境

[MacBook Air (13-inch, Early 2015)](http://amzn.to/2rGKKuU)
macOS Sierra バージョン 10.12.4

# 開発環境

[Arduino IDE](https://www.arduino.cc/en/main/software)
上記サイトよりダウンロードしてインストール。

# ドライバーのインストール

[ダウンロードサイト](http://www.wch.cn/download/CH341SER_MAC_ZIP.html)よりダウンロードしてインストール。

[参考URL] [MacOSX+CH340G搭載Arduino互換ボードの動作メモ](http://qiita.com/hnw/items/f5272421292eb5420546)

インストール後に再起動。

# Arduino IDEの初期設定と動作確認

起動し、「ツール」-「ボード」-「Arduino Nano」を選択。

「ツール」-「シリアルポート」「/dev/cu.wchusbserial1410」を選択。

以下のコードを書き込む。

```c:
int val = 0;

void setup() {
    Serial.begin(9600); //シリアル通信のデータ転送レート9600bpsで通信
    val = 0;
}

void loop() {
    Serial.println(val); //シリアルモニタにvalの数値を表示＆改行する
    delay(1000);
    val = val + 1;
}
```

シリアルモニタを起動し、数値が1ずつ増加していることを確認。

# 配線

以下のとおり配線。

![IMG_4449.JPG](https://qiita-image-store.s3.amazonaws.com/0/114240/f7279857-ff5c-de40-0fbe-e7d00f560f56.jpeg)

# ソースコード

以下のとおり入力。
ボタンを押すとサーボモーターが1往復するという内容です。

```c:
#include <Servo.h>

Servo myservo;

int pos = 0;
int value = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(3,INPUT);
  myservo.attach(2);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (digitalRead(3) == HIGH) {
    for(pos = 0; pos <= 180; ++pos) {
      myservo.write(pos);
      value = myservo.read();
      Serial.println(value);
      delay(5);
    }
    
    for(pos = 180; pos >= 0; --pos) {
      myservo.write(pos);
      value = myservo.read();
      Serial.println(value);
      delay(5);
    }
  }
}
```

上記コードをボードに書き込む。

# 動作確認

ボタンを押し、サーボモーターが動作することを確認。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Arduino nanoでサーボモーターを動かしてみた(^-^) <a href="https://t.co/MnQuKgqm49">pic.twitter.com/MnQuKgqm49</a></p>&mdash; Shinobu Kimura (@mix_dvd) <a href="https://twitter.com/mix_dvd/status/866504973822992385">2017年5月22日</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

できた(^-^)/
Javaの勉強 - 10

# whileを使った処理の繰り返し
これも形で覚える。

```java
while( 条件 ){
	// 処理内容
}
```

・条件を満たす間は繰り返し処理内容を実行
・条件で使える「==」とか「>」はifのときと同じ

5回処理を繰り返す場合は

```java
int i;

i = 1;
while (i <= 5) {
	System.out.println(i);
	i++;  // ←これがないとループする
}
```

・「i」の初期値はwhile前に「i=1」で設定
・「i」が「5」以下のとき**while**内を実行
・while内で「i++」として1回処理される毎に「i」を「1」加算
・「i」が「6」になったら、条件から外れるので終了

こんなところかな？
いつものフォーマットに↑のやつを追加して実行。

実行
![pic001.JPG](https://qiita-image-store.s3.amazonaws.com/0/179949/17a88c04-a9e1-cd72-fcbe-5e212523928b.jpeg)

それっぽく動いた。

# 0回繰り返し
要するにwhile内の処理を一度も実行しない。
whileより前で、条件が一致しないようにすればいい。

```java
int i;

i = 6;
while (i <= 5) {
	System.out.println(i);
	i++;
}
```

実行
![pic004.JPG](https://qiita-image-store.s3.amazonaws.com/0/179949/790a106f-3f5f-0399-f345-eb44ed4150c7.jpeg)


whileの前で「i=6」になってるからwhileの条件を満たさず
whileはスルーされる。

なぜ0回繰り返しをわざわざ試したかと言うと
次の「do-while」につながっていて。。。

# do-whileを使った処理の繰り返し
whileと同じような感じなのだけど、とりえあえず
これも形で覚えてしまう。

```java
do {
	// 処理内容
} while ( 条件 );    // ← ;を忘れがちなので気を付ける
```

・条件を満たす間は繰り返し処理内容を実行
・条件で使える「==」とか「>」はifのときと同じ

ここまではwhileと同じで、whileと異なるところが。

・**必ず一回はdo-while内の処理内容が実行される**

条件を満たしていなくても、一度はdo-while内の処理を実行する。
条件を後ろに書いてるからそうなる、ってイメージしておくか。

■ do-while前で条件を満たすとき

```java
int i;

i = 1;
do {
	System.out.println(i);
	i++;
} while (i <= 5);
```

実行
![pic002.JPG](https://qiita-image-store.s3.amazonaws.com/0/179949/a87167cc-f58e-15f9-55e2-d9484246d036.jpeg)

まぁ、whileのときと同じ結果になる。

■ do-while前で条件を満たさないとき

```java
int i;

i = 6;
do {
	System.out.println(i);
	i++;
} while (i <= 5);
```

実行
![pic003.JPG](https://qiita-image-store.s3.amazonaws.com/0/179949/07759a7a-71b4-c772-2395-0f807384a368.jpeg)

なるほど、確かに一度はdo-while内の処理が実行されてる。

条件に関係なく、一度は処理を実行したいってときは
「while」ではなく「**do-while**」を使うってことね。

おそらくそういう処理をしたい日が来るのだと思う。
ブルスク,エラーがあまりにも多発するときの対処法 [Windows10]

<h1></h1>
<h2>問題</h2>
<h3>特に重い作業をしているわけでもないのに、いきなりPCが止まる→青い画面→再起動を繰り返す。</h3>
<h2>解決法</h2>
<h3>Windowsのセーフリブートを切る</h3>
<!--more-->

Windows10になってからやけにフリーズするということで相談を受けることが多くなってきました。
今回はフリーズ→ブルスク（エラー画面）→再起動が頻繁に起こる方たちへの<strong>一時的</strong>な解決法を説明していこうかと思います。
<h2>まず</h2>
先に言っておきますが私はこの解決法を推奨しません。
元来システムがブルスクを出して再起動するのはPCに致命的なエラーが発生した時であり、再起動はエラーをそれ以上進行させないための措置です。ですので、いまから説明します方法でブルースクリーンが発生しなくてもPC内部で致命的なエラーが起きていることを忘れないで下さい。ブルスクの原因のうちのいくつかのものはユーザ（私たち）で完璧に解決しますが、それ以外のものは基本的に修理に出すか、OS自体の欠陥だったりします。ですのでブルースクリーンが出ている場合はなるべくPCの相談センターによるか、いっそのこと新しいPCを買って、気分をリフレッシュしましょう。要望があれば近いうちにHDDのデータ移行についてもまとめます。
<h2>本題の|設定方法|</h2>
お待たせしました。では手順を説明していきます。
まず、Windows10 or 8.1のデスクトップを表示させて下さい。
そしてスタートメニューを右クリック。
デスクトップだしてー
スタートメニュー（画像では右上にありますが大多数の方は左下にあります）を<strong>右</strong>クリック<a href="http://ztaka.com/wp-content/uploads/2016/12/WS000000.jpg"><img class="aligncenter size-full wp-image-90" src="http://ztaka.com/wp-content/uploads/2016/12/WS000000.jpg" alt="" width="1366" height="768" /></a>
するとこんな小メニューが！<a href="http://ztaka.com/wp-content/uploads/2016/12/WS000001.jpg"><img class="aligncenter size-full wp-image-91" src="http://ztaka.com/wp-content/uploads/2016/12/WS000001.jpg" alt="" width="1366" height="768" /></a>
そして　<strong>システム　</strong>を選択

<a href="http://ztaka.com/wp-content/uploads/2016/12/WS000002.jpg"><img class="aligncenter size-full wp-image-92" src="http://ztaka.com/wp-content/uploads/2016/12/WS000002.jpg" alt="" width="1366" height="768" /></a>
するとこんな画面になります。
左側にある　<strong>システムの詳細設定</strong>　をクリックします。

<img class="alignnone size-full wp-image-110" src="http://ztaka.com/wp-content/uploads/2016/12/WS000005.jpg" alt="" width="493" height="540" />
そして　<strong>起動と回復の設定</strong>　を押します。

<a href="http://ztaka.com/wp-content/uploads/2016/12/WS000004.jpg"><img class="alignleft size-full wp-image-94" src="http://ztaka.com/wp-content/uploads/2016/12/WS000004.jpg" alt="" width="647" height="585" /></a>

するとこんな画面が出ますので、システムエラー欄の　<strong>自動的に再起動する　</strong>のチェックを外します。

これを。('ω')ノ

<a href="http://ztaka.com/wp-content/uploads/2016/12/WS000003.jpg"><img class="alignleft size-full wp-image-93" src="http://ztaka.com/wp-content/uploads/2016/12/WS000003.jpg" alt="" width="647" height="585" /></a>

こうじゃ。('ω')

このサイトをみているがいまいちわからないということがあればコメントでもメールでもください。
大学PCサポートセンターからこのサイトを案内された方はこれでもわからなければメールください。
キャンパス内であれば手伝います。
Homebrew部　Python3にPyaudio導入の裏技

もう語録無視します。
#概要
- Homebrewでスッキリ（管理）したい。
- なんだかOpenCV3も使いたい気分だし、画像と音声の取り扱いをPython3でしたいなって人向け。
- Homebrew及びpython3導入について先駆者兄貴にお任せします。
- macOS Sierra 10.12.4
- HOMEBREW_VERSION: 1.2.1
- pip 9.0.1

#pip3でpyaudioを挿れる
もうこれが言いたいだけなんです。アホくさ。
以下のコマンド入力してください。

```
pip3 install pyaudio
```

```bash:実行画面
~$pip3 install pyaudio
Collecting pyaudio
Installing collected packages: pyaudio
Successfully installed pyaudio-0.2.11
```
じゃけん、対話モードでimportしてみましょうね。

```bash:実行画面
~$python3
```
:relaxed:

```bash:実行画面
>>> import pyaudio
Could not import the PyAudio C module '_portaudio'.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/site-packages/pyaudio.py", line 116, in <module>
    import _portaudio as pa
ImportError: dlopen(/usr/local/lib/python3.6/site-packages/_portaudio.cpython-36m-darwin.so, 2): Library not loaded: /usr/local/opt/portaudio/lib/libportaudio.2.dylib
  Referenced from: /usr/local/lib/python3.6/site-packages/_portaudio.cpython-36m-darwin.so
  Reason: image not found
```
:scream:ファッ！？これだけだとimportエラーが普通に起きて、<font color="DeepPink">"port"audio</font>関連と推測できるがファイルがないって怒られるゾ。この問題はpython2でも別の形のエラー文で、pyaudio導入に<font color="DeepPink">portaudio</font>のライブラリが不足していると怒られた経験済みの兄貴は多いはずです。

既にportaudioを導入していたらそもそも怒られないので、ここから先は蛇足。
portaudioを導入していない人はhomebrewでportaudioをインストールしましょう。

```
brew install portaudio
```

```bash:実行画面
~$brew install portaudio
==> Downloading https://homebrew.bintray.com/bottles/portaudio-19.6.0.sierra.bot
Already downloaded: /Users/username/Library/Caches/Homebrew/portaudio-19.6.0.sierra.bottle.tar.gz
==> Pouring portaudio-19.6.0.sierra.bottle.tar.gz
==> Using the sandbox
🍺  /usr/local/Cellar/portaudio/19.6.0: 33 files, 452.7KB
```
再び対話モードでimport確認。
結果が同じになる安心感の為に一応書いておきます。

```bash:実行画面
~$python3
Python 3.6.1 (default, Apr  4 2017, 09:40:21) 
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyaudio
>>> 
```
:relaxed:
#編集後記
　pip3でPython3のライブラリをインストールする事は当たり前なのですが、"Python3 pyaudio"で検索を掛けてもあまりにもapt-getとpython2の話ばかりで、この結論に至るに時間が掛かりました。Homebrew部の皆さんに、このページを捧げます。
Goでのアルゴリズムクイックリファレンス第2版(クイックソート)

Goに慣れるためとアルゴリズムの復習の為に週1ぐらいで更新していきます。[アルゴリズムクイックリファレンス 第2版](https://www.amazon.co.jp/gp/product/4873117852/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4873117852&linkCode=as2&tag=amesho-22&linkId=b7688201ae37a6234596fa96dfd3ccdd)を読んで各種アルゴリズムをGoで実装して行きます。

前回: [Goでのアルゴリズムクイックリファレンス第2版(4.3 ヒープソート)](http://qiita.com/amesho/items/9dfebcfaf5bcc7c96e24)


今回は[クイックソート](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%82%A4%E3%83%83%E3%82%AF%E3%82%BD%E3%83%BC%E3%83%88)です。

+ アルゴリズム
    + ピボットを選択
    + ピボットより小さい数を前方、大きい数を後方に移動
    + 二分割された各々のデータをソート

https://play.golang.org/p/VjUN303ejs

```go
package main

import (
	"fmt"
	"math/rand"
)

func quickSort(a *[]int, left int, right int) {
	var pivot int

	if right > left {
		pivot = partition(a, left, right)
		quickSort(a, left, pivot-1)
		quickSort(a, pivot+1, right)
	}
}

func partition(a *[]int, left int, right int) int {
	tmp_left := left
	pivotItem := (*a)[left]
	for left < right {
		for (*a)[left] <= pivotItem {
			left++
		}
		for (*a)[right] > pivotItem {
			right--
		}
		if left < right {
			(*a)[right], (*a)[left] = (*a)[left], (*a)[right]
		}
	}
	(*a)[tmp_left] = (*a)[right]
	(*a)[right] = pivotItem
	return right
}

func main() {
	var ary []int
	size := 30
	for i := 0; i < size; i++ {
		ary = append(ary, rand.Intn(size-1))
	}
	fmt.Println(ary)
	quickSort(&ary, 0, len(ary)-1)
	fmt.Println(ary)
}
```


次回はバケツソートの予定です。
Python 3 標準の unittest でテストを書く際のディレクトリ構成

Python 3 でテストを書く際に [pytest](https://docs.pytest.org/en/latest/) がよく使われているというのは耳にしたものの、とりあえず標準である [unittest](https://docs.python.jp/3/library/unittest.html#module-unittest) で書いてみるか、と思って試行錯誤したのでまとめる。

## ディレクトリ構成とコード例
いくつかのパッケージの構成を見た限りでは、パッケージのディレクトリと同じ階層にテストディレクトリを作るのがセオリーらしい。

``` console
$ tree
.
├── foo
│   ├── foo.py
│   ├──   :
│   └── xxx.py
└── tests
    ├── test_foo.py
    ├──   :
    └── test_xxx.py
```

``` python:foo/foo.py
class Foo:

    def say(self):
        return 'foo'
```

``` python:tests/test_foo.py
from unittest import TestCase
from foo.foo import Foo

class TestFoo(TestCase):

    def test_say(self):
        self.assertEqual(Foo().say(), 'foo')
```

## テスト実行

### `tests` ディレクトリ内のすべてのテストケースを実行する
``` console
$ python -m unittest discover tests
```

unittest では [discover サブコマンド](https://docs.python.jp/3/library/unittest.html#test-discovery) を使うことでディレクトリ内のテストをまとめて実行することができる。

デフォルトでは、指定したディレクトリ内の `test*.py` ファイルをすべて実行するが、オプションで変更することもできる。

サブディレクトリを再帰的に辿ってくれたりはしないらしい。

### ひとつのテストケースだけを実行する
``` console
$ python -m unittest tests.test_foo
```

注意点として、直接 `$ python tests/test_foo.py` のように実行することはできない。Python では実行されたファイルのディレクトリ (`/tests`) がトップレベルの階層として扱われるため、それより上の階層に遡ってパッケージのファイルを import することができず、エラーになってしまう。
Ruby で C言語ライクな enum を行うライブラリをつくった

[ブログ記事](http://secret-garden.hatenablog.com/entry/2016/04/14/212913)からの転載です。<del>実装があれなので書き直したい</del>

Ruby で C言語ライクな `enum` をするライブラリをつくった。  

- github - https://github.com/osyo-manga/gem-cstyle_enum

## インストール

    $ gem install cstyle_enum

## 使い方

```ruby
require "cstyle_enum"

class Color
	# enum or cstyle_enum
	Colors = enum {
		RED
		GREEN = 3
		BLUE
	}
end

Color::RED     # => 0
Color::GREEN   # => 3
Color::BLUE    # => 4
Color::Colors  # => {:RED=>0, :GREEN=>3, :BLUE=>4}
```

`#enum` のブロック内に定数を記述すると自動的にナンバリングされた定数が定義されます。  
C言語と同様に `=` で代入すればその値から続けてナンバリングされます。  
また `#enum` の戻り値は定義した定数の Hash が返ってきます。  
ユーザコードはかなり書きやすくなっているんですが、実装がかなり闇になってる…。
日付関連

```python:sample.py
from datetime import datetime 
from datetime import timedelta

today = datetime.now()
print('today = ' + str(today))
#文字列に変換
str_today = datetime.strftime(today, '%Y-%m-%d')
print('str_today = ' + str_today)
#文字列の日付指定
str_day = '2017年05月01日'
print('str_day = ' + str_day)
#日付に変換
day = datetime.strptime(str_day, '%Y年%m月%d日')
print('day = ' + str(day))

#5日前
before5 = today - timedelta(days=5)
print('before5 = ' + str(before5))
```

```
today = 2017-05-22 03:34:49.888859
str_today = 2017-05-22
str_day = 2017年05月01日
day = 2017-05-01 00:00:00
before5 = 2017-05-17 03:34:49.888859
```
MySQL大量データの削除

# いきさつ
レポート用として1時間毎にデータを作成しているのですが、レコード数が増え続けた結果、ストレージが予想以上に減ってました。
しかも、このままのペースで減ると、3ヶ月後には残ストレージがゼロに。。。

# 現状の確認
MySQLのバージョンは5.6.34です。
RDSのt2.smallで起動しています。

まずは下記SQLでサイズの大きいテーブルを確認

```sql
SELECT
    table_name,
    table_rows,
    ROUND((data_length + index_length) / 1024 / 1024) AS total_size_MB, -- 合計サイズ
    ROUND(data_length / 1024 / 1024) AS data_size_MB, -- データサイズ
    ROUND(index_length / 1024 / 1024) AS index_size_MB -- インデックスサイズ
FROM
    INFORMATION_SCHEMA.TABLES
ORDER BY
    total_size_MB DESC
;
```

一番大きなテーブルで約5200万レコードありました。
このテーブルからデータを一部残して削除したいと思います。

# 削除その１　単純にDELETE（結果：失敗）
LIMITで件数指定しながら削除しました。
が、時間がかかり過ぎます。

10万件の削除で10分以上かかり、そんなこと何度もやってられませんね。。。

# 削除その２　既存テーブルにパーティション追加（結果：未実施）
年月単位のパーティションを作成し、古いものから消していこう！
と思ったのですが、パーティション作成中は書き込みロックがかかりますね。
試しに試験系の1600万レコードでパーティション作成してみると、完了まで約40分。
本番の5200万レコードだと単純計算でも約3倍。つまり120分以上。

冒頭でお話しした1時間毎のINSERT処理に影響が出るので、別の方法を考えることに。

# 削除その３　一時テーブル（結果：OK！）
残すレコードを一時テーブルに保存。
その後、テーブル名の変更で対応することができました。

なお、数ヶ月後に同じ状況になることが予想されるので、削除しやすいようパーティションも作成しておきます。

###一時テーブルを作成
PKやINDEXの定義ごとコピーした、空のテーブルを作成します。

```sql:
CREATE TABLE
    tbl_name_tmp  -- 一時テーブル
    LIKE tbl_name  -- 元のテーブル
;
```

###パーティション作成
パーティションを作っておけば、次からの削除が楽になります。

```sql:
ALTER TABLE												
    tbl_name_tmp
PARTITION BY RANGE COLUMNS(date_column) (
    PARTITION p201701 VALUES LESS THAN ('2017-02-01 00:00:00'),
    PARTITION p201702 VALUES LESS THAN ('2017-03-01 00:00:00'),
    PARTITION p201703 VALUES LESS THAN ('2017-04-01 00:00:00'),
    （省略）
    PARTITION p202110 VALUES LESS THAN ('2021-11-01 00:00:00'),
    PARTITION p202111 VALUES LESS THAN ('2021-12-01 00:00:00'),
    PARTITION p202112 VALUES LESS THAN ('2022-01-01 00:00:00'),
    PARTITION p999912 VALUES LESS THAN (MAXVALUE)
);
```

（参考）パーティション指定の削除
パーティション指定の削除は一瞬で終わります。

```sql:
ALTER TABLE
    tbl_name_tmp
DROP PARTITION
    p201701  -- 削除するパーティション名
;
```

###データのコピー
件数が多い場合は条件を指定し、何回かに分けたほうが早いかもしれません。

```sql:
INSERT INTO
    tbl_name_tmp  -- 一時テーブル
SELECT
    *
FROM
    tbl_name  -- 元のテーブル
WHERE
    date_column >= '2017-02-01 00:00:00'  -- 残すデータの抽出条件
    AND date_column <= '2017-03-01 00:00:00'
;
```

###テーブル名を変更

```sql:
ALTER TABLE tbl_name RENAME TO tbl_name_old;  -- 元のテーブルに「_old」をつける
ALTER TABLE tbl_name_tmp RENAME TO tbl_name;  -- 一時テーブルの「_tmp」を消す
```

これで次回からはパーティション単位で削除できるはず。
つまり、作業時間は数分で終わるはず。

できればパーティションのDROPを定期実行するのが良いのですが、そこは後日調べます。(^ ^;)