OmniAICreator/Qiita-1.07M huggingface dataset:
rubyのコードで改行したい時〜♬

コーディング規約とかで80文字とか、120文字とかで改行したい時のtips

### 文字列
\エスケープして継続

```ruby:sample.rb
pry(main)> str = "AAAAAAAAAAAAAAAAAAAAAAAAA"\
pry(main)> "AAAAAAAAAAAAAAAAAAAAAAAAA"\
pry(main)> "AAAAAAAAAAAAAAAAAAAAAAAAA"\
pry(main)> "AAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
```

### 正規表現
optionにxを付与

```ruby:sample.rb
pry(main)> hoge = /東京
pry(main)> 都/x
/\u6771\u4EAC
\u90FD/x
pry(main)> "東京都".scan(hoge)
[
    [0] "東京都"
]
```
モデル・RakeタスクでWickedPdfを使って無理やりPDFを生成する方法

### 概要
印刷用のPDFを生成するときがあります。
[Ruby/RailsでPDF作成Gemのまとめ](http://ruby-rails.hatenadiary.com/entry/20140906/1409995011)

様々な方法がありますが動的に生成しようとすると、1度に5秒くらいかかるので、<b>若干ストレス</b>です。
そこで、<b>バッチ処理や情報が更新された時だけ非同期でPDFを生成し直す</b>など、
モデルやRakeタスクでPDFを生成したいです。

しかし、いざやろうとすると、既存の部分テンプレートなどを使ったり、ヘルパーメソッド、ルーティングなどを使うこともありいろいろ<b>「コントローラ通さずどうやってやんだ(> <)」</b>という状況になります。
今回、いろいろ調べたので、端的にその方法だけまとめます。

### 実際にやる方法
直接コードだけ書きます。

```rb
# コントローラのインスタンスを作る
controller = ActionController::Base.new
# 擬似的にリクエストを生成する
# これをしないと、url_forなどのルーティングのメソッドが使えなくなる
controller.request = ActionDispatch::TestRequest.new
# これも一応extend
controller.extend(Rails.application.routes.url_helpers)
# viewを生成する。viewのテンプレートのパスを入れる
view = ActionView::Base.new(Rails.root.join('app', 'views'), {}, controller)

# Application Helperをextend
view.extend(ApplicationHelper)
# その他、自作のHelperがあればそれもextend
view.extend(SamplesHelper)
# ルーティング用のヘルパーもextend
view.extend(ActionView::RoutingUrlFor)
# 最後にurlヘルパーをextend
view.extend(Rails.application.routes.url_helpers)

# Erb指定してrenderし、それをWikedPdfでpdfを生成
# パラメータなど、いろいろ渡してあげる
pdf = WickedPdf.new.pdf_from_string(view.render(template: 'sample/print_template.html.erb', locals: { params: params }, encoding: 'UTF-8'))

# パスを指定して保存する
save_path = Rails.root.join('tmp', "sample.pdf")
File.open(save_path, 'wb') do |file|
  file << pdf
end
```

### まとめ
ヘルパーとか、controllerのrequestを手動で生成するやり方が分からずいろいろ困りましたが、
とりあえずこれでいけます。
なにか不備があればご指摘いただけると嬉しいです。
IE9 > Digikey非対応

```txt:動作環境
IE9 on Windows 7 pro
```

http://www.digikey.jp/
のサイトで購入できない、という報告を受けた。
購入手順を進めていたら以下のエラーが出る。

> Internet Explorerではこのページは表示できません

調べたらIEのバージョンが9だった。

IEのEOL(End of Life)の情報は以下に整理されている。
http://qiita.com/sawadays0118/items/41bab56358742fe2a646

上記の状況での対応としては

- IEをv11に上げる
- 別のブラウザを使う

IEをv11に上げるかどうかの判断としては、IEで動かすシステムがv11対応しているかどうか。
Android Studio で保存時に自動整形やimport行の整理

Android Studio でファイルの保存時にソースを自動整形したり import 行を整理したいことがあります。というか常にそうしたいです。昔はマクロを作ってがんばっていたようですが、現在は [Save Actions] というプラグインを使えば良いようです。

- [JetBrains Plugin Repository - Save Actions][Save Actions]

[Save Actions]: https://plugins.jetbrains.com/plugin/7642

プラグインの設定画面は↓のような感じ。ソースに変更がない場合は、保存時に自動整形しないこともできますね。便利です。

![スクリーンショット 2016-09-07 11.14.35.png](https://qiita-image-store.s3.amazonaws.com/0/43781/33fca706-b291-b70b-be9d-774875f0f89a.png)
Hello nodejs

このページでは、ノードのインストールとかは置いておいて、とりあえずnode.jsのプログラムを書いてみるページです。
nodeコマンドとnpmコマンドがすでに使える状態になっていることを前提とします。

## 準備
パッケージマネージャーをセットします。
プログラムだけ書きたい人はとばしちゃえ

まずはプログラムを入れるディレクトリを作成

```
$ mkdir hello
```

パッケージマネージャーで初期化

```
$ npm init
```

## プログラムを書く
下記ソースを書いてindex.jsとして保存

```index.js
console.log("hellow! node.js");
```

保存したら、下記コマンドで実行します。

```
$ node index.js
```

`hellow! node.js`と表示されればokです。
MySQLのテーブル内のメールアドレスのドメイン部分を一括置換するクエリ


`hoge` テーブルの `mail` 列のドメインを `fuga.com` に置換するばあい。

```sql
UPDATE
  `hoge`
SET
  `mail` = CONCAT(
      LEFT(
          `mail`,
          INSTR(`mail`, '@')
      ),
      'fuga.com'
  )
WHERE
  `mail` NOT LIKE '%@fuga.com';
```

[INSTR()](https://dev.mysql.com/doc/refman/5.6/ja/string-functions.html#function_instr) で `mail` 列の `@` の出現位置を取得し、
[LEFT()](https://dev.mysql.com/doc/refman/5.6/ja/string-functions.html#function_left) で `mail` の先頭から `@` までの位置の文字列を抜き出し、
[CONCAT()](https://dev.mysql.com/doc/refman/5.6/ja/string-functions.html#function_concat) で `fuga.com` と結合したものをSETする感じです。

##### 参考 
[Mysql-how to update the “domain.com” in “address@domain.com”](http://stackoverflow.com/questions/2913861/mysql-how-to-update-the-domain-com-in-addressdomain-com)
Android タブレットを IP Webcam で監視カメラ化

# 背景
タブレットの液晶が落下により映らなくなってしまった。
幸い MHL で画面は見れるが、このタブレット何かに使えないだろうか。。。
そうだ、監視カメラ化してみよう。という流れ。のメモ。

# セットアップ環境
ARROWS Tab F-05E (液晶破損)
Aterm WG1800HP2
IP Webcam

# Android 端末のセットアップ
## 1. IP アドレス固定化
新たに SSID1 という名前のアクセスポイントに接続すると仮定。

(1) [設定] を開く

(2) [無線とネットワーク] から [Wi-Fi] を選択
> ON になってなければ ON にする

(3) 右上の [+] ボタンを押下

(4) ネットワーク SSID を入力（例: SSID1）

(5) セキュリティを選択（例: WPA/WPA2 PSK）

(6) パスワードを入力

(7) [詳細オプションを表示] にチェックをつける

(8) プロキシ設定を選択（例: なし）

(9) IP 設定を [静的] に設定

(10) IP アドレス、ゲートウェイ、ネットマスク、DNS を設定
> ゲートウェイや DNS は使ってるルーターの IP アドレスを入れたよ

(11) [保存] ボタンを押下して設定を保存

# IP Webcam のセットアップ
## 1. IP Webcam のインストール
Google Play より [IP Webcam](https://play.google.com/store/apps/details?id=com.pas.webcam&hl=ja) をインストールする。
インストール後、IP Webcam を起動する。
> メニューが日本語になってた。

## 2. IP Webcam の設定
(1) ログイン名/パスワードの設定
一応、念のため、[接続設定]-[ローカルネットワークへの配信設定] から、[ログイン/パスワード] を選択し、ログイン/パスワードを設定する。

(2) ポート番号の設定
同じく、、[接続設定]-[ローカルネットワークへの配信設定] から、[ポート] を選択し、任意のポート番号に変更。

(3) 電源起動時に開始
[その他]-[端末起動時にアプリを起動] をチェック

> 画面が映らないのでチェックしてみた。

(4) この他、メニューの設定一覧から必要な設定を変更。
> 上記が必要最低限かなと思う。

## 3. IP Webcam の起動
[サービス コントロール]-[映像ストリーミング開始] を選択して起動する。

## 4. IP Webcam 起動確認
他の端末から Android 端末の IP アドレスと IP Webcam のポート番号を指定してアクセスできるか確認。
LAN 内からの確認なら、http://固定 IP アドレス:ポート番号/ で確認可能。（例: http://192.168.xxx.xxx:port/ ）

> アクセスできない場合、ローカルポート開放が必要？

# ルーターのセットアップ
## 1. ポートマッピング設定
(1) クイック設定 Web を開く（例：http://aterm.me/ ）

(2) 左ペインから [詳細設定]-[ポートマッピング設定] を選択

(3) 右ペインのポートマッピング画面から [追加] ボタンを押下
> このとき、すでに登録済みの設定があれば、その設定の「優先度」の数字をメモしておく。

(4) NAT エントリ追加画面が表示されるため、必要な情報を入力し、[設定] ボタンを押下

| 項目名 | 設定値 | 備考 |
|:--|:--|:--|
| LAN側ホスト | 192.168.xxx.xxx | Android 端末の固定 IP アドレス |
| プロトコル | TCP |  |
| ポート番号 | 8080 | IP Webcam で設定したポート番号等 |
| 優先度 | 1 | 登録済みの設定がある場合は空いている数字、数字が小さいほど優先度は高い |

(5) 設定完了後、左ペインの [保存] ボタンを押下

(6) 右ペインから [前のページへ戻る] を選択

(7) [NAT エントリ] に設定情報が表示されていることを確認

## 2. ホーム IP ロケーション設定
(1) クイック設定 Web を開く（例：http://aterm.me/ ）

(2) 左ペインから [詳細設定]-[その他設定] を選択

(3) 右ペインから [ホームIPロケーション機能] を [使用する] にチェックし、[設定] ボタンを押下
> [メンテナンスバージョンアップ機能] が [使用する] になっていないと設定できない

(4) なお、使用条件のポップアップメッセージが表示された場合は、よく読み、[OK] ボタンを押下

(5) 設定完了後、左ペインの [保存] ボタンを押下

(6) 左ペインから [情報]-[現在の状態] を選択

(7) 右ペインに [ホームIPロケーション名] が表示されていることを確認


# 外部 (WAN) からのアクセス確認
グローバル IP アドレスまたはホーム IP ロケーションでポートを指定してアクセスする。
（例: http://home.ip.local.xxx.xxx:port/ ）

# 参考
[ポートマッピング設定手順 - Aterm サポートデスク](http://www.aterm.jp/support/guide/category/enjoy/port/002/main.html)
[ホームIPロケーション設定手順 - Aterm サポートデスク](http://www.aterm.jp/support/guide/category/special/home_ip/002/main.html)
apacheのOptions Index表示されるファイルリストはIndexHeadInsertでカスタマイズできるよ。

# IndexHeadInsertとは
一覧表示に外部CSSや、JSを埋め込めるようになります。

- まずはサンプル、画像にプレビュー機能をつけてみました。

![サンプル](https://github.com/misak1/.htaccess-filelist/blob/master/out2.gif?raw=true "サンプル")

これは.htaccessを置くだけで出来ています。

その.htaccessファイルはこちら
https://github.com/misak1/.htaccess-filelist/blob/master/.htaccess

面白い使いかたが出来そうなので。紹介させていただきました。
AWS上で実行しているELB（ロードバランサ）経由のEC2上でクライアントIPアドレスをExpressで取得する

# Node.js(express)でのクライアントIPアドレスの取得

基本的には`req.connection.remoteAddress`でクライアントのIPアドレスが取れるが、
ロードバランサを通すと当然ロードバランサのIPになるので、ロードバランサが送信してくださる`X-forwarded-for`ヘッダーから取得する。

```js:nodejs
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
```

#### ひとつ問題が。

`req.connection.remoteAddress`はIPv6形式になっている。
`192.168.1.10`は`::ffff:192.168.1.10`にマップされる。
`X-forwarded-for`は通常IPv4。

開発環境はELBナシ、本番環境はELB通すとかになってると本番環境でバグが発覚する可能性ありなので気をつけましょう。

#### Stackoverflowに良い回答があったので紹介
[request.connection.remoteAddress Now Prefixed in ::ffff in node.js](http://stackoverflow.com/questions/24896386/request-connection-remoteaddress-now-prefixed-in-ffff-in-node-js)

* 取得できる値は、IPv4をIPv6にマッピングしたIPv6の値。
* 通常はNodeサーバーは同一のソケットでIPv6とIPv4のコネクションを処理している
* ::ffff:192.168.1.10 はIPv4であり、IPv6でもある。
* IPv6かどうかを確認するには、単純にコロンが含まれているかどうかでOK

とのことです。


### 備考
他にもアクセス元のプロトコル(http/https),ポートを取得できる。

以下ELBが送信してくれる`X-Forwarded-*`系のヘッダー

* X-Forwarded-For　：クライアントのIPアドレス
* X-Forwarded-Proto　：クライアントがアクセスしてきたプロトコル（HTTP または HTTPS）
* X-Forwarded-Port　：クライアントがアクセスしてきたポート番号

※参考　[HTTP ヘッダーおよび Elastic Load Balancing](http://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/classic/x-forwarded-headers.html)
scikit-learnで糖尿病データの回帰分析をやってみた

元は [scikit-learnで線形モデルとカーネルモデルの回帰分析をやってみた - イラストで学ぶ機会学習](http://qiita.com/kotaroito/items/4eb29d42d7f8c534332f)に書いていましたが、ややこしいので別記事にしました。

データセットは[sklearn.datasets.load_diabetes](http://scikit-learn.org/dev/modules/generated/sklearn.datasets.load_diabetes.html) を使います。

糖尿病患者442名のデータが入っており、基礎項目（age, sex, body mass index, average blood pressure）と6つの血液検査項目を入力とし、1年後の進行状況を予測ターゲットにします。


#### データを見る

まずやるべきはデータの性質を調べることです。


```py3
import pandas as pd
import numpy as np
from sklearn import datasets
import matplotlib.pyplot as plt
import seaborn as sns

%matplotlib inline

diabetes = datasets.load_diabetes()

train_data = diabetes.data[:-20]
test_data  = diabetes.data[-20:]
train_target = diabetes.target[:-20]
test_target = diabetes.target[-20:]

df = pd.DataFrame(diabetes.data, columns=("age", "sex", "bmi", "map", "tc", "ldl", "hdl", "tch", "ltg", "glu"))
df['target'] = diabetes.target
```

入力データは正規化されていることがわかります。

![スクリーンショット 2016-09-03 11.51.10.png](https://qiita-image-store.s3.amazonaws.com/0/20304/5c7c1ff5-0a15-0d00-93a0-4135cdb433e4.png)


seabornでいくつかのデータをプロットしてみます。


```py3
import seaborn as sns

sns.jointplot(x="age", y="target", data=df)
sns.jointplot(x="sex", y="target", data=df)
sns.jointplot(x="ltg", y="target", data=df)
```

![diabetes_age.png](https://qiita-image-store.s3.amazonaws.com/0/20304/dc86b840-f213-eb11-227b-b36acd1ffbf3.png)

![diabetes_sex.png](https://qiita-image-store.s3.amazonaws.com/0/20304/ce9fa0f2-51b6-a3f5-bfa2-d8efeb0d834b.png)

![diabetes_ltg.png](https://qiita-image-store.s3.amazonaws.com/0/20304/3b1399ba-c42e-3f68-ab32-69017998c768.png)


ltgにはある程度の相関が見られますが、ageやsexにはあまり相関が見えません。

#### 線形モデルでの回帰

```py3
from sklearn import linear_model
from sklearn.kernel_ridge import KernelRidge
from sklearn.gaussian_process import GaussianProcess

regr = linear_model.LinearRegression()
regr.fit(train_data, train_target)

print(regr.score(test_data, test_target))
```

スコアは 0.58 でした。


#### カーネルモデルでの回帰

散布図を見ると、カーネルモデルではフィッティングしづらそうですが、一応やってみます。

```py3
k_ridge = KernelRidge(alpha=1.0, kernel='rbf')
k_ridge.fit(train_data, train_target)

print(k_ridge.score(test_data, test_target))
```

スコアは 0.20 でした。
[rails] viewのリンクがおされた時に特定の処理をする機能を素早く作るためのコピペシート

#この記事を書いてルーティングについて何も知らなすぎると思いちゃんと勉強することにした
http://qiita.com/rorensu2236/items/e06704f39538452c8d9b

このページタイトルの内容を実現したい場合上記記事の一番下、もしくは参考サイトをごらんください。

###以下非推奨なRailsのルーティング設定が記述されています。



# viewのボタンを押したら、rails側で色々処理をするボタンを新規に作りたい
![image](https://qiita-image-store.s3.amazonaws.com/0/69647/5724ec95-92d3-4be0-2e89-d4ff01dd7d18.png)

こんなボタンがあって押したら
@user = User.first
@user.name = ""
@user.save
こんな感じのことをしてほしい時に使うコピペシート

# routes

```rb:routes.rb
get 'clients/price_set/:id', to: 'clients#reset', as: :reset
```

# view
```rb:test.html.erb
= link_to 'テスト', admin_reset_path(client)
```

# controller
```rb:clients_controller.rb
class Admin::ClientsController < AdminController
  #省略
  def reset
    binding.pry
  end
  #省略
end
```

# 解説　(読まなくても大丈夫)

## routes解説
get 'clients/reset/:id'
今回はクライアントの情報を変更するのでclients/で
この/reset/の部分はなんでも大丈夫なのでよしなに、それぽいやつを
最後に渡したい:id　などを指定しましょう

この時コントローラーに渡されるparamsの値
{"controller"=>"admin/clients", "action"=>"reset", "id"=>"1"}

to: 'clients#reset'
これでクライアントコントローラのresetメソッドを呼び出せます


 as: :reset
これでヘルパーを生成します使う時は　reset_path というように語尾に_pathをつけましょう
namespaceを実装している場合はadmin_reset_pathというように前にもnamespaceをつけましょう。
```rb:test.html.erb
= link_to 'テスト', admin_reset_path(client), :class => 'delete_data_button'
```

## view解説
admin_reset_path(client)
これでclientのidを送れます、client.idと書かなくてもrailsがよしなに.idが必要なんだろうなーと空気を読みます。




## controller解説
今回追加したいメソッドresetを定義する、ここのbinding.pryでparamsを見ると先ほどの
{"controller"=>"admin/clients", "action"=>"reset", "id"=>"1"}
が取れる、ここからはもう無双ですね (^・ω・^)
このIDの値を使って様々なrubyの処理が書けます。
認証プロキシ環境下でのchocolateyインストール

## 書いた理由
- 背景とかどうでも良いからやり方が知りたい人向け
- 認証プロキシ chocolateyでググってもまどろっこしくて古いバージョン向けが多かった

## 対象環境
- chocolatey 0.10.5
- Win10 Pro 64bit
- win7 Ult 64bit

## 導入手順
### 事前準備
- 公式サイトから[ファイルを取得](https://chocolatey.org/install.ps1)
- プロキシを超えるためにファイル内の以下行を書き換える
    - $explicitProxy = "プロキシサーバ:ポート"
    - $explicitProxyUser = "ユーザー名"
    - $explicitProxyPassword = "パスワード"
- ファイルを保存して閉じる

### 手順
1. パワーシェルを管理者権限で起動
1. コマンド"Set-ExecutionPolicy RemoteSigned"を実行
1. 事前準備で引っ張ってきたinstall.ps1を実行

## 導入後のproxy向けの設定
1. パワーシェルを管理者権限で起動して以下のコマンドを入力
    - choco config set proxy プロキシサーバ:ポート
    - choco config set proxyUser ユーザ名
    - choco config set proxyPassword パスワード

## 導入完了
cmdでchocoと打って下みたいのが表示されればOK

    Chocolatey v0.10.5
docker の古い image を削除

CI で `docker build` してると古い images が disk を圧迫して 

```shell-session
Step 11 : ADD . ./
Untar re-exec error: exit status 1: output: write /app/assets/images/hoge.gif: no space left on device
```

みたいなことになるので、 docker build, push したあとに古い image を削除するコマンドを実行しておくとよい。

shell-session:直近 100 images より古い `myimage` と tag なしの image を削除
`docker rmi -f $(docker images -q myimage | sed -n '100,$p') $(docker images -q --filter "dangling=true")`
Firebase HostingとCIの連携

[Firebase Hosting](https://firebase.google.com/docs/hosting/)とCIを連携する方法を書きます(•̀ᴗ•́)و 
[GitHub](https://github.com/)にpushされるとCIが動き、通ったらFirebase Hostingにdeployする感じです。

今回は、CIに**[Travis CI](https://travis-ci.org/)を使います。**
※一応、暇の時に他のCIも書いていく予定です。

# ①Webサイト作成とFirebase Hostingの設定

はじめにWebサイトを作成します。
そして、`firebase deploy`できる環境を作ります。

**この辺りのことは、[こちら](http://qiita.com/gupuru/items/25a6722f6f802d3a5250)に詳しく書かれていますので、参考にしてください^^**

# ②GitHubとTravis CI
※Travis CIやGitHubの**登録がまだの方は先に登録してください。**

GitHubにリポジトリを作成し、そのリポジトリをTravis CIに追加します。
※すでにあるリポジトリを使う場合はこの作業は不要です。

Travis CIの管理画面のプラスボタンを押すと、GitHubのリポジトリ一覧が表示されます。
![スクリーンショット 2016-09-07 7.29.29.png](https://qiita-image-store.s3.amazonaws.com/0/53996/2a5ea9f4-3eed-11a9-37ca-dea01c6e16ae.png)

この中から、先ほど作成したリポジトリを選びます。
![スクリーンショット 2016-09-07 7.29.42.png](https://qiita-image-store.s3.amazonaws.com/0/53996/fa3237df-e337-2888-7f7b-dd3c8c3860af.png)

Travis CIの詳しい説明はここでは省略しています。使い方などは[この辺り](http://knowledge.sakura.ad.jp/tech/3754/)をみると分かりやすいと思います。

# ③`.travis.yml`の作成

deployするだけならこれで、大丈夫です(•̀ᴗ•́)و 
テストなどの所は、お好きなように書いてください（笑）
`$FIREBASE_TOKEN`については、次で説明します。

```.travis.yml
language: node_js

node_js:
  - "4.0"

script:
  - echo "Deploy"

install:
  - npm install -g firebase-tools
  
after_success:
  - firebase deploy --token $FIREBASE_TOKEN
```

# ④FIREBASE_TOKENの取得

CIからFirebase Hostingに**deployするにはtokenが必要**です。
はじめに、こちらをターミナルで実行します。

```
firebase login:ci
```

ブラウザが開きログイン画面が開くので、ログインします。

![スクリーンショット 2016-09-04 23.34.06.png](https://qiita-image-store.s3.amazonaws.com/0/53996/2f4d5999-e475-ec17-8e03-8980dbc2ef90.png)

ログインが成功するとこんな画面が表示されます。

![スクリーンショット 2016-09-04 23.34.16.png](https://qiita-image-store.s3.amazonaws.com/0/53996/b5681f42-d8b2-c3c7-ad37-31a7626f1807.png)

で、ターミナルには`Success! Use this token to login on a CI server:`と表示されているはずです。
その下辺りにtokenがあるので、このtokenをコピーします。

![スクリーンショット 2016-09-04 23.34.24.png](https://qiita-image-store.s3.amazonaws.com/0/53996/2233a6d3-3f5f-ac61-9106-25a1d5253294.png)

# ⑤FIREBASE_TOKENをTravis CIに設定

④のtokenをTravis CIに設定します。

まず、Travis CIのリポジトリの`Settings`を開いてください。

![スクリーンショット 2016-09-06 22.56.26.png](https://qiita-image-store.s3.amazonaws.com/0/53996/a78df6e6-fa60-d6f8-4959-7066fc786c8f.png)

`Environment Variables`に先ほどのtokenを入れて`Add`を押して追加(^O^)／

![スクリーンショット 2016-09-04 23.35.12.png](https://qiita-image-store.s3.amazonaws.com/0/53996/a31c1b9a-90d1-d9e5-ed6e-813213a7eb33.png)

# ⑥CIをまわしてみる＼(^o^)／

⑤ですべての設定が完了です。
あとは、GitHubにPushする度に、こんな感じにTravis CIが動くはずです。

![スクリーンショット 2016-09-06 23.08.44.png](https://qiita-image-store.s3.amazonaws.com/0/53996/a95ce08f-29cc-e466-1923-25cdef0cca09.png)

そして、 無事にパスできたら、Firebase Hostingにdeployされているはずです( *• ̀ω•́ )b
Errbotで作るポモドーロタイマー

# なぜ作ったし

急に作りたくなって、つい（使うか？と言われると、使わないかも？）

# 中身

```python:pomodoro.py
# -*- coding:utf8 -*-
from __future__ import division, print_function, absolute_import
"""Pomodoro timer
"""
from errbot import BotPlugin, botcmd


class Pomodoro(BotPlugin):
    def __init__(self, bot):
        super().__init__(bot)
        self._timer = [None, None]
    
    def activate(self):
        super().activate()
        self.start_poller(60, self.pomodoro)

    def pomodoro(self):
        time_counter = self._timer[0]
        target = self._timer[1]
        if time_counter is None:
            return
        time_counter += 1
        if time_counter >= 25:
            time_counter = -5
            self.send(target, "5分間休憩")
        elif time_counter == 0:
            self.send(target, "25分間集中")
        self._timer[0] = time_counter

    @botcmd(name='pomodoro_start')
    def start(self, msg, args):
        self._timer = [0, msg.frm]
        return 'タイマーオン'

    @botcmd(name='pomodoro_stop')
    def stop(self, msg, args):
        self._timer = [None, None]
        return 'タイマーオフ'
```

[インストール用はこちら](https://github.com/attakei/errbot-pomodoro-timer)(公開用にちょっと調整しています)

* `!pomodoro_start` でタイマー開始。
    * 約25分後に「休憩しましょう」ポストがErrbotから飛んでくる
    * 休憩が5分経つと、「仕事しましょう」ポストがErrbotから飛んでくる
* `!pomodoro_stop` でタイマー終了

# こんな挙動メモ

## スケジューリングでの機能呼び出し

以前書いたように、Errbotは`start_poller()`を用いることで、一定間隔で機能を呼び出すことができる。
タイマーの有効/無効は一旦脇に置いた上で、とりあえず本体ロジックは毎分動くようにする。

## 本体ロジックはただのカウンターチェック

* タイマーがオフなら`None`になる
* タイマーがオンになったら-5 〜 24 の整数が入る
* タイマーがオンの間は、毎分のロジック呼び出しごとに、カウンターを加算
* カウンターが25になったら−5に戻して休憩ポスト
* カウンターが0になったら仕事ポスト


# その他

どう見ても一人用なので、せっかくだからと多人数版を作成中
CUIエディタをGUIとして立ち上げる

GUIのIDEやファイラから、外部のエディタを開くときに便利なTips.

CUIエディタ + ターミナルエミュレータしかない環境でも、新しいウィンドウで外部エディタを起動したいときがごくまれにあります。例えばIDEから指定のファイルを好きなエディタで開きたい時や、ファイラからエディタを開きたい時など。外部コマンドとしてvimやemacsを指定しても、ターミナルエミュレータ上じゃないと、起動できません。

こんな場合、ターミナルエミュレータに起動するコマンドを渡します。

```sh
xterm -e "vim $FILENAME"
```

gnome-terminalの場合もおなじく

```sh
gnome-terminal -e "vim $FILENAME"
```

もちろんemacsだって

```sh
xterm -e "emacs $FILENAME"
gnome-terminal -e "emacs $FILENAME"
```

##<i class="fa fa-asterisk"></i> alternatives を使った場合

デフォルトのコマンドを管理できるalternativesを使うと、コマンドをハードコードする必要がなくなります。

```sh
x-terminal-emulator -e "editor $FILENAME"
```
swiftでAnyObjectに、Realmを個別にぶっこむ

CollectionViewのデータを好きなようにソートしたくて、
AnyObject型にRealmを入れたり、空データを入れたりした時の例、
普通にRealmで初期データ作った方が大幅に楽でしたが。汗


```:swift
var cellList = [AnyObject]()
```

```:swift

        // ソート用にrealmを内包した配列を用意
        for i in 0..<100 {
        
            if self.result?.filter("id ==" + String(i)).count > 0 {
                let data = self.result?.filter("id ==" + String(i)).last!
                cellList.append(data!)
            }else{
                
                // 空用のデータを用意
                let data = myData()
                data.scanDate = NSDate()
                data.id = i
                data.status = 0
                
                cellList.append(data)
              
            }
        }
        
        println("cellList \(cellList)")
        
```
UITabbarのバッジを色んなところからアクセス


```:swift

self.tabBarController?.tabBar.items![0].badgeValue = "New" // 0番目のタブにNew

```

```:swift
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem!) {
     self.tabBar.items![0].badgeValue = "New"
}

```

```:swift
for i in 0..<5 {
    let tabItems = self.tabBar.items! as [UITabBarItem]
    tabItems[i].badgeValue = "New"
}
```
【javascript】reduce

reduceメソッドについてまとめます。

# reduceメソッドとは
隣り合う2つの配列要素に対して左から右へ同時に関数を適用し、単一の値にする。というメソッドです。
例えば、「配列の中身を一つずつ足していって合計を求める」ということができます。


# reduce()
以下、構文です。

#### array.reduce(callback [, initialValue])

- array：対象となる配列
- callback：配列内の各値に対して実行される関数、4つの引数を持つ
    - accumulator：現在処理されている要素よりも一つ前の要素かinitialValue、もしくは一つ前の要素で実行された関数の結果
    - currentValue：現在処理されている要素
    - currentIndex：現在処理されている要素のインデックス
    - array：対象となっている配列
- initialValue：最初の実引数として渡される値

参考：[Array​.prototype​.reduce()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
)

initialValueは省略可能です。
initialValueが指定されている場合、一番最初の関数実行時のaccumulatorにはinitialValueの値が入り、currentValueには配列の最初の値が入ります。
initialValueが省略されている場合は、一番最初の関数実行時のaccumulatorには配列の最初の値が入り、currentValueには配列の2番目の値が入ります。

また、callback関数の中のcurrentIndex、arrayも省略可能です。

サンプルを通じて詳しく説明します。


# サンプル

まずは配列内の数値をすべて足して、その値を表示します。

```js:sample_sum.js
var array = [1, 2, 3];

var result = array.reduce(function (accumulator, currentValue, currentIndex, array) {
    return accumulator + currentValue;
});

console.log(result); // 6
```
sample_sum.jsではinitialValueを省略しています。
関数実行のイメージは以下のようになります。

| 関数実行回数 | accumulator | currentValue | currentIndex |
|:-:|:-:|:-:|:-:|
| 1回目 | 1 | 2 | 1 |
| 2回目 | 3 | 3 | 2 |

関数実行1回目のaccumulatorには配列の一番最初の要素である`1`が入ります。
currentValueには`2`が入ります。
ここで関数が実行されると、`1 + 2`で`3`がreturnされます。

関数実行2回目のaccumulatorには、一つ前の要素で実行された関数の結果である`3`が入ります。
currentValueには3番目の要素である`3`が入ります。
そして関数が実行された結果、`6`がreturnされます。


以下のように、配列の中で一番大きい値を求めることもできます。

```js:sample_max.js
var array = [10, 100, 30, 50];

var result = array.reduce(function (accumulator, currentValue, currentIndex, array) {
    if(accumulator > currentValue){
        return accumulator;
    } else {
        return currentValue;
    }
});

console.log(result); // 100
```


以上でreduceの基本は終わりです。
CoreOS用cloud-config.ymlメモ2

## 参考

* [Setup CoreOS with iptables on DigitalOcean · Matt Carrier](https://mattcarrier.com/post/core-os-iptables/)
* [Scheduling Tasks with systemd Timers](https://coreos.com/os/docs/latest/scheduling-tasks-with-systemd-timers.html)
* [CoreOS用cloud-config.ymlメモ - Qiita](http://qiita.com/tukiyo3/items/f49e51045b34c7f600ab)


# cloud-config.yml

## user,ssh鍵

```bash:userのパスワード文字列生成
$ openssl passwd -salt coreos -1 fjpoaeifji
$1$coreos$5tow1kTF0qjJ0qi.G8N9/1
```

```rb:cloud-config.yml
users:
  - name: core
    passwd: $1$coreos$5tow1kTF0qjJ0qi.G8N9/1
    ssh-authorized-keys: 
      - ssh-rsa ... osx/id_rsa
  - groups:
      - sudo
      - docker
```

## hostname

```rb:clod-config.yml
hostname: core01
```

## reboot strategy

```rb:clod-config.yml
coreos:
  update:
    reboot-strategy: off
```

```bash:手動アップデートする場合以下コマンド
update_engine_client -update
```

## sshd


```rb:clod-config.yml
coreos:
  units:

    - name: sshd.socket
      command: start
      content: |
        [Socket]
        #ListenStream=22
        ListenStream=2222
        Accept=yes
        #
        PermitRootLogin no
        PasswordAuthentication no
        AllowUsers core
```

## iptables

```rb:clod-config.yml
coreos:
  units:

    - name: iptables-restore.service
      enable: true
      command: start

write_files:
  - path: /var/lib/iptables/rules-save
    permissions: 0644
    owner: 'root:root'
    content: |
      *filter
      :INPUT DROP [0:0]
      :FORWARD DROP [0:0]
      :OUTPUT ACCEPT [0:0]
      -A INPUT -i lo -j ACCEPT
      -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
      -A INPUT -p tcp -m tcp --dport 2222 -j ACCEPT
      -A INPUT -p tcp -m tcp --dport 8888 -j ACCEPT
      COMMIT
```

## screen

```rb:clod-config.yml
write_files:

  - path: /home/core/install_screen.sh
    permissions: 0700
    owner: core:core
    content: |
      sudo wget -q https://raw.githubusercontent.com/tukiyo/coreos-screen.run/master/screen.run -O /usr/share/oem/screen.run
      sudo sh /usr/share/oem/screen.run
```
Ubuntuで画面操作のgifを作る


個人のただのメモ
たぶんもっと効率良い方法はあると思う。

1. kazamでmp4で動画を取る
2. `ffmpeg -i my.mp4  -r 5 'frames/frame-%03d.jpg'`でフレームごとのjpgに変換
3. `convert -delay 20 -loop 0 *.jpg myimage.gif` でgifができる

以上
RESTful APIのリソース設計

RESTful APIの設計を行う上で、まずはリソース設計を行う。リソース設計では以下を検討する。

### 1. 何をリソースとするか
とにもかくにも何をリソースとするかを決める必要がある。APIの利用者がどのようなリソースを必要としているか、そのリソースをどのように利用するか、といったユースケースを考えながらリソースを抽出する。

### 2. リソースに対するCRUD操作
抽出したリソースに対して、どのようなCRUD操作が必要かを検討する。なお、CRUD操作に関しては[「RESTful APIとは何なのか」のRESTの原則 - 統一インターフェース](http://qiita.com/NagaokaKenichi/items/0647c30ef596cedf4bf2#rest%E3%81%AE%E5%8E%9F%E5%89%87)でも述べた通り、HTTPの標準メソッドを利用する。

### 3. リソース間の従属関係(親子関係)
それらのリソース間でどのような従属関係があるかを検討する。例えば、会社には部署があり部署には部員が所属する、といったようなイメージ。

### 4. リソースの各項目のデータ型の定義
リソースの各項目のデータ型を定義する(String、boolean、Number等)。

### 5. リソース定義の明文化
API利用者、API開発者のために、リソース定義を明文化する。ちなみに、明文化するにあたり、

|項目名|名称|データ型|詳細|
|:--|:--|:--|:--|
|firstName|名|String|-|
|lastName|姓|String|-|
|age|年齢|String|-|

のような感じで明文化しても良いが、JSON Schemaを利用することで以下のメリットを得られる。

* 既存のデータ型を記述できる
* 人にも機械にも読める文書になる
* 完全に構造化されたデータの検証ができる

そのため、明文化にはJSON Schemaを利用した方が良いかもしれない。
※http://json-schema.org/examples.html のサンプルを拝借

```
{
	"title": "Example Schema",
	"type": "object",
	"properties": {
		"firstName": {
			"type": "string"
		},
		"lastName": {
			"type": "string"
		},
		"age": {
			"description": "Age in years",
			"type": "integer",
			"minimum": 0
		}
	},
	"required": ["firstName", "lastName"]
}
```



### 留意したいこと
リソース設計 = DBのER設計ではないということ(DBのER設計とは切り離して考えたほうが良い)。また、「4. リソースの各項目のデータ型の定義」と「5. リソース定義の明文化」に関しては、インターフェース設計(後で投稿予定)で検討でも良い。

# 参考
[RESTful Webサービス](https://www.amazon.co.jp/RESTful-Web%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9-Leonard-Richardson/dp/4873113539)
[Web API: The Good Parts](https://www.oreilly.co.jp/books/9784873116860/)
テキストファイルの文字コードは中身で決まる。らしい。

今まで文字コードって、ファイルのメタ情報的な領域にファイルごとに定義されていて、それを元にテキストエディタなりがそのファイルを開くときに文字のバイト列をうまく変換するのかと思っていたのですが、どうやらそういう感じではないらしい、ということを知ったのでまとめてみます。

# ざっくりファイルシステムについて

そもそもコンピューターはファイルをどうやって管理しているのか、というファイルシステムの話なのですが、[こちらの知恵袋](http://note.chiebukuro.yahoo.co.jp/detail/n77470) がとても勉強になりました。

ざっくり言うと、ファイルの内容はディスク上の一定のサイズで区切られた領域に記録されていて、管理領域にその場所やファイル名、パーミッション情報などが記録されている、ということらしいです。

# 文字コード情報は？

では文字コードは「管理領域」に記録されているのでしょうか。
というわけで実験してみました。

```
$ echo あ >> a.txt
$ nkf -g a.txt
UTF-8
```

単純に「あ」と書かれたファイルを作ると、それは UTF-8 と認識されるようです。（PCの設定によって変わりそうです）

次に、比較用に EUC-JP のファイルを作ります。

```
$ nkf -e a.txt > e.txt
$ nkf -g e.txt
EUC-JP
```

```a.txt```の内容を```nkf -e```でEUC-JPに変換し、それを```e.txt```として保存します。
```e.txt```はEUC-JPと認識されています。ここまでは想定通りですね。

では、```a.txt```に```e.txt```の内容を追記してみます。
もしファイルの管理領域に「このファイルはUTF-8である」という情報が保持されているのであれば、EUC-JP形式のバイト列が混ざろうがそれはUTF-8ファイルと認識されるはずです。

```
$ cat e.txt >> a.txt
$ nkf -g a.txt
BINARY
```

UTF-8でもなくEUC-JPでもなくBINARYと表示されました。もはや文字コードじゃないですね。。。
UTF-8だと解釈してもEUC-JPと解釈しても正常に読み取れない部分があるということで、もはやテキストデータではないと判断されて感じですね。

いずれにしても、内容次第で文字コードが変わるということは、文字コードはファイルの管理領域に記録されているのではなく、ファイルの内容自体から判定されていることがわかりました。

最後に、```a.txt```の一行目を削除して（つまりEUC-JPの行だけ残して）みます。

```
$ vi a.txt
# 一行目を削除

$ nkf -g a.txt
EUC-JP
```

EUC-JPになりました。
ファイルを編集しただけでコロコロ文字コードの判定が変わる、ということは、やはり文字コードはファイルの内容から判定されているだけだということがわかりますね。

# まとめ

今までファイルの文字コードを変えるというと、```nkf -e```したり秀丸で文字コードを変更して保存したりと、何となく変更して何となくちゃんと表示てきてOKとしていたのですが、実際にファイル自体にどんな変化が起きているのかを正確には把握できていませんでした。実際はファイル内の日本語部分のエンコーディングの形式を変えているだけということですね。

その他にも、ファイルの中身で文字コードが決まるということは、例えばHTMLで最初にファイルのエンコーディングを定義しておけば、その通りにブラウザが表示してくれる、という仕組みも何ら不思議ではないことが分かります。きっとブラウザはファイル内の文字列のバイト列が何の文字コードで表現されたバイト列なのかよりも、HTMLタグで定義された文字コードを優先する、というところでしょうか。

また、半角英数字しか含まれないファイルの文字コードがASCIIになるのもその通りですね。

```
$ echo a >> b.txt

$ nkf -g b.txt
ASCII
```

ファイルの文字コードの判定の仕組みの他にも、ファイルシステムの仕組みも簡単に知ることができたことも良い勉強になりました。
GCPUG Tokyo Aug 2016


## App Engine Flexible Environment

sinmetalさん

http://qiita.com/sinmetal/items/080a79702b060b33de69

## Tensorflow入門

fujiwaraさん

Tensorflowの基本的な話

### TensorFlowって何？

色んな記事で紹介されてるけど、記事によってけっこうブレブレ。

**数値計算ライブラリ**

開発はGoogle Brainチーム
PythonとC++のAPI
C++の方はないものとかあったりして茨の道かも
Pythonのがオススメ

なぜ機械学習の中で話されるのか
ニューラルネットを簡単に実装できる
機械学習に特化した数値計算ができる

並列分散処理が得意

アルゴリズムを実装するための道具。

### TensorFlow使うと作れる（かもしれない）もの

- AlphaGo
	- たしか。
- Cloud Vision API

### TensorFlowと計算グラフ

計算グラフ（データフローグラフ）を作る
計算グラフは作った時点では計算しない。
計算順序の宣言。
ここら辺重要。

実行と計算グラフで明確に処理が分かれている。

### 計算グラフを作るメリット

どんな計算をマシンに伝えておくことができる
どの計算がどの計算に依存しているかわかりやすい
時間がかかるところの見積もりがしやすい

計算のための複数デバイスがある場合に、適切な割り振りができる。

Cloud MLとの相性が良い。

### 計算の実行

オペレーションの実行をした時に依存関係のあるものだけが実行される
デバイス間の通信もオペレーション
デバイス間通信はTensorFlowが吸収してくれる

依存関係をわかってるから、デバイス間通信もうまいことやってくれる。

中の仕組みはホワイトペーパーが公開されるから見るといいよ

### 事前に計算グラフを作るデメリット

- 場合分けなどの柔軟な処理はちょっと苦手
- 書けるけどツラい
- クセがけっこうある感じ

### GCPにどう関わってくるか

デバイス間通信と言われてもそんなマシンリソースはない
GCPがそのマシンリソースを提供してくれる

Cloudd Machine Learning
TPUが使えるかもしれん

## GCP運用Tips

運用中に気付いたこととかのTips
守永さん

### GCE環境構築手法

- Developer Console
- gcloudコマンド
- Compute Engine API

#### コンソール

複雑な構成とかは使わない
ちょこっと作るときに使う
HTTP LB作るときはぽちぽち使う

スケールダウンのレコメンドとかしてくれる
適用すると再起動かかるので注意

#### gcloudコマンド

GCP操作の履歴

```
gcloud compute operrations list
```

Live Migrationの履歴とかを定期的に監視してる

ネットワーク情報はLegacyとサブネットのやつで出力が違うので注意

#### Compute Engine API

あんまり直接叩くことはない
Terraform使ってるのでそいつが叩いてる
### HTTP(S)ロードバランサ

つまづかないための講座
ハマったところ解説

LBのすごいところ
フロントのリクエストをウォームアップなしで秒間100万リクエスト捌ける

- webサーバに適切なFWを設定
	- 130.211.0.0/22
	- これはGoogleのネットワーク。
- インスタンスグループは複数リージョンをまたぐ
- インスタンスグループには最低2台インスタンスを用意する
	- 1台だけだと、たまにヘルシーインスタンスがいないって判断されることがある
	- 502が返ってくる
	- LBの仕様
	- 正常なインスタンスがないと判断される頻度が高まる

### Preemptive VM

強制シャットダウン前にプリエンプション通知が来る
30秒以内に終わる処理だけ

### Manage Accounts

一時的にauthorized_keysをroot権限にすることがあるから注意！

### メタデータサーバ

3つの役割

- Metadata Server
- Name Sever
- Default Gateway

ホスト名Resolveできないことがある
メタデータサーバを利用する場合は、503をハンドリングしましょう

### Cloud Storage API

たまに500返す。
→ SLAの範囲内（ドヤ
ちゃんとハンドリングしよう。

## 見せてやろう、FEの実力を！

3Dデータ解析サーバー

### 元々のシステム

Python(Flask)で書かれたAPI
スゴイ長い処理なのに、HTTPリクエスト受けてレスポンス返すようなクソな仕組み…

- デプロイ手順が多い
- つまる
- ログが閲覧しづらい
	- SSHで入って見に行くしかない
	- ミドルレイヤーが増えるとログ検知がしづらい
	- そもそも監視してなかった

**ツラい**

### そうだ、FE化しよう

- デプロイ手順が多い
	- gcloudコマンドでデプロイ可能に
- つまる
	- キューを使ってかつ監視
- ログ
	- Log Viewwerで見れる

FEで全て解決
技術英語 > You can use global variables [as substitutes for] named constants.

@ Code Complete (No. 11359 / 36077)
> You can use global variables <font color=red>as substitutes for</font> named constants.

http://ejje.weblio.jp/content/substitute
> (劇の)代役 〔for〕.

<hr>
関連して思い出したのは

http://qiita.com/7of9/items/c627f378aff46a9d31c5
> Test doubleという用語がある。
doubleはstunt doubleのように「代役」の意味。
Cmder alias

正式かわからないけど`::`と`=`で挟むとコメントアウト。


```bat
e.=explorer .
ls=ls --show-control-chars -F --color $*
pwd=cd
clear=cls
history=cat %CMDER_ROOT%\config\.history
grep=grep --color $*
find=find . -name $*
unalias=alias /d $*

su="sublime_text.exe" $*

py="python" $*
ipy=ipython
spy=spyder
jpy=cmd /k "jupyter qtconsole --style=monokai" -new_console:t:"Jupyter" -new_console:b


g= git $*
gf=git flow $*

::add,commit,push=
ga= git add 
gaa= git add . 
gan= git add -n .
gaundo= git reset HEAD
gac=git commit -am $*
gc= git commit -m $*
gcundo=git commit --amend  
gp=git push $*
gpo=git push origin $*

::status=
gs= git status --short $*
gsb=git status --short --branch $*  
gl=git log --oneline --all --graph --decorate $*
gls=git ls-files $*  
gd= git diff --color-words $*  

::branch=
gch=git checkout $*  
gb=git branch $*  
gm=git merge $*
gt=git tag $*
```
DockerでRuby on Railsの開発環境を構築

## 概要

ubuntu 16.04 をベースに以下の構成でイメージを作成しました。

* rails 4.2.6
* ruby 2.2.5
* PostgreSQL 9.5

Dockerさえインストールしていれば、すぐにRuby on Railsでの開発が始められると思います。

## 環境
* OS X 10.10.5
* Docker 1.12.0

## ソース

https://github.com/mktktmr/docker-rails-postgresql

## イメージのインストール

いずれかの方法で、コンテナのイメージをインストールしてください。

### a. Docker Hub から pull

```bash
$ docker pull mktktmr/docker-rails-postgresql
```

### b. ソースからビルド

```bash
$ git clone https://github.com/mktktmr/docker-rails-postgresql.git
$ cd docker-rails-postgresql
$ docker build -t mktktmr/docker-rails-postgresql .
```

### 確認

`docker images` でイメージの存在を確認。

```bash
$ docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
mktktmr/docker-rails-postgresql   latest              ba322d4f4504        59 minutes ago      925.5 MB
ubuntu                            latest              bd3d4369aebc        11 days ago         126.6 MB
```

## コンテナの起動

`docker run` でコンテナを起動する。

```bash
$ docker run -it --name rails -p 3000:3000 mktktmr/docker-rails-postgresql
```

コンテナが正常に起動すれば、コンテナのコンソールに切り替わります。

```bash
root@58f24edfbd76:~#
```

`Ctrl + d`などでコンテナから抜けられます。

```bash
root@58f24edfbd76:~# exit
```

### オプションについて

#### -it

ターミナルでインタラクティブにコンテナの操作ができるようになります。

#### --name

コンテナに任意の名前を付けることができます。

#### -p

ホストOSとコンテナのポートマッピングを設定します。

## 永続化

コンテナは基本的にステートレスであるため、再起動するとコンテナ上で作成したファイルなどは消えてしまいます。

データベースのデータなどを保持したい場合、永続化のための作業が必要です。

色々と方法があるみたいですが、一番手軽（だと思う）な方法を紹介します。

今回は例としてPostgreSQL(DB)の永続化。

### ボリュームを作成

`docker volume create` でマウント用のボリュームを作成

```bash
$ docker volume create --name postgresql
```

作成したボリュームは `docker volume ls` で確認できます

```bash
$ docker volume ls
DRIVER              VOLUME NAME
local               postgresql
```

### ボリュームをマウントしてコンテナを起動

`docker run` の `-v` オプションで作成したボリュームとPostgreSQLのディレクトリをマウント。

```bash
$ docker run -v postgresql:/var/lib/postgresql -it --name rails -p 3000:3000 mktktmr/docker-rails-postgresql
```

これで、コンテナを再起動してもデータベースが消えることがなくなります。

## 参考

[『Docker実践入門――Linuxコンテナ技術の基礎から応用まで』](https://www.amazon.co.jp/dp/B015IZT854)

## 所感

仮想化もそうですが、ローカルを汚さずに環境を構築できることはいいことですね。

「過去に構築した環境が競合して〜」みたいなトラブルもないですし、気軽に環境を壊したり作り直したりできます。

最近はDockerがWindowsやMacでも仮想環境をかまさずに動くので、

今回のようなちょっとした開発環境の構築にも利用しやすくなっているのではないかと思います。

## 課題

1コンテナ1プロセスという構成にするのが、Dockerのベストプラクティスみたいだけど、

今回は開発環境構築の簡略化がテーマだったので、管理が煩雑にならないよう、RailsもDBも一つのコンテナにまとめました。

が、管理が煩雑にならずに上記のベストプラクティスを維持できる方法があれば取り入れたい（誰か教えて下さい）。
今更ながら掲示板を作ってみた（ver.2）画像添付機能付


なんだかんだで、丸一日かかってしまった…

とりあえず今回は Github にでも上げておこうと思ったので、 **初心者でも利用できる** こと、SQLite3 が動作すれば、動くように作った。PHPが動作する環境なら、SQLite は当然入っているよねってことで。

**フリーで配布している掲示板には古いものも多く、Undefined index とか大発生するような古いものがたくさんある** ので、その辺の考慮と、最低限のセキュリティは担保されていると思います。

あとは、再利用しやすいように、Bootstrap3 に対応しております。

ソースコード丸見えなので、ある程度の上級者のコードレビューにも耐えられるように書いてみました。手抜きなし（嘘）

##機能
* スレッド式
* 画像投稿機能（ON/OFF設定可能）
* 削除機能
* スレッド本文、コメント内検索機能
* レスポンシブ・デザイン

##動作環境

* PHP5.4以上
* SQLite3
* GDモジュール（画像投稿利用時）

##ダウンロード

ソースコードはこちらから [Github](https://github.com/ShibuyaKosuke/KS_BBS)

##ライセンス
MIT とします。
個人利用、商用利用を問わず利用可能です。

##余談

今回BBSを作ってみて思ったのだが、 **初心者が、データベースやセキュリティの基本を勉強するにはとてもいい題材** だと思う。 **実務で作成することになるようなWEBアプリケーションにしても、基本的な機能としては掲示板となんら変わりない。** 
全くの未経験の新入社員が1年程度の見習い期間を経たころには、自力で作成できる程度にはなっていてほしい。

ちょっと洗い出してみると、以下のようになる。

* 条件分岐
* データベースの使い方
* XSS 対策
* CSRF 対策
* SQLインジェクション 対策
* ユーザー関数
* 再帰関数（スレッド式の場合）
* クラス、メソッド（使わなくても作成はできるが…）

自分なりの持っている知識を総動員して作ってみるのは、いいと思う。できるならそれを **上級者にレビューしてもらうといい** だろう。

逆にこういった目的のための題材としては、向かないなと思ったのが、 **MVCなどの概念を無理やり当てはめようとすると、無理** が生じる。

あくまで **基本文法を学んだ人が知識と技術の確認のために作るもの** だということだ。
ただし、10年前なら掲示板を作っても楽しいだろうけど、今どき、サイトにBBSを準備する意味って…ほとんど…

追記）
無駄に **画像投稿機能** をつけてみた。
ついでに **削除機能** もつけた

##スクリーンショット

![スクリーンショット 2016-09-07 5.16.11.png](https://qiita-image-store.s3.amazonaws.com/0/46841/e7efabdf-6699-6344-2d7e-f598ace9201b.png "スクリーンショット 2016-09-07 5.16.11.png")

![localhost_2016-09-16_13-36-34.png](https://qiita-image-store.s3.amazonaws.com/0/46841/a397fc94-97d3-9f06-d80b-d4b088cd0ca3.png "localhost_2016-09-16_13-36-34.png")
Open AI GymのCartPoleコードをいじりながら仕組みを学ぶ（１）

過去６回で、Ubuntu14.04、CUDA、chainer、dqn、LIS、Tensorflow、Open AI Gymを順次インストールした。特に前回はOpen AI Gymのモデルをいくつか試してみた。
http://qiita.com/masataka46/items/227fbfbda98a901f6720

今回はOpen AI GymのHPに載ってるCartPoleゲームのサンプルコードをいじりながら、仕組みを学んでいく。前回と同様、公式HP
https://gym.openai.com/docs
に従って進める。


以下のCartPoleコード(test06.py)をいじりながら仕組みを学ぶ

```python
import gym
env = gym.make('CartPole-v0')
for i_episode in range(20):
    observation = env.reset()
    for t in range(100):
        env.render()
        print(observation)
        action = env.action_space.sample()
        observation, reward, done, info = env.step(action)
        if done:
            print("Episode finished after {} timesteps".format(t+1))
            break
```
##reset()の戻り値を出力する
まずtest06.py ４行目。

```python
observation = env.reset()
```

このreset()関数でゲームが始まる。戻り値は初期状態のobservation。よって、この段階のobservationを出力してみる。

```python
print "initial observation = ",
print observation
```

結果

```
initial observation =  [ 0.01497125  0.03562966 -0.0273448  -0.01692216]
[ 0.01497125  0.03562966 -0.0273448  -0.01692216]
```

初期状態のobservationと1 step目のobservationは同じになった。よくみたら７行目でそのまま出力されてるので当たり前。

##action_spaceを出力する
まずenvクラス
https://github.com/openai/gym/blob/master/gym/core.py
を見ると、env.action_spaceはspaceクラスのオブジェクトで、有効なactionを表しているそう。
test06.py　８行目のenv.action_spaceがそれ。よって

```python
if i_episode == 0 and t == 0:
    print(env.action_space)
```

として確かめてみる。結果、


```
Discrete(2)
```

と出力された。Discreteクラスは
https://github.com/openai/gym/blob/master/gym/spaces/discrete.py
に書かれている。spaceクラスの子クラス。discrete(２)は、取りうるべきactionが０と１の２つを意味するそう。

##observation_spaceを出力する
env.observation_spaceは
https://github.com/openai/gym/blob/master/gym/core.py
にはspaceクラスのオブジェクトで、有効なobservationを表すそう。このobservation_spaceを出力してみる。

```python
if i_episode == 0 and t == 0:
    print(env.observation_space)
```

結果、

```
Box(4,)
```

と出た。Boxクラスはここ
https://github.com/openai/gym/blob/master/gym/spaces/box.py
に書かれている。やはりspaceクラスの子クラス。有効なobservationは４次元だそう。

さらにBoxクラスにはhighとかlowとかの属性があるので、それを出力してみる。

```python
if i_episode == 0 and t == 0:
    print("env.observation_space.high is "),
    print(env.observation_space.high)
    print("env.observation_space.low is "),
    print(env.observation_space.low)
```

結果、

```
env.observation_space.high is 
[  4.80000000e+00   3.40282347e+38   4.18879020e-01   3.40282347e+38]
env.observation_space.low is 
[ -4.80000000e+00  -3.40282347e+38  -4.18879020e-01  -3.40282347e+38]
```

などと出力された。
kintone タブ表示プラグイン Ver.4

[タブ表示プラグイン Ver.5](http://qiita.com/rex0220/items/1af3527d60fbaecbfceb) がリリースされました。

本ページの内容は、旧バージョンのものです。


#タブ表示プラグイン Ver.4

新デザインに合わせたタブ表示プラグインの新バージョンです。
タブ表示プラグイン Ver.3 を設定済みで、Ver.4 を「読み込む」とVer.3 の設定内容を引き継ぎます。

- 新デザインに合わせたタブ表示スタイル
- 旧デザイン画面で表示した場合は、Ver.3 のスタイルでタブ表示
- タブ数の最大数を１５に増加
- プラグインの有効／無効設定追加
- 設定画面の数字入力チェック改善
- jQuery 競合対策


ヘッダ固定行、タブ切替、フッター固定行を設定表示できます。
[rex0220 stores](https://rex0220.stores.jp)で、販売中です。

![ktab01.png](https://qiita-image-store.s3.amazonaws.com/0/100572/a8cfda2b-2d8b-b622-4ad6-71c457587ece.png)

#詳細画面

![ktab02.png](https://qiita-image-store.s3.amazonaws.com/0/100572/997ae859-4e49-8caf-6fa4-c8357669a078.png)

#編集画面

![ktab03.png](https://qiita-image-store.s3.amazonaws.com/0/100572/64d89608-0c26-46f7-cbf6-0f41a39385c9.png)

#画面切り替えのタブ表示

詳細画面から編集画面に切り替えても、タブ位置は変わりません。

![ktab04.png](https://qiita-image-store.s3.amazonaws.com/0/100572/f198075d-c591-63cb-bbed-46bd72323c6d.png)


#プラグイン設定画面

各項目を指定して、「保存する」をクリックします。
下記の入力エリアでタブ名と表示行数欄を入力していただくとレイアウト欄に自動反映されます。
タブ名または表示行数欄の入力エリアをクリックすると、入力可能となります。
タブ名を入力し、Enter キーで確定後に、さらにEnter キーかTabキー、矢印キーで移動すると入力確定します。
※入力確定前に、マウスで別の入力エリアをクリックしますと入力内容がリセットされます。

- プラグインの有効／無効
- タブ表示エリアの表示幅
- ヘッダ部固定表示行数
- 各タブと表示行数を設定し、保存します。
- グループ・サブテーブル・関連テーブルは、１行で計算します。

![ktab05.png](https://qiita-image-store.s3.amazonaws.com/0/100572/4ea072eb-1137-7880-7df3-8becbee66f78.png)

#入力チェック機能改善

数字エラー表示を追加して、入力しやすくなりました。

![ktab06.png](https://qiita-image-store.s3.amazonaws.com/0/100572/360e7265-0974-24f2-df2a-f4a983cb875c.png)


#旧デザイン対応

旧デザイン画面で表示した場合は、Ver.3 のスタイルでタブ表示します。

![ktab11.png](https://qiita-image-store.s3.amazonaws.com/0/100572/34ccf4d8-6880-2bde-9a82-67a9f8de414e.png)


#注意事項

- 既に、JavaScript によるカスタマイズを行っているアプリの場合、処理が競合して、エラーになる場合があります。その場合は、該当するアプリでプラグインの使用を中止してください。
- アプリ設定を変更した場合は、プラグインを再設定してください。
vuejsで無限ロードを実装

まずライブラリで対応出来ないか検討した。

- https://github.com/ElemeFE/vue-infinite-scroll
- https://github.com/PeachScript/vue-infinite-loading

## vue-infinite-scroll

サンプルを触ってみたところ、`infinite-scroll-distance`でしきい値を決めて、その高さが画面に入ったらローディングを初めるライブラリのようだ。

## vue-infinite-loading

サンプルを触ってみたところ、`vue-infinite-scroll`と同じく`distance`でしきい値を決めて、その高さが画面に入ったらローディングを初める。

`infinite-scroll-distance`との違いは、おそらく`<infinite-loading :on-infinite="onInfinite"></infinite-loading>`を書いた場所の親要素の下部がしきい値になっていることである。

https://peachscript.github.io/vue-infinite-loading/#!/spinners によると、ローディングのデザインは５種類から選ぶことが出来る。

`v-if`を使うことで、ローディングを終了することが出来る。
https://peachscript.github.io/vue-infinite-loading/#!/properties

## まとめ

vue-infinite-loadingを使うことにした。
has_secure_passwordでauthenticateメソッドが追加される仕組み

Railsでおなじみの`has_secure_password`ですが、どんな仕組みでできているのでしょうか。

```rb
class User < ActiveRecord::Base
  has_secure_password
end

user = User.new
user.authenticate('password')
```

動的にメソッドが追加される仕組みにより、これ以上無いくらいすっきりモデルの定義が書けますよね。

自作のGemなどでこんなAPIを作りたいと思ったので、調べました。

読んだソースコードは[これ](https://github.com/rails/rails/blob/b965ce361b89ad33a4a4b422f8e564233926c723/activemodel/lib/active_model/secure_password.rb)です。

# 結論

見かけ上は、下記のコードで同等の振る舞いを持たせることが可能です。

```rb:secure_password.rb
module SecurePassword
  def has_secure_password
    include SecurePassword::InstanceMethodsOnActivation
  end

  module InstanceMethodsOnActivation
    def authenticate
      true
    end
  end
end
```

```rb:active_record.rb
require_relative './secure_password'

class ActiveRecord
  extend SecurePassword
end
```

```rb:user.rb
require_relative './active_record'

class User < ActiveRecord
  has_secure_password
end
```

とすると、

```rb
require_relative './user.rb'

user = User.new
puts user.authenticate
#=> true
```

となります。

# 解説

正直、まだよくわかっていないのですが、モジュールのメソッドをクラスに取り入れるには、下記2つの方法があります。（多分他にもある）

- `extend SomeModule` クラスメソッドとして
- `include SomeModule` インスタンスメソッドとして

[こちら](http://docs.ruby-lang.org/ja/2.0.0/method/Object/i/extend.html)にも書いてあります。

また、Rubyではクラスの直下？ではクラスメソッドが実行できますが、インスタンスメソッドではクラスメソッドを実行できません。

さっきの例で、`has_secure_password`はUserクラスのクラスメソッドになっているので、下記はエラーになります。

```rb
class User < ActiveRecord
  has_secure_password

  def test
    has_secure_password
  end
end

user = User.new
puts user.authenticate
puts user.test
# => undefined method `has_secure_password'
#    for #<User:0x0055b91a9f0280> NoMethodError
```

多分知っている人からすると非常に初歩的な内容かと思いますが、けっこう理解に時間がかかったのでまとめてみました。
Mac版 Atlassian SDKのインストール / アップデート


久しぶりの投稿で、かつ単一トピック的な内容になります。
## 今回とりあげること

- Atlassian SDKをMacにインストールすること
 - dmgでのインストールではなくHomebrewを利用 
- コマンドから検証・開発用のJIRAやConfluenceのインスタンスを立ち上げること

### Atlassian SDKについて

Atlassian SDKを利用すると、開発用のConfluenceやJIRAのインスタンスを起動することができます。データの永続性はありませんが、ローカルの環境でプラグインを開発する際に便利なクイックデプロイやデバッグが可能になります。

下記にいくつか記事を書いておりますので、そちらもよろしければご参照ください。

- [Atlassian SDKでREST API Browserを使ってみます](http://qiita.com/akiko-pusu/items/94fa00c40ba670b92483)
- [Atlassian SDKを入れてみる/開発用JIRAの起動](http://qiita.com/akiko-pusu/items/54fee7ce9afaa39907e6)

## HomebrewでのSDKのインストール

Mac版も含め、いろいろな環境でのsdkのインストール方法は、こちらのページに記載されています。

- [Install the Atlassian SDK on a Linux or Mac system](https://developer.atlassian.com/docs/getting-started/set-up-the-atlassian-plugin-sdk-and-build-a-project/install-the-atlassian-sdk-on-a-linux-or-mac-system)

インストール時には、下記のコマンドを実行します。

```
$ brew tap atlassian/tap
$ brew install atlassian/tap/atlassian-plugin-sdk
```

行っていることは、下記の通りです。

- brew tap コマンドで、公式以外のリポジトリを追加します
 - https://github.com/atlassian/homebrew-tap/network
- tapで追加されたリポジトリにしたがって、SDKを追加します
 - 実際はAtlassianのmavenリポジトリからSDKを取ってきます

## SDKの更新

さて、いったんインストールしたのはいいのですが、このSDKも日々バージョンアップされています。
SDKを使うとJIRAやConfluenceのインスタンスを立ち上げることができるのですが、JIRAなどプロダクトのバージョンが上がると、SDKのバージョンも上げないとうまくビルドと起動ができないことがあります。

ということで、時々SDKの更新が必要になります。
20160906現在、6.2.4になっています。

```
$ brew upgrade atlassian/tap/atlassian-plugin-sdk

# 更新処理が走る

# バージョンの確認
$ atlas-version 

ATLAS Version:    6.2.4
ATLAS Home:       /usr/local/Cellar/atlassian-plugin-sdk/6.2.4/libexec
ATLAS Scripts:    /usr/local/Cellar/atlassian-plugin-sdk/6.2.4/libexec/bin
ATLAS Maven Home: /usr/local/Cellar/atlassian-plugin-sdk/6.2.4/libexec/apache-maven-3.2.1
AMPS Version:     6.2.3
--------
```

## さらに更新

いったんhomebrew側を更新した後、実際には、さらに利用可能なSDKのバージョンが上がっている場合があります。
その場合は、atlas-update コマンドを実行します。

```
# 
$ atlas-update

# バージョンの確認
$ atlas-version 
ATLAS Version:    6.2.9
ATLAS Home:       /usr/local/Cellar/atlassian-plugin-sdk/6.2.4/libexec
ATLAS Scripts:    /usr/local/Cellar/atlassian-plugin-sdk/6.2.4/libexec/bin
ATLAS Maven Home: /usr/local/Cellar/atlassian-plugin-sdk/6.2.4/libexec/apache-maven-3.2.1
AMPS Version:     6.2.6

```
20160906現在、6.2.9になっています。

今回は以上でした！
Hortonworks Sandbox on VirtualBox

Hortonworks SandboxをVirtualBoxで起動する手順を記載します。

事前にVirtualBoxを以下からダウンロードして、インストールしておきましょう。
https://www.virtualbox.org/wiki/Downloads

推奨環境

- VirtualBox： 4.2 or later
- CPU： 64-bit machine with a multi-core CPU that supports virtualization
- BIOS： enable for virtualization support
- RAM： At least 8 GB of RAM(The more,the better)

# Hortonworks Sandboxのダウンロード

以下手順に従ってダウンロードします。

URL： https://jp.hortonworks.com/downloads/#sandbox

1.「VIRTUALBOX用ダウンロード」ボタンを選択します。

![01.png](https://qiita-image-store.s3.amazonaws.com/0/61606/52d41951-59a3-4cd7-29e6-8f07243d4624.png)

2.「REGISTER YOUR SANDBOX」に必要事項を入力して「SUBMIT」ボタンを選択します。

![02.png](https://qiita-image-store.s3.amazonaws.com/0/61606/c4df7662-3899-c59c-da1d-faf92b30ffe7.png)

3.「OK」を選択します。

容量が約9GBあるため、ダウンロードに少し時間がかかります。

![000.png](https://qiita-image-store.s3.amazonaws.com/0/61606/7cfdedb0-cc72-52ce-3899-1c0c046d1ce1.png)

# VirtualBoxへのインポート

1.VirtualBoxを起動し、[ファイル]-[仮想アプライアンスのインポート]を選択します。

![001.png](https://qiita-image-store.s3.amazonaws.com/0/61606/5b5ab47f-8847-fb8b-f247-4311b1995682.png)

2.参照ボタンを選択します。

![002.png](https://qiita-image-store.s3.amazonaws.com/0/61606/463523a1-09c2-2ee9-bfbd-8bcd781c4dce.png)

3.ダウンロードした「HDP_2.4_virtualbox_v3.ova」をダブルクリックします。

![003.png](https://qiita-image-store.s3.amazonaws.com/0/61606/81252fff-e51b-1fe0-1848-960a62c01705.png)

4.「インポート」ボタンを選択します。

![005.png](https://qiita-image-store.s3.amazonaws.com/0/61606/93d0436f-ffef-6b5b-90d1-e9ad3a29ed72.png)

5.しばらく待ちます。

![006.png](https://qiita-image-store.s3.amazonaws.com/0/61606/989928e6-0f98-d4e5-42e3-0a280ff4295f.png)

6.Hortonworks Sandbox with HDP2.4 という仮想マシンが出来るので、起動します。

![007.png](https://qiita-image-store.s3.amazonaws.com/0/61606/ba3d338d-8b82-c6d5-8e59-325a013a308b.png)

7.Linux/Windowsの場合は、<Alt + F5>、Mac OS Xの場合は、<Fn + Alt + F5>を押して、ログイン画面を表示します。

![002.png](https://qiita-image-store.s3.amazonaws.com/0/61606/6662adc2-0ed4-a4a9-6065-1eb8a61e92d0.png)

11.ユーザをroot、パスワードをhadoopでログインし、初期パスワードの変更を行い、ログイン完了となります。

![003.png](https://qiita-image-store.s3.amazonaws.com/0/61606/a3e64bc8-4572-4332-c93c-9c2c392a1fe7.png)

# 管理画面の起動

1.ブラウザを起動し、http://127.0.0.1:8888/ に接続します。

![004.png](https://qiita-image-store.s3.amazonaws.com/0/61606/321ba4c1-16d0-cbb7-439e-b1a72de018ee.png)

以上で Hortonworks Sandbox on VirtualBox は完了となります。
mac でも ps コマンドでプロセスのツリーを表示したい(--forest)


mac の `ps` コマンドには、-f (--forest) 無い。

```bash
% ps auxf
ps: illegal option -- f
usage: ps [-AaCcEefhjlMmrSTvwXx] [-O fmt | -o fmt] [-G gid[,gid...]]
          [-u]
          [-p pid[,pid...]] [-t tty[,tty...]] [-U user[,user...]]
       ps [-L]
```

代わりと言っちゃなんですが、`pstree` というのがあるらしい。

```bash
% brew install pstree
```

こんな感じで微妙に表示が違うけど、満足。

```bash
-+= 00001 root /sbin/launchd
 |--= 00045 root /usr/sbin/syslogd
 |--= 00046 root /usr/libexec/UserEventAgent (System)
 |--= 00048 root /usr/libexec/kextd
 |--= 00049 root /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/FSEvents.framework/Versions/A/Support/fseventsd
(以下略)
```

で、以下余談。
`pstree` の表示結果に `pstree` 自体を発見。

```bash
 |         \--- 40396 root ps -axwwo user,pid,ppid,pgid,command
```

内部的には、上記オプションで `ps` コマンドを実行してるみたい。
てことで、同じコマンドを試した結果が下記。

```bash
% ps -axwwo user,pid,ppid,pgid,command
USER              PID  PPID  PGID COMMAND
root                1     0     1 /sbin/launchd
root               45     1    45 /usr/sbin/syslogd
root               46     1    46 /usr/libexec/UserEventAgent (System)
root               48     1    48 /usr/libexec/kextd
root               49     1    49 /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/FSEvents.framework/Versions/A/Support/fseventsd
(以下略)
```

これらの情報を、うまいこと加工して表示してくれてるのね。