OmniAICreator/Qiita-1.07M huggingface dataset:
機械学習の内輪向け勉強会: 概念の理解

本エントリーは、内輪向けの勉強会向けに書いたメモです。
元になっているのは、2冊の書籍です。

- [機械学習Pythonプログラミング(インプレス)](http://amzn.to/2iKe2r5) 
- [ITエンジニアのための機械学習理論入門(技術評論社)](http://amzn.to/2hYYoGX)

基本的な部分は、「機械学習Pythonプログラミング」を元にし、「ITエンジニアのための機械学習理論入門」で補足する方でまとめています。

なお、本記述に間違い勘違いなどがあれば気軽にご指摘ください。

# 種類

## 学習方法 **重要**

- 教師あり
- 教師なし・ラベルなし
- 強化学習

## 目的の種類

(from 機械学習理論入門)

- 分類 ・・Positive(P) or Negative(N) の判定
- 回帰分析　・・数値を予測する
- クラスタリング　・・教師なしで、グループ化
- 類似マッチング　・・類似物を見つける (書籍では単語のみ紹介)
- 共起分析　・・レコメンデーション (書籍では単語のみ紹介)
- リンク予測　・・つながり (書籍では単語のみ紹介)

# 各種用語

## 学習度合い **重要**

- 過学習・バリアンスが高い・オーバーフィッティング
- 学習不足・バイアスが高い

## 変数

(from 機械学習理論入門)

- 説明変数・特徴変数・特徴ベクトル
- 目的変数


# 前処理系

- 欠損値補完
- 特徴量の選択
- 特徴量の抽出
- 次元削減
- 主成分分析(PCA)
- 線形判別分析(LDA)
- カーネル主成分分析
- 探索的データ解析


# アルゴリズム名、変換器、推定器

- パーセプトロン
- ロジスティック回帰
- SVM
- カーネルSVM
- 決定木
- ランダムフォレスト
- k近傍法
- k-平均法(k-means)
- ランダムフォレスト回帰
- アンサンブル学習 ・・・ 複数のアルゴリズムを混ぜて多数決などで判断
- BoW (Bag-of-Words)


# 検証方法など

- テストデータの分割
- k分割交差検証(クロスバリデーション) **重要**
- グリットサーチ
- 混同行列(Confusion matrix) (TP/TN/FP/FN)
- 誤差の考え方
    - 残差・誤差
    - 平均二乗誤差(MSE)
    - 誤差平方和(SSE)
    - 決定係数(R2)



# Python機械学習プログラミングの本の内容

- 学習モデルの基本的な手順・方法の説明
- 機械学習アルゴリズムのトレーニングの基礎を、構築する
- scikit-learnの活用方法
- データ前処理
- 次元削減でデータを圧縮する
- モデルの評価とハイパーパラメータのチューニング
- アンサンブル学習--異なるモデルの組み合わせ
- 感情分析をもちいて適すデータの変換、機械学習アルゴリズムに適用
- Webアプリケーション(Flask/Picle)
- 回帰分析--連続地を取る目的変数の予測
- クラスタ分析--ラベルなしデータの分析
- ニューラルネットワーク -- 画像認識トレーニング
- ニューラルネットワーク -- 数値計算ライブラリTheanoによるトレーニング


# 機械学習理論入門で使っているアルゴリズム

## 最小二乗法

- 教師あり
- 回帰分析

## 最尤推定法

- 教師あり
- 回帰分析

## パーセプトロン

- 教師あり
- 分類

## ロジスティック回帰

- 教師あり
- 分類
- 最尤推定法を用いる
- ROC曲線を使って機械学習の適用をする考え方も学ぶ

## k平均法

- 教師なし
- クラスタリング

## k近傍法

- 教師あり
- クラスタリング
- これは、機械学習なのか？

## EMアルゴリズム

- 教師なし
- クラスタリング
- 最尤推定法を用いる

## ベイズ推定

- パラメータ値を確率的に推測する



# ツール類の説明

セットアップ方法: http://qiita.com/terapyon/items/e4a759de90fb687e7332

## NumPy

数値計算モジュール

## SciPy

科学技術計算モジュール

## Pandas

データフレーム

## matplotlib

グラフ出力

## scikit-learn

様々な機械学習アルゴリズムが実装されている

チートシート

http://scikit-learn.org/stable/tutorial/machine_learning_map/

- regression: 回帰
- classification: 分類
- clustering: クラスタリング
- dimensionality reducion: 次元削減


## jupyter notebook (IPython notebook)

Webブラウザで実行できるPython環境


# scikit-learnで何かをやってみよう

## TBD


## 参考

- PyData Tokyo Tutorial #1
    - https://pydatatokyo.connpass.com/event/11860/
    - イントロ: http://www.slideshare.net/hijiki_s/20150307-py-datatutorial
    - Data Handling: https://pydata.tokyo/ipynb/tutorial-1/dh.html
    - Machine Learning: https://pydata.tokyo/ipynb/tutorial-1/ml.html
Raspberry piにNASをマウントした時の覚書

#作業手順
1. cifs-utilsのインストール
2. マウント用ディレクトリの作成
3. mountコマンドによりマウント
4. 起動時に自動でマウントするように設定

#cifs-utilsのインストール

```shell-session
sudo apt-get install cifs-utils
```

問題なく完了

#マウント用ディレクトリの作成

```shell-session
sudo mkdir /mnt/nas
sudo chmod 777 /mnt/nas
```

#マウント

```shell-session
sudo mount -t cifs //192.168.1.XX/share /mnt/nas -o username=XXXXXX,password=XXXXXX,iocharset=utf8
```
usernameはNASにアクセス出来るID

ここまでは順調。

#起動時に自動でマウント

最終的な/etc/fstabの記述

```shell-session
//192.168.1.xxx/share /mnt/nas cifs username=xxxxx,password=xxxxx,file_mode=0777,dir_mode=0777,iocharset=utf8,uid=1000,gid=1000,forceuid,forcegid,defaults 0 0
```
uid,gid,force*は不要な気もするが、今動いているので放っておく。

/etc/rc.localのexit 0の前に、

```shell-session
sleep 20
sudo mount -a
```

を追加。
20秒は長すぎる気がするが、5秒だとNGだったので、長めに設定した。
Typescriptバージョンを2.0にしたら、sublimeで_thisが重複のエラーのビルドエラー

Typescriptバージョンアップしたら、_thisが重複のエラーのビルドエラーが発生
** error TS2400: Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference.
    2 **

1.8で問題ないですが、2.0にしたら、_this重複のエラーが出ています。
原因はアロー関数をかくと、thisを自動的に_thisに置換するそうです。（2.0から？）
[http://stackoverflow.com/questions/12710303/should-creating-a-variable-named-this-conflict-with-this]

とりあえず、Sublime設定のtypescript_tsdkを1.8に設定して、ビルドエラー出なくなりました。

そもそも_thisを使わないほうがいいですね。
ADに参加していないPCが頻繁にアカウントロックされる


PCがドメインに参加しておらず、共有ファイルの一部がAD管理な環境で、パスワードを更新した所、頻繁にアカウントロックが発生してしまうようになった件についての対応メモ

##状況

Windows7
資格情報マネージャーからADの接続情報を消しても、新しいパスワード以外で接続され、自動で再試行してしまう為に、即座にアカウントがロックされてしまう事になっていた。

##結果

ローカルユーザーがドメインユーザーと同じIDであったため

1. ローカルからドメインにつなぐ
2. ドメイン側にローカルID/PASSで認証が飛ぶ
3. ドメイン側で一致したIDのアカウントとパスワードが一致しない
4. ロックがかかるまで自動で再試行される
5. アカウントロック

という流れだった模様

https://blogs.technet.microsoft.com/jpntsblog/2016/04/19/account-lockout-1/
こちらの「※ (1) のドメインとローカルで同じユーザーアカウントを使用している場合の動作について」参照

##対応

###Windowsでアカウントを変えてみる

→ アカウント名の変更では流石にIDは変わらなかった

###Windows 転送ツールを使用

新しいIDを作成し、プロファイルを移行

http://pasofaq.jp/controlpanel/nusrmgr/migwizcopyprofile.htm

DC側のイベントログに、新しいIDでの失敗ログが入り、ドメインユーザでの認証で入れたことを確認

##未解決

- アカウントロックがかかる際、クライアント側から一度接続しようとするだけで、ロックの上限まで自動的に再試行が行われてしまうので、一度認証に失敗したらダイアログが出るような設定は出来るのかどうか

- ローカルユーザー
bundle installでBuildErrorとかが出てしまった時やった対処法

##前置き

```
$ bundle exec rake db:create db:migrate db:seed
```
をコマンドで打ったり

```
$ rails -v
```
をコマンドで打ったときになぜか

```
Your bundle is locked to activesupport (4.2.4), but that version could not be found in any of the sources listed in your Gemfile. If you haven't changed sources, that means the author of activesupport (4.2.4) has removed it. You'll need to update your bundle to a different version of activesupport (4.2.4) that hasn't been removed in order to install.
Run `bundle install` to install missing gems.
```

というエラーメッセージが帰ってくるようになってしまい、bundle installしても

```
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
```
とか

```
An error occurred while installing libv8 (3.16.14.15), and Bundler
cannot continue.
Make sure that `gem install libv8 -v '3.16.14.15'` succeeds before bundling.
```
とかエラーになってしまうので、どうしたもんかと思って解決策を探ってみました。

エラーメッセージの内容で検索をしてみたところ
An error occurred while installing libv8 (3.16.14.15), and Bundler
cannot continue.
この部分でヒットしたものが解決策になりました。

[参考(というかほぼそのままw)](http://qiita.com/ooyabuh/items/32e7086917e29356b532)

```
$ gem install libv8 -v '3.16.14.11' -- --with-system-v8
$ bundle config build.libv8 --with-system-v8
$ bundle update
```

これでinstallできてなかったものがしっかりとインストールできて

```
rails -v
```
とかでもしっかりとrailsのバージョンを明示してくれるようになりました。
アンチウイルスソフトの活動でファイル書き込みに失敗していた

# アンチウイルスソフトの活動でファイル書き込みに失敗していた

MFCでアプリ開発していた時のこと

```cpp
CFile file
file.Open(_T("dump.bin", CFile::modeWrite | CFile::modeCreate);
```
上記でファイルオープンしてデータを書きこむアプリをデバッグ中に、
ときどき、Openに失敗(戻り値 FALSE)となることがあった。

<原因>
アンチウイルスソフトが、裏でdump.binの内容を解析していて、
かつOpenで共有モードを指定していなかったので、デフォルトのCFile::shareExclusiveとなっていたため、ファイルがすでに開かれており、Openエラーとなっていた。
*.binという名前は疑われる？

<対策>
file.Open(fname, CFile::modeWrite | CFile::modeCreate | CFile::shareDenyWrite);

とした。
nginxで .git や .htaccess など隠しファイル/フォルダを公開しない

# nginxで .git や .htaccess などの隠しファイル/フォルダを公開しない設定

    # .git などの隠しファイルを返さない
    location ~ .*/\..* {
        deny all;
    }

正規表現でURL内に /. を見つけると弾くようにしている。
js HTML Entitiesへの変換

##お題
HTMLマークアップにおいて頻繁に用いられると思われる文字(下記)をHTML Entities(文字実体参照)へ変換する。

|文字  |文字実体参照  |説明  |
|---|---|---|
| < |\&lt; | 小なり記号（半角） |
|>|\&gt;|大なり記号（半角） |
| & |\&amp; | アンパサンド（半角） |
| " |\&quot; | 二重引用符（半角） |
| ' |\&apos; | 引用符（半角） |

*[HTML Entities](https://dev.w3.org/html5/html-author/charref)

```js
function convertHTML(str) {
  htmlEntities={
    '&':'&amp;',
    '<':'&lt;',
    '>':'&gt;',
    '\"':'&quot;',
    '\'':"&apos;"
  };
//write your code
}
convertHTML("Dolce & Gabbana");//Dolce &​amp; Gabbana
```
 
##出力結果　例

```js
convertHTML('Stuff in "quotation marks"') // Stuff in &​quot;quotation marks&​quot;
convertHTML("Shindler's List") // Shindler&​apos;s List
convertHTML("<>") // &​lt;&​gt;
convertHTML("abc") // abc
```

##使ったもの
split()
map()
join()

##考えかた
・変換する文字と文字実体参照をオブジェクトで用意する。
・split()で分割した引数をmap()で個別に変換する。
割り当てた文字に該当するものがあれば変換し、なければそのまま返す。
・さいごにjoin()で一緒にしておわり

##コード

```js
function convertHTML(str) {
  htmlEntities={
    '&':'&amp;',
    '<':'&lt;',
    '>':'&gt;',
    '\"':'&quot;',
    '\'':"&apos;"
  };
  return str.split('').map(function(entity){
    return htmlEntities[entity] || entity;
  }).join('');
}
```

##正規表現を使ったコード

```js
function convertHTML(str) {
  str = str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,"&apos;");
return str;
}
```

###他にもコードが浮かんだ方、コメントおまちしております。
[OpenCV3.2.0] Eclipse(Java)の設定(for Mac)

MacでOpenCV3.2.0を入れた時、かなり苦労しましたので、メモしておきます。
Windowsではダウンロードしてすぐ使えるらしいですが、Macだと結構面倒でした。
##環境
・OS X El Capitan 10.11.6
・Eclipse Neon
・OpenCV 3.2.0

###1. OpenCV3.2.0をインストール
Homebrewがインストールされていないなら、インストールしておきましょう。

以下のコマンドを実行
brew tap homebrew/science
brew install opencv3 --with-java

cmakeにリンクされないなどのエラーが出ましたら、言われた通りにすれば大丈夫です。

インストールができれば、/usr/local/Cellar/opencv3/3.2.0/share/OpenCV/javaフォルダに以下の２つのファイルがあります。
+opencv-320.jar
+libopencv_java320.dylib

これでOpenCVのインストールが完了です。次にEclipse側の設定をします。
###2. Eclipseの設定
意外とEclipseの設定に苦労しました。まず新しいプロジェクトを作っておきます。

#####+「Java Build Path」画面で「Libraries」タブを開く
File -> Properties -> Java Build Path -> Librariesタブ
#####+ライブラリを追加
「Add Library」　-> 「User Library」　-> 「User Libraries」ボタン
「New」 -> 「opencv-3.2.0」を入力　-> 「OK」
#####+Jarファイルを指定
「Add External JARs」を押下し、「opencv-320.jar」を指定
Jarを指定したら実行できるかと思ったらダメでした。
いろいろ調べたら、ネイティブライブラリも指定しないといけないらしいです。
#####+ネイティブライブラリを指定
「Native library location」を選択し、「Edit」をクリック
パスは/usr/local/Cellar/opencv3/3.2.0/share/OpenCV/javaを指定
（3.1まではlibopencv_java◯◯◯.dylibまで指定したらしいですが、3.2では〜/javaまで指定しないと動かないです)

##3. 動作確認
ソースコードを書いて実行できたらOK。
####ソースコード：
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
 
public class Main {
    public static void main(String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat m  = Mat.eye(3, 3, CvType.CV_8UC1);
        System.out.println("m = " + m.dump());
    }
}

####実行結果
m = [  1,   0,   0;
   0,   1,   0;
   0,   0,   1]
Vulsゆく年くる年

この記事は、[Vuls Advent Calendar 2016](http://qiita.com/advent-calendar/2016/vuls)の25日目の記事です。

あけおめことよろ、浅香光代です。今日もいい天気だね。

![Pasted image at 2016_12_09 05_13 PM.png](https://qiita-image-store.s3.amazonaws.com/0/22462/5ea684f5-4bab-5c91-f3a9-7087e80a8fac.png)

投稿が遅れてメンゴです。
年末はreport subcommandの実装[#270](https://github.com/future-architect/vuls/pull/270)や、実家で磯自慢を飲んでたもんですので、あたしゃ忙しかったんだよ。

2016年は4/1にVulsを公開し、結構バズり、勉強会やでっかいカンファレンスで10回以上も登壇したりと目まぐるしかったねぇ。
VulsをOSSで公開した瞬間からあたしのエンジニャー人生変わったよ。
Vulsを使って世の中のサーバから脆弱性が減ったはずで、
サーバ運用担当者が楽になった、ソーサンクスって言われることもたまにはあるもんですので、
こんなしょうもない僕でも少しは世界の平和に貢献できたかな。

さて、今年2017年は
Vulsを脆弱性のスキャンツールの中で、スキャン精度で一番にしたいね。
その実績を持って、Vulsで海外のカンファレンスでの登壇を目指すよ。
あたしゃワクワクしてるね。

以下に今考えている今年の改造ポイントをメモっておくね。
# スキャン精度向上

- OVAL
    - https://oval.mitre.org/repository/about/other_repositories.html
- Ubuntu Security
    - Clairのを参考にする
- RedHatの情報を取り込む
    - https://www.redhat.com/security/data/metrics/
- Debsecanを参考に
 
# Reportingのプラギン化
- input, formatter, outputをプラグイン化したいね。成功しているOSSってプラグインを上手く使ってコミュニティ活性化してる感じだもんね。FluentdとかMackerelとかいいよね。VulsにもHipChat対応してよというissueがあるけど、正直ぼくHipChatつかってないもんだで、作る気にならないよ。このへんを普段使いしている人がサクッと作れるようにしたいね。

ポイントは、

- プラギンはライセンス自由に
- プログラミング言語も自由に（可能なら）
- 作った人が目立つように（Vulsのドキュメントプロジェクトに写真入りで載せたいね）

Go1.8でPluginの仕組みが導入されるようなので上手く使えればいいよね。1.8は2017年2月リリース予定だってさ。来月やん。
    - http://qiita.com/qt-luigi/items/47a7913145fc747da0c7

# エージェント化

Vulsは中央のVuls実行環境からスキャン対象のサーバにSSHで接続するんだけど、それだとセキュリティ的にアレですという環境があるとわりとよく聞くね。というわけでエージェント的にも動作するようにしたいね。

# サーバレスVuls

[AWS LambdaでVulsを使おうと試みた話](http://blog.jicoman.info/2016/12/vuls_lambda/)で挙げられた課題をいい感じに直してサーバレスでサクッと動くようにしたいね。AWSやAzure, GCPなどとの連携はまだまだ応用例が沢山ありそうだよね。みなさんもどんどんノウハウ共有していきたいね。

# 2017年はガンガンいくよ

細かいこと含めまだまだ改善のアイディアはあるので、ガンガン改善していくよ。Slackなどでフィードバックいただけると、凄くありがたいね。

去年の後半は発表詰め込みすぎて若干開発が遅くなったのが反省っちゃ反省かな。でもおかげでいろんな方にPRできたし、いろんな方とつながれたし、とてもいい経験になったよ。今年も頑張るよ。というわけで今年もよろしくお願いします。
dateコマンドでサーバの時刻を変更しても，少し経つと勝手に時刻が戻されてしまうのでいっそのことサーバの時刻を0.1秒間隔で変更し続ける

## TL;DR

```
$ sudo watch -n0.1 date 012213002017
```

※ サーバの時間を0.1秒間隔で変更し続けます


## そもそも何がしたかったのか

サーバの時刻を好きな値に設定して，日付によって挙動がガラリと変わるプログラムのチェックを行おうとしていました。
今回大切なのは日付で，時刻はまぁある程度指定出来れば何時でも大丈夫でした。

## どんな問題が起きたか

[dateコマンドでLinuxサーバの時刻変更 - Qiita](http://qiita.com/na0AaooQ/items/af6b853faf32c58c21d3)を参考にして`date`コマンドでサーバの時刻を変更したはいいけれど，**少し時間が経つと勝手に時刻が戻ってしまいます**。

```
$ date
2017年  1月  6日 金曜日 14:20:01 JST

$ sudo date -s "2017/01/22 13:00"
2017年  1月 22日 日曜日 13:00:00 JST
>>> elapsed time 382h39m57s

$ date
2017年  1月 22日 日曜日 13:00:01 JST

$ date
2017年  1月 22日 日曜日 13:00:02 JST

$ date
2017年  1月 22日 日曜日 13:00:03 JST

$ date
2017年  1月 22日 日曜日 13:00:04 JST

$ date
2017年  1月 22日 日曜日 13:00:05 JST

$ date
2017年  1月 22日 日曜日 13:00:06 JST

$ date
2017年  1月 22日 日曜日 13:00:08 JST

$ date
2017年  1月 22日 日曜日 13:00:09 JST

$ date
2017年  1月  6日 金曜日 14:20:14 JST
```

えぇ…… なんでぇ……。
もちろんcronやら何やらで戻しているわけでもなく，他の誰かがイジっているわけでもなく……。

ちょこっと調べてみると，`-s`は本来時刻を設定するオプションではないとかなんとか。
そうなの? じゃあ……。

```
$ date
2017年  1月  6日 金曜日 14:21:57 JST

$ sudo date 012213002017
2017年  1月 22日 日曜日 13:00:00 JST
>>> elapsed time 382h38m1s

$ date
2017年  1月 22日 日曜日 13:00:01 JST

$ date
2017年  1月 22日 日曜日 13:00:02 JST

$ date
2017年  1月 22日 日曜日 13:00:03 JST

$ date
2017年  1月  6日 金曜日 14:22:04 JST
```

はい，関係ナス。

## 定期的に実行する

Linuxには定期的にコマンドを実行する方法として，`watch`コマンドがあるみたいです。
今回は正確には年月日を指定したくって，時間はまぁどうでも良かったので，今度は**0.1秒間隔で指定した日時に変更し続ける**ことを考えます。

早速`watch`コマンドを使います。
いざ!!

```
$ sudo watch -n1 date -s "2017/01/22 13:00"
Every 1.0s: date -s 2017/01/22 13:00                                                       Fri Jan  6 14:23:39 2017
date: the argument `13:00' lacks a leading `+';
                                              when using an option to specify date(s), any non-option
                                                                                                     argument must be a format string beginning with `+'
                                                                                                                                                        詳しくは `date --help' を実行して下さい.

```

ちょっと上手くいったかと思いましたが今度は少し経つとエラーが出ます。
なんだか`date`コマンドのオプションとして指定している`"2017/01/17 13:00"`の`半角スペース`の所為か`13:00`で変な解釈? が始まっている? っぽいのかなこれ?

で，あればスペースを抜けば良いのかな?
と言うことでコチラを実行したところ，安定して動作します。

```
$ sudo watch -n1 date 012213002017
Every 1.0s: date 012213002017                                                             Sun Jan 22 13:00:01 2017

2017年  1月 22日 日曜日 13:00:00 JST
```

これでも安定したとは言え，たまーに，ふと元の時刻に戻る事があります。
`watch`の実行間隔は現在1.0[s]としているので，この合間を縫って勝手に時刻が戻ることがあるのでしょう。

## 解決

```
$ sudo watch -n0.1 date 012213002017
Every 0.1s: date 012213002017                                                             Sun Jan 22 13:00:00 2017

2017年  1月 22日 日曜日 13:00:00 JST
```

素晴らしい……。
やっと思うように ~~日付を変更~~ 0.1秒間隔で指定した日時に変更し続けることが出来ました。

以上!!

※ サーバの解釈する時をほぼ止めるような挙動になるので，本番などのサーバ上では行わないように注意をして下さい
※ ローカル環境などの，自分しか触らないようなサーバでのみ試してみて下さい
Bash on Ubuntu on Windowsでping/ポートスキャンをする

Bash on Ubuntu on Windows（といいつつ、個人的にはzshで使っていますが…）ではpingすらできなくて、とても不便に感じていました。

ところが、実はBash on Ubuntu on Windowsでもpingやポートスキャンも出来る…ということで、その方法のご紹介です。

## ping
Admin権限で起動してあげます。それだけです。「管理者として実行」でBash on Ubuntu on Windowsを起動します。（cmderの場合はコマンドラインの先頭に`*`をつけます）

```
$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=56 time=3.00 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=56 time=2.29 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=56 time=2.50 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=56 time=2.43 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=56 time=2.30 ms
^C
--- 8.8.8.8 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4004ms
rtt min/avg/max/mdev = 2.291/2.507/3.000/0.262 ms
```

## ポートスキャン
Admin権限でもnmapは動きません。

```
$ nmap x.x.x.x

Starting Nmap 6.40 ( http://nmap.org ) at 2017-01-06 14:14 DST
Problem binding to interface , errno: 22
socket_bindtodevice: Invalid argument
NSOCK ERROR [1.0590s] mksock_bind_device(): Setting of SO_BINDTODEVICE failed (IOD #1): Invalid argument (22)
NSOCK ERROR [1.0600s] mksock_bind_device(): Setting of SO_BINDTODEVICE failed (IOD #2): Invalid argument (22)
NSOCK ERROR [1.0600s] mksock_bind_device(): Setting of SO_BINDTODEVICE failed (IOD #3): Invalid argument (22)
Problem binding to interface , errno: 22
socket_bindtodevice: Invalid argument
Problem binding to interface , errno: 22
socket_bindtodevice: Invalid argument
```

なので代わりにnc(netcat)を使います。こちらは**Admin権限でなくても**動きます。

```
$ nc -vz x.x.x.x 20-23
nc: connect to x.x.x.x port 20 (tcp) failed: Connection refused
nc: connect to x.x.x.x port 21 (tcp) failed: Connection refused
Connection to x.x.x.x 22 port [tcp/ssh] succeeded!
nc: connect to x.x.x.x port 23 (tcp) failed: Connection refused
```

結果が長いので、開いてるポートだけ見るには

```
$ nc -vz x.x.x.x 20-23 2>&1|grep succeeded
Connection to x.x.x.x 22 port [tcp/ssh] succeeded!
```

## その他
自分の場合は、その他、`dig`や`whois`あたりをよく使いますが、こちらは問題なく使えているのでワークアラウンドは不要です。


## 参考（というかまんまですが…）
- [Bash on Ubuntu on Windows: Windowsのドライブに名前付きパイプは作れるか](http://qiita.com/o_-____-___-o/items/fe410c3a93825c052e84)
- [nc コマンド 使い方メモ](http://qiita.com/yasuhiroki/items/d470829ab2e30ee6203f)
どのようにアプリを成長させるか

運営はアプリを成功させるキーである。そして、技術者は運営（チーム）にサービスを提供している。
初期段階では、以下の指標が最も重要である：
1. AU（DAU，MAU）
2. ユーザー維持率


## AU(アクティブユーザー)
AU値はユーザー数を反映している。（au値が高ければ、ユーザー数が多い）
以下はAUを上げる方法：
1. 広告
2. 口コミ，WOM（word of mouth)
3. 有料でレビューを書いてもらう

### 広告
お金がかかる。ユーザー維持率が低い場合には、広告を使うことは全く意味がない。

### 口コミ
最も効率的な方法。ユーザーにより、アプリを（積極的に）推薦することがかなり困難である

### 有料でレビューを書いてもらう
評価を買うことは広告より、費用が安い。そして、この方法は中国やアメリカの企業に使われている

## ユーザー維持率
アプリの品質、及びその機能がユーザーのニーズに応えるかどうかについては、ユーザーの維持率からあらわれる

ユーザー維持率を上げる方法：

1. ユーザーのニーズ（潜在的なニーズ）を捉える
2. アプリの品質を向上させる。特にバグ・クラッシュ率を下げ、高速化し、安定性を上げる。
3. 競合製品分析。例えば、競合製品がうまくできないことを実現し、そして、競合製品のミス・間違ったことを避ける
GKEでIngressで登録しているHTTP LoadBalancerのCloud CDNをCLIでInvalidationする

そもそもの前提として、現状Ingressの設定だけでバックエンドサービスのCloudCDNを有効にすることは出来ないっぽいです(対応予定はあると思うのですが https://github.com/kubernetes/contrib/issues/1680) 。なので作成後直接手で有効にしてます… :joy:

CI上で動かそうと思って調べたけど、結局必要無さそうなのでメモとして。

## 値の取得と実行

Cloud CDNのキャッシュをinvalidationするには、バックエンド サービスにリクエストをルーティングするURL Mapの名前が必要になります。詳しくは[公式](https://cloud.google.com/compute/docs/load-balancing/http/)を見てもらえればと思いますが、Ingressで構築している場合は `k8s-xx-xxxx--adsfsewfwefewfwef`みたいな名前が自動的に振られています。

```bash
kubectl get ingress $ingress -o go-template='{{ index .metadata.annotations "ingress.kubernetes.io/url-map" }}'
```

Ingressの情報を取得するには`kubectl`を使うのが手っ取り早いです。metadata.annotationsにurl-mapの情報が入っているのでそれを取得しましょう。

Cloud CDNのinvalidationは`gcloud`から実行できます。

```bash
gcloud compute url-maps invalidate-cdn-cache $urlmap --path "$target_path"
```

## 例

引数処理などは簡略化してます。

```bash
#!/bin/sh

project=$1
cluster=$2
zone=$3
ingress=$4
target_path=$5

gcloud --project=$project container clusters get-credentials $cluster --zone $zone 
urlmap=$(kubectl get ingress $ingress -o go-template='{{ index .metadata.annotations "ingress.kubernetes.io/url-map" }}')

gcloud compute url-maps invalidate-cdn-cache $urlmap --path "$target_path"
```

## おわり

本来はGCSで完結できれば上記のような事は不要なんですが、GCSではHTTPS・カスタムドメインが使用できない + HTTP LoadBalancerのバックエンドサービスをGCSバケットに指定するのはまだAlphaなので、本番ではちょっと使えなかったんですよね :innocent: その内来ると思うので、その場合には出来る限りGCSを使いましょう。
Rustでもtraitを特殊化したい！

Rustは現在(2017/1/6)のstable(1.14)ではtraitの特殊化をサポートしてないようだ。でもやりたいので遊んでたらできたのでまとめておく。

```rust
let a: f64 = 1.0;
let b: f32 = a.into();
```

そもそものモチベーションはこれがコンパイルできない事だった

```output
trait `f32: std::convert::From<f64>` not satisfied
```

と怒られる。いや切り捨て以外の選択肢とかないだろと思いつつ、既存のtrait`From<f64>`を既存の型`f32`には実装できないので、新しくtraitを作ることにする。

```rust
trait Fromf64 {
  fn from_f64(f64) -> Self;
}
```

これは既存の`From<f64>`インスタンスには`from()`を使って`f32`には`as f32`で変換したい。

```rust
impl<A: From<f64>> Fromf64 for A {
  fn from_f64(v: f64) -> A {
    v.into()
  }
}

impl Fromf64 for f32 {
  fn from_f64(v: f64) -> f32 {
    v as f32
  }
}
```

しかしこれが通らない

```
error[E0119]: conflicting implementations of trait `Fromf64` for type `f32`:
  --> src/main.rs:11:1
   |
5  | impl<A: From<f64>> Fromf64 for A {
   | - first implementation here
...
11 | impl Fromf64 for f32 {
   | ^ conflicting implementation for `f32`
```

これが通らないのが納得いかないが、通らない以上仕方がない(´・ω・｀)
試行錯誤の結果、ダミー型を一つかませるといけることに気付いた

```rust
pub trait Fromf64<Dummy> {
    fn from_f64(f64) -> Self;
}

impl<A: From<f64>> Fromf64<A> for A {
    fn from_f64(v: f64) -> A {
        v.into()
    }
}

impl Fromf64<()> for f32 {
    fn from_f64(v: f64) -> Self {
        v as f32
    }
}
```

使うときはこの`Dummy`を省略できるようにする

```rust
let a = f32::from_f64(1.0);
```

これで`A::from_f64(v)`で変換できるようになったが、釈然としない。。。

## 参考資料
- Tracking issue for specialization (RFC 1210): https://github.com/rust-lang/rust/issues/31844
- How to use specialization features: https://users.rust-lang.org/t/how-to-use-specialization-features/6023
本番環境のios9.0から9.2での謎のクラッシュ原因


ここで書く内容は、多くのFrameworkを使用しているアプリでクラッシュするというのとは違います。[参考記事](http://in.fablic.co.jp/entry/2016/06/09/150000)。

それよりも、かなりマニアックなクラッシュだと思います。誰にも役に立たないかもしれませんが、残しておきます。

crashレポートを見ると、様々なところで ```OS_xpc_object``` で落ちていました。例えば、以下のように。

```
[OS_xpc_object isEqualToString:]: unrecognized selector sent to instance 
```

ただ、このcrashレポートをいくら解析しても原因はわかりませんでした。アプリによっては、違うエラーメッセージで落ちている場合もあるかもしれません。

原因は、画像でした。

ios9.0〜9.2では、8-bit sRGB assetsでないとクラッシュするようです。[参考](https://forums.developer.apple.com/thread/60919)

macで、ショートカットCommand+Shift+4で切り出した画像を利用していたのですが、それを外したらクラッシュがなくなりました。

この画像のカラープロファイルを見ると利用しているディスプレイによって違うようですが、おそらく、どのディスプレイでもクラッシュを起こすのではないかと思います。
Docker上でGo言語のcronを設定する。

はまったのでメモ。

##Dockerfile

```
FROM golang:latest

RUN apt-get update && apt-get install -y cron

# timezone
RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

#workspase
RUN mkdir -p /go/src/app
WORKDIR /go/src/app

# this will ideally be built by the ONBUILD below ;)
CMD ["go-wrapper", "run"]

ONBUILD COPY . /go/src/app
ONBUILD RUN go-wrapper download
ONBUILD RUN go-wrapper install

#localfileのenvから環境変数を取得
RUN env > /env

#cron setting
#分 時 日 月 曜日 <実行コマンド>
CMD echo '*/1 * * * * cd /go/src/app; env - `cat /env` go run /go/src/app/batch.go >> /var/log/cron.log 2>&1' | crontab - && cron -f
```

cronの時間の設定は[こちら](http://qiita.com/hikouki/items/e744b3a4d356d2af12cf)を参考にしてください。

##はまった点
###1つ目
cronの処理の際は環境変数がリセットされるみたいなので、envコマンドを使って環境変数を設定してあげる必要があった。
###2つ目

```
env - `cat /env`
```

のシングルコーテーションをダブルコーテーションで実行しているとうまく動作しなかった。

##デバッグ

```
〜〜　>> /var/log/cron.log 2>&1　〜〜
```

で標準logとエラーlogを記憶している。


##参考
http://qiita.com/ABCanG1015/items/d568982899c52615488c
Ethereum & truffle 開発環境パッケージを作ってみた

![](http://blog.carl.pro/wp-content/uploads/2016/06/docker-on-ethereum-blocks3.png)
*http://blog.carl.pro/2016/06/building-an-ethereum-environment-with-docker/*
## EthDevCon
https://github.com/syrohei/ethdevcon

### インストール  
インストールにはdockerとdocker-composeが必須

コンテナビルド

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

コンテナーに入る

```
$ docker exec -it dev /bin/bash
```

option ワンライナー: ~/.bash_profile を更新して永続化（デフォルトでコンテナに入る）

```
$ bash ./install_osx_linux.bash
```

Ethereumの環境構築や依存関係が複雑になってきたので、基本的に利用する開発用パッケージをひとまとめにしました。
これにより、チーム内での開発環境の統一が図られるので無駄な環境構築コストをだいぶ圧縮できます。

今後も分散型のアプリケーション開発は個人的にはtruffleとtestrpcが最強と考えています。

コントラクトのアップデートもデプロイも自動化されフロントエンド開発も可能なので実証実験等で開発されている方にはぜひおすすめです。

今後はエンドユーザ向けのわかりやすいアプリケーションがこれらの開発環境で爆速で立ち上がってくることを期待しています。
dial tcp [::1]:80: getsockopt: connection refused というエラー


##原因
dockerを使って複数のコンテナを立ち上げた時にコンテナ間のやりとりをhttpdのpostを使ったらはまった。

##解決策
```go
 resp, err := http.PostForm(
      "http://localhost/test.php",
      url.Values{
        "test": bar,
      },
  )
```

ではなく

```go
resp, err := http.PostForm(
      "http://コンテナのhostname/test.php",
      url.Values{
        "test": bar,
      },
  )

```

とやるとコンテナ間でやりとりができるようになった。
VirtualboxにCentOS6.8を構築

##前提
- Virtualbox 5.1.10
- CentOS 6.8

##VirtualboxにCentOS6.8をインストールする

1.まずCentOS6.8を下のダウンロードサイトからどれでもいいので選んで、
次に表示される画面で「CentOS-6.8-x86_64-bin-DVD1.iso」を選択する。
(勝手にダウンロードが始まる)
[CentOS Mirror](http://isoredirect.centos.org/centos/6/isos/x86_64/)

2.CentOS7 isoのダウンロードが終わったらVirtualboxを立ち上げて、[新規]を押す。

3.名前/タイプ/バージョンを以下のように設定して[次へ]。

|        |         |
|:-----------------|:------------------|
| **名前**            |         CentOS6.8|  
| **タイプ**           |          Linux |    
| **バージョン**           |     Red Hat(64-bit) |       


4.次の画面からはトントンと行きます。以下のように設定して仮想マシンが作成されていることを確認。

|        |         |
|:-----------------|:------------------|
| **メモリサイズ**            |        2048|  
| **仮想ハードディスク**           | 仮想ハードディスクを作成する|    
| **ハードディスクのファイルタイプ**           |VDI（VirtualBox Disk Image）|
|**物理ハードディスクにあるストレージ**|可変サイズ|
|**ファイル名**|CentOS6.8|
|**仮想ハードディスクのサイズ**|8GB|

5.作成した仮想マシンを選択し、画面上の[起動]を押すと、
「起動ハードディスクを選択」という画面が出るので
先ほどダウンロードしてきたCentOS-6.8-x86_64-bin-DVD1.isoを選択する。

6.「Welcome to CentOS 6.8!」など表示されたら[Enter]を押す。

7.「Disk Found」という画面では[skip]を押す。

8.次の項目からどんどん設定していきます。

| |    |      
|:-----------------|:------------------|
|**言語** |Japanese(日本語)  |    
|**どちらのタイプの...**|基本ストレージデバイス|  
|**ストレージデバイスの警告**|はい、含まれていません。...|
|**ホスト名**|自由に(例:CentOS)|
|**ネットワークの設定**|eth0選択し、手動でIPを振る|
|**タイムゾーン**|アジア/東京|
|**rootパスワード設定**|自由に設定|
|**どのタイプのインストール...**|既存のLinuxシステムを入れ替える|
|**ストレージ構成をディスクに...**|変更をディスクに書き込む|
|**インストールタイプの選択**|Desktop(GUIが良い人)|  
設定が終わったら[次へ]を押すとインストールが始まる。

9.インストールが完了したら画面右下の[再起動]をクリック。
再起動後、「ようこそ」画面が表示される。

10.**ユーザの作成**･･･ユーザ名、パスワードを設定する。

11.**日付と時刻**･･･「ネットワーク上で日付と時刻を同期化します」にチェック。

12.「kdumpを有効にしますか？」のチェックをはずす。

13.すべての設定が終了し、CensOSが起動したら先ほど作成したユーザが表示されるので、クリックして同時に設定したパスワードを入力してログインする。

##まとめ
VirtualboxでCentOSの構築は7より6.8のがちょっと楽。
ただやっぱりマウス統合できないの不便だぁ…
AWS Lambda で CloudWatch アラームからの障害対応自動化

# 概要
障害対応 = 昔からよくあるアラート検知したらとりあえずプロセス再起動的なやつ。

CloudWatch アラームの SNS メッセージを Lambda で受け取って、対象インスタンスに対して EC2 Run Command (SSM) で定義されたコマンドを実行する。


![01.png](https://qiita-image-store.s3.amazonaws.com/0/105824/93f64588-40f9-8a7a-f012-b29744b28736.png)


# EC2 セットアップ

**1. IAM Role 作成**
EC2 に紐付ける Role に以下の Policy をアタッチして作成する。

 - AmazonSSMFullAccess


**2. EC2 インスタンス作成**
上記で作成した IAM Role を付与してインスタンス作成。

OS は以下で構築。

 - Amazon Linux AMI 2016.09.1 (HVM)


**3. SSM エージェントインストール**
起動したインスタンスで以下コマンドでインストール。

```
$ sudo rpm -ivh https://amazon-ssm-us-east-1.s3.amazonaws.com/latest/linux_amd64/amazon-ssm-agent.rpm
```

エージェントが起動しているか確認。

```
$ sudo status amazon-ssm-agent
amazon-ssm-agent start/running, process 22819
```

# Lambda セットアップ

**1. SNS topic 作成**
とりあえず subscription は空で OK。


**2. Lambda function 作成**
trigger で先ほど作成した SNS topic を選択。
(**Enable trigger** にチェックを入れる)

Runtime は Python2.7 を選択。

Lambda コードは以下の通り。

```py
from __future__ import print_function

import boto3
import json
import logging
 
logger = logging.getLogger()
logger.setLevel(logging.INFO)

ssm = boto3.client('ssm')

def lambda_handler(event, context):
    logger.info("Event: " + str(event))
    message = json.loads(event['Records'][0]['Sns']['Message'])
    logger.info("Event: " + event['Records'][0]['Sns']['Message'])

    instanceid = message['Trigger']['Dimensions'][0]['value']
    alarm_name = message['AlarmName']
    new_state = message['NewStateValue']
    reason = message['NewStateReason']
    logger.info("%s - %s state is now %s: %s" % (instanceid, alarm_name, new_state, reason))

    try:
        ssm.send_command(
            InstanceIds = [
                instanceid
            ],
            DocumentName = "AWS-RunShellScript",
            Parameters = {
                "commands": [
                    "service httpd restart"
                ],
                "executionTimeout": ["3600"]
            },
        )
        logger.info("restarting httpd.")
    except Exception as e:
        logger.error(e)
```

※EC2 Run Command が実行されるインスタンスは、Cloudwatch アラーム から instanceid を取得して指定する。
※インスタンスで実行されるコマンドを commands にカンマ区切りで記載する。
※実行するコマンドは、とりあえず apache 再起動。


Create a custom role で作成した Role に、以下の Policy をアタッチする。

 - CloudWatchLogsFullAccess
 - AmazonSSMFullAccess


# Cloudwatch アラーム作成

**1. ALARM 作成**
トリガーとなるメトリクスに閾値、Action を設定する。

Actions に以下を設定する。

```
Whenever this alarm:	State is ALARM
Send notification to:   "先ほど作成した SNS topic を指定"
```

# 実行テスト

**Cloudwatch ALARM 送信**
テストなので閾値低めとか、プロセス停止とか。

# 実行結果確認

Lambda の実行結果は CloudWatch Logs から確認できる。
![02.png](https://qiita-image-store.s3.amazonaws.com/0/105824/f1cbdd30-6f83-9a8a-2214-771401cdbb91.png)

EC2 Run Command からも Output が確認できる。
![03.png](https://qiita-image-store.s3.amazonaws.com/0/105824/26d5a193-ecbe-1bed-82a3-ce1d678f4ca0.png)
Azure portal のテーマカラーを変える裏技


[Azure portal](https://portal.azure.com)のUIはブレードという概念があるようで、階層が進む毎に、ブレードが右に展開されていくUIになっています。
そのブレードの裏側？背景？をダブルクリックするとテーマカラーが切り替わる裏技の紹介です。

# やり方
とにかくダブルクリックする背景を画面に表示させれば良いです。
一番簡単な例は、リソースグループを作って、リソースグループを選択してください。

すると、右側に背景が現れます。
![Azure_background_for_changing_thema.png](https://qiita-image-store.s3.amazonaws.com/0/1533/8ef59ee7-4547-1351-6840-965993fd79c0.png "Azure_background_for_changing_thema.png")

そこをダブルクリックするとテーマカラーが変わります。

# 見え方紹介
アカウント無い方やめんどくさい方のために結果を一部お見せしますが、全部で４パターン有り



背景だけが変わるパターン
![Azure_theme_white_background.png](https://qiita-image-store.s3.amazonaws.com/0/1533/aa3f935d-3b5f-b183-c2be-eaccd00e78c0.png "Azure_theme_white_background.png")


ブレード内のテーマも変わるパターン
![Azure_theme_black.png](https://qiita-image-store.s3.amazonaws.com/0/1533/5a613372-e5fc-78f4-37cf-caf3f4924a85.png "Azure_theme_black.png")

等の計４パターンあります。
個人的には、下の黒ベースのテーマが気に入ってます。
Toolbarのテキスト色をstyleで指定する


基本的な指定の仕方はこちら。
[ToolBarの背景色やオプションメニューの色を変更する方法](http://qiita.com/konifar/items/cf6a5226828be9c6a5a2)

themeの指定とは違うテキスト色をToolbarに指定したい時、単純に`textColor`をセットするだけでは反映されません。これは、themeの指定で上書きされてしまうからです。

Toolbarにテキスト色をstyleで指定する場合は、themeとなるstyleを定義してそれをセットする必要があります。

```styles.xml
<style name="BaseToolbar" parent="@style/Widget.AppCompat.Toolbar">
    <item name="android:theme">@style/ToolbarTheme</item>
</style>

<style name="ToolbarTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:textColorPrimary">@color/toolbar_text</item>
    <item name="android:textColorSecondary">@color/toolbar_text</item>
</style>
```

```layouts/activity_main.xml
<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    style="@style/BaseToolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
```

以上です。
[Mac]Finderでフォルダを右クリックからAtomで開く

Qiitaでは[こちらの記事](http://qiita.com/shibukk/items/88ac8f342a3954c2b347)を見つけたのですが、最初ちょっとうまく行かなかったので、補足的な内容です。

1. Automator.appを開きます
  ![スクリーンショット 2017-01-06 12.24.27.png](https://qiita-image-store.s3.amazonaws.com/0/92539/17ca45b5-e5db-65c5-7eef-e661b8f3a36a.png)

2. 新規作成のダイアログが表示されたら、サービスを選択します。
  ![スクリーンショット 2017-01-06 12.01.30.png](https://qiita-image-store.s3.amazonaws.com/0/92539/86d61dfc-daff-eef3-7363-cd16367cfa34.png)

3. 左側のペインで、`ファイルとフォルダ` > `Finder項目を開く` を選択し、右側のペインにドラッグ&ドロップします。
4. `"サービス"は、次の選択項目を受け取る`に`ファイルまたはフォルダ`を選択します。
5. `検索対象`に`Finder.app`を選択します。
6. `このアプリケーションで開く`に、`Atom.app`
を選択します。
　　![スクリーンショット_2017-01-06_11_59_06.png](https://qiita-image-store.s3.amazonaws.com/0/92539/fbb167d9-715b-a2dd-cd29-0e6724fdd842.png)
7. `command + s`で、名前を`Open in Atom`と設定します。
  ![スクリーンショット 2017-01-06 12.33.27.png](https://qiita-image-store.s3.amazonaws.com/0/92539/b1a018bd-f6b3-e026-69d7-dce400d48429.png)


以上で、Finderを右クリックで、サービス > に `Open in Atom` が選択できるようになりました。
![スクリーンショット 2017-01-06 12.31.25.png](https://qiita-image-store.s3.amazonaws.com/0/92539/b86be054-9ea6-2975-b077-ff7201e96969.png)

また、作成したサービスは、`~/Library/Services`配下に`.workflow`ファイルとして保存されています。
BluemixでGitHubの連携やWeb IDE、Delivery Pipelineを利用できるようにする

# 前置き
## Bluemixとは
- IBMが提供するPaaS(Platform as a Service)。
- 迅速かつ簡単にクラウド上でアプリケーションを作成、デプロイ、管理することができる。
- 数多くのアプリやサービスが提供されており、自然言語を解釈するWatsonなどが有名。

## 経緯
IBMハッカソンに参加したことがきっかけでBluemixに触れる。
その後、IBMユーザ研究会、IT勉強会と触れることが増えて、やってきたことを備忘録として残そうと考えた。

# 実際にやってみる
## 前提
BluemixのIBM IDをすでに登録済み（トライアルでも可）であること
登録していない人はhttps://console.ng.bluemix.net/registration から登録

## 内容
1. Node-RED Starterアプリの作成
「カタログ」の「ボイラープレート」のカテゴリからNode-REDを選択し、アプリを作成する。
![スクリーンショット 2016-12-27 12.50.00.png](https://qiita-image-store.s3.amazonaws.com/0/153015/115b216f-6f49-49f2-71f6-439711cb3e7e.png)

1. 継続的デリバリーの有効化
アプリ内の「継続的デリバリー」枠の「有効化」ボタンから、DevOpsのToolChainsと連携させる。
![スクリーンショット 2016-12-27 12.53.00.png](https://qiita-image-store.s3.amazonaws.com/0/153015/a7b95c21-dd8a-4b8f-73a7-0b4e28480aed.png)

1. GitHubの有効化
GitHubでエラーが出る場合がある(初回は必ず出るはず)ので、GitHubのアカウントと連携する。
![スクリーンショット 2016-12-27 12.55.00.png](https://qiita-image-store.s3.amazonaws.com/0/153015/de87be3b-05b9-76ae-5155-0fc8a711df4b.png)

## 補足
Web IDEやGitHub経由でアプリをデプロイすると、メモリの容量は**アプリの概要画面で設定したものではなく、manifest.ymlに記載された方が優先となる**ため、従量課金の金額を気にしている人は気を付けること。
GitBucketにて作成したGitレポジトリをRedmineで参照（Windows Server 2012）

ひとまず勢いでメモ書き。

以下の手順に従い、Redmine(Bitnami)＋GitBucket(Tomcat)をインストール。
http://kuttsun.blogspot.jp/2016/04/gitbucket.html

GitBucketにて作成したGitレポジトリをRedmineで参照すると404エラーになり表示できない。
redmine_bitbucketgit_hookもバージョンが合わないせいか、正常に動作しない。

Windows環境でGitBucketを動かしている場合、GitBucketのデータは以下の場所に保存される。

```:ログイン中のユーザーで実行した場合
C:\Users[ユーザー名].gitbucket
```
```:サービスとして登録した場合
C:\Windows\System32\config\systemprofile\.gitbucket
```
今回、Tomcatでサービスとして登録しており、C:\Windows\System32以下に配置されていた。

```:production.log
Shelling out: "C:\Bitnami\redmine\git\bin\git.exe" --version --no-color
Shelling out: "C:\Bitnami\redmine\git\bin\git.exe" "--git-dir" "C:\Windows\System32\config\systemprofile\.gitbucket\repositories\makin\study.git" "-c" "core.quotepath=false" "-c" "log.decorate=no" "branch" "--no-color" "--verbose" "--no-abbrev"

Shelling out: "C:\Bitnami\redmine\git\bin\git.exe" "--git-dir" "C:\Windows\System32\config\systemprofile\.gitbucket\repositories\makin\study.git" "-c" "core.quotepath=false" "-c" "log.decorate=no" "ls-tree" "-l" "HEAD:"
```

ログに載っていた上記コマンドを実行するとエラー。
C:\Windows\System32以下のフォルダが見つからず、同フォルダを別のパスにコピーして検証すると動作。

# 解決方法
C:\Windows\System32以下のフォルダのシンボリックリンクを作成する。

```:cmd
cd c:\Git
mklink /D .gitbucket C:\Windows\System32\config\systemprofile\.gitbucket
```

Redmineのレポジトリはシンボリックリンクのアドレスを指定する。
```リポジトリ
C:\Git\.gitbucket\repositories\makin\study.git
```
macOS Sierra の tmux 上で pbcopy と pbpaste が動くようにする

**tmux 2.6 で問題が解消されたので、この記事の対応は不要となりました。**

---

Mac には、ターミナル上でクリップボードへのコピーとペーストを行う `pbcopy` と `pbpaste` というコマンドがありますが、 Sierra にアップグレードしたら tmux 上でこれらのコマンドが効かなくなってしまいました。

## 環境

- macOS Sierra

    ```sh
    $ sw_vers
    ProductName:	Mac OS X
    ProductVersion:	10.12.2
    BuildVersion:	16C68
    ```

- tmux 2.3

    ```sh
    $ tmux -V
    tmux 2.3
    ```

既に同様の声が多く上がっており、暫定的な対応策として [reattach-to-user-namespace](https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard) というラッパーが作られていたのでこれを入れます。

## reattach-to-user-namespace で `pbcopy` と `pbpaste` を動くようにする

### 1. reattach-to-user-namespace をインストールする

[Homebrew](http://brew.sh) を使っていればこれでインストールできます。

```sh
$ brew install reattach-to-user-namespace
```

### 2. `.tmux.conf` に設定を追加する

自分の `.tmux.conf` に設定を追加します。

```sh
$ echo 'set -g default-command "reattach-to-user-namespace -l ${SHELL}"' >> /path/to/your/.tmux.conf
```

### 3. tmux を再起動する

```sh
$ tmux kill-server
```

これで `pbcopy` と `pbpaste` が使えるようになりました。

## reattach-to-user-namespace を作った経緯

reattach-to-user-namespace の README に [Quick Summary](https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard#quick-summary) として作成の経緯が書いてありました。

> - tmux で Mac OS X の pbpaste と pbcopy が動かなくなった。 [screen](https://www.gnu.org/software/screen/) も同様の影響を受けている。
> - ドキュメントになっていないプライベート API 関数でこの問題を解決できる。
> - その関数は安定していない (現に 10.6 で引数が追加されている) ので、 tmux にパッチを当てるより小さなラッパーを使った方がいいと思い reattach-to-user-namespace を作った。

ということでこの方法はあくまで応急措置であり、当該のプライベート API がパブリックになるなどすれば tmux 本体で対応されるかもしれませんね。

## 参考
[Problems copying text on Mac OS Sierra · Issue #543 · tmux/tmux](https://github.com/tmux/tmux/issues/543)
如何变成大海


app运营需要关注的指标有非常多，但是我们在初期，重点关注两个：
1. AU（DAU，MAU）
2. 留存率



## AU
AU就像是水源，越大量越好
提高AU的方法主要有：
1. 广告
2. 用户的口口相传
3. 刷榜

### 广告
广告烧钱，在未达到良好留存之前，就直接广告，就比较拼运气

### 口碑
最佳的，最便宜的传销方式，然而往往也是最难的

### 刷榜
也是烧钱的方法，相比广告，更直接低俗，但是更便宜，中国，美国刷榜的很多，包括一些非常大的应用，你都想不到


## 留存
留存就是用户忠诚度的直接体现，和用户需求和应用质量直接挂钩
提高用户留存的方法主要有：
1. 抓到用户真正的需求，特别是无法启齿的，说不明白的
2. 提高应用质量，特别是稳定性
3. 关注竞品，不要做别人做错的事儿，做别人没做的事儿
4. 把握人文细节，不要做冷冰冰的应用

## 运营
运营是核心，技术是服务，与大家共勉
Leaflet.jsでgoogleマップを生成しマーカーを立ててクリック時に吹き出し展開

# GitHub

https://github.com/Ryosuke-Hujisawa/Leaflet-JavaScript-Googlemap

GitHubの内容と同じです

&nbsp;

<h1>やりたいこと</h1>

Leaflet.jsとGoogle.jsを使用してgooglemapを生成してから

指定の位置にマーカーを立ててクリック時に吹き出しを展開させる

&nbsp;

<h1>参考にしたサイト</h1>

Google Maps APIを使って複数のマーカーと吹き出しを設置してみる

http://www.tam-tam.co.jp/tipsnote/javascript/post7755.html



Google Maps API ウェブ向け Maps JavaScript API

https://developers.google.com/maps/documentation/javascript/examples/marker-labels?hl=ja



James Croft’s Block 2197701

http://bl.ocks.org/crofty/2197701</br>



&nbsp;

<h1> index.html </h1>

```javascript

<!DOCTYPE html>
<html>
  <head>
    <title>Leaflet</title>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.3.1/leaflet.css" />
    <script src="http://cdn.leafletjs.com/leaflet-0.3.1/leaflet.js"></script>
    <script src="http://maps.google.com/maps/api/js?v=3.2&sensor=false"></script>
    <script src="http://matchingnotes.com/javascripts/leaflet-google.js"></script>
  </head>
  <body>
    <div style="width:500px; height:500px" id="map"></div>
    <script type='text/javascript'>
      var map = new L.Map('map', {center: new L.LatLng(51.51, -0.11), zoom: 9});
      var googleLayer = new L.Google('ROADMAP');
      map.addLayer(googleLayer);

      var myLatlng = new google.maps.LatLng(51.51, -0.11);
      var mapOptions = {
        zoom: 4,
        center: myLatlng
      }
      var map = new google.maps.Map(document.getElementById("map"), mapOptions);

      var marker = new google.maps.Marker({
          position: myLatlng,
          title:"Hello World!"
      });

      infoWindow = new google.maps.InfoWindow({ // 吹き出しの追加
              content: '<div class="sample">ロンドンだよ</div>' // 吹き出しに表示する内容
          });
          marker.addListener('click', function() { // マーカーをクリックしたとき
              infoWindow.open(map, marker); // 吹き出しの表示
          });

      // To add the marker to the map, call setMap();
      marker.setMap(map);

    </script>
  </body>
</html>

```

<img width="512" alt="スクリーンショット 2017-01-06 12.14.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/135794/59d524f4-2f63-7c6f-ca3d-303cfc399e1e.png">
[nginx] クエリストリングでリダイレクトさせるには？

Nginx でクエリストリングを処理するには、以下の内部変数を使用します。

- [$arg_name](http://nginx.org/en/docs/http/ngx_http_core_module.html#var_arg_) argument name in the request line 
- [$args](http://nginx.org/en/docs/http/ngx_http_core_module.html#var_args) arguments in the request line

クエリストリング hoge の値を使用してリダイレクトさせたい時に以下の方法で説明されている記事をたびたび見かけますが。

```text
set $keyword_value "";
if ( $args ~ "hoge=(.*)" ) {
    set $keyword_value $1;
}
if ( $keyword_value != "" ) {
    rewrite ^(/.*)$ $1/$keyword_value/? permalink;
    break;
}
```

この方法だとクエリストリングが ```?hoge=1&fuga=2``` だった場合に ```$keyword_value``` が ```1&fuga=2``` となってしまい、辛い目にあいます。
なので、積極的に ```$arg_name``` を使用しましょう。
(クエリストリングとして ```?hoge=1``` が与えられている場合 ```$arg_hoge``` を参照することで hoge にセットされた値がわかります。）

```text
if ( $arg_hoge != "" ) {
    rewrite ^(/.*)$ $1/$arg_hoge/? permalink;
    break;
}
```

また ```year```, ```month```, ```day``` のような複数のクエリストリングを元にリダイレクトしたい場合が結構ありますが、こういったときも簡単です。
例えば ```?year=2017&month=01&day=06``` を```/2016/01/07/``` にリダイレクトさせたい時なんかは、こうなりますかね？

```text
# year がセットされていなければ month を無視、year, month がセットされていなければ day を無視
set $keyword_date "$arg_year";
if ( $keyword_date != "" ) { set $keyword_date "$keyword_date$arg_month"; }
if ( $keyword_date != "" ) { set $keyword_date "$keyword_date$arg_day"; }

# year だけがセットされていた時
if ($keyword_date ~ "^[12][0-9][0-9][0-9]$") {
    rewrite ^(/.*)$ $1/$arg_year/? permalink;
    break;
}

# year, month がセットされていた時
if ($keyword_date ~ "^[12][0-9][0-9][0-9][01][0-9]$") {
    rewrite ^(/.*)$ $1/$arg_year/$arg_month/? permalink;
    break;
}

# year, month, day がセットされていた時
if ($keyword_date ~ "^[12][0-9][0-9][0-9][01][0-9][0-3][0-9]$") {
    rewrite ^(/.*)$ $1/$arg_year/$arg_month/$arg_day/? permalink;
    break;
}
```
SQL*Plus に標準入力からSQL文を流し込む

ググると結構出てきますが、備忘として。

sqlplus コマンドは、実行するSQL文を標準入力から読み込むことができます。

```bat:シンプルな実行例
> echo select * from dual;  | sqlplus scott/tiger

SQL*Plus: Release 11.2.0.1.0 Production on 金 1月 6 01:23:45 2017

Copyright (c) 1982, 2010, Oracle.  All rights reserved.



Oracle Database 11g Release 11.2.0.3.0 - 64bit Production
に接続されました。
SQL>
D
-
X

SQL> Oracle Database 11g Release 11.2.0.3.0 - 64bit Productionとの接続が切断されました。
```

これを使うと、バッチファイル中にちょっとしたSQL文をかけて、なおかつ「一時SQLファイル」といったファイルを作らなくて済みます。

そのため、例えば、今回のバッチで必要な DIRECTORY を一時的に作りたい、一時データを消したい、といった場面で重宝します。

実行状況をコンソールから眺めていると「SQL>」の表示で一旦固まりますが、しばらくすると実行されていきます。
※一旦固まる現象は、環境によるのかもしれません。

# 単一の文を実行

```bat:単一.bat
set CONN=scott/tiger

echo drop directory aaadir;  |  sqlplus %CONN%
echo create directory aaadir as 'd:/aaa';  |  sqlplus %CONN%

REM 何か処理をする...

echo drop directory aaadir;  |  sqlplus %CONN%
```

# 複数の文を一気に実行

```bat:複数.bat
set CONN=scott/tiger

(
echo select * from dual;
echo select 1 from dual;
) | sqlplus %CONN%

REM 何か処理をする...
```

# 注意点(ログの残し方)

冒頭の「シンプルな実行例」にあるように、標準入力で渡したSQL文は標準出力に出力されません。
SQL*Plus の実行結果をログに出力したい場合、標準出力だけを使っているとSQL文がログに残らない（実行結果はログに残る）ということに注意が必要です。

```bat:何を実行したか不明なログのとりかた.bat
set CONN=scott/tiger
echo select * from dual;  |  sqlplus %CONN% > hoge.log
```

```:実行結果(hoge.log)

SQL*Plus: Release 11.2.0.1.0 Production on 金 1月 6 01:23:45 2017

Copyright (c) 1982, 2010, Oracle.  All rights reserved.



Oracle Database 11g Release 11.2.0.3.0 - 64bit Production
に接続されました。
SQL> 
D
-
X

SQL> Oracle Database 11g Release 11.2.0.3.0 - 64bit Productionとの接続が切断されました。
```

## 対策1. 別途、処理内容を出力する

対策としては、SQL文を実行する手前でログファイルに処理内容を出力するようにすることが考えられます。

```bat:最低限の状況説明を出力する.log
set CONN=scott/tiger
echo 【接続テスト】 > hoge.log
echo select * from dual;  |  sqlplus %CONN%  >> hoge.log
```

```:実行結果(hoge.log)
【接続テスト】 

SQL*Plus: Release 11.2.0.1.0 Production on 金 1月 6 11:02:07 2017

Copyright (c) 1982, 2010, Oracle.  All rights reserved.



Oracle Database 11g Release 11.2.0.3.0 - 64bit Production
に接続されました。
SQL> 
D
-
X

SQL> Oracle Database 11g Release 11.2.0.3.0 - 64bit Productionとの接続が切断されました。
```

## 対策2. SPOOL を使う

また、SPOOL で指定したファイルには、標準入力で渡したSQL文が出力されました。

```bat:SPOOLを使ったログ出力.bat
set CONN=scott/tiger

echo 前処理... > hoge.log

(
echo spool d:/spool_hoge.log
echo select * from dual;
echo spool off
) |  sqlplus %CONN%
rem 結果が重複するので、sqlplus の標準出力は使わない

type d:\spool_hoge.log >> hoge.log
```

```:実行結果(hoge.log)
前処理... 
SQL> select * from dual;

D
-
X

SQL> spool off
```
FuelPHPのマイグレーションで複数個のカラムのUPDATEがUPDATEされない場合

## 概要

FuelPHPのマイグレーションで複数個のカラムにデフォルト値を設定する場合、
マイグレーションは成功するのに値がUPDATEされないという場合があります。

そのときのコードは以下のようになっていました。

```
	public function up()
	{
		\DB::update('table')
		->set(['column1' => 1,　'column2' => 1])
		->execute();
	}

```

これだとなぜかマイグレーションが成功するのにUPDATEされませんでした…

## 修正後

以下のコードだとマイグレーションが成功し、かつUPDATEされました。

```
	public function up()
	{
		\DB::update('table')
		->set([
			'column1' => 1,
			'column2' => 1,
		])
		->execute();
	}
```

改行して、配列の２つめの最後にカンマをつけただけですが、
なぜか動きました…

PHPのシンタックス的には修正前でも問題ないのに、
どうしてうまく動かないのか…

お困りの際は試してみてください。
WordPressで投稿の項目を追加する方法

今回はカスタム投稿タイプについてまとめました。
まず初めにカスタム投稿タイプとは自分で投稿タイプをカスタマイズできる機能です。
通常「投稿」と「固定ページ」の2種類の投稿タイプがありますが、カスタム投稿タイプを使う事で新しく投稿タイプを増やす事が可能になります。
ですので投稿に対して「お客様の声」や、「商品の紹介ページ」などをテンプレートとしてカスタム投稿タイプを利用することができるようになり独立したコンテンツを作りたい場合等に非常に便利に扱えます。

カスタム投稿タイプを増やしていく方法はいくつかありfunctions.phpでもできるのですが今回はCustom Post Type UIというプラグインを用いてカスタム投稿タイプを増やしていく方法をご紹介していきます。



まずはプラグインの検索フォームからCustom Post Type UIと検索してインストールして有効化に設定してください。完了するとサイドメニューにCPT UI のアイコンが追加されます。

<img width="318" alt="スクリーンショット 2017-01-06 10.23.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/132753/098bd658-40cb-11f2-e821-6092195d8811.png">


投稿タイプを追加/編集をクリックするとこのようなページに進みます。
<img width="779" alt="スクリーンショット 2017-01-06 11.28.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/132753/da0fcc8f-20a0-6750-fd2d-38ec6cd94dc0.png">
●投稿タイプスラッグ
スラッグとはページのURLの最後に使われる文字列のことです。WordPressでは投稿ページや固定ページなどのIDとして登録されます。SEOにも関係してくるので非常に重要です。
書き方にもルールがあります。
1. 投稿20文字以内
2.半角英数で入力。
3.大文字やスペースは使えない。
4.post, page, attachment,revision, nav_menu_itemはWordPressのシステムで既に使用されているので使用しない。

●複数形のラベル
サイドバーに表示される名前です。こちらは日本語でも英語でも可能です。

●単数形のラベル
必須項目ではないので空白でも大丈夫ですが、英語を用いる際は複数形と単数形に区別を付けるため、この項目があります。




こちらを記述して最後に投稿カスタムタイプを追加ボタンをクリックすれば下記画像のようにサイドメニューに追加されているはずです。
<img width="159" alt="スクリーンショット 2017-01-06 10.56.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/132753/c4bf43bd-ade3-9bb9-7476-2e2684d5fe4f.png">

以上簡単にまとめましたが、追加のラベルや設定については日本語表示でわかりやすいと思うのでお好みでカスタマイズしてみてください。
日本語で行間をいじった時のバグ

文字列表示で行間をいじる時、NSAttributedString,NSParagraphStyleを使うと思います。

```
let style = NSMutableParagraphStyle()
style.lineSpacing = 10.0 // 行間設定
        
let attr = [NSParagraphStyleAttributeName: style, NSFontAttributeName: font]
let attrStr = NSMutableAttributedString(string: text, attributes: attr)
label.attributedText = attrStr
```

ただ日本語で1行のみの表示の時、下に本来は入るはずのない行間のスペースが入ってしまいます。
(原因はわかりませんでした。。)
複数行やアルファベットの時は想定通りになります。

![スクリーンショット 2017-01-06 11.05.26.png](https://qiita-image-store.s3.amazonaws.com/0/107427/3a7e6dd6-7f5b-ae9d-0ce8-1586d03db49f.png)

## 対策
1行の場合かつ高さが`フォントの高さ+行間スペース`の場合のみ高さを`フォントの高さ`に合わせるサブクラスを実装しました。

```
class LineSpacingLabel: UILabel {
    var adjustedHeight = CGFloat(0.0)
    var adjustedForLineSpacingBug = false
    
    override func drawText(in rect: CGRect) {
        var baseRect = rect
        
        // 本来の描画されるスペースを小さくしているため、そのままにすると上下が切れてしまうのでここで調整する
        if adjustedForLineSpacingBug {
            baseRect.origin.y = adjustedHeight / 2.0
        }
        
        super.drawText(in: baseRect)
    }
    
    override var intrinsicContentSize: CGSize {
        let baseSize = super.intrinsicContentSize
        
        adjustedHeight = 0.0
        adjustedForLineSpacingBug = false
        
        // lineSpacingを設定しているかつlineSpacingが0以外の時のみ処理を行う
        if let paragraphStyle = attributedText?.attribute(NSParagraphStyleAttributeName, at: 0, effectiveRange: nil) as? NSParagraphStyle,
            paragraphStyle.lineSpacing != 0.0 {
         
            let fontHeight = ceil(self.font.lineHeight)
            let lineSpacing = paragraphStyle.lineSpacing
            
            // 固有サイズの高さがフォントの高さ+行間スペースの場合(1行だけど下に行間スペースが挿入されている場合)
            // 本来の高さに変更する
            if baseSize.height == fontHeight + lineSpacing {
                adjustedHeight = lineSpacing
                adjustedForLineSpacingBug = true
                return CGSize(width: baseSize.width, height: fontHeight)
            }
        }
        
        return baseSize
    }
}
```
![スクリーンショット 2017-01-06 11.30.57.png](https://qiita-image-store.s3.amazonaws.com/0/107427/cf16dea8-9285-58f0-575e-cd45cb0836bf.png)

これで日本語1行の時でも変なスペースが開かなくなりました。
TextKitとか使ってもうちょっと厳密にやってもいい気はしますが、今回は問題なかったので一旦放置。

##その他
もっといい実装ありましたらコメントいただければと思います！

それとNSAttributedStringを扱う時はこれ使うとめっちゃ楽！
https://github.com/delba/TextAttributes

この実装のサンプルは以下になります。
https://github.com/furuyan/LineSpacingSapmle
Tortoisegit環境で https認証を省略する方法

# 前提
* windows10環境で Torotisegitを使用している環境
* とりあえず今回は github をリモートとして使う場合

# やりたい事概要
* ssh 接続ではダウンロードが遅いので https経由でリモートのリポジトリを使いたい
* でも、アクセスする際に認証を毎回入力するのが面倒なので省略したい
* とりあえずお手軽にやりたい

# 実現方法
* %HOME%_netrc ファイルを作成して認証情報を記載すれば良い
* windows10 の場合は "C:\Users\%ユーザ名%\_netrc" かな

```
machine github.com
login <githubのログインユーザ>
password <githubのログインパスワード>
```

# 確認
* fetch、push等のgit操作を問題なく行える事を確認

# 備考
* パスワードがファイルにベタ書きになるので セキュリティ上は好ましくない
* 通信速度が気にならなければ sshの鍵認証を使った方が良いと思います

# 参考にした情報
* http://omoshiro-device.jp/blog/view/311/git-tortoisegit-%E3%81%A7%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E5%90%8D%E3%83%BB%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%82%92%E8%A8%98%E6%86%B6%E3%81%99%E3%82%8B
* http://schima.hatenablog.com/entry/2013/11/29/193738
3分でできるCakePHP公式ドキュメントの誤訳を直す方法

お疲れ様です！
GMOリサーチの石黒です。

私は普段からCakePHP3の公式ドキュメントを翻訳しています。
今回は、既に翻訳された公式ドキュメントの誤訳やタイポを簡単に修正する方法をご紹介します。

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

以上

---
#①誤訳を発見する

Chronosのドキュメントを眺めていたら「インストールためには」という文を発見したので、今回はこれを「インストールするためには」に修正します。
※今回は明らかに誤訳というかタイポですが、誤訳であるかどうかは、英語の原文と見比べて判断しましょう。

![image](https://qiita-image-store.s3.amazonaws.com/0/103853/2e0b5c5b-837e-e891-fe47-f33af1e005b3.png)

---
#②修正画面に飛ぶ
画面右の鉛筆マークをクリックすると、Githubで管理されているcakephp/docsというリポジトリの対象ファイルの修正画面に飛びます。

![image](https://qiita-image-store.s3.amazonaws.com/0/103853/e03d4282-2368-a019-00ac-216645ed0730.png)

---
#③修正する

![image](https://qiita-image-store.s3.amazonaws.com/0/103853/0d492f77-ea2e-e95e-f288-c0ee3f6dbd58.png)

この画面内で修正できます。
※画面上部にメッセージが出ているように、このリポジトリを直接修正することはできません。事前に自分のGithubアカウントでforkしておく必要があります。

---
#④コミットする
コミットメッセージを入力してコミットします。
メッセージは何を修正したか分かれば良いです。
英語が望ましいです
~~が、日本人のコントリビューターもいますので、日本語でもOKです。~~
→コミットメッセージは単語を並べたレベルでも良いので英語が望ましいとのことです。

![image](https://qiita-image-store.s3.amazonaws.com/0/103853/cd4a8a4c-0593-641a-0f12-2824192c1494.png)

---
#⑤プルリクエスト作成
コミットすると、自動でpatch-*というブランチが作られ、
プルリクエスト作成の手前の画面まで飛びます！

![image](https://qiita-image-store.s3.amazonaws.com/0/103853/9233c268-6c57-ce8f-7b71-2dfb851c640a.png)

プルリクエストのタイトルを入れてプルリクエストを作成します。

![image](https://qiita-image-store.s3.amazonaws.com/0/103853/be864042-7347-e50a-d01b-373dadd48a04.png)

作成されました。

![image](https://qiita-image-store.s3.amazonaws.com/0/103853/e219eca3-32b3-fa91-beb0-b47070d930ef.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/103853/948c1ec5-2079-318c-14c6-6b03ffce56e6.png)

裏でTravisCIが動いて、ビルドがOKかNGか返してくれます。
内容が合っていてビルドOKならきっとそのうちマージしてもらえます！