OmniAICreator/Qiita-1.07M huggingface dataset:
AtomのLinterでエラー内容をコピペできない時はGitHubの最新版をインストールしよう！

2017/3/17 追記

いつの間にか、Linter 2.1.0が正式公開されてapmからインストールできるようになっていました。普通にインストールすればエラーメッセージのコピペも出来るようになっています。めでたい！

以下の情報は古くなってしまいましたが、参考までに残しておきますね。

---

Atomで[Linterプラグイン](https://atom.io/packages/linter)を使い始めてしばらく経ちました。
メッセージ内容でググったり設定ファイルに追記したりする機会が多いのに、ステータスバーで警告・エラーメッセージを選択して`Cmd-c`押してもコピーしてくれないので、泣く泣く手打ちしてました。

でもいい加減に面倒くさくなってきたので、真剣に方法を探したところ、 **apmでインストールされたものを削除してgitから最新版を持ってきてインストール**することで、クリップボードが使える上に大幅に機能がアップすることが判明！
超便利なのに何故か日本語の情報が全然ないので、画面紹介しながらまとめてみました。

[Linter-UI-Defaultの公式サイト](https://github.com/steelbrain/linter-ui-default)に載ってる方法で、プロトコルはhttpsに変えてインストール出来ました。

```
cd
cd .atom/packages
git clone git@github.com:steelbrain/linter-ui-default.git
git clone https://github.com/steelbrain/linter-ui-default.git
git clone https://github.com/steelbrain/linter.git
cd linter-ui-default
npm install
cd ../linter
npm install
```

この2つのリポジトリ、最新のtagがapmから落とせる最新バージョンなのですが、masterブランチは最新タグよりも全然新しいソースになっているんですね！なんとなくmaster=最新tagってイメージだったのでびっくり。apmでの大きなアップデートは慎重にやってるんだと思うけど、開発中のソースがどんどんmasterに載っていくとは。。。

2017/3/1時点での最新tagとmasterのバージョン対応はこんな感じでした。

|   | master | 最新tag |
|:--|:-------|:--------|
| linter            |       1.11.23 <br> (2017/2/14更新) | 1.99.0 <br> (2017/2/22更新) |
| linter-ui-default | Prepare 0.0.3 <br> (2016/3/21更新) |  0.0.3 <br> (2017/2/23更新) |

インストール完了後のUIはこんな感じ。
（わざとlinterに引っかかるソース書いたんだからね！）
![linter1.png](https://qiita-image-store.s3.amazonaws.com/0/24333/ca502cba-daac-31c9-3760-623d7d816677.png)
ボタンがシンプルになったり、結構見た目が違いますね！
ステータスバーの警告メッセージを選択して`Cmd-c`を押したところ、普通にコピー成功しました。やったー！

さらにさらに、超便利な新機能。
ポップアップ警告の最後に🔗こんなアイコンが追加されていますが、
![linter2.0.png](https://qiita-image-store.s3.amazonaws.com/0/24333/92ce557c-daec-a79a-b43c-2f18528ade13.png)

これをクリックするとブラウザが開いて、対象の警告メッセージ全体をそのまんまググってくれるのです！

```
RuboCop Prefer single-quoted strings when you don't need string interpolation or special symbols. (Style/StringLiterals)
```
バァーーーン！
![linter4.png](https://qiita-image-store.s3.amazonaws.com/0/24333/c63a205d-e1cf-32bd-6fd9-b19fe025570c.png)
まぁそのまんまググって情報が見つからんことも多いけど、その場合は一部削ればいいし「手打ちでググる」よりは相当早いのでOK！

まだ僕も入れたばっかでこれから使い込んでいきますが、超良さそうなのに普及してないっぽいのはなぜだろうか？この記事が本邦初公開だったりして(笑)

この記事読んで初めて最新版使ってみた方、すでに愛用してる方、前使ってたけど理由があってやめた方など、情報あればコメントお待ちしてます！
iOS(Swift)でアラート画面のようにViewの背景透過をする

#アラート画面をカスタマイズしたい

コードは[github](https://github.com/ngo275/ModalView)に上げておきました。
要は`vc.modalPresentationStyle = .overCurrentContext`をつけるだけと言う感じです。

##イメージ
アラート画面をカスタムする時、背景透過をするのに地味に時間がかかったのでメモ。

![modal.gif](https://qiita-image-store.s3.amazonaws.com/0/122365/773a9797-515a-3bad-9470-e0597ba539ef.gif)

##遷移元の実装

Storyboardをつかってやってみます。

遷移元のViewControllerは、アラート画面を表示した時に背景透過が確認できるように、適当な背景画像を差し込んでおきます。中央に開くボタンを設置しておいてViewControllerと繋いでおきます。

<img width="1141" alt="Screen Shot 2017-03-01 at 16.47.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/122365/43cffcae-8453-f234-4993-f59df28bdaa0.png">


```遷移元のViewController.swift

import UIKit

class ViewController: UIViewController {
    ////

    // StoryboardとUIButtonをつなぎます
    @IBAction func openAction(_ sender: Any) {
        let sb = UIStoryboard(name: "Modal", bundle: nil)
        let vc = sb.instantiateInitialViewController() as! ModalViewController
        // 背景が真っ黒にならなくなる
        vc.modalPresentationStyle = .overCurrentContext
        
        present(vc, animated: false)
    }

}

```

##遷移先の実装

遷移先のViewControllerは以下のようにStoryboardで設定しておきます。 `UIView` を差し込んでその中に `UILabel` と `UIButton` （cancel用）を入れました。ViewControllerのViewの背景色を画像のようにします。

<img width="1138" alt="Screen Shot 2017-03-01 at 16.48.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/122365/13a82c0f-c59b-dd0b-f13d-71340c4996b5.png">



```遷移先のViewController.swift

import UIKit

class ModalViewController: UIViewController {
    ////

    // StoryboardとUIButtonをつなぎます
    @IBAction func cancelAction(_ sender: Any) {
        dismiss(animated: false)
    }
    
}

```

##アラートの角を丸める

これだけだと表示したアラート画面の角が丸くなっていないので丸めます。Storyboardできるので設定します。
`layer.cornerRadius` の `Number` を設定。
`layer.masksToBounds` を `true` にします。

<img width="1139" alt="Screen Shot 2017-03-01 at 17.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/122365/16322e95-309a-a39a-d484-81e39f5291fd.png">

あとは遷移先のViewをいじるだけです。
備忘録 FuelPHPプロジェクトをGitで管理する手順(Windows)

####プロジェクトを置くディレクトリに移動

```
$ cd プロジェクトを置くディレクトリのパス
```

####FuelPHPのプロジェクトをクローン

```
$ git clone --recursive git://github.com/fuel/fuel.git プロジェクト名
```

####プロジェクトルートに移動

```
$ cd プロジェクト名
```

####プロジェクトにパッケージ類をインストール

```
$ php composer.phar self-update
$ php composer.phar update
```

####既存のGitリポジトリを削除

```
$ rm -rf .git/
```

####Gitのユーザ名メールアドレスを登録
コミットした際のユーザ名になる

```
$ git config --global user.name "ユーザ名"
$ git config --global user.email "メールアドレス"
```

以下のコマンドで正しく登録できているか確認できる

```
$ git config --global --list
user.name=ユーザ名
user.name=メールアドレス
```
####新たにGitリポジトリを作成

```
$ git init
```

####プロジェクト内のファイルをステージングエリアに追加

```
$ git add -A
```

####リポジトリにコミット

```
$ git commit -m "コミットメッセージ"
```

git log コマンドでコミットの履歴を確認できる

```
$ git log
commit SHA-1 チェックサム
Author: ユーザ名 <メールアドレス>
Date:   コミット日時

    コミットメッセージ

例：
commit 8a0934628eb658251cb182c1929daec27a3f205e
Author: Shimattta <Shimattta@g.com>
Date:   Wed Mar 1 15:20:25 2017 +0900

    Commit!
```

####リモートリポジトリの追加

```
$ git remote add origin 追加したいリポジトリのURL
```

以下のコマンドでリモートリポジトリの確認ができる

```
$ git remote -v
origin リモートリポジトリのURL (fetch)
origin リモートリポジトリのURL (push)
```

####リモートリポジトリにプッシュ

```
$ git push origin master
```

####2回目以降のaddからFuelPHPのconfigファイルを除く設定

```
$ git update-index --skip-worktree fuel/app/config/*.php
$ git update-index --skip-worktree fuel/app/config/*/*.php
```
Unity　ミニマップの作り方

unityの勉強を始めてからまだ１ヶ月ほどの者です。
ネット上のある講座？を受けて教わった事を忘れないうちにココにメモっておきます。

今回はミニマップの作り方。


Main Cameraとは別のカメラをフィールドの上に設置し、下にあるモノを映す事によってマップのようなものにする方法。

ここで説明する方法はミニマップに映すのは特定のオブジェクト(Playerだけ等)にする場合の方法です。



１，Hierarchyのcreateボタンで新しいcameraを用意。位置は上からフィールド全体を映せるように調整。Rotate(90,0,0)にすると真上から映せました。


2,設置したCameraの設定を変更する。cameraのインスペクタ内にある
｢Clear Flag｣をSolid Colorにする。
｢Projection｣をOrthograhicにする。


![miniMap.png](https://qiita-image-store.s3.amazonaws.com/0/168203/5ee2e381-e614-f27f-add0-adc8082f5883.png)



こんな感じです。




3,Imageを２つ用意する。
ミニマップの背景用(上の画像でいう白い部分)と映したいオブジェクト用のために２つ用意します。
Imageの位置、カラーは好みで。


3,ミニマップに映したいオブジェクトの下にオブジェクトを作る。
要はミニマップに映したいオブジェクト自体を映すのではなく、代役的な○とか■とかを映すのです。

![miniMap2.png](https://qiita-image-store.s3.amazonaws.com/0/168203/309f9a4f-d665-4fb7-c7b8-ca93bb82f0e6.png)


右上のやつみたいなシンプルなミニマップですね。


説明に戻ります。

Hierarchyのところにあるであろうオブジェクトを右クリック→3D object(私は3Dモードで作っていたので)→Cube(ここはお好みで)でオブジェクトを生成。
この時このオブジェクトのインスペクタを見るとColliderがついていると思いますが、ミニマップ専用のものに当たり判定はいらないので(あったら困る)これは削除します。

オブジェクトに色をつけたい場合は、ProjectのCreateボタンでMaterialを生成。Materialで好きな色を作り、それをオブジェクトをアタッチすればOK。



4,3,で作ったオブジェクトをミニマップに映すためにレイヤーを新しく作る。

cameraに映したいオブジェクトを限定するためにはcameraに映すレイヤーを限定すればいいみたいです。
まずは、そのレイヤー作りから。

3,で作ったオブジェクトのインスペクタの上にあるLayersをクリック→Edit layersをクリック

![MiniMap3.png](https://qiita-image-store.s3.amazonaws.com/0/168203/785cd6e4-7860-c7e0-6f41-969129c872fc.png)


User Layersにお好みの名前を設定。
これでレイヤーの設定は終わりです。

後はcameraに戻り、Culling MaskをEverythingからNothingにした後に、先程作ったレイヤーの名前を選択。


これでOK,なはず。


unityをほぼ何も知らない私でも実装できた方法なので、おそらく誰でも簡単にできる方法です。

以上、ミニマップ作成でした。


もっと効率のいい実装方法とかあれば是非教えてください。


ではでは。
マウスデバイスかどうかの判定

タッチデバイスかどうかは

```javascript:supportTouch.js
var supportTouch = 'ontouchstart' in document;
```

で判定できますが、window系のタブレットでは、この方法が使えません。

そこで考えたマウスデバイスかどうか判定する方法は、連続したmousemoveが発生した場合に、マウスデバイスと判定する方法です。

```javascript:detectMovableMouse.js
(function(){
  
  // over 2 mousemove events fired in 300ms
  var over = 2, period = 300; 

	var count = 0;
	var timer = null;
	   
	var mousemove = function(evt){
		if ( !timer ) {
			timer = setTimeout(function(){
				timer = null;
				count = 0;
			}, period);
			return;
		}
		if ( ++count < over ) {
			return;
		}
		document.removeEventListener('mousemove', mousemove);
		window.movableMouse = true;
		document.documentElement.classList.add('movableMouse');
		fireEvt();
	};

	var fireEvt = function(){
		var evt = document.createEvent('HTMLEvents');
		evt.initEvent('movableMouse', false, false);
		document.dispatchEvent(evt);
	};

	window.movableMouse = false;
	document.addEventListener('mousemove', mousemove);

})();
```
NMEA フォーマット > GPRMCとGPGGAの違い

http://www.hiramine.com/physicalcomputing/general/gps_nmeaformat.html

NMEA (NMEA 0183の略称)フォーマットにおいて、GPRMCとGPGGAという2つのセンテンスがある。
この二者の違いとどちらを使うかについて。

http://piyajk.com/archives/302
> GGAセンテンスからは、経度・緯度とともに、衛星の補足状態や数がわかります。GGAには測位時刻は含まれるものの「日付」が含まれません。日付を確認するためには後述のRMCセンテンスを見る必要があります。
...
> 最後はGPS測位まとめデータのような存在のRMC。基本的な情報（高度情報以外）はこのRMCセンテンスのみで取得できます。位置情報とともに日付と速度が記載されており、とても便利で重要な1行です。

http://sakaik.hateblo.jp/entries/2009/10/15
上記のリンク先の以下において「151009」が日付(2009年10月15日)のようだ。

```
 ---,$GPRMC,022236.000,A,3552.9565,N,14012.4307,E, 0.00, 0.00, 151009, ,*0A
```

日付、時刻、緯度・経度を取得する場合は、GPRMCをパースすればよさそう。
一方で、衛星の補足状態を調べる目的では、GPGGAをパースすることになるだろう。
cloud_sql_proxyをfabric経由でバックグラウンド起動する

## 背景
cloud_sql_proxyをfabric経由でバックグランド起動しようとしてハマったのでメモ

## 解決策
- オプションにpty=Falseを指定する必要あり。fabricは擬似端末でrunを実行しているので、オプションなしでバックグランド実行しても、リモートではプロセス起動しない。
- `>& /dev/null` が必要。ないと接続時に落ちる。

```
@task
def start_cloud_proxy():
    """Start cloud_proxy servers"""
    run("./cloud_sql_proxy -instances=%(gcs_id)s=tcp:3306 >& /dev/null &" % { 'gcs_id':env.gcs_id}, pty=False)
```

env.gcs_idにはcloud_sqlの接続情報が入ります.(project_id:asia-northeast1:instance-nameみたいなやつ)

## 参考
http://qiita.com/ictusidera/items/b9d78f7d213ce2a6ed84
Play Framework で FirebaseAuth をつかってカスタム認証フローを作る

# 概要

FirebaseAuth は Java 向けに SDK を公開していますが、Java の資産を活かせる言語であればこの SDK を使うことが出来ます。
この記事では、Scala 用の Play Framework でサーバを構築し自前でユーザ認証フローを作っている場合に、FirebaseAuth を組み込んでカスタム認証の対応をする手順を紹介します。

# Firebase SDK の導入

`build.sbt`に依存を追加します。

```scala:build.sbt
libraryDependencies ++= Seq(
  "com.google.firebase" % "firebase-admin" % "4.0.3",
);
```

コンパイルして完了です。

```
$ activator compile
```

# FirebaseApp の初期化

## サービスアカウントの設定

[サーバに Firebase を追加する](https://firebase.google.com/docs/server/setup?hl=ja)ページにある通り、サービスアカウントをコンソールで作成します。作成したら、認証情報をふくむ JSON ファイルをダウンロードし、プロジェクトの`conf`ディレクトリ以下に配置します。

## FirebaseApp の設定

`GlobalSettings#onStart(Application)`をオーバライドして、アプリケーションの起動時に初期化するようにします。

```scala:GlobalConfig.scala
object GlobalConfig extends GlobalSetting {
  override def onStart(app: Application): Unit = {
    super.onStart(app)
    val options = new FirebaseOptions.Builder()
        .setServiceAccount(new FileInputStream("conf/service_account_info.json"))
        .setDatabaseUrl("https://your_app_name.firebaseio.com")
        .build()
    FirebaseApp.initializeApp(options)
  }
}
```

# カスタムトークンの取得

`FirebaseAuth#createCustomToken(String)`を使います。同期的な処理のフローで使う場合は、`Tasks.await(Task<Result>)`で包んで使います。

```scala:AuthService.scala

// REST な API の要求を受けてユーザ情報を検証・保存し、そのユーザ情報をクライアントに返すまでの処理をするクラス
class AuthService {
  def auth(): UserData = { // this method could have some args
    val user = // build a new user or fetch user data from database
    val token = // token data for this server (e.g. access token, refresh token) (not for firebase)
    val customToken = Tasks.await(FirebaseAuth.getInstance().createCustomToken(user.id))

    new UserData(user.id, user.name, token, customToken)
  }
}
```

カスタムトークンをクライアントに返せば、クライアントがそれを使って Firebase にサインインできるようになります。

# 注意点

FirebaseApp の初期化の手順は Play Framework のホットスワップと最高に相性が悪いので、コードの変更の都度アプリケーションを再起動してやる必要があります。(FirebaseApp が初期化されたかどうかのチェックをするメソッドがない。FirebaseApp#getInstance()で例外をキャッチしたら初期化みたいなことをすればよいかもしれないが…)
Linuxで時刻を調整

中古で買ったThinkPad X240で時刻が合わなかったので調整した。そのメモ。


```bash
# ローカルタイムを設定
sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

# ハードウェア時刻を設定
sudo hwclock --set --date '1 Mar 2017 3:23'

# ハードウェア時刻をシステム時刻にシンクロ
sudo hwclock --hctosys
```

参考
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/sect-Configuring_the_Date_and_Time-hwclock.html
ターミナルでフォルダ名を一括置換

# 背景
フォルダ名が連番などで保存されていて、そのフォルダ名をまとめて置換したい場合に適用できます。
　具体的な例だと、folder0, folder1, folder2, ... , folder100 といったフォルダ名をまとめてdir0, dir1, dir2, ... , dir100　と置換したい場合。
　最初は、awkで変換してたけど、もっと簡単な方法(renameとshellの変数展開）をコメントで教えてもらいました。

# 方法
## renameを利用する方法
おそらくこれが一番簡単。 

```Bash:terminal
rename s/folder/dir/ folder*
```

## bashの変数展開を利用する方法
Bashを使ってる場合は、シェル変数の展開時に文字列を置換してしまうことができます。

```Bash:terminal
for n in folder*; 
  do mv $n ${n/folder/dir};
done
```

## awkで変換する方法
最初に思いついた方法。ちょっとシンプルじゃなくて恥ずかしいですね。

```Bash:terminal
ls -d1 folder[0-9]* | awk '{print $1, $1}' | awk '{gsub("folder", "dir", $2); print "mv", $1, $2}' | sh
```
Mac OS Xでmysqlのパスワードを消去する方法

brew install mysqlでインストールしたmysqlのパスワードを消去する方法
時間を置いて2回はまったのでメモしとく

# 手順
1. /usr/local/bin/mysql.server stop
- /usr/local/bin/mysql.server start --skip-grant-tables
 - これでパスワード無しでmysqlにログインできるようになる
- mysql
 - 以後、mysqlでのコマンド
- use mysql;
- update user set authentication_string=PASSWORD("") where User='root';
- flush privileges;
- exit
- /usr/local/bin/mysql.server restart
- おわり
SKK用のはてな辞書を作成する(追記あり)

# SKK用のはてな辞書を作成したい
一昨日、SKKに出会って感動する。(ユーザ生活3日目w)
Google系のCGI Serverを使いたくないので辞書生活を選択。
はてな辞書が良いらしい。

## Ruby?Pythonでおｋ
### Ruby環境ないし・・・・
- rubyでのソースは沢山あるのにpythonがない
- 10分かからずpythonコードはできた
- ~~CorvusSKKで読み込む→文字コードエラー→苦しむ~~
  - ~~家でビルドして、Dictionary持ってきたがエラー~~
  - ~~CorvusSKK?Windows?の問題くさい~~
- SKKFEPは辞書作るのが楽そう
 - SKKFEPで登録できた!
 - SKKFEPと生きていきます!

### 追記(2017/3/3)
- CurvusSKKでの取り込みを教えて貰いました
    - @corvussolisさん、ありがとうございます。

てことで、対したことないがソース

```py:make_skk_dic.py
# coding=utf-8
import pandas as pd
import numpy as np
import codecs
import re


def furi_del_norm(txt):
    r = re.match(r"[ァ-ヶ]", txt)
    if r:
        return np.Nan
    return txt


def main():
    df = pd.DataFrame()
    with codecs.open("keywordlist_furigana.csv", 'r', "euc_jp", "ignore") as file:
        df = pd.read_table(file, delimiter="\t")
    df.columns = ["furi", "word"]

    df = df.dropna()
    df["word"] = df["word"].replace('\r')
    df["furi"] = df["furi"].replace('\r')
    df["furi"] = df["furi"].apply(furi_del_norm)
    df = df.dropna()

    df = df.sort(columns=["furi"], ascending=True)

    # to_csv駄目
    TMP_FILE_PATH = "SKK-JISHO.hatena"
    with codecs.open(TMP_FILE_PATH, 'w', "utf-8", "ignore") as file:
        # CorvusSKKなら以下を有効に(追記:2017/03/03)
        # file.write(";; okuri-ari entries.")
        # file.write(";; okuri-nasi entries.")
        for i, row in df.iterrows():
            file.write("%s /%s/" % (str(row["furi"]), str(row["word"])))
            file.write("\n")


if __name__ == "__main__":
    main()

```
CSVでいっぺんにBacklogチケットを流し込む方法


##プログラム

Gitで公開されている以下のプログラムがとっても便利です。

https://github.com/ikikko/backlog-template-issue-gas/wiki

手順については上記Wikiで十分にわかると思うので省略します。

##注意点

パスワードなどの入力ダイアログが出てこなくて困りました。
「Backlog > 課題一括登録」を選択したときの認証アカウントと、シートのコピーをしたGoogleアカウントが一致しないと駄目みたいです。
複数アカウントをお持ちの方はご注意ください。

###BacklogのスペースID

BacklogのURLに入ってるやつです
参考　http://www.backlog.jp/faq/service/what-id.html
PHPerがつまづいたRubyの仕様(その3)

PHPから離れてだいぶ経つけど脳内は相変わらずPHPer。
で、あるデータを加工しなきゃってときの実装時にちょいハマったのでメモ。

---

intはsym化できない

```
[1] pry(main)> a = :1
SyntaxError: unexpected tINTEGER, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END
[1] pry(main)> a = :'1'
=> :"1"
[2] pry(main)> a.to_i
NoMethodError: undefined method `to_i' for :"1":Symbol
from (pry):32:in `<main>'
[3] pry(main)> a.to_s.to_i
=> 1
```

まぁ、ここまでは当たり前っちゃ当たり前なんだろうけど、PHPer的に

```
{
  1: 'hoge',
  3: 'piyo',
}
```

みたくハッシュを書こうとしたときに怒られちゃった...(´・ω・`)
OpenSSH 6.6.1p1 にて sshd_config の StrictModes (yes|no) それぞれの authorized_keys パーミッションの挙動について

# OpenSSH 6.6.1p1 sshd_config StrictModes パラメーターごとの、authorized_keys パーミッション設定の挙動について

- CentOS 7.2 パッケージ : openssh-server-6.6.1p1-25.el7_2.x86_64

## /etc/ssh/sshd_config StrictModes **yes** 時(デフォルト)の挙動

- authorized_keys パーミッションが、オーナー(owner)以外に**読み込み権限**のみある場合、公開鍵認証は許可される。
- authorized_keys パーミッションが、オーナー(owner)以外に**書き込み権限**がある場合、公開鍵認証は**拒否**される。
- authorized_keys パーミッションが、オーナー(owner)に対して読み込みのみでも、読み書き両方に権限があっても、公開鍵認証に影響は無い。

## /etc/ssh/sshd_config StrictModes **no** 時の挙動

- authorized_keys パーミッションが、オーナー(owner)以外に**読み込み権限**のみある場合、公開鍵認証は許可される。
- authorized_keys パーミッションが、オーナー(owner)以外に**書き込み権限**がある場合でも、公開鍵認証は**許可**される。
- authorized_keys パーミッションが、オーナー(owner)に対して読み込みのみでも、読み書き両方に権限があっても、公開鍵認証に影響は無い。

## authorized_keys ファイル以外への影響

- 2017/3/1 時点では未調査
- man sshd_config を参照するに、"Specifies whether sshd(8) should check file modes and ownership of the user's files and home directory before accepting login." と書かれているのみで、user's files が具体的にどれを指すのか列挙されていない。
- 他のホームディレクトリ内に設置される openssh 関連ファイル、ディレクトリに影響があると考えられる。
ZIPから導入したCakePHP(2系)にComposerをセットアップ

CakePHP本体をzipやtarから導入したあとにComposerで色々なライブラリを入れたい場合があるかと思います。
app/Vendor配下に色々とzipからライブラリを入れた後に、Composerを後追いで入れたい場合もあるかと思います。

CakePHPをComposerから導入する記事は多いのですが、このケースの記事はあまり見かけませんでした。。
ということで、zipから導入したCakePHPに対してComposerをセットアップする方法をまとめました。


概要としては、以下を満たせればよさそうでした。

* CakePHPではvendorではなくVendor(先頭大文字)なのでディレクトリ名を明示
* Vendor/autoload.phpをConfig/bootstrap.phpで読み込む


appディレクトリ直下に以下のcomposer.jsonを配置します。

```json:app/composer.json
{
    "config": {                                                                                                                                                                           
        "vendor-dir": "Vendor"
    }
}
```

appディレクトリ直下で、composerを実行します。

```bash
$ composer require {library}

や、composer.jsonに記述したうえで

$ composer install
```

app/Vendor/autoload.phpが生成されるので、app/Config/bootstrap.phpで読み込みます。

```app/Config/bootstrap.php
App::import('Vendor', 'autoload');
```

この状態で、ModelやControllerからComposerで導入したライブラリを呼び出せるようになりました。
ComposerからCakePHPを導入した場合は、appディレクトリより上にcomposer.jsonがあると思いますので、それをそのまま使うほうが良いかと思います。

参考）
https://soarcode.jp/posts/201
KOMAINOプログラミングで気づいた雑多なこと

# KOMAINOプログラミングで気づいた雑多なこと

千石電商やシリコンハウス共立で売っている、ESP-WROOM-02をMicro:bit風に仕立てたKOMAINOについて、はまったこと、調べたことなどを書き連ねます。

- 本家サイトはこちら。http://omniment.co.jp/komaino/ja/
- 開発チュートリアルはこちら。http://omniment.co.jp/komaino/ja/start/
- GitHubリポジトリはこちら。https://github.com/Omniment/KOMAINO

##Arduino IDEについて
プログラムのアップロードには、USBケーブルではなく、WiFi経由のArduinoOTAで行います。

APモードのKOMAINOにWiFiで接続するのですが、WiFiパスワードが、チュートリアルの「1.環境構築」のページではなく、「2.文字を流す」のページに書かれているので、「1-2.KOMAINOをSTAモード（子機モード）にする」のプログラムを書き込もうとして、戸惑いました（後づけで、この章を挿入したのでしょう）。

WiFi接続後、しばらく待てば、ArduinoIDEメニューの「シリアルポート」に、ネットワークポートとして、「KOMAINO-xxxxxx at 192.168.4.1」という項目が出現するはずなのですが、いつまで待っても出現しませんでした。ここで、Bonjourブラウザでデバイスを検索すると、直ちに項目が出現するので、KOMAINOの問題ではなさそうです。

以下は、Bonjourブラウザで観察したKOMAINOからの通知です。

![bonjourbrowse.jpg](https://qiita-image-store.s3.amazonaws.com/0/119076/355d5aab-8c94-1673-0798-98ed4bac8c9d.jpeg)

KOMAINOのボードマネージャーには、ESP8266のボードマネージャを全て含んでいるようなので、KOMAINO専用ライブラリとバッティングしない限り、ESP8266のライブラリは全て使用できるはずです。

##シリアルポートについて
KOMAINOに面ファスナーで接着されている電池ボックスをはずすと、2.5mmミニジャックが見え、基板にCOM_EXTの刻印があります。
![KOMAINO-serial.jpg](https://qiita-image-store.s3.amazonaws.com/0/119076/20018508-d929-e4ec-bcc4-14822e617e97.jpeg)

4極と思われますが、ジャックを見ると、3極かもしれません。接続は、以下の図のようになっていました。
![シリアルポート4極プラグ.jpg](https://qiita-image-store.s3.amazonaws.com/0/119076/9dd1a323-e31c-0627-e7c9-b162be464ed1.jpeg)

TxD、RxDは、KOMAINO側の表記です。RxDは、ESP-WROOM02の11ピン（RxD）と8ピン（Boot SEL2）に接続されているので、リセット時にこの線をLOWレベルにセットしておくと、WROOM02をダウンロードモードで起動できます。PC側のシリアルポートに接続するときは、RxDとTxDをクロスして接続します。

KOMAINOのシリアルポートをUSBシリアル変換器経由でArduinoIDEのシリアルモニタに接続して、Serialオブジェクトからの出力を受信することができました。しかし、プログラムのアップロードは、エラーが出てできませんでした。
ssh_config で Host名を動的に設定する

## やりたいこと

`ansible` や `chef` を使ってサーバを簡単に構築できるようになった昨今、デプロイにおいても「新しいサーバを構築して古いサーバを捨てる」といった手法ができるようになっています。
新規で構築されるサーバには無論新しいIPが振られる訳ですが、毎度 `.ssh/config` に追加していくのは正直ダルいなーと思っていたので、 `config` いじらずにやる方法ないかなーと思って調べてみました。
が、意外といい情報が見つけられず・・・、、

## やったこと

`ssh_config` の `ProxyCommand` を使います。（この子は多段SSH目的でよく使われるようです。）

```~/.ssh/config
Host group01-*
  ProxyCommand /bin/nc 172.31.1.$(echo %h |cut -d- -f2) %p
```

### 使い方

```
$ ssh group01-5
=> connect to 172.31.1.5
```


### 参考

- [SSH_CONFIG の man](https://euske.github.io/openssh-jman/ssh_config.html)
TextViewのテキストをObjectAnimatorでいじる

TextviewのsetTextの中で`---`をアニメーションで表すめも。

ObjectAnimatorを作るメソッド

```
 public static ObjectAnimator addHyphen(TextView targetView) {
        ObjectAnimator objectAnimator = ObjectAnimator.ofObject(targetView, "Text", new TypeEvaluator() {
            @Override
            public Object evaluate(float fraction, Object startValue, Object endValue) {
                return (fraction < 0.5) ? startValue : endValue;
            }
        }, "-", "--", "---");
        objectAnimator.setRepeatCount(ValueAnimator.INFINITE);
        objectAnimator.setDuration(3000L);
        return objectAnimator;
    }
```

呼び出し側

```
ObjectAnimator objectAnimator = addHyphen(textView);
objectAnimator.start();
~~
objectAnimator.cancel();
```

これで`-`→`--`→`---`となるアニメーション作れる。
元
http://stackoverflow.com/questions/8227899/objectanimator-using-charsequence-setters
wgetで対象URLのページを表示するためのソースを引っ張る(js, css, img含め)

wgetをちゃんと使ったことがなかったのでメモ。

表題のことを実現するコマンド

```bash
$ wget -k -p -nH -N https://hoge.com/
```

- 403とかで怒られた場合、`-U ""`でユーザーエージェントを設定できる

```bash
$ wget -k -p -nH -N -U "" https://hoge.com/
```

- postデータが必要なページの場合  
postデータはchromeの場合、Networkタブで該当ページのHeadersを見る  
Headersの一番下のForm Dataのview sourceをクリックすれば見れる  

```
$ wget -k -p -nH -N -U "" --post-data="hoge=fuga" https://hoge.com/
```

- wordpress等動的なサイトの場合

`--html-extension`を追加

```
$ wget -k -p -nH -N --html-extension  -U "" https://hoge.com/
```


recursiveオプションとかでwebサイト一式ダウンロードも可能なようなので  
使う時があったら追記します。。
CentOS7+MariaDB10.1でGaleraClusterを構築する

# インストール手順
CentOS7にMariaDB10.1をインストールしてGalera Cluster有効にする手順です

## MariaDB 10.1のインストールと設定
yum リポジトリを追加

```
# cat /etc/yum.repos.d/MariaDB.repo
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.1/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
```

MariaDBをインストール

```
# yum --enablerepo=mariadb -y install MariaDB-server
```

設定ファイル

```
# cat /etc/my.cnf.d/galera.cnf
[galera]
# Mandatory settings
wsrep_on=ON
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_address="gcomm://{{all_ipaddress}}" 
wsrep_cluster_name="Galera_Cluster" 
wsrep_node_name="{{ inventory_hostname }}" 
wsrep_node_address="{{ ansible_host }}" 
binlog_format=row
default_storage_engine=InnoDB
```

* {{all_ipaddress}}　クラスタに参加するサーバのIPアドレスを , 区切りで並べたもの。動作しているサーバのIPが一つでもあればよい。例）192.168.1,10,192.168.1,11,192.168.1,12
* {{ inventory_hostname }}　サーバ自身のホスト名
* {{ ansible_host }}　サーバ自身のIPアドレス

↑実はansibleの設定ファイルのテンプレート

# 起動
１台目（最初に起動するサーバ）
```
galera_new_cluster
```
２、３台目
通常のmysqlの起動方法でOK
```
systemctl status mysql
```
# 起動方法について
wsrep_cluster_addressに記載されたIPのどれか一台が起動していないと起動できない。
このため、１台目は、特別なコマンドgalera_new_clusterで起動する

１台目の起動方法は、ネット上に古い情報が多くる
wsrep_cluster_address="gcomm://" とする方法は、古い方法
service mysql bootstrapで起動する方法は、CentOSではsystemdを使ている為、うまくいかない
galera_new_cluster　コマンドを使う方法が正しい。
クラスターが動作している状態で起動するときに１台目を停止、起動する場合には、mysqlのサービス開始でよい。galera_new_clusterを使用するのは、一台も動作していない状態で起動する時。
crossorigin属性の追加によりChromeでCORSが発生する問題

`Access-Control-Allow-Origin`ヘッダを正常に追加したにもかかわらずapp.jpからassets.app.jpにあるアセットにアクセスしようとした際に以下のエラーが出ることがあります。

```
Access to Script at 'https://assets.app.jp/application-abcdefghijklmn.js' from origin 'https://app.jp' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://app.jp' is therefore not allowed access.
```

これは `Access-Control-Allow-Origin`ヘッダが付いていない状態でscriptタグによるjsの読み込み部分に `crossorigin`属性を追加した時と同じ挙動です。発生原因はjsのキャッシュです。

[こちら](https://bugs.chromium.org/p/chromium/issues/detail?id=409090)によるとChromeでは `Access-Control-Allow-Origin`などのヘッダーがキャッシュされないために起こる問題と書かれています。

## 回避方法
以下の2つの回避方法が考えられます。

* ファイル名を変える
* ACCESS_CONTROL_MAX_AGEをなるべく短く設定する([参考](https://productforums.google.com/forum/#!topic/chrome/n54KLDxBuY0))

自分の場合はRailsのproduction環境だったのでasset:precompileで生成されるハッシュを変えればよさそうだったため適当なjsファイルに空行を追加してデプロイしました。
i18nを利用した、多言語対応サイトで良くある事

## translation missing に悩まされていたら

```<span class="translation_missing" title="translation missing: hogehoge">hogehoge</span>```

## 下記を記述してリクエストスペックで解決!

```ruby
module I18nMacros                                                                                                                                                                                              
  def t(*args)
    I18n.translate!(*args)
  end
end
```
```ruby
RSpec.configure do |config|
  config.include I18nMacros
end
```
Neutron LBaaS で https な Web サーバの負荷分散を行う際の留意事項

# イントロ

OpenStackのエコシステムの中でネットワークを担当する Neutron には、L2やL3の基本機能以外にも、FWaaS、VPNaaS、LBaaS 等、さまざまな拡張があることはもう周知のことかと思います。

LBaaS を使ってWebサーバの負荷分散を行いたいと思った場合、https なサービスをどう扱ってやればよいのか、少し留意事項があるので紹介したいと思います。

# Neutron LBaaS v2 のわかりにくいところ

Neutron LBaaS v2 では、https 用のリスナ(listener)を作成することになります。
コマンドとしては、```neutron lbaas-listener-create``` に適切なオプションで所望のパラメータを指定します。このマニュアルは以下にあるのですが...

https://docs.openstack.org/cli-reference/neutron.html#neutron-lbaas-listener-create

ここで出てくる、--protocol として指定できる TCP, HTTP, HTTPS, TERMINATRED_HTTPS の4つがそれぞれ何を意味しているのかわかりにくい…というのが今日の本題です。

以下、前提として、バランサの実体としては Neutron LBaaS 標準の HAProxy を使うことを想定します。また、以下の記述は Octavia driver を使うかどうかには依存しないはずですが、私は Mitaka + Octavia 環境で確認を行っています。

## TCPはどういう場合に指定するべきなのか？

haproxy の haproxy.cfg の　listen セクションで tcp と指定したことになります。
したがって、L7ではなくL4レベルのバランシングを指定したことになります。
http/https 以外のプロトコルのバランシングを行う場合にはこれを使います。

## HTTP

これは文字通りです。
haproxy の haproxy.cfg の　listen セクションで http と指定したことになります。

## HTTPS と TERMINATED_HTTPSの違い

これが一番わかりにくいはまりどころだと思います。

まず、HAProxy の上流のマニュアルを眺めてみてください。

* https://www.haproxy.com/doc/aloha/7.0/deployment_guides/tls_layouts.html

大きく4つのやりかたがあることがわかります。

## HTTPS とは

--protocol に HTTPS と指定した listener を作成した場合、HAProxy で言うところの "SSL/TLS passthrough"　を使うことになります。

* https://www.haproxy.com/doc/aloha/7.0/deployment_guides/tls_layouts.html#ssl-tls-passthrough

具体的には、HAProxyは単純に tcp 443 (通常の場合。port は変更することも可能)待ちうけてTCPを終端します。この後、TLSやSSLの処理はいっさい行わず、そのまま backend server群にTCPでコネクションをはり、トラフィックをそのまま流します。

言い換えれば、この場合はバランサ(実体は通常 HAproxy)は、トラフィックの中身に関知しないということです。さらに言えば、アクセス元の client のIPを拡張ヘッダ(X-Forwarded-For:)で backend に通知するというようなこともできません。

## TERMINATED_HTTPS とは

一方、TERMINATED_HTTPS と指定した場合は、HAProxy で言うところの "SSL/TLS offloading" を指定したことになります。

* https://www.haproxy.com/doc/aloha/7.0/deployment_guides/tls_layouts.html#ssl-tls-offloading

この場合、HAProxy が TLS/SSL レベルで終端処理を行います。
また、HAProxy 用語で言うところの backend へは、暗号化なしの HTTP でトラフィックを転送します。
このように、暗号処理をWeb サーバからロードバランサに移転しているため、"offloading" と呼ばれています。

なお、重要なポイントとして、この場合は HAProxy にサーバ証明書と private key を配置する必要があるわけですが、OpenStack Neutron LBaaS v2の枠組みでは、Barbican というコンポーネントに証明書と private key の集中管理をまかせることになります。Neutron LBaaS は、Babican から必要な証明書と private key を入手します。この際、private key は **passphrase なしで運用**する必要があるというのも重要な留意事項かと思います。

# まとめ

* Neutron LBaaS v2 で https をバランシングしたい場合、--protocol オプションに HTTPS か TERMINATED_HTTPS のいずれかを指定できます。
* passthrough (HAProxyは中身に関知しない)を使いたい場合は HTTPS を指定してください。
* offload を使いたい場合は、TERMINATED_HTTPSを指定してください。
  * TERMINATED_HTTPSを使用する場合、証明書/private key を Barbican に管理させる必要があります。
MacのTerminalでのショートカットキー 

# はじめに
検索しても見つからなかったので、実際に色々検証した結果をまとめていきます。
今後も何か見つかれば、追加していきます。

何か間違いや記載されていないコマンドなどありましたら、ご教授いただければ幸いです。

# カーソル移動


|  入力  | 効果 |
| ---- | ---- |
| Ctrl + f | １文字右に移動（カーソル→と同じ） |
| Ctrl + b | １文字左に移動（カーソル←と同じ） |
| Ctrl + a | 行先頭に移動 |
| Ctrl + e | 行末尾に移動 |
| Esc, f | １単語分右に移動 |
| Esc, b | １単語分左に移動 |
| option + → | １単語分右に移動 |
| option + ← | １単語分左に移動 |
| fn + ↑ | １画面分上にスクロール |
| fn + ↓ | １画面分上にスクロール |

# カット・ペースト

|  入力  | 効果 |
| ---- | ---- |
| Ctrl + k | カーソル位置から行末までの入力を切り取る |
| Ctrl + u | カーソル位置から行頭までの入力を切り取る |
| Ctrl + w | 前の単語を切り取る |
| Esc, Del | 前の単語を切り取る（Ctrl + wと同じ？） |
| Esc, d | 後ろの単語を切り取る |
| Ctrl + y | 切り取った文字列を貼り付ける |

# 画面クリア

|  入力  | 効果 |
| ---- | ---- |
| Ctrl + l | 現在のカーソル行を一番上に（clearと同じ） |
| ⌘ + k | 現在のカーソル行を一番上に（clearと違い以前のものは見れない）|
| ⌘ + l | １つ前に実行したコマンドの表示を削除 |

# 画面分割

|  入力  | 効果 |
| ---- | ---- |
| ⌘ + d | 縦に分割 |
| ⌘ + Shift + d | 分割を解除 |

# 入力補助

|  入力  | 効果 |
| ---- | ---- |
| Ctrl + n | １つ後に入力したコマンド表示（カーソル↓と同じ） |
| Ctrl + p | １つ前に入力したコマンド表示（カーソル↑と同じ） |
| Ctrl + _ | 元に戻す（Undo） |

# その他

|  入力  | 効果 |
| ---- | ---- |
| Ctrl + j | 実行（Enterと同じ） |
| ⌘ + ↑ | １つ前の入力をハイライトで表示 |
| ⌘ + ↓ | １つ後の入力をハイライトで表示 |
| ⌘ + , | 環境設定を開く |
| ⌘ + . | Enter押したみたいになるけれど、何も実行はされない |
RailsでenumのカラムをSTIとして使う

# `enum` の中身で処理が別れるようなコード
`enum` を使っていると以下のようなコードが増えていくことがある。
明らかに `enum` の値によって振舞いを変えているので、 `enum` の値によってそもそもクラスを変えていきたい。 というわけでenumで使っているカラムをSTIとしても使えないのか試してみました。

```ruby
class Payment < ActiveRecord::Base
  enum means: { credit_card: 0, bank_transfer: 10, paypal: 20 }
  
  def complete!
    if credit_card?
    # do something
    elsif bank_transfer?
    # do something
    end
  end
  
  def cancel!
   if credit_card?
   # do  something
   elsif bank_transfer?
   # do  something
   end
  end
end
```


# `enum` のカラムをSTIでも使う
結論、以下のように書けばいけるっぽい。

```ruby
class Payment < ActiveRecord::Base
  enum type: { credit_card: 0, bank_transfer: 10, paypal: 20 }

  class << self
    def find_sti_class(type)
     type_name = types.key(type.to_i) # enumのhashから該当するkeyを取得する
      "Payment::#{type_name.to_s.camelize}".constantize
    end

    def sti_name
     types[name.demodulize.underscore]
    end
  end

  def complete!
    fail NotImplementedError
  end

  def cancel!
    fail NotImplementedError
  end
end
```

こうしておけば、 通常のSTIと同じく、 各 `type` に対応するクラスを定義できる。

```ruby
class Payment::CreditCard < Payment
  def complete!
  end

  def cancel!
  end
end

class Payment::BankTransfer < Payment
  def complete!
  end

  def cancel!
  end
end

class Payment::PayPal < Payment
  def complete!
  end

  def cancel!
  end
end
```

最初から `enum` で処理を変える必要があることがわかっているのであれば、素直にテーブルを分けたり普通のSTIを選択した方がハマりどころも少なそうで良いとは思います。
が、これはこれでDBにクラス名がそのまま入ることもないし、`enum` で生成されるスコープや `credit_card?` みたいなメソッドはそのまま使えるので、実は結構有りなのでは・・・！と思ったりしました。
デバッグ時に大きな配列の一部要素を確認する方法

Android Studioデバッガのデフォルト設定では、要素数が多い配列の先頭100要素しか同時に表示されない。末尾「...(_NNN_ more items. Double-click to see)」をダブルクリックすれば後続要素も表示できるが、マウス操作が必要なため手間がかかる。

## 方法1
[Debugger: working with sub-ranges for arrays and lists](https://blog.jetbrains.com/idea/2011/09/debugger-working-with-sub-ranges-for-arrays-and-lists/)

Variablesペインで該当の配列型変数を選択し、右クリックメニューから「Adjust Range...」を選択する。表示したい要素範囲を指定する（変数毎に設定保持される）。

## 方法2
Watchesペインに[`Arrays#copyOfRange`](https://developer.android.com/reference/java/util/Arrays.html)メソッドを介した式を設定する。下記例では配列`arr`の要素範囲 [1000, 1150) を表示する。

```
java.util.Arrays.copyOfRange(arr, 1000, 1150)
```
2017年版のGo msgpackライブラリベンチマーク

http://qiita.com/yosisa/items/f21d3476bc8d368d7494

Goのmsgpackのライブラリ比較として上記の記事があるのですが、 https://github.com/vmihailenco/msgpack のREADMEを見てるとそんなに遅くないっぽいので、当時からどのくらい改善されてるのか、現時点での比較を取ってみました。
(書いた後に気づいたんですが、別の方もコメントに同様の結果を投稿されてますね)

コードは上記の記事そのまま実行しています。

## 結果

### 前回 (2014)

```shell
$ go test -bench .
testing: warning: no tests to run
PASS
BenchmarkCodecEncode     1000000              1970 ns/op
BenchmarkCodecDecode     1000000              2543 ns/op
BenchmarkMsgpackEncode    500000              5274 ns/op
BenchmarkMsgpackDecode    500000              6793 ns/op
ok      _/Users/yoshihisa/junk/msgpack  10.761s
```

### 現在 (2017)

```shell
$ go version
go version go1.7.3 darwin/amd64

$ go test -bench .
testing: warning: no tests to run
BenchmarkCodecEncode-4           1000000              1937 ns/op
BenchmarkCodecDecode-4            300000              5637 ns/op
BenchmarkMsgpackEncode-4         1000000              1684 ns/op
BenchmarkMsgpackDecode-4          500000              3077 ns/op
PASS
ok      github.com/daichirata/playground/msgpackbench   6.999s
```

なんと、本当に今は`github.com/vmihailenco/msgpack`の方が早いんですね。もちろん機能差や、色々なワークロードを試しているわけではないので一概には言えないですが、`github.com/ugorji/go/codec`よりは`github.com/vmihailenco/msgpack`の方がGoっぽいAPIで個人的には好きなので、今であれば選択肢として検討しても良さそうかなと思います。
Link > ppm > Netpbm color image format

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 14.04 LTS desktop amd64
TensorFlow v0.11
cuDNN v5.1 for Linux
CUDA v8.0
Python 2.7.6
IPython 5.1.0 -- An enhanced Interactive Python.
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
```

任意の英単語を画像化して、その正立をinputノードに、倒立をoutputノードに入れて学習の様子を見ようと検討中。

ImageMagickを用いて英単語を画像化する方法は見つかった。

その画像を読もうとして、PythonのPILとPillowをセットアップしようとしたが、うまくいかない。No module named PILなどになる。
pip install, easy_installやlnを使った方法など色々試してだめだった。

セットアップにより環境を壊して、TensorFlow環境を再構築するはめにならないように、別の方法を検討することにした。

10年くらい前に画像を読む方法としてPPMファイルを読込んだことがある。そのソースコードはHDDのどこにあるかは不明。
PPMでテキスト形式にしておくと、フォーマットに従って読込めばいいだけ。

フォーマットは以下で紹介されている。
http://netpbm.sourceforge.net/doc/ppm.html

bashでImageMagickを使いながら画像を逐次生成し、test_in.csvとtest_out.csvに追記していく処理をPythonかCで実装することになる。

PPM以外でも現在の環境で画像からcsvにしやすい方法があれば、そちらを採用するかもしれない。

shellscriptでPPMファイルを処理している例もある。
https://uec.usp-lab.com/JOURNAL/CGI/JOURNAL.CGI?POMPA=KAIGAN_journal15
Swift 3のUIScrollViewでカルーセルUI（ページング／画像などをスワイプで行き来できるView）をつくる

カルーセルUIを実装しようとしてUICollectionViewでやろうとしたり[iCarousel](https://github.com/nicklockwood/iCarousel)がいいかなーと悩んだりしたのですが、UIScrollViewを用いた方法がとても平易で分かりやすかったのでSwift 3版載せさせていただきます。

出典はこちら↓

[XCODE] UIScrollViewを用いてページングUIを実現する方法 / YoheiM.NET
http://www.yoheim.net/blog.php?q=20120715

# Storyboard

<img width="720" alt="螢幕快照_2017-03-01_11_52_08.png" src="https://qiita-image-store.s3.amazonaws.com/0/15144/fbf73f58-ea88-b61c-61a1-172e359d5b62.png">

必ず **`Paging Enabled` にチェック** を入れます。

# Code

```swift:ViewController.swift
let size = CGSize(width: scrollView.frame.size.width, height: 200)

let contentRect = CGRect(x: 0, y: 0, width: size.width * 4, height: size.height)
let contentView = UIView(frame: contentRect)

let subContentView = UIView(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
subContentView.backgroundColor = .green
contentView.addSubview(subContentView)

let secondContentView = UIView(frame: CGRect(x: size.width, y: 0, width: size.width, height: size.height))
secondContentView.backgroundColor = .blue
contentView.addSubview(secondContentView)

let thirdContentView = UIView(frame: CGRect(x: size.width * 2, y: 0, width: size.width, height: size.height))
thirdContentView.backgroundColor = .red
contentView.addSubview(thirdContentView)

let fourthContentView = UIView(frame: CGRect(x: size.width * 3, y: 0, width: size.width, height: size.height))
fourthContentView.backgroundColor = .yellow
contentView.addSubview(fourthContentView)

scrollView.addSubview(contentView)
scrollView.contentSize = contentView.frame.size
scrollView.contentOffset = CGPoint(x: size.width, y: 0)
```

# Result

![hoge.gif](https://qiita-image-store.s3.amazonaws.com/0/15144/90e4fe5d-13bc-4509-25da-282453f285b7.gif)

:sunglasses::+1: DEAL WITH IT!

# コード置いときます。

[https://github.com/keisei1092/CarouselByUIScrollViewPractice](https://github.com/keisei1092/CarouselByUIScrollViewPractice)
sakuravps で メールサーバーだけ conoha

さくらvpsでメールサーバーだけconohaを使いたい。

設定
・conoha でメールアドレスを作成
・ムームードメインは一切触らなくていい
・SPFレコード
・DKIM
も設定する

・MXレコードを設定する
（最後にドット必須なので注意）
10 mx.unit01.paasmail.your.conoha.io.


って感じでしょうか。

DNSの設定はさくらサーバーだけでいい。

設定後は


![hogeman.png](https://qiita-image-store.s3.amazonaws.com/0/31338/d22a2106-dabc-4bc4-0907-7a8e8506e1af.png)



こんな感じになります。

注意としては、Aレコードを複数設定しない。
するとSSLエラーになる。

mxレコードの最後にドットをつける。

以上。
ひさしぶりに gem ライブラリをバージョンアップして rubygems.org にリリースしたメモ

あまり更新していなかった gem ライブラリに p-r がきたので、マージした上で久しぶりにバージョンアップ & リリースした際のメモ。

## リポジトリをもってくる

ギットクローン。

```
$ git clone https://github.com/tily/ace-client-ext.git
Cloning into 'ace-client-ext'...
remote: Counting objects: 145, done.
remote: Total 145 (delta 0), reused 0 (delta 0), pack-reused 145
Receiving objects: 100% (145/145), 15.56 KiB | 0 bytes/s, done.
Resolving deltas: 100% (40/40), done.
Checking connectivity... done.
```

作業ディレクトリに移動。

```
$ cd ace-client-ext/
```

## docker コンテナで作業できるようにする

Dockerfile 作成。

```
$ vi Dockerfile
```
```
FROM ruby
WORKDIR /work
RUN apt-get update && apt-get install -y vim
ADD Gemfile .
ADD Gemfile.lock .
ADD ace-client-ext.gemspec .
ADD VERSION .
RUN bundle install
```

docker-compose.yml 作成。

```
vi docker-compose.yml 
```
```
version: "2"
services:
  lib:
    build: .
    volumes:
      - ./:/work
    command: tail -f /dev/null
```

ドッカーコンポーザップディー。

```
$ docker-compose up -d
```

## バージョンアップ & リリース

docker コンテナにログイン。

```
$ docker-compose exec lib bash
```

git のなまえ・メアド設定。 (この手順は Dockerfile に書いちゃってもいいかな…。)

```
> git config --global user.email tidnlyam@gmail.com
> git config --global user.name tily               
```

VERSION ファイル編集。 (v0.0.10 -> v0.0.11)

```
> vi VERSION
> git diff VERSION 
diff --git a/VERSION b/VERSION
index 7c1886b..2cfabea 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.0.10
+0.0.11
```

ギットアッド。

```
> git add VERSION
```

ギットコミット。

```
> git commit -m "version up to 0.0.11"             
[master bce0ef3] version up to 0.0.11
 1 file changed, 1 insertion(+), 1 deletion(-)
```

レイクリリース。

```
> rake release
ace-client-ext 0.0.11 built to pkg/ace-client-ext-0.0.11.gem.
Tagged v0.0.11.
Username for 'https://github.com': tily
Password for 'https://tily@github.com': 
Username for 'https://github.com': tily
Password for 'https://tily@github.com': 
Pushed git commits and tags.
rake aborted!
Your rubygems.org credentials aren't set. Run `gem push` to set them.

Tasks: TOP => release => release:rubygem_push
(See full trace by running task with --trace)
```

`rake build` / `git tag v0.0.11` / `git push --tags` / `git push origin master` までは成功するが、`gem push` するところでこけた。エラーメッセージ通り、手動で gem push してみる。

```
> gem push pkg/ace-client-ext-0.0.11.gem 
Enter your RubyGems.org credentials.
Don't have an account yet? Create one at https://rubygems.org/sign_up
   Email:   (rubygems.org に登録してるメアド)
Password:   

Signed in.
Pushing gem to https://rubygems.org...
Successfully registered gem: ace-client-ext (0.0.11)
```

正しいメアドとパスワードの組み合わせを忘れてしまっていてあせったけど、なんとか思い出してリリースすることができた。
あとで Dockerfile と docker-compose.yml もコミットしておこう。
Pollyの発音がおかしいやつがあるので自分で調整する



Pollyはレキシコンで発音とか、イントネーションを適用できるのですが、日本語だとまだ対応されていません。

すごい泥臭い方法ですが、以下のようにすると発音を調整できます。

例えば`おいしい`はそのまま発音させると、なんかおかしいのですが、`おいし'い`のように、`し`と`い`の間に`'`をいれてあげると望んだ通りの発音になります。

その他にもカタカナにしたりローマ字にしたり、最終的には文にして、目的の単語が読まれたところだけをAudacityとかで切るとればまあなんとかできそうです。

# まとめ

まとめるほどではないのですが、Polly日本語はどろくさい
bashで任意の文字列が作成されるまでループする

```bash
#!/bin/bash
set -eu

KAWAII='桑原由気'
STRINGS=(`echo ${KAWAII} | grep -o '.'`)
NUM=${#STRINGS[@]}
YUSYOU=''

while true; do
	sleep 0.05
	random=$(((RANDOM%${NUM})))
	string=${STRINGS[$random]}
	YUSYOU=${YUSYOU}${string}
	echo -n ${string}
	if [ "${YUSYOU:$((${#YUSYOU}-${#KAWAII}))}" = "${KAWAII}" ] ; then
		echo
		echo ${KAWAII}
		echo '優勝'
		break
	fi
done
```

実行結果

![yuki.gif](https://qiita-image-store.s3.amazonaws.com/0/6406/038c62d2-e9d3-6a1c-c950-f94e7baa29b1.gif)
UIStackViewを使って詳細ページの実装をシンプルにする

> この記事は[VASILY DEVELOPERS BLOG](http://tech.vasily.jp/entry/detail_page_used_stackview)にも同じ内容で投稿しています。よろしければ他の記事もご覧ください。

# はじめに
<img width="265" alt="スクリーンショット 2017-02-27 18.58.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/69901/bcdee1a0-f7a3-1e35-dd0b-ab44d66a9398.png">

このような表示コンテンツの多い詳細ページを実装する際に、みなさんは何を使用していますか？

UIStackViewはiOS 9から追加されたクラスですが、
まだUITableViewやUICollectionViewで詳細ページを実装されている人も多いのではないでしょうか？

IQONも詳細ページをUITableViewやUICollectionViewを使って実装してきました。
しかし、UITableView、UICollectionViewは同じモジュールの繰り返しを表示するのには適していますが、詳細ページなどの違うモジュールを表示するのには、ビジネスロジックのコードなどでDataSourceがとても複雑になってしまいました。

UIStackViewを使うことで、複雑になりがちな詳細ページがとてもシンプルに実装することができました。
詳細ページを実装する際に、少しでも参考になれば幸いです。


# 実装について
今回、詳細ページを実装する上で考慮したのはモジュールの出し分けをViewController側に書かないようにすることです。
ViewControllerにモジュールの出し分けを書かないようにすることで、ViewControllerの肥大化を防ぐことができます。また、ViewControllerはViewModelから受け取ったModelをViewに渡すだけにすることでコードがシンプルになります。

<img width="460" alt="スクリーンショット 2017-02-27 19.07.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/69901/a20ce133-8d93-c7f6-c4d4-21d0ef4f85a7.png">


実装は以下のとおりです。

<img width="973" alt="65a01176-9517-e34a-20cb-fcd865890362.png" src="https://qiita-image-store.s3.amazonaws.com/0/69901/a31f6388-be4b-33fc-0923-e8e0b9b120d4.png">


``` swift
// ViewModel.swift

class ViewModel {

    var modelA: Model?
    var modelB: Model?

    func request() {
        // APIリクエストして返ってきたレスポンスをもとに各Modelオブジェクトを更新
    }
}
```
<br>

``` swift
// ViewController.swift

class ViewController: UIViewController {

    private var viewModel: ViewModel = ViewModel()

    @IBOutlet private weak var viewA: CustomView!
    @IBOutlet private weak var viewB: CustomView!

    override func viewDidLoad() {
        super.viewDidLoad()

        viewModel.request { [weak self] in
            self?.setupLayout()
        }
    }

    private func setupLayout() {
        viewA.model = viewModel.modelA
        viewB.model = viewModel.modelB    
    }
}
```
<br>

``` swift
// ContentView.swift

class CustomView: UIView {

    var model: Model? {
        didSet {
            setupLayout()
        }
    }

    private func setupLayout() {
        guard let model = model else { return }

        isHidden = (model == nil)
    }
}
```

UITableViewやUICollectionViewで実装するよりもはるかにシンプルになったと思います。
この実装方法だと、表示するモジュールが多くなった場合でもViewControllerが肥大化しなくて済みます。

また、表示しているモジュールの並び替えがとても簡単で、UIStackViewのサブビューの並びを変えるだけで良いのです！

<img width="689" alt="1da39b10-4d71-06dd-2261-74a9793c4b2b.png" src="https://qiita-image-store.s3.amazonaws.com/0/69901/58c6c5bf-f84c-d4b9-8f74-782fd9055f85.png">

# まとめ
UIStackViewを使った詳細ページの実装について紹介しました。

表示要素が多い詳細ページはUITableViewやUICollectionViewを使用して実装するとViewControllerが肥大化してしまいがちです。
UIStackViewを使用することでViewControllerの実装が複雑にならず肥大化せずに実装でき、メンテナンスもしやすくなるので詳細ページをUIStackViewで実装するのはおすすめです！
ぜひ、詳細ページを実装する際に試してみてください。
ウイルス対策をしているLinuxなんだね！（ServerProtect導入）

#はじめに
　Linuxサーバにウイルス対策ソフトを導入しなければならない悲しい人用
　TrendMicro社のServerProtect導入時に問題が発生しまくったので共有

#環境
　Red Hat Enterprise Linux 6
　Redhat6への導入を例に手順を記載します。
#事前準備
### 導入サーバで確認

yumでlibuuid-2.17.2-12.24.el6.x86_64にアップデートすると
telnetの表示がおかしくなるバグがあるので注意

```bash
# rpm -qa <パッケージ>
```

```
libc-2.12-1.7.el6.i686
zlib-1.2.3-25.el6.i686
compat-libstdc+±296-2.96-144.el6.i686
libuuid-2.17.2-6.el6.i686
nss-softokn-freebl-3.12.7-1.1.el6.i686
libgcc-4.4.4-13.el6.i686
```

### カーネルフックモジュールについて
　[TrendMicroサポートページ](https://esupport.trendmicro.com/submitcaseonline/corporate/corpsrf.aspx?cm_re=Sup-_-sp-_-inq_mail)よりサーバに対応したKHMを依頼する

　**注意**
　[こちら](http://downloadcenter.trendmicro.com/index.php?regs=NABU&clk=latest&clkval=111&lang_loc=1#fragment-111)からもダウンロードできますが、最新バージョンが必要な場合はサポートページから問い合わせないといけない
　最新版を導入しないとサーバが謎のハングアップした際に最新バージョンのカーネルフックモジュールではないのでサーバがハングアップしましたとか回答されちゃう

### TrendMicroへ送る情報

```
    サーバ情報
    # cat /etc/redhat-release
    CPU情報
    # cat /proc/cpuinfo
    システム情報
    # uname -a
    カーネルのrpm情報
    # rpm -qi <カーネル>
    例：# rpm -qi kernel-smp-2.6.9-11.EL
```

#導入手順

## ServerProtectのインストール
ServerProtectのインストールファイルが含まれるディレクトリで次のコマンドを入力します。
-s オプションをつけると導入規約みたいなものを読まなくて済む

```bash
# ./SProtectLinux-3.0.bin -s
```

ライセンスに同意

```bash
> Do you wish to connect this SPLX server to Trend Micro Control Manager?(y/n)
 n
```

アクティベーションコードを入力

```bash
Activation Code: xx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx
```

インストールを実行

```bash
> Please input your choice [Yes] :
yes
```

## KHMのインストール
Server Protect 停止

```bash
# /etc/init.d/splx stop
```

/opt/TrendMicro/SProtectLinux/SPLX.moduleへKHMを配置

```bash
# cp -ip <WorkDir> splx_kernel_module-X.X.X.0014.rhel6_2.6.32-XXX.el6.x86_64.x86_64.tar.gz
```

解凍

```bash
# tar xzvf splx_kernel_module-X.X.X.0014.rhel6_2.6.32-XXX.el6.x86_64.x86_64.tar.gz
```

Server Protect 起動

```bash
# /etc/init.d/splx start
```

## 修正パッチのインストール
以下のパッチを導入してください。**注意**: 更新される可能性あり
splx-30-lx-en-sp1-patch7.tar.gzが新しく提供されていた。
私自身まだこちらの導入実績がないため何とも言えない。次の導入時に感想を追記します。


- splx-30-lx-en-sp1-patch7.tar.gz

```bash
# tar zxvf splx_30_lx_en_sp1_patch7.tar.gz
# chmod u+x splx_30_lx_en_sp1_patch7.bin
# ./splx_30_lx_en_sp1_patch7.bin
```

## Webコンソールへのアクセス
次のURLからServerProtectのWebコンソールにアクセスすることができます。
あとは良しなに設定してください。

- http://<ホスト名>:14942/
- https://<ホスト名>:14943/

> WebコンソールからServerProtectにアクセスする場合、Linuxシステム上のポート番号「14942」および「14943」が使用可能であることを確認してください。

**注意**
初回のパターンファイルアップデートはTMCMより配信してください。
サーバからパターンファイルをダウンロードすると絶対ハングアップする仕様らしいです・・・
AndroidのSpeechRecognizerでコールバック返って来ない問題

# 概要
AndroidにおけるSpeechRecognizerに不具合がでてるようです。
自分のアプリケーションに対して特に変更していないのに、急にユーザーから苦情がきたので気づきました。

# 再現方法
2017年2月下旬における最新版Googleアプリ(6.12.25.21.arm)にアップデートしていた場合、再現が可能です。
※AndroidのSpeechRecognizerの認識処理はGoogleアプリで行われているため

1. デバイスをオフラインにします
2. SpeechRecognizerでstartListeningをします
3. わざと認識失敗します。（なにも喋らなければOK）
4. 認識失敗の音がなります
5. :boom: onErrorのコールバックが返ってきません

# 回避策

* オフラインでの音声認識を制限方法
これはユーザービリティに関わるのであまりやりたくないのですが、コールバック待ちでフリーズする問題は防げます。

* SpeechRecognizerにTimeoutを設定する方法
SpeechRecognizerをRx化してる場合は特にTimeout設定すると簡単に出来ます。SpeechRecognizerは連続音声認識ではないので、十数秒でTimeoutを設定すれば十分なlistening durationがkeep出来ます。

# 最後に
Googleアプリは日々アップデートされますが、SpeechRecognizer周りも結構変更があるので、Googleアプリをダウングレードするなどして確認できる環境を整える必要があると感じました。

# 余談
認識失敗時の音もならなくなったようです。認識成功時の音は変わらず。認識をキャンセルするときは失敗時の音がなります。
NEXT_DAY関数、TRUNC関数を使って、向こう1000日分のプレミアムフライデーを求めてみる。(Oracle Database)

これでワイもプレミアムや！彡(ﾟ)(ﾟ)

```sql
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY/MM/DD';
 SELECT TRUNC(NEXT_DAY(SYSDATE+LEVEL, 'friday'), 'MM')      AS TUKI
      , MAX(TRUNC(NEXT_DAY(SYSDATE+LEVEL, 'friday'), 'DD')) AS PREMIUM
   FROM DUAL
CONNECT BY LEVEL <= 1000
  GROUP BY TRUNC(NEXT_DAY(SYSDATE+LEVEL, 'friday'), 'MM')
  ORDER BY TUKI;

TUKI       PREMIUM
---------- ----------
2017/03/01 2017/03/31
2017/04/01 2017/04/28
2017/05/01 2017/05/26
2017/06/01 2017/06/30
2017/07/01 2017/07/28
2017/08/01 2017/08/25
2017/09/01 2017/09/29
2017/10/01 2017/10/27
2017/11/01 2017/11/24
2017/12/01 2017/12/29
2018/01/01 2018/01/26

TUKI       PREMIUM
---------- ----------
2018/02/01 2018/02/23
2018/03/01 2018/03/30
2018/04/01 2018/04/27
2018/05/01 2018/05/25
2018/06/01 2018/06/29
2018/07/01 2018/07/27
2018/08/01 2018/08/31
2018/09/01 2018/09/28
2018/10/01 2018/10/26
2018/11/01 2018/11/30
2018/12/01 2018/12/28

TUKI       PREMIUM
---------- ----------
2019/01/01 2019/01/25
2019/02/01 2019/02/22
2019/03/01 2019/03/29
2019/04/01 2019/04/26
2019/05/01 2019/05/31
2019/06/01 2019/06/28
2019/07/01 2019/07/26
2019/08/01 2019/08/30
2019/09/01 2019/09/27
2019/10/01 2019/10/25
2019/11/01 2019/11/29

33 rows selected.
```

※再帰WITH句の書き方も追記したやで彡(ﾟ)(ﾟ)

```sql
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY/MM/DD';
WITH rec(lv) AS (
  SELECT 1 FROM DUAL
   UNION ALL
  SELECT lv + 1
    FROM REC
   WHERE lv < 1000
)
SELECT TRUNC(NEXT_DAY(SYSDATE+lv, 'friday'), 'MM')      AS TUKI
     , MAX(TRUNC(NEXT_DAY(SYSDATE+lv, 'friday'), 'DD')) AS PREMIUM
  FROM rec
 GROUP BY TRUNC(NEXT_DAY(SYSDATE+lv, 'friday'), 'MM')
 ORDER BY TUKI;

TUKI       PREMIUM
---------- ----------
2017/03/01 2017/03/31
2017/04/01 2017/04/28
2017/05/01 2017/05/26
2017/06/01 2017/06/30
2017/07/01 2017/07/28
2017/08/01 2017/08/25
2017/09/01 2017/09/29
2017/10/01 2017/10/27
2017/11/01 2017/11/24
2017/12/01 2017/12/29
2018/01/01 2018/01/26

TUKI       PREMIUM
---------- ----------
2018/02/01 2018/02/23
2018/03/01 2018/03/30
2018/04/01 2018/04/27
2018/05/01 2018/05/25
2018/06/01 2018/06/29
2018/07/01 2018/07/27
2018/08/01 2018/08/31
2018/09/01 2018/09/28
2018/10/01 2018/10/26
2018/11/01 2018/11/30
2018/12/01 2018/12/28

TUKI       PREMIUM
---------- ----------
2019/01/01 2019/01/25
2019/02/01 2019/02/22
2019/03/01 2019/03/29
2019/04/01 2019/04/26
2019/05/01 2019/05/31
2019/06/01 2019/06/28
2019/07/01 2019/07/26
2019/08/01 2019/08/30
2019/09/01 2019/09/27
2019/10/01 2019/10/25
2019/11/01 2019/11/29

33 rows selected.

```
[PhpStorm] 使用するPHPのバージョンの設定を変更する

# PhpStorm で PHP のバージョンを指定する

PHPのどのバージョンでコードを書いていて、
チェックをさせるかの設定を変更する方法。

# 経緯

PHP7.1 でコードを書くようになったが、
PHP7 の記法がエラー扱いになっていたので設定を変更した。

# PHPStorm

1. Preferences を開く
2. Languages&Frameworks　の項目を開く
3. PHP を選択
4. PHP language level を お好みのバージョンを選択する
5. 設定完了する

### PHP language levelが変更できない場合

1. Preferences を開く
2. Languages&Frameworks　の項目を開く
3. PHP　の項目を開く
4. composer を選択
5. Synchronize IDE settings with composer.json のチェックを外す
6. 設定完了する

設定後、PHP language level を変更できるようになる。