OmniAICreator/Qiita-1.07M huggingface dataset:
LaravelのAppをHerokuにデプロイ


**Paas**であるHerokuでLaravelをDeployする方法。

#Heroku

- PHPが利用可能なPaaSサービス
- サーバーの知識がなくてもデプロイあk脳

##PaaS

- クラウドサービスの１つ
- サービス側がめんどくさいところをやってくれる
- VPSとかにくらべるとインフラの管理・構築は劇的にラクになる

Heroku以外のPaaSではPHPが使えないものもある。
他のクラウドサービスとしてIaaS（例：Amazone EC2）、SaaS（例：Google Apps）などがある。

##補足：レンタルサーバー / VPS のデメリット

###レンタルサーバー

細かい設定、セキュリティとかちゃんとできない

###VPS

一からできるけど大変、セキュリティやパッチ（プログラムの修正や更新のこと）が大変

#準備

1. Herokuアカウントの作成
2. Herokuの管理画面からアプリケーションを作成（名前がアドレスになる）
3. Heroku toolbeltをインストール（ターミナルでherokuを打っていろいろ出てきたら入ってる）

#Heroku Procfileの作成

- Heroku上でサーバーを立ち上げるために必要なファイル
- サーバーのほか、ワーカーを立てることも可能
- `$git push`したときにどんなファイルを立ち上げるかを書く

```
web: vendor/bin/heroku-php-apache2 public/
```

と中に記述する。
ワーカー（サーバーと違ってずっと動き続けるようにする）にしたい場合は`web`以外の名前でProcfile中に記述する。

#アプリケーションキーの設定

`.env`の`APP_KEY`を管理画面 **Settings > Config Variables** に書く。

##Config Variablesの中身をコンソールに表示する

```
heroku config
```

```
heroku config -s
```

にすると.envファイルにそのまま貼れる形になる。


#Herokuにデプロイ

`{appname}`は準備の2.で決めた名前。

```
# git のリモートを追加
heroku git:remote -a {appname}

# deploy
git push heroku master

# 確認　
heroku open
```

##エラーになりがちなこと

キーの設定し忘れ。
管理画面の **Settings > Config Variables** でAPP_KEYを設定。

#Heroku Buildpackの設定について

作成されるインフラのベースとなるもの。
勝手に設定してくれていることもあるが、`.package.json`の構成からNode.jsになってることもあるらしい。

その場合はCLI経由で

```
heroku buildpacks:set heroku/php
```

とするか、管理画面の **Settings > Buildpacks** で設定する。

#GitHubと連携

管理画面の **Deploy** で

- **Deployment method** をGitHubにする
- **App connected to GitHub / Automatic deploys** も設定する

**Automatic deploys** を設定しておくことで、GitHubにpushすると同時にherokuにもpushされるようになる。

##エラーになりがちなこと

GitHubにProcfileをpushし忘れる。

#Logを見る

```
heroku logs
```

監視（tail mode）する場合は

```
heroku logs -t
```

#アドオン

Herokuの拡張機能とか。
「メール系」「監視系」「ログ系」「キャッシュ用」などがある。

##Heroku Postgres

アドオンの１つ。
検索して追加すれば、自動的に設定のConfig Variablesにurl（Heroku PostgresのDBアドレス）が入る。

```
postgres://{username}:{password}@host:port/{dbname}
```

LaravelのDBnameとかをConfig VariablesにいれたらOK。

#その他メモとか

##pushするたびに前のサーバーは捨てられる

前にpushしたときの状態に戻したいときは管理画面の **Activity > Roll back** から。

##Resourcesからプランを追加できたりする

アカウントの設定からクレジットカードも登録すればそれだけで拡張機能も使えるようになる。

##HerokuのDBとHerokuの上のLaravelは別物

Heroku Postgresを使うのであればConfig valueをかきかえる。

#参考サイトとか

- [HerokuでRailsアプリを公開](http://techacademy.jp/magazine/6401 "HerokuでRailsアプリを公開")
- [クラウドサービスの違い](http://iot.mb.cloud.nifty.com/iotcolumn/baas_saas_%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%82%B5-%E3%83%93%E3%82%B9%E9%81%95%E3%81%84 "クラウドサービスの違い")
- [VPSとクラウドの違い](https://www.gmocloud.com/suggest/vps/ "VPSとクラウドの違い")
- [クラウドとレンタルサーバーの違い](https://www.idcf.jp/cloud/column/rentalserver_cloud.html "クラウドとレンタルサーバーの違い")
Mac で sudo rm -f /cores/* したらものすごくストレージが空いた

OSX El Capitan(10.11.6)で試してます。

ストレージが常にいっぱいいっぱいで、大してアプリ入れてないしiPhoneのバックアップもとってないのになぜ？
と思ってストレージの使用割合を調べてみました。


ありがたく先人の知恵を借ります。

> フォルダの容量を調べる
http://korechi.hatenablog.com/entry/2015/11/16/121827


一番左が使用容量(GB)です。

```sh
$ sudo du -gxd 5 / | awk '$1 >= 5{print}'
Password:
6	/.Spotlight-V100/Store-V2/6B7856A8-D432-47F8-9611-07CDD6ED8A8D
6	/.Spotlight-V100/Store-V2
6	/.Spotlight-V100
9	/Applications/adt-bundle-mac-x86_64-20140702/sdk/system-images/android-22
9	/Applications/adt-bundle-mac-x86_64-20140702/sdk/system-images
14	/Applications/adt-bundle-mac-x86_64-20140702/sdk
14	/Applications/adt-bundle-mac-x86_64-20140702
5	/Applications/Xcode.app/Contents/Developer/Platforms
6	/Applications/Xcode.app/Contents/Developer
6	/Applications/Xcode.app/Contents
6	/Applications/Xcode.app
37	/Applications
30	/cores                  <----- こやつ！！
8	/Library
8	/private/var
8	/private
12	/System/Library
12	/System
```


/coresで30GB...って**なんじゃこりゃーーー！**

いつの間にかcoreが溜まっていたんですね。まったく不要なんでサクッと削除。


```sh
sudo rm -f /cores/*
```


一気に30GBも空いてすっきり。
ついでに他の不要なファイルも削除するとさらに心の平安が手に入ります。
ちなみにアプリ開発していると、XcodeとかADT,ASあたりがすごくストレージを消費してますな。。

容量不足に困っているあなたにぜひ試してほしいコマンドです。
Xcode8のlogが邪魔なので、disableしてみた。

みんなもう知ってるかもしれないけど、忘れっぽいおいらようの備忘録として。

Xcode8 を普通に使うとlog画面にだーっと、

`xxxxx bundleid: xxx.xxx.xxx, enable_level: 0, persist_level: 0, propagate_with_activity: 0
xxxxx xxxx[xx:xx] Created DB, header sequence number = 248
xxxxx xxxx[xx:xx] subsystem: com.apple.UIKit, category: HIDEvents, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 0, privacy_setting: 0`

こんな感じで出るわけです。(便利ではあるのですが、ちょっと情報過多ですね……　)

邪魔

なので、非表示にします。

Xcode の menu から Product > Scheme > Edit Scheme (スキーマをいじるわけです。なのでProject毎にやらないといけません)
Run > Arguments > Environment Variables の下に + して、

`OS_ACTIVITY_MODE disable`

とします。

![CsMl3FpUIAEHbRC.jpg](https://qiita-image-store.s3.amazonaws.com/0/4810/39a8a41b-6781-1b04-ae39-002be99c7b91.jpeg)


disabled や no って書く手もあるけど、この辺はlldbの問題なので、こういう
https://github.com/fpillet/NSLogger
のを通して全部記録するのも手。

ご自分に合うように。(ご利用は計画的に
自分用メモ-忘れて調べることが多いことメモ 2016.10

## Rails

# Railsサーバーのバックグラウンド起動

```
▼バックグランドでサーバー起動
rails s -d 

▼外部公開もする
rails s -d -b 0.0.0.0
```

## Python
# リストの中に特定の要素があるか確認
```py3
data = ["A","B" "C"]

if "B" in data:
    print("B is found")
```

## Mongo

```
▼起動
mongo

▼dbの選択
use dbName

▼collectionの表示
show collections

▼document件数の表示
db.colName.count()

▼特殊なコレクション名（数字やハイフンなど）を参照する場合
db.getCollection('2016-09-01').  ...
という形で getCollectionを使う。

▼特定の条件にあてはまるドキュメントを取得
db.colName.find({keyName:value}）

▼全件表示
db.colName.find()

▼csvエキスポート
mongoexport -d [データベース名] -c [コレクション名] -out[出力ファイル名].csv --csv --fields xx,yy,zz
```

## PHP

```php
▼配列を出力する
var_dump($array)

▼JSONを配列化してから出力する

$json = '{"a":1,"b":2}';
$decode1 = json_decode($json)
$decode2 = json_decode($json)

//$decode1
object(stdClass)#1 (2) {
    ["a"] => int(1)
    ["b"] => int(2)
}

//$decode2
array(2) {
    ["a"] => int(1)
    ["b"] => int(2)
}

※arrayなのに、echo等を使っていると「Error: Array to string conversion」エラーが出る。
PHP久々すぎて忘れてた^^;

▼JSONを綺麗に出力する
echo '<pre>';
var_dump($json);
echo '</pre>';
```

#HTML (ほとんど書かないのですぐ忘れる)

```html
▼コンボボックス
<select><option></option></select>

▼form
<form acition="..." method="...">
 <input type="text" name="name" size="20"/>
 <input type="submit" value="送信"/>
</form>
```

#MySQL (ほとんど書かないのですぐ忘れる)

```mysql
▼起動
mysql.server start

▼インタラクティブIF
mysql -uroot -p

▼CREATE TABLE
CREATE TABLE {TABLENAME}(email varchar(100),name varchar(100));

▼主キー
CREATE TABLE {TABLENAME}(email varchar(100) PRIMARY KEY);

▼デフォルト値
CREATE TABLE {TABLENAME}(email varchar(100),complete bit(1) DEFAULT 0);

▼権限付与

・権限付与
GRANT ALL PRIVILEGES ON {TABLENAME}.* TO {USERNAME}@{HOSTNAME} IDENTIFIED BY {PASSWORD}

・パスワード変更
SET PASSWORD FOR ユーザ名@"ホスト名"=password('変更後のパスワード');

▼INSERT文
INSERT INTO ｛TABLENAME} (email) VALUES ('test1@test.com');

▼スキーマの確認
show columns from {TABLENAME};

▼カラム操作

・追加
ALTER TABLE <テーブル名> ADD <カラム名> <型情報>;

・変更
ALTER TABLE test CHANGE num number int;

・削除
ALTER TABLE <テーブル名> DROP <カラム名>;

・初期値の設定
ALTER TABLE <テーブル名> ALTER <カラム名> SET DEFAULT <初期値>;

▼関数
UPDATE test SET num = num+1 WHERE name = "hoge";
```

#Nodejs
##ファイル入出力
```js
▼ファイル出力（上書き）
fs.writeFile(filename, data, encoding='utf8', [callback])
fs.writeFileSync(filename, data, encoding='utf8', [callback])

※上が非同期、下が同期

▼ファイル出力（追記）
fs.appendFile(filename, data, encoding='utf8', [callback])
fs.appendFileSync(filename, data, encoding='utf8', [callback])

※上が非同期、下が同期
```

## ターミナル

権限関連

```shell-session

▼権限の確認
ls -l <ファイル名またはパス>

▼権限の付与
sudo chmod  <アクセス権限(数字)> <ファイル名またはパス>

▼権限の細かい設定
sudo chmod <権利者>  + /-  <アクセス権限(アルファベット)> <ファイル名またはパス>

▼所有者変更
chown root:root file
```
KotlinでRealm Mobile Platformを使ってみる

先日新しく[Realm Mobile Platform](https://realm.io/products/realm-mobile-platform/ "Realm")がアナウンスされました。
公式にkotlinのサンプルがなかったので簡単なチャットツールを書いてみました。
ソースコードは[こちらです。](https://github.com/sacchin/RealmMobilePlatformSample "Realm")

# Realm Object Serverのインストール
[Install Realm Object Server](https://realm.io/docs/realm-mobile-platform/install-realm-object-server/ "Realm")を参考に進めて問題ありません。私は提供されているAWS/AMIを利用しました。
公式にも記載されているように、9080ポートは開けておきます。

# kotlin + Realm のセットアップ
公式に[kotlinExample](https://github.com/realm/realm-java/tree/master/examples/kotlinExample "Realm")がありますので、参考にしてください。
kotlin-android-extensionsはハマりそうな予感がしたので、今回は利用していません。

# Realm Mobile Platform への対応
クライアント側の対応については、[このページ](https://realm.io/docs/java/latest/#the-realm-mobile-platform "Realm")に記載されています。まずはbuild.gradleに数行加えます。

```build.gradle
realm {
  syncEnabled = true;
}
```

次にユーザの登録・ログインは以下の感じです。

```
//ユーザ登録はsignupをtrueに、ログインはsignupをfalseにします。
val credentials = Credentials.usernamePassword(email, password, signup)
val authUrl = "http://xx.xx.xx.xx:9080/auth"

User.loginAsync(credentials, authUrl, LoginCallback())
```

登録・ログインが成功したらRealmインスタンスを作成します。

```
val user = User.currentUser()

//同期させたくないユーザ固有のデータを扱う場合は以下のようにする
//val serverURL = "realm://xx.xx.xx.xx:9080/${user.identity}/default"
val serverURL = "realm://xx.xx.xx.xx:9080/~/default"
val configuration = SyncConfiguration.Builder(user, serverURL).build()

realm = Realm.getInstance(configuration)
realm.addChangeListener(OnRealmChangeListener())

```

あとはいつものようにデータを挿入していきます。

```
val user = User.currentUser()

realm.executeTransaction {
    val temp = realm.createObject(Message::class.java)
    temp.time = System.currentTimeMillis()
    temp.message = text
    temp.user = user.identity
}

```

# まとめ
特にハマることなく実装できたと思います。
すでにkotlin + Realmで開発されているアプリケーションについてはすぐに対応できそうです。

p.s.
The Realm Browser の Windows版と心待ちにしております。
今回データを確認できずヤキモキしました。
VSTSからAzure Web Appsにデプロイする

## はじめに
Web Appsにアプリケーションをデプロイする場合、いくつか方法があります。
その中でも、Microsoftが提供するVisual Studio Team Services(VSTS)は、非常にAzureのサービスとの親和性が高いVCSです。
そこで今回は、AzureのWeb Appsに対してVSTSを使用してアプリケーションをデプロイする方法をご紹介します。
※今回は、VSTSの新しいUIをベースに説明します。

## VSTSにAzureのサブスクリプションを登録する
はじめにVSTSにAzureのサブスクリプションを登録します。
サブスクリプションの登録には、Service PrincipalやテナントIDなどが必要になります。
[ここ](https://raw.githubusercontent.com/Microsoft/vso-agent-tasks/master/Tasks/DeployAzureResourceGroup/SPNCreation.ps1)のスクリプトを使用するとそれらが取得できるのでローカルの適当な場所に保存します。
実行時に、登録するサブスクリプション名とService Principal用のパスワードを聞かれるので、入力します。
実行が完了すると

* Connection Name
* Subscription Id
* Subscription Name
* Service Principal Id
* Service Principal Key 
* Tenant Id

が表示されます。表示されたものをそれぞれどこかにメモしておきましょう。

これらの情報が取得出来たらVSTSに設定します。
下記の図のように画面上部から設定画面に移動してAzure Resource Managerを選択します。
![vsts_build6.png](https://qiita-image-store.s3.amazonaws.com/0/28367/e99c7e2b-f0b7-b8b0-b9d5-999f9f15108b.png)
そこで開いた画面に先ほど取得した情報を入力します。
<img width="501" alt="vsts_build5.png" src="https://qiita-image-store.s3.amazonaws.com/0/28367/f528ac38-aba2-334c-3ffc-88e22cd091a0.png">

入力後にVerify connectionを押してVerifiedになったら登録完了です。

## ビルド定義を作成する
VSTSからWeb Appsにデプロイする場合は、ビルド時にWeb Deploy パッケージを作成する必要があります。
VSTSのトップ画面上部からBuildを選ぶとビルド定義管理画面に移動します。その中のNewを選択します。
![vsts_build10.png](https://qiita-image-store.s3.amazonaws.com/0/28367/8f5f4175-2acc-0243-4858-ff0388e240f1.png)


Newを選択すると新規でのビルド定義の作成画面が立ち上がります。
今回は、下図のようにVisual Studioを選択します。
![vsts_build_2.png](https://qiita-image-store.s3.amazonaws.com/0/28367/ace349c3-72ff-18de-e2de-d6f5c7a069ee.png)

テンプレートを選択したら、リポジトリとブランチを選択してデフォルトのビルド定義を作成します。
![vsts_build_3.png](https://qiita-image-store.s3.amazonaws.com/0/28367/33f72db6-4340-55e9-c9e1-2874da87f087.png)

デフォルトのビルド定義が作成されたらビルドの設定をします。
今回は、下図のようにBuild SolutionのMSBuild ArgumentsでMSBuildの引数を追加します。
![vsts_build_4.png](https://qiita-image-store.s3.amazonaws.com/0/28367/b2a326bc-0c4e-dbbd-2cdf-35f7aaff906d.png)
引数は

```
/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:CreatePackageOnPublish=true
```
を入れます。
これでWeb Deploy パッケージがビルド時に生成されるようになります。

次に、ビルドで生成された成果物を扱いやすいように別の場所にコピーします。
Copy Filesのタスクを追加して下記の図のように設定します。
![vsts_build7.png](https://qiita-image-store.s3.amazonaws.com/0/28367/9226150a-55cf-14b5-8190-ccc56648d1a2.png)

これにより$(build.sourcesdirectory)\**\obj\$(BuildConfiguration)\**\ 以下にWeb Deploy パッケージが配置されます。

最後にデプロイタスクを下記の図のように追加します。
今回は、ARMのWeb AppsにデプロイするのでDeploy AzureRM Web App を選択します。
![vsts_build8.png](https://qiita-image-store.s3.amazonaws.com/0/28367/f2c7b211-8850-c764-92e3-1a66d2f6d62a.png)
サブスクリプションとデプロイするWeb Appsとパッケージの場所を指定して保存します。

## デプロイする
ビルド定義が完成したらあとは、ビルドをしてデプロイするだけです。
下図のように画面上部にQueue new buildの項目があるのでそれを選択してビルドを実行します。
![vsts_build9.png](https://qiita-image-store.s3.amazonaws.com/0/28367/89f8fe54-faee-0513-71d4-c5746042cde2.png)

これでビルドが通ればそのままWeb Appsにデプロイまでが自動的に実行されます。

## まとめ
CIなどが完了したらWeb Appsに自動デプロイするこの設定を行えば、毎回の面倒なリリース作業を簡略化して時間を有効活用できます。Gitではなく、TFVCを使ってバージョン管理をしていればゲートチェックインが通ったらデプロイといったことも可能です。

また、VSTSの特徴としてリリースの管理ができるため、例えば本番環境へのデプロイにたくさんの偉い人の許可が必要といった状況を自動化して許可が下りたら自動デプロイといったことも可能です。

業務の効率改善など、AzureとVSTSでできる部分がかなり多いと思うのでぜひ使用してみてください。
Auto incrementでレコード消したら歯抜きになるのを直す

#問題
MysqlでAuto incrementをオプションにしてるidなどのカラムで，
途中でレコードを消すと，そこが抜けたまま次のidが入れられてしまう
それをかっこ悪いので直したい

#手順
1.次の連番番号を決める
`ALTER TABLE テーブル名`
`AUTO_INCREMENT=次に始まる番号;`

2.歯抜きをきれいにする
`SET @i := 0;`
`UPDATE テーブル名 SET id = (@i := @i +1) ;`

それだけです
courseraのmachine-learning(week1)のメモ


たまにメモしないと何も覚えずに終わりそうなので

# Week1
[courseraのwiki](https://share.coursera.org/wiki/index.php/ML:Introduction)から引用したり、動画見ながらメモ取ったり
## 機械学習　"Machine Learning"
>Arthur Samuel described it as: "the field of study that gives computers the ability to learn without being explicitly programmed." This is an older, informal definition.

古い定義だと、"コンピュータに明示的にプログラムすることなしに機能を学ばせる学問領域"である。

>Tom Mitchell provides a more modern definition: "A computer program is said to learn from experience E with respect to some class of tasks T and performance measure P, if its performance at tasks in T, as measured by P, improves with experience E."

うまく訳せる気がしない
テキトー訳
タスク（分類）Tと性能（測定値）Pに関連した学習データEを得た時にそれによって学習するコンピュータプログラムのこと


![DataScienceの分類](http://3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com/wp-content/uploads/2013/11/Data_Science_VD-300x286.png)
DataSienceの分類 from "http://machinelearningmastery.com/what-is-machine-learning/"

## 教師あり学習 "Supervised Learning"
正解がある学習データを基に学習する。授業で扱ったのは回帰問題(regression)と分類問題(classification)。分類については、特徴量の数だけ分類する数を増やすことができるが、サポートベクターマシン（SVM）の登場によって無限に分類するプログラムを作ることができるとかなんとか。
以下、引用
>In supervised learning, we are given a data set and already know what our correct output should look like, having the idea that there is a relationship between the input and the output.
Supervised learning problems are categorized into "regression" and "classification" problems. In a regression problem, we are trying to predict results within a continuous output, meaning that we are trying to map input variables to some continuous function. In a classification problem, we are instead trying to predict results in a discrete output. In other words, we are trying to map input variables into discrete categories.

訳：
教師あり学習では、データ集合が与えられ正しい出力がどのように成るべきか既に知っている。我々は、この時の入力と出力の間にある関係を得る手法を考える。
教師あり学習問題は回帰問題と分類問題にわけられる。回帰問題では、連続的出力として結果を予測しようとする。これは入力変数をなんらかの連続的関数にマッピングしようとすることを意味する。分類問題では離散的出力として結果を予測しようとする。他の言い方をすると、入力変数を離散的な種類にマッピングしようとすることである。

## 教師なし学習　"Unspervised Learing"
正解のない学習データから学習する。クラスタリングともいう？
データの中からクラスタを見つける、構造を見つけ出すデータ分析。
以下、引用
>Unsupervised learning, on the other hand, allows us to approach problems with little or no idea what our results should look like. We can derive structure from data where we don't necessarily know the effect of the variables.
We can derive this structure by clustering the data based on relationships among the variables in the data.
With unsupervised learning there is no feedback based on the prediction results, i.e., there is no teacher to correct you.

訳：
一方、教師なし学習では結果がどうなるべきか少ししかわからないかもしくは全くわからない上で問題に取り組む。
変数の影響を知る必要のないデータから構造を見つけ出すことができる（よくわかんない）。この構造を、データの変数間の関係に基づいてクラスタリングすることで導く。教師なし学習では予測した結果に基づいたフィードバックは存在しない。
備忘録：Mavenのプロジェクト内にローカルリポジトリを作成する

セントラルリポジトリに無いライブラリ（jar）をプロジェクト内のローカルリポジトリに置いて参照する方法。

プロジェクト内の任意の場所にリポジトリ用ディレクトリを作成。

```:リポジトリ用ディレクトリ（repo）を作成したプロジェクト構成例
D:\workspace
└─my-project
    └─src
        ├─main
        ├─repo
        └─test
```

リポジトリ用ディレクトリにライブラリをインストール。

```dos:コマンド例
mvn install:install-file -Dfile=D:/tmp/hogehoge.jar -DgroupId=com.hogehoge -DartifactId=hogehoge -Dversion=1.0 -Dpackaging=jar -DlocalRepositoryPath=D:/workspace/my-project/src/repo
```

pom.xmlの\<repositories>にリポジトリ用ディレクトリを追加し、ライブラリインストール時のgroupId、artifactId、versionで\<dependency>を記述。

```xml:pom.xml
     :

    <repositories>
        <repository>
            <id>local</id>
            <url>file://${basedir}/src/repo</url>
        </repository>
    </repositories>

     :

    <dependencies>

     :

        <dependency>
            <groupId>com.hogehoge</groupId>
            <artifactId>hogehoge</artifactId>
            <version>1.0</version>
            <scope>runtime</scope>
        </dependency>

     :

    </dependencies>
```

参考記事
[Mavenプロジェクトで3rdパーティJARを扱う方法 ](http://ameblo.jp/ouobpo/entry-10051976866.html)
Docker MySQL公式イメージを使用してDBに初期データを流し込む

一時期はalpineに乗っかったMySQLを使おうとしましたがMariaDBだったので断念。
いくら互換だとはいえ、まだ自分には早い。

そんなわけでDocker MySQL公式イメージの5.5を利用してDBを構築。

> 公式イメージ
https://hub.docker.com/_/mysql/


初期データを投入した状態でgithubにpushしようとしたら、rejectされてしまいました。
調べてみるとGithubのファイルサイズ制限にひっかかった模様

> Working with large files
https://help.github.com/articles/working-with-large-files/

1ファイルあたり100MBまでとのこと。
InnoDBのibdata1がサイズ制限を超過していたのでした。かなりデータを厳選したんだけどな〜。
初期データインポートに使用したdumpファイルはせいぜい10MB程度なので、これを使ってDocker起動時に初期データを投入する方向で調べました。

すると公式イメージには便利機能が！

https://hub.docker.com/_/mysql/

によれば

> **Initializing a fresh instance**
When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. You can easily populate your mysql services by mounting a SQL dump into that directory and provide custom images with contributed data.


/docker-entrypoint-initdb.dに.sqlや.shを置いておけば初回起動時に実行してくれるとのこと！
すごい行き届いている！


一応コードを確認してみるとこの辺ですね。

https://github.com/docker-library/mysql/blob/78c736cef063f6c69256aa34f87ee463949af34f/5.5/docker-entrypoint.sh

```docker-entrypoint.sh
#108行目付近
for f in /docker-entrypoint-initdb.d/*; do
    case "$f" in
        *.sh)     echo "$0: running $f"; . "$f" ;;
        *.sql)    echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;
        *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;
        *)        echo "$0: ignoring $f" ;;
    esac
    echo
done
```

というわけで、docker-compose.ymlで/docker-entrypoint-initdb.dにローカルディレクトリをマウント

```docker-compose.yml
mysql:
  image: mysql:5.5
  volumes:
    - "./mysql:/var/lib/mysql"
    - "./mysql/init:/docker-entrypoint-initdb.d"
  environment:
    - MYSQL_ROOT_PASSWORD=password
```


./mysql/initにDBクリエイト用SQLとデータインポート用shを置いておいきます。
ちなみにasciiコード順に実行されるっぽいので、実行したい順番に頭に数字のプレフィクスを付けておくとわかりやすくてよし。


```
+ docker-compose.yml
+- mysql
    +- init
        + 1_create_db.sql
        + 2_import.sh
        + dump1.gz
        + dump2.gz
```


初期DBをひとつ構築するだけなら、docker-compose.ymlでもできるけど、複数構築したいので、sqlで。

```1_create_db.sql
create database test_db1;
create database test_db2;
```

```2_import.sh
cd /docker-entrypoint-initdb.d/
echo "import data1..."
gzip -dc ./dump1.gz | mysql -h localhost -u root -ppassword -P 3306 test_db1

echo "import data2..."
gzip -dc ./dump2.gz | mysql -h localhost -u root -ppassword -P 3306 test_db2

echo "done."
```


``docker-compose up -d``で初回起動時にデータが投入されます。素晴らしい！


というわけでなにかの役にたてば。
Mackerel のServiceMetricsにRubyから値をアップロードする

# コード

```rb
require 'faraday'
require 'faraday_middleware'

class Mackerel
  HOST = 'https://mackerel.io/'.freeze
  API_URL = '/api/v0/services/__SERVICE_NAME__/tsdb'.freeze
  METRICS_PREFIX = '__SERVICE_METRICX_PREFIX__'.freeze

  APIKEY = '___API_TOKEN___'.freeze

  def initialize
    @con = Faraday.new(url: HOST) {|build|
        build.request :json
        build.response :json
        build.adapter Faraday.default_adapter
      }
  end

  def put_metrics(group, metrics)
    post_date = metrics.map {|metric|
        {
          name: "#{METRICS_PREFIX}.#{group}.#{metric.name}",
          # for Rails: time: Time.current.in_time_zone('Tokyo').to_i, 
          time: Time.now.to_i
          value: metric.value
        }
      }

    @con.post {|req|
      req.url(API_URL)
      req.headers['X-Api-Key'] = APIKEY
      req.body = post_date
    }
  end
end

Metric = Struct.new(:name, :value)

metrics = [
  Metric.new('all', 1)
]

mackerel = Mackerel.new
mackerel.put_metrics('ProcessingCount', metrics)
```

# 結果
これで `__PREFIX__.ProcessingCount.all`という感じで入ってくる。
graphのグルーピングは最後の `.` らしいので、 `__PREFIX__.ProcessingCount.*` になる。

詳しくは[公式ドキュメント](https://mackerel.io/ja/api-docs/)がわかりやすいので是非。
SDKMANでのモジュールのインストールの最後にデフォルトにするかどうかを聞いてくるアレを抑制する

# 設定ファイルがあるよ

$SDKMAN_DIR/etc/config に[設定](http://sdkman.io/usage.html#config)があるようです。
config内の、sdkman_auto_answerをtrueに設定すれば良いみたいです。

Dockerfileにて、sdkman経由でもろもろインスコしたいときには、この設定が必須ですね。

こちらを参考にしました。
https://github.com/donbeave/docker-sdkman/blob/master/Dockerfile
Google Groupsの特定フォーラムのAtomフィードを取得する方法

OSS等の最新動向を追いたいときに、RSSやAtomフィードをZapierやIFTTTで取得して、SlackやChatWorkに流す、ということをやっています。Google Groupsをソースに同じことをしたいなぁ、と思って調べてみました。

`https://groups.google.com/forum/feed/フォーラム名/topics/atom_v1_0.xml`

例:

フォーラム名: coreos-user
フォーラム: https://groups.google.com/forum/#!forum/coreos-user
RSS: https://groups.google.com/forum/feed/coreos-user/topics/atom_v1_0.xml
メモ: css3のa href= 属性セレクタ

## 参考

* [属性セレクタ - CSS | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/Attribute_selectors)

## 例

* http://localhost/?hoge=1&fuga=2&action=search&piyo=3

というURLがあるとして、`search`という文字が含まれるCSSを対象としたい場合


```css
a[href*=search] {
  background-color:red;
}
```

とか書ける。
また 先頭文字や最終文字でもマッチングがかけられる。

* a[href^=value]
* a[href$=value]

他にもダブルクォーテーションで以下にもかける

```css
a[href*="&action="] {
  background-color:red;
}
```
PhpStormでカーソルを複数行移動できるようにしてみた

PhpStormでカーソルを1行じゃなく複数行上下に移動したい・・！
でもページ移動だと移動しすぎるからやだ :sweat: 
5~10行くらいを一気に移動できるといいなー
そんなあなたに捧げるマクロです。
AtomやSublime Textを使っている人は[line-jumper](https://packagecontrol.io/packages/LineJumper)の機能といった方が通じるかも :eyes:


作り方は簡単です。

1.PhpStormで適当なファイルを開く
2.メニューの[Edit]-[Macros]-[Start Macro Recording]を選択して、マクロの記録を開始
3.手順1で開いているファイルで自分が一気に移動したい行数だけ下にカーソル移動
4.メニューの[Edit]-[Macros]-[Stop Macro Recording]を選択して、マクロの記録を終了
5.任意の名前を付けて保存します。ここでは仮に「Move Down Multiple Lines」としておきます。

これでカーソルを複数行下に移動出来るマクロが完成しました :hand: 

実際にマクロの動作を確認。
メニューの[Edit]-[Macros]の中に作成したマクロ名が表示されるので、それを選択するとマクロが実行されます。
すると複数行一気に下にカーソル移動されるはず。

逆にカーソルを複数行上に移動するマクロは↑のマクロ作成手順3で上に移動すれば出来ます。
マクロ名は先ほどの下に移動するマクロとの関連が判りやすいようにここでは「Move Up Multiple Lines」としておきます。

ただこれで終わりではありません。
これらのマクロはショートカットで出来ないと意味ないのでショートカットキーを登録しておきましょう。


1.メニュー[PhpStorm]→[Preferences]を選択し、設定画面を開きます。
2.左メニューの[KeyMap]でショートカットキー設定を開いて、検索ボックスで自分が作ったマクロ名を入力すると一覧に表示されます。
3.マクロ名をダブルクリックして[Add Keyboard Shortcut]でお好みのショートカットキーを登録しましょう。
![スクリーンショット 2016-09-30 9.12.33.png](https://qiita-image-store.s3.amazonaws.com/0/71113/22a1306e-64ca-7510-ccd3-a2eb79ff03ae.png)

これでカーソル移動が気持ち良くできるようになりました :+1:
win10 > link > Windows 10で利用できるアカウントの種類と管理方法

Windows10(windows8.1?)になってからアカウントの扱いがWindows7とは違う。

以下の情報が整理されていて分かりやすかった。
http://www.atmarkit.co.jp/ait/articles/1509/17/news040.html
NSUserDefaultsが消える

#NSUserDefaultsが消える

最近、iOS9.2でセーブしたデータがよく消えてLINEとかでログインを求められます。

簡易的な解決方法として

http://qiita.com/batibati/items/52a7a72b7aa93ed4c6fc

を参考に強制的にメインスレッドに戻して

```swift
dispatch_async(dispatch_get_main_queue(), {
    //セーブ
})
```

でも直るようですが
これでも時たま消えます。

一番いいのは自分のアプリ内にplistを作って管理することみたいです。

ただしこの症状はXcodeとiOSとの関係性のバグなのでリリース時は起きませんし、
開発時にデータが消えて困るという方だけお使いください。

#RM

iOS10では起こらないみたいです。
Net::SMTPでメール送信時にHELO ドメインを指定する

## 参考

* [Class: Net::SMTP (Ruby 2.0.0)](http://ruby-doc.org/stdlib-2.0.0/libdoc/net/smtp/rdoc/Net/SMTP.html)
* [library net/smtp (Ruby 1.8.7)](https://docs.ruby-lang.org/ja/1.8.7/library/net=2fsmtp.html)

## 方法

```diff
- Net::SMTP.start('smtp.example.com', 25) {|smtp|
+ Net::SMTP.start('smtp.example.com', 25, 'yourdomain.example.com') {|smtp|
```

```diff:受信したメールヘッダーを確認
- Received: from localhost.localdomain (srv1 [1.2.3.4])
+ Received: from yourdomain.example.com (srv1 [1.2.3.4])
```
技術英語 > [Admittedly], this routine with its six cases is longer than the single routine needed to print the buoy temperature message.

@ Code Complete (No. 13874 / 36077)

> <font color=red>Admittedly</font>, this routine with its six cases is longer than the single routine needed to print the buoy temperature message.

http://eow.alc.co.jp/search?q=admittedly
> 確かに、認めざるを得ないことだが、明らかに、正直なところ、ご指摘の通り

http://ejje.weblio.jp/sentence/content/%22I+admit%22
> Though I admit that the story is true.
> しかしその話は本当だということは認める。 - Weblio Email例文集

Voyagerでも"I admit."というフレーズは時々出てきたと思う。
PyQtGraphでグラフを描写する その3 - PlotWidgetの設定

# その3 PlotWidgetの設定
グラフの枠、軸の方向、背景色、サイズを設定する。

![3.png](https://qiita-image-store.s3.amazonaws.com/0/55744/16d7714f-451e-4ea7-564e-1c976b60b65e.png)

```py3
import sys
from PySide.QtCore import *
from PySide.QtGui import *
import pyqtgraph as pg


class GraphWindow(QMainWindow):

    def __init__(self, parent = None):
        
        super(GraphWindow, self).__init__(parent)
        
        # 1 PlotWidgetを作成する
        ## 3 PlotWidgetの枠線、軸の方向を設定する
        pw = pg.PlotWidget(viewBox = pg.ViewBox(border = pg.mkPen(color='#000000'),
                                                invertX = False, invertY = True))

        # 1 ウィンドウにウィジェットを設定する
        self.setCentralWidget(pw)

        ## 3 背景色を設定する(#FFFFFF00: Transparent)
        pw.setBackground("#FFFFFF00")

        ## 3 グラフのサイズを固定する
        pw.setMinimumSize(500, 400)
        pw.setMaximumSize(500, 400)

        # 1 plotItemを呼び出す
        p1 = pw.plotItem

        # 1 散布図と折れ線グラフを描写する
        # 2 プロットの詳細を設定する
        p1.addItem(pg.PlotCurveItem(x = [0, 1, 2, 3 ,4], 
                                    y = [0, 1, 2, 3 ,4], 
                                    pen = pg.mkPen(color = "r", style = Qt.SolidLine),
                                    antialias = True))
        p1.addItem(pg.ScatterPlotItem(x = [0, 1, 2, 3 ,4], 
                                      y = [4, 3, 2, 1, 0], 
                                      symbol = "x", 
                                      pen = pg.mkPen(None), 
                                      brush = pg.mkBrush("b"),
                                      size = 7.5,
                                      antialias = True))


if __name__ == '__main__':
    # Qt Applicationを作ります
    app = QApplication(sys.argv)
    # formを作成して表示します
    mainWin = GraphWindow()
    mainWin.show()
    # Qtのメインループを開始します
    sys.exit(app.exec_())
```
PyQtGraphでグラフを描写する その2 - プロットの詳細設定

# その2 プロットの詳細設定

![2.png](https://qiita-image-store.s3.amazonaws.com/0/55744/84bc3c53-a739-6c11-9d41-d96fbb91af39.png)

```py3
import sys
from PySide.QtCore import *
from PySide.QtGui import *
import pyqtgraph as pg


class GraphWindow(QMainWindow):

    def __init__(self, parent = None):
        
        super(GraphWindow, self).__init__(parent)
        
        # 1 PlotWidgetを作成する
        pw = pg.PlotWidget()

        # 1 ウィンドウにウィジェットを設定する
        self.setCentralWidget(pw)

        # 1 plotItemを呼び出す
        p1 = pw.plotItem

        # 1 散布図と折れ線グラフを描写する
        ## 2 プロットの詳細を設定する
        p1.addItem(pg.PlotCurveItem(x = [0, 1, 2, 3 ,4], 
                                    y = [0, 1, 2, 3 ,4], 
                                    pen = pg.mkPen(color = "r", style = Qt.SolidLine),
                                    antialias = True))
        p1.addItem(pg.ScatterPlotItem(x = [0, 1, 2, 3 ,4], 
                                      y = [4, 3, 2, 1, 0], 
                                      symbol = "x", 
                                      pen = pg.mkPen(None), 
                                      brush = pg.mkBrush("b"),
                                      size = 7.5,
                                      antialias = True))


if __name__ == '__main__':
    # Qt Applicationを作ります
    app = QApplication(sys.argv)
    # formを作成して表示します
    mainWin = GraphWindow()
    mainWin.show()
    # Qtのメインループを開始します
    sys.exit(app.exec_())
```
PyQtGraphでグラフを描写する その1 - 作図

# PyQtGraphについて
は、[ここ](http://qiita.com/nebula121/items/dd9f81da351175a85d41)に書きました。が、放置しすぎたので仕切り直しで…。コード中心にざっくりまとめます。

# その1 作図まで

![1.png](https://qiita-image-store.s3.amazonaws.com/0/55744/01d8ea9e-703d-c2af-b507-126c2ca306a4.png)

```py3
import sys
from PySide.QtCore import *
from PySide.QtGui import *
import pyqtgraph as pg


class GraphWindow(QMainWindow):

    def __init__(self, parent = None):
        
        super(GraphWindow, self).__init__(parent)
        
        ## 1 PlotWidgetを作成する
        pw = pg.PlotWidget()

        ## 1 ウィンドウにウィジェットを設定する
        self.setCentralWidget(pw)

        ## 1 plotItemを呼び出す
        p1 = pw.plotItem

        ## 1 散布図と折れ線グラフを描写する
        p1.addItem(pg.PlotCurveItem(x = [0, 1, 2, 3 ,4], 
                                    y = [0, 1, 2, 3 ,4]))
        p1.addItem(pg.ScatterPlotItem(x = [0, 1, 2, 3 ,4], 
                                      y = [4, 3, 2, 1, 0]))


if __name__ == '__main__':
    # Qt Applicationを作ります
    app = QApplication(sys.argv)
    # formを作成して表示します
    mainWin = GraphWindow()
    mainWin.show()
    # Qtのメインループを開始します
    sys.exit(app.exec_())
```
LINE Beaconを試してみた

9/29のLINE DEVELOPER DAY 2016に参加したところ、こんなに豪華なお土産をいただきました。
![b1.jpg](https://qiita-image-store.s3.amazonaws.com/0/142643/d06e3e3c-4e77-4031-5876-2d5ad4927d53.jpeg)

オシャレなタンブラーも嬉しいですが、何といってもこれ！
![b2.jpg](https://qiita-image-store.s3.amazonaws.com/0/142643/b28895e8-0f40-9dac-2b5b-c5a28d0b21d2.jpeg)

LINE Beacon！！（基盤むき出し！！！）


ってことでワクワクしながら帰ってさっそく試してみました。

#まずLINE BOTを作成する
LINE BUSINESS CENTERの「Developer Traialを始める」からBOTの作成を進めます。
https://business.line.me/ja/services/bot

今回のDEVELOPER DAYと同時にLINE BOTの正式版が発表され、APIも新しくなったようですが、LINE BOTの設定についてはトライアル版とさほど変わってませんでした。
BOTの設定に関しては他の方が詳しく記事を書いてくれているので割愛します。
(後で必要になるので、Webhook URLの設定まで終わらせると良いです)


#LINE BOTとLINE Beaconの連携
BOTの作成が終わったら、ビーコンと連携を行います。
ビーコンが入っていた箱の中にURLが貼ってあるので、そこにアクセス。

BOTを作ったLINEアカウントでサインインすると、こんな画面になると思います。
![beacon1.png](https://qiita-image-store.s3.amazonaws.com/0/142643/8a36776f-7490-324c-131e-fba72e0d801b.png)
連携させるBOTを選択してください。

次に、ビーコンの端末IDとパスコードの入力です。
![beacon2.png](https://qiita-image-store.s3.amazonaws.com/0/142643/f364b19b-0314-1aef-1f39-878c482e22cb.png)


端末ID？？パスコード？？なんぞ？？？

と思ったら電池の裏に書いてありました。

電池引っこ抜いてみてください。
![b3.jpg](https://qiita-image-store.s3.amazonaws.com/0/142643/1c86cab4-9291-0929-a1e1-fb55348cd406.jpeg)
（電源は単三電池2本なんですね）

これで連携は完了です。

#いざ電源ON！！
・
・
・

基盤が点灯したものの、何も起こりません。
LINE DEVELOPER DAYの会場に設置されたビーコンでは、
近寄るとLINEの画面上に通知が飛んできたんですが・・・
あの機能は提携企業にのみ提供されているようです。残念。

BOTと友だちになった状態でビーコンに近寄ると
BOTサーバー(Webhook URL)にイベントが飛ぶとのことなので、
そちらの確認をしてみました。

#ビーコンイベントのキャッチ
新しくなったAPIリファレンスを見ながら、(https://devdocs.line.me/ja/)
ビーコンイベントのキャッチ & レスポンス処理を書いてみました。

```php:hook.php
<?php

$json_string = file_get_contents('php://input');
$json_object = json_decode($json_string);

foreach ($json_object->events as $event) {
	if('message' == $event->type){
		api_post_request($event->replyToken, $event->message->text);
	}else if('beacon' == $event->type){
		api_post_request($event->replyToken, 'BEACONイベント!!');
	}
}

function api_post_request($token, $message) {
    $url = 'https://api.line.me/v2/bot/message/reply';
    $channel_access_token = '<BOT設定画面から取得したトークン>';
    $headers = array(
        'Content-Type: application/json',
        "Authorization: Bearer {$channel_access_token}"
    );
    $post = array(
    	'replyToken' => $token,
    	'messages' => array(
    		array(
    			'type' => 'text',
    			'text' => $message
    		)
    	)
   	);

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($post));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_exec($curl);
}
```
メッセージイベントならユーザーの入力文をオウム返しし、
ビーコンイベントなら「BEACONイベント!!」と返信するようにしました。

結果はこちら
![b4.png](https://qiita-image-store.s3.amazonaws.com/0/142643/6348c7c5-a7c3-d52e-7cd7-b3e514dd16dc.png)

この通り、メッセージのオウム返しと「BEACONイベント!!」返しができました。

電源ONからイベントが飛んでくるタイミングや間隔がイマイチわかりませんでしたが、
とりあえず何か面白いものが作れそうです。
PowerShell の Get-ChildItem の -Filter の挙動

PowerShell の Get-ChildItem で以下のようにすると、余計なファイルがヒットする。

```ps1
PS C:\foo> Get-ChildItem -Filter *.htm


    ディレクトリ: C:\foo


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2016/09/30      0:22              0 file1.htm
-a----       2016/09/30      0:22              0 file2.html ← 余計なファイル
```

以下の場合はヒットしない。

```ps1
PS C:\foo> Get-ChildItem *.htm


    ディレクトリ: C:\foo


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2016/09/30      0:22              0 file1.htm
```

ちょっと調べて、Get-ChildItem の -Filter は MS-DOS の挙動に合わせている、と理解。

* http://stackoverflow.com/questions/12913734/powershell-get-childitem-filter-operates-differently-to-where-clause-with-same
* http://stackoverflow.com/questions/6628875/powershell-file-system-provider-get-childitem-filtering-where-are-the-offic
* http://superuser.com/questions/825615/windows-wildcards-with-files-having-more-than-3-characters-extensions
gocsvを使ってラクにCSVファイルをつくる


標準パッケージの`encoding/csv`を使ってもいいですが、[gocsv](https://github.com/gocarina/gocsv)つかうとラク出来ますよ、という話。社内の業務アプリケーションだとデータをダウンロードしたい要求が強く、REST APIのレスポンス形式の一つとしてjsonとcsvみたいなケース、結構あります。

そんな時、jsonもcsvもGoの構造体（struct）で管理出来たら良いよねーと思って探していたら、上記のライブラリが見つかった次第。

## 使い方

```main.go
package main

import (
    "fmt"
    "os"

	"github.com/gocarina/gocsv"
)

type Client struct { // 構造体にcsvタグをつける、これがCSVに出力される際のタイトルになる
	Id   string `json:"id" csv:"id"`
	Name string `json:"name" csv:"名前"`
	Age  string `json:"age" csv:"年齢"`
}

func main() {
 
  clients := []*Client{}
  clients = append(clients, &Client{Id: "12", Name: "John", Age: "21"}) // Add clients
  clients = append(clients, &Client{Id: "13", Name: "Fred"})

  file, _ := os.OpenFile("sample.csv", os.O_RDWR|os.O_CREATE, os.ModePerm)
  defer file.Close()

  // csvファイルを書き出し
  gocsv.MarshalFile(&clients, file)
  
  // ファイルではなく文字書き出しをする場合
  // csvStr, err := gocsv.MarshalString(&clients)
}
```

これでCSVファイルの作成ができる。かんたーん。

## sjis化

まあ大体の一般利用者はCSVはエクセルで開くわけで。SJIS化は必須なわけで。
そんなときは`SetCSVWriter`で設定を上書きしてあげる。

 * golang.org/x/text/encoding/japanese
 * golang.org/x/text/transform

が別途必要。

```main.go
pakcage main

import (
	"encoding/csv"
	"io"
	"golang.org/x/text/encoding/japanese"
	"golang.org/x/text/transform"
	
	"github.com/gocarina/gocsv"	
)

func main() {
...
    // SetCSVWriterでオーバーライド
 	gocsv.SetCSVWriter(func(out io.Writer) *csv.Writer {
		return csv.NewWriter(transform.NewWriter(out, japanese.ShiftJIS.NewEncoder()))
	})
...
    gocsv.MarshalFile(&data, file)

}
```

こんな感じ、注意点としては内部的にreflectを結構使ってるので、パフォーマンスに気を遣っている方は自前実装したほうが良いかと思いますー。
Linuxチートシート｜Mailサーバ(Postfix)編

## メモ
 - PostfixはSendmail互換のメール転送エージェント

## チートシート

``` sh
# メール送信
$ mail MAILADDRESS

# Postfixサービスの起動/再起動/終了
$ systemctl start postfix
$ systemctl restart postfix
$ systemctl stop postfix

# Postfixサービスの自動起動の有効化/無効化
$ systemctl enable postfix
$ systemctl disable postfix

# Postfixの設定値を確認
$ postconf

# Postfixの設定値を確認（デフォルト設定からの変更分のみ）
$ postconf -n

# /etc/postfix/accessファイルをバイナリ化
$ postmap /etc/postfix/access

```

## 設定ファイル

``` bash
# Postfixの設定ファイル
/etc/postfix/main.cf

# アクセス制御
/etc/postfix/access

# ログ
/var/log/maillog

```

## 各種設定の参考
 - [Postfix設定パラメータ](http://www.postfix-jp.info/trans-2.3/jhtml/postconf.5.html)
 - [/etc/postfix/accessで迷惑メール対策](http://qiita.com/tukiyo3/items/902b3c859346f6c00168)
LINE Messaging API が BOT API から変わったところ。

#サンプルbotは[こちら](http://qiita.com/TetsuyaImagawa/items/60096dc66ea0a3f709ed)
#変更点
良: 友達50人限定だったものが無制限に！
悪: Push API（botから話しかける機能）が月21,600円のプロ版でしか使用できない…


#送受信json
##メッセージ受信時
###BOT API

```receiving_message_bot.json
{"result":[
  {
    "from":"u2ddf2eb3c959e561f6c9fa2ea732e7eb8",
    "fromChannel":1341301815,
    "to":["u0cc15697597f61dd8b01cea8b027050e"],
    "toChannel":1441301333,
    "eventType":"138311609000106303",
    "id":"ABCDEF-12345678901",
    "content": {
      "location":null,
      "id":"325708",
      "contentType":1,
      "from":"uff2aec188e58752ee1fb0f9507c6529a",
      "createdTime":1332394961610,
      "to":["u0a556cffd4da0dd89c94fb36e36e1cdc"],
      "toType":1,
      "contentMetadata":null,
      "text":"Hello, BOT API Server!"
    }
  },
  ...
]}
```

###Messaging API

```receiving_message_messaging.json
{
  "events": [
      {
        "replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
        "type": "message",
        "timestamp": 1462629479859,
        "source": {
             "type": "user",
             "userId": "u206d25c2ea6bd87c17655609a1c37cb8"
         },
         "message": {
             "id": "325708",
             "type": "text",
             "text": "Hello, world"
          }
      }
  ]
}
```

##メッセージ送信時
###BOT API
https://trialbot-api.line.me

```http:HTTP_Headers.
POST /v1/events HTTP/1.1
Host: trialbot-api.line.me
Content-type: application/json; charset=UTF-8
X-Line-ChannelID: YOUR_CHANNEL_ID
X-Line-ChannelSecret: YOUR_CHANNEL_SECRET
X-Line-Trusted-User-With-ACL: YOUR_CHANNEL_MID
```

```sending_message_bot.json
{
  "to":["u5912407b444e54885d00111f7b0ce375"],
  "toChannel":1383378250,
  "eventType":"138311608800106203",
  "content":{
    "contentType":1,
    "toType":1,
    "text":"Hello, Jose!"
  }
}
```
###Messaging API(プロ版のみ)
https://api.line.me/v2/bot/message/push

```HTTP_Headers.
POST
Content-Type:application/json
Authorization: Bearer {ENTER_ACCESS_TOKEN}
```

```sending_message_messaging.json
{
    "to": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "messages":[
        {
            "type":"text",
            "text":"Hello, world1"
        },
        {
            "type":"text",
            "text":"Hello, world2"
        }
    ]
```

###Messaging API(返信)

https://api.line.me/v2/bot/message/reply

```reply_messaging.json
{
    "replyToken":"nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
    "messages":[
        {
            "type":"text",
            "text":"Hello, user"
        },
        {
            "type":"text",
            "text":"May I help you?"
        }
    ]
}
```

シンプル！
しかしPush API使いたくて課金してしまう未来の自分が見える…
ディレクトリ内のファイルサイズの平均を計算するコマンド

例えばログを毎日ローテートしていて一日の平均サイズを知りたい場合などに。出力結果は byte 単位。

```
ls -l | awk '{s+=$5; n++} END {print s/n}'
```

さらにピンポイントな用途ですが、ローテートしたログを圧縮保存していて、生のログの平均サイズが知りたい場合、
以下のようにすると解凍せずに計算することができます。

```
gzip -l *.gz | sed -e 1d | awk '{s+=$2; n++} END {print s/n}'
```
Go WEBフレームワークEchoでmiddlewareを自作する


## 発端

Go言語の高パフォーマンスWAFである[Echo](https://echo.labstack.com/)を利用したアプリを開発している際、 **特定のクエリパラメータ値が一致しなけれ処理を通さない** という要件があった。各ルート以下でいちいちQueryParamをvalidするのも馬鹿らしく、なんとかしてミドルウェアと模索した結果、割と簡単に出来たのでメモ程度に共有。

## echoのmiddleware

* https://echo.labstack.com/recipes/middleware

expressよろしく`next`で繋いでいくスタイルらしい。そんなわけで下記コード。

```main.go
package main

import (
	"net/http"
	"os"

	"github.com/labstack/echo"
	"github.com/labstack/echo/engine/standard"
	"github.com/labstack/echo/middleware"
)

// CustomMiddleware
func CustomMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
	return func(c echo.Context) error {
	
		// QueryParam ?hoge=にあるパラメータを取得
		hoge := c.QueryParam("hoge")
		
		if hoge != os.Getenv("hoge") {
			
			// 一致してなければUnauthorizedを返す（ステータスは適当）
        	return echo.NewHTTPError(http.StatusUnauthorized)
		}
		return next(c)
	}
}

func main() {
	e := echo.New()

	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	// 自作ミドルウェアをグループ化
	m := e.Group("", CustomMiddleware)

	// グループに適用させるルーティング
	m.GET("/", func(c echo.Context) error {
		return c.Render(http.StatusOK, "index", "HOGEHOGE")
	})
	m.POST("api/v1/upload", Upload)
	m.GET("api/v1/download", Download)

	// App Server Run
	e.Run(standard.New(":" + os.Getenv("PORT")))
}
```

これで想定どおりに動いた。コツは`Group`のmiddlewareとして動作させることで、単純に`e.Use(...)`とかやると全体にかかりすぎて、htmlやcssといったstaticなコンテンツの取得にまで影響してしまった。あくまでもルーティングパスのみに掛けること。
Linuxチートシート｜DNSサーバ(BIND)編

Linuxの学習メモをチートシートとして残します。

## メモ
 - BINDはデフォルトでセキュリティ設定がかなり甘く、実用には様々な設定が必要
 - リゾルバ：名前解決の問い合わせを行うソフト
 - ゾーン：DNSサーバが管理するドメインの範囲（複数ドメイン可）
 - マスタDNSサーバ：オリジナルのゾーンファイルを保持
 - スレーブDNSサーバ：ソーンファイルのコピーを保持（マスタからゾーン転送）
 - キャッシュサーバ：問い合わせ結果を一時的にメモリ上に保持
 - セキュリティ上の理由からchroot環境での実行を推奨（要bind-chrootインストール）

## チートシート

```bash
# ホスト名の確認
$ hostname

# 正引き問い合わせ
$ host DOMAINNAME
$ dig DOMAINNAME

# 逆引き問い合わせ
$ host IPADDRESS
$ dig -x IPADDRESS

# BINDサービス起動/再起動/停止
$ systemctl start named
$ systemctl restart named
$ systemctl stop named

# BINDサービスの自動起動を有効化/無効化
$ systemctl enable named
$ systemctl disable named
 
# BINDサービス起動/再起動/停止（chroot環境）
$ systemctl start named-chroot
$ systemctl restart named-chroot
$ systemctl stop named-chroot

# BINDサービスの自動起動を有効化/無効化（chroot環境）
$ systemctl enable named-chroot
$ systemctl disable named-chroot



```

## 設定ファイル
``` bash
# hostsファイル
/etc/hosts

# BINDの設定ファイル（ブートファイル）
/etc/named.conf
/etc/named/*

# ゾーンデータファイル
/var/named/*

# 名前解決の問い合わせ順設定
/etc/nsswitch.conf

# リゾルバ用設定ファイル
/etc/resolv.conf
```

## 各種設定の参考
 - [備忘録）BIND named.conf の記載について。](http://qiita.com/dumpty-alma@github/items/536f21de67d0ed2c8e85)
 - [自宅サーバのDockerでDNSを運用する](http://qiita.com/74th/items/a7e0c044497c95ecc04a)
 - [DNSサーバのチューニング　其の一](http://qiita.com/digitalpeak/items/210d0eea3c5340e46123)
 - [DNSサーバ構築](http://qiita.com/digitalpeak/items/e61f0b6a32b345883bce)
Ubuntuで人工知能・機械学習(TensorFlow、Caffe)を試す環境を作るansible playbookを作りました。

Ubuntuで人工知能・機械学習(TensorFlow、Caffe)を試す環境を作るansible playbookを作りました。

TensorFlowはともかく、Caffeは設定も少々あったりで時間がかかるので
すぐに実行環境を作れるようにansibleで書きました。

今後他の機械学習フレームワークの追加とMac対応をする予定です。

https://github.com/kurokurosawa/DeepLearning_Ubuntu

参考
https://www.amazon.co.jp/dp/B01LXSSR7X/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

```
---
- name: 基本パッケージをインストール
  apt: name={{item}} state=present update_cache=yes
  with_items:
      - libatlas-base-dev
      - libprotobuf-dev
      - libleveldb-dev
      - libsnappy-dev
      - libopencv-dev
      - libboost-all-dev
      - libhdf5-serial-dev
      - libgflags-dev
      - libgoogle-glog-dev
      - liblmdb-dev
      - protobuf-compiler
#      - g++-4.6
      - hardening-wrapper

#- name: Install -y g++-4.6
#  shell: apt-get install -y g++-4.6

- name: git clone Caffe
  shell: chdir=~/ git clone https://github.com/BVLC/Caffe
  become: no

- name: Makefile.config
  shell: cp ~/Caffe/Makefile.config.example ~/Caffe/Makefile.config
  become: no

- name: Makefile.config CPU_ONLY := 1
  shell: sed -i -e 's/# CPU_ONLY := 1/CPU_ONLY := 1/g' ~/Caffe/Makefile.config
  become: no

- name: Makefile.config CUSTOM_CXX := g++-4.6
  shell: sed -i -e 's/# CUSTOM_CXX := g++/CUSTOM_CXX := g++-4.6/g' ~/Caffe/Makefile.config
  become: no

- name: make
  command: chdir=~/Caffe make
  become: no

- name: make test
  shell: chdir=~/Caffe make test
  become: no

- name: make runtest
  shell: chdir=~/Caffe make runtest
  become: no
```
CentOS7.2にCaffeをインストールして物体認識のサンプルを動かしてみる（20161003版）

# 改版履歴
* 10/03改版
    * 物体認識のサンプルが動作するまでの手順を追加
    * pip installで発生するパッケージが無いエラーを解消するため、以下を追加インストール

        ~~~
wget lapack-devel blas-devel numpy-f2py freetype-devel libpng-devel libjpeg-turbo-devel
        ~~~

    * ビルド後のDockerイメージサイズを更新
    * Dockerfileの動作確認を実施

# 手順

* Caffeの物体認識を試してみたかったので、ネットの記事を参考に環境構築を行ったメモ。

* ライブラリのインストール(10/03修正)
    
    ~~~
yum install -y epel-release
yum install -y make cmake gcc gcc-c++ doxygen git python-devel python-pip numpy numpy-f2py unzip wget
yum install -y protobuf-devel leveldb-devel snappy-devel opencv-devel boost-devel hdf5-devel gflags-devel glog-devel lmdb-devel atlas atlas-devel blas-devel openblas* lapack-devel freetype-devel libpng-devel libjpeg-turbo-devel
    ~~~

* Caffeのインストール

    ~~~
curl -OL https://github.com/BVLC/caffe/archive/master.zip
unzip master.zip -d /opt
mv /opt/caffe-master /opt/caffe
cd /opt/caffe
cp Makefile.config.example Makefile.config
make all -e CPU_ONLY=1 -e BLAS=open
make test -e CPU_ONLY=1 -e BLAS=open
make runtest -e CPU_ONLY=1 -e BLAS=open
  ~~~

* 物体認識のサンプル動作環境の設定

    ~~~
cd /opt/caffe/data
curl -OL http://www.vision.caltech.edu/Image_Datasets/Caltech101/101_ObjectCategories.tar.gz
tar xf 101_ObjectCategories.tar.gz
cd /opt/caffe/data/ilsvrc12
./get_ilsvrc_aux.sh
cd /opt/caffe/models/bvlc_reference_caffenet/
curl -OL http://dl.caffe.berkeleyvision.org/bvlc_reference_caffenet.caffemodel
cd /opt/caffe/python/
cat requirements.txt  | xargs -n1 pip install
    ~~~

* 残りは以下を参照
  http://habatafuture.hatenablog.jp/entry/2015/09/19/001335
  　

* Dockerfile

    上記までの作業を行ったDockerfileを以下に登録。ビルドすると2.4GB程度になる。(10/03更新)
    https://github.com/r-hirakawa/docker
    　

* 補足
    * CentOS7でatlasを使うとmakeでエラーが出るため、makeのオプションに「-e BLAS=open」を指定し、openblasを利用
    * CPU版を利用するためmakeのオプションに「-e CPU_ONLY=1」を指定
    * 「pip install -r requirements.txt」は動かなかったので「cat requirements.txt  | xargs -n1 pip install」に変更
問題を難しくするな。

問題を難しくするな。

- ほんの少しの厄介さも、数が増えれば手に負えなくなる。
    - そのような厄介さを確実に減らしていこう。
- フールプルーフを考えていないシステムは、複雑度が上がりすぎると手に負えなくなる。
    - UIが利用者にとって不可思議な前提を要求したり、押し間違いなどへの対策がないなど、そういう項目が増えすぎると手に負えなくなる。32桁の英数字をタイプすることを考えてみよう。これは128桁などのなったときには、タイプミスを生じないことは考えにくい。そのようなときには、本来の操作をすることには無関係のところで手に負えなくなってしまう。
- 性能がこういう状態では出にくくなるとわかっているギリギリのところで動作させようとするな。
    - 雪道で、道の端っこを歩こうとするようなものです。いずれ側溝に足を突っ込むことになります。
- ものごとが100%精度でうまくいくようにはできない種類の問題に対して、100%の精度がでたらという前提で
　話を進めるのはやめよう。
- 考えている手法がうまくいかない場合の、「逃げ」の手法を考えておこう。
    - 物事が自分の予想しているとおりに簡単に解決できるとは限りません。常に「逃げ」の手法を考えておきましょう。
- CPUの性能を上げれば済む問題なら、CPUの性能を上げよう。
- 問題を明確化しよう。
    - 問題が解決できていない状況では、問題を明確に記述できていないことが多い。
    - 問題を明確に記述できていないから、必要以上に騒ぎ立てる人も出てしまう。
- 問題を単純化しよう。
    - 前提条件の少ない形で問題を記述しよう。依存しているものが多い記述ではなく、依存性の少ない記述にしよう。単純化することで、「さまざまな問題が込み入った問題」から「単純化された小さな問題が、いくつか同時にある問題」となります。単純化された小さな問題は、「さまざまな問題が込み入った問題」よりもはるかに解きやすくなります。
- 解決できた部分については、解決できたことを共有しよう。そうすることで進展した部分での成果を使って次の解決がしやすくなっている。
    - 問題の全てが同時に解決することはない。そこで１つの問題を解決したときに、「まだ、○○が解決できてないじゃないか」などと言ってはいけない。えてして、そのような発言によって、課題解決にあたっていた人のやる気をそぐことになる。
- 「ベストを目指すな」、「許容できる設計をしよう」
    - それがベストであることを示すのは、ほとんどの場合とても面倒です。ベストを見つけてベストを実装するのはとても厄介です。でも、必要なことは、使う状況の範囲でその手法が十分に問題なく使えるかということです。例をあげれば、最適なソート（ならびかえ）のアルゴリズムを実装するのと、バブルソートを実行するのでは、目的によって使い分けるべきだということです。利用する状況によってはバブルソートでも十分なことがあります。高速なソートアルゴリズムを実装するのは楽ではありません。（ここでは、作業の例としてあげているのであって、あなたが解決する問題の中では、別の作業です。ですから、STLのsortを使えば一発じゃないという突っ込みは不要です。）

繰り返し言う。
問題を過度に難しくすれば、どんな問題だって解決不能になる。
開発に投入できる人員と、許された期間の中で、妥協できる性能を出すことです。
「ベストを目指すな」、「許容できる設計をしよう」


付記：
問題を簡単にするための例を書き始めてみたが、逆に発想を制約してしまうことに気づいた。
Linuxチートシート｜ネットワーク設定編

Linuxの学習メモをチートシートとして残します。

## メモ

 - RHEL7系ではネットワーク管理はNetworkManagerの利用を推奨
 - 従来のifconfigなどを利用する場合は要インストール

## チートシート

``` bash
# ネットワークを有効化
$ nmcli networking on

# ネットワークを無効化
$ nmcli networking off

# NetWorkManagerの状態を確認
$ nmcli general status

# デバイスとコネクションの接続状態を確認する
$ nmcli device status

# デバイスを接続
$ nmcli device connect DEVICENAME

# デバイスを切断
$ nmcli device disconnect DEVICENAME

# ホスト名を変更
$ nmcli general hostname HOSTNAME

# コネクションを確認
$ nmcli connection show

# コネクションを有効化
$ nmcli connection up CONNECTIONNAME

# コネクションを無効化
$ nmcli connection down CONNECTIONNAME

# コネクションのIPアドレスを変更
$ nmcli connection modify CONNECTIONNAME ipv4.addresses IPADDRESS

# デバイスにコネクションを追加
$ nmcli connection add type ethernet con-name CONNECTIONNAME ifname DEVICENAME

# デバイスからコネクションを削除
$ nmcli connection delete CONNECTIONNAME

# ホスト名を確認
$ hostname

# ホスト名を変更（専用コマンド）
$ hostnamectl set-hostname HOSTNAME

# ホスト名を確認（専用コマンド）
$ hostnamectl status

# ICMPパケットを5回送信
$ ping -c5 IPADDRESS

# ソケットの統計情報を確認
$ ss

```