OmniAICreator/Qiita-1.07M huggingface dataset:
僕がピチピチJCの時に作ったガバガバdocker管理ソフトを晒す

```sh:docker-manger
#!/bin/bash

while true ; do
        echo -e "\n\n\n\n\n########################################イメージ（起動ディスク）一覧########################################"
        docker images
        echo -e "\n\n########################################コンテナ（仮想マシン）一覧########################################"
        docker ps -a
        echo -e "\n1 コンテナを起動する  2 コンテナを一時停止する  3 コンテナのシェルに接続  4 ファイルを送信・受信  5 ファイルを同期  6 コンテナの削除 0 終了"
        echo -e -n "\n番号を入力してください > "
        read -s -n1 char
        echo $char
        if [[ $char == 1 ]]; then

                echo -ne "\nコンテナID またはコンテナName を入力してください > "

                read char
                docker start $char

        elif [[ $char == 2 ]]; then

                echo -ne "\nコンテナID またはコンテナName を入力してください > "

                read char
                docker stop $char

        elif [[ $char == 3 ]]; then

                echo -ne "\nコンテナID またはコンテナName を入力してください > "

                read char
                echo -e "\n==exitと打つことでコンテナを起動したまま抜けられます。==\n\n"

#               docker exec -it $char /bin/bash
                docker attach $char

        elif [[ $char == 4 ]]; then
                char="";
                while [[ $char != 1 ]] && [[ $char != 2 ]] ; do
                        echo -ne "\n1 ホストマシン→仮想マシン  2 仮想マシン→ホストマシン > "
                        read -n1 char
                        if [[ $char != 1 ]] && [[ $char != 2 ]] ; then
                                echo -e "\n1または2を入力してください\n"
                        fi
                done

                echo -ne "\n\n送信または受信するコンテナID またはコンテナName を入力してください > "
                read cont

                echo -ne "\n\n送信するファイルの絶対パスを入力してください > "
                read fpath

                echo -ne "\n\n送信するファイルの絶対パスを入力してください > "
                read fpath

#               if [[ $char == 1 ]]; then
#                       docker cp
#               elif [[ $char == 2 ]]; then

#               else
#               fi
                #docker exec -it $char /bin/bash

        elif [[ $char == 0 ]]; then

                exit 0

        fi
        char=""
done
```


以上
iOSの審査に関するまとめ

iOSアプリの審査についてある程度知見がたまってきたので忘備録程度に残しておきます。

#SubmitからIn Reviewになるまでの期間

以前は審査開始までに**5~10日**程度かかりましたが2016年5月から平均審査時間が**48時間**に短縮すると正式に公表されました。実際に何本かリリースしてきましたが早い時は24時間以内に「In Review」→「Ready for Sale」まで審査が進むようになりました。とはいえ時期によっては１週間以上かかる場合もあるようなので審査の平均時間を調べられる「[Average App Store Review Times](http://appreviewtimes.com/)」を参考にしています。
2018年1月現在はiOS、Mac Appともに平均2日で審査されるようです。

[◼︎Average App Store Review Times](http://appreviewtimes.com/)

![スクリーンショット 2017-01-27 16.56.14.png](https://qiita-image-store.s3.amazonaws.com/0/89972/28eed10d-7a41-2f98-c1ca-e2446c9b8946.png)

#審査が行われる時間帯

アプリの審査は平日にアメリカで行われます。
日本とは約15時間程度時差があるため実際にレビューされる時間は日本時間で
**AM1:00~AM11:00**
の時間帯にレビューが帰ってくることが多いです。深夜に「In Review」状態になり朝起きて「Rejected」もしくは「Ready for Sale」になるイメージです。

#In Reviewが長い時の対処

審査してからその日に「In Review」になったもののそれから２週間以上放置されたことがありました。調べてみるとこれまでに同じことが起きている方が何人かいました。対策としてはAppleに直接催促することで解決できました。
単純に審査が長引いてる可能性があるので一週間程度はまった方が良さそうです。

**[催促手順]**
1. iTunes Connectにアクセス
2. 下部にある「連絡先」をクリック
3. お問い合わせ画面が開くので「App Review」「App Store Review」「Check Review Status」を順に選択して「contact us」をクリック（画像参照） 

![スクリーンショット 2017-01-27 17.32.11.png](https://qiita-image-store.s3.amazonaws.com/0/89972/4ad00198-0351-5391-a59c-66879d69f2cc.png)

5.「Apple ID of App」「App Name」「Date Last Binary Submitted」に情報を入力（画像参照）
6.「Describe your inquiry regarding the review status of your app or In-App Purchase」に催促文を入力

![スクリーンショット 2017-01-27 17.38.13.png](https://qiita-image-store.s3.amazonaws.com/0/89972/e92e2de2-0e03-7f60-bc7a-38855f8bfe7e.png)

催促文のテンプレートは以下です。

>Dear The iTunes Store team,

>It has taken over than ○ hours for “In Review”, does it be proceeded？
>And we would like to know the outcome earlier if possible.

>Regards,

[日本語訳]
>iTunes Storeチーム様 
>「In Review」の状態になってから○時間経っていますが経過はいかがでしょうか？
より早い結果を期待しています。

催促への返答は約一日程度で帰ってくると思います。

**[参考]**
・[Apple、App Storeをアップデートへ―審査を高速化、検索広告と開発者取り分85%プラン等を導入](http://jp.techcrunch.com/2016/06/09/20160608apple-to-introduce-search-ads-on-app-store-along-with-changes-to-app-review-discovery-and-splits/)
・[App Storeの審査でIn Reviewが長いまま1週間以上放置しておいた話](https://kanasys.com/tech/505)
・[In Review が長いときの催促方法｜iTunesConnectでAppleの審査期間が長くなった場合の問い合わせ](http://hnut.co.jp/blog/iphone/1221)
個人的フロントエンド開発環境2017

2017年版、オレオレフロントエンド開発環境です。


## 前提条件
* ここでいうフロントエンド開発とは、ペライチ、もしくは数ページから数十ページのWebサイトのこと
* サーバサイドとやりとりなどはあまりなく、ランディングページやキャンペーンサイト、コーポレートサイトをよく実装する


## 構成
まず、ざっくりと構成です。

* HTMLはEJSで書いてコンパイル
* CSSはSass(SCSS記法)で書いてコンパイル
	* MixinライブラリはBourbon
* JSはES2015で書いてBabelでコンパイル
	* Browserifyでバンドルする
* タスクランナーはGulp
* パッケージマネージャはnpm


## 省略記法に疲れた
つい最近まで、HTMLはPug(Jade)で、CSSはStylusで書いてました。省略記法で書ける楽でのええわ〜、省略記法で書いてる俺カッコいい！と思ってましたが、なんだかだんだん疲れてきた。

JadeとStylusがAtomで書きにくい(コピペなどでインデントがずれて修正が面倒)、JadeだとEmmetが使えない、JSだけ省略記法じゃないのが気持ち悪い、などの理由で、できるだけ省略しない書き方に戻していこうというコンセプトの構成です。

EJSはだいたいHTMLみたいなもんだし、Sass(SCSS)はデファクトスタンダードみたいなもんだし、どちらも学習コストが低いです。他の人と一緒に開発する時でも、教えることが少なくなるのはいいなと思います。

EJSじゃなくてHTMLで良くない？という感じですが、コンポーネント化や、JSONを読み込んで下層ページを大量に生成したりもするので、静的サイトジェネレータ的にも使えるEJSで。


## JSのライブラリは別ファイルにする
Browserifyでなんでもかんでもimportしてバンドルせず、ライブラリは別の`lib.js`というファイルにまとめてしまった方がいいなと最近考えるようになりました。

というのも、Browserify/Webpack readyではないJSのライブラリも沢山あり、例えばbrowserify-shimを使ってimportしようとし、うまくいかずに疲れる…というのは悲しいし、それなら普通にconcatしようぜ、というアプローチです。
（ライブラリをグローバルに出しても特に問題ない要件なので）

GulpでJSのライブラリをライセンスを残したままconcatし、BrowserifyでバンドルしたJSの直前で読み込みます。ライブラリのオブジェクトはグローバルに生成されるので、他のJSでimportせずとも利用可能になります。


## CSSの書き方
以前はCSSの設計に凝っていたときもあったんですが、最近は分かりやすくてクラス名が重複しなければなんでもいいなと思って書いています。BEMをアレンジしたような、よく分からないルールで書くことが多いかも。


## Gulp + gulp-sass + node-bourbonのタスクの書き方
gulp-sassでBourbonを使うには、node-bourbonというパッケージをimportし、以下のようにすると使えます。あと、エラーが出てもタスクが止まらないようにするgulp-plumberの書き方です。

[\[Gulp\] run\-sequenceでgulp\-eslintを実行した時にエラーでもタスクを続行する方法](http://qiita.com/ryo_dg/items/d649c58bc69f928fa5e2)

```js:gulp/tasks/sass.js
import gulp from 'gulp';
import filePath from '../filePath';
import sass from 'gulp-sass';
import autoprefixer from 'gulp-autoprefixer';
import plumber from 'gulp-plumber';
import sourcemaps from 'gulp-sourcemaps';
import bourbon from 'node-bourbon';

gulp.task('sass', () => {
  return gulp
    .src([
      filePath.source.stylesheets + '**/*.{scss,sass}',
      '!' + filePath.source.stylesheets + '**/_*.{scss,sass}'
    ])
    .pipe(plumber({
      errorHandler(err) {
        console.log(err.message);
        this.emit('end');
      }
    }))
    .pipe(sass({
      outputStyle: 'expanded',
      includePaths: bourbon.includePaths
    }))
    .pipe(autoprefixer({
      browsers: ['last 2 versions']
    }))
    .pipe(gulp.dest(filePath.build.stylesheets));
});
```

## まとめ
Webpackが流行ってるし、今年こそはWebpackで…と思ったりしましたが、僕の作るサイトだとBrowserifyでなんら問題はありませんでした。

Vue.jsでSPAを作る時に、ビルド時に静的サイトを吐き出してくれる [prerender-spa-plugin](https://github.com/chrisvfritz/prerender-spa-plugin)というパッケージがWebpackのみで動くらしく、これを一度使ってみたいので、今年はいよいよWebpackデビューか…と思ってます。

要件や好みなどによってもろもろ開発環境は変わってきますし、あくまで一例ということで。


## 追記 2017/01/29
### JadeでもEmmetが使えるらしい
マジかよ…。情報ありがとうございます。
でもやっぱりコピペでインデントがずれるし(Atom)、EJSの方がいいかなぁと思ってます。

### テストはしないのか
大規模なWebサービスなら、目視確認の前にプログラムが動作確認してくれるというのはありがたいと思うんですが、↓の前提条件のようなサイトなら目視確認で十分で、テストって必要ありませんよね…？

テストが必要な文化圏にいませんので、正直よく分かってません。すみません。今年の課題だなぁ。

### PostCSSじゃないのか
CSSは、ネストやルートのセレクタを選択できたり、Mixinが使えれば別に困らないので、別にSassでいいよなぁという気持ちです。

数年後に「Sassはオワコン」とか言われていたら乗り換えます。

### 脱Gulpをしないのか
Gulpをやめるメリットをあまり感じられないので。

Gulpはなんだかんだ便利だし、gulpfileさえ作ってしまえば、各種コンパイルやブラウザの自動リロード、画像のSprite化などを数文字のコマンドで実行できるのはやはり魅力的です。

追記終わり。
mosesのインストール

Mosesのインストール　=> [Moses](http://www.statmt.org/moses/?n=Development.GetStarted)

OS：Ubuntu

`sudo apt-get install build-essential git-core pkg-config automake libtool wget zlib1g-dev python-dev libbz2-dev`

`sudo apt-get install libsoap-lite-perl`

`git clone https://github.com/moses-smt/mosesdecoder.git `

`cd mosesdecoder`

`make -f contrib/Makefiles/install-dependencies.gmake`

`./compile.sh`
GPSデータをUTM変換してポイント間の距離を計算する

#gDistance
以下のようなデータを使う。

![image](https://qiita-image-store.s3.amazonaws.com/0/153729/8de836b8-d079-3a60-2ef3-75dbbb9092b9.png)

UTM 座標に変換した後、rgeos パッケージの gDistance 関数で計算する。

```R:gDistance
library(rgeos)
library(sp)

# ファイルの読み込み
d<-read.csv(適切な csv ファイル)
# GPSデータ（緯度経度形式）をまず sp 形式にする
d_longlat<-SpatialPoints(d[,c("longitude","latitude")],proj4string = CRS("+proj=longlat +ellps=WGS84"))
# UTM に変換
d_utm<-spTransform(d_longlat,CRS("+proj=utm +north +zone=52 +ellps=WGS84"))

# id 列を GPS データにひもづけ
idd_sp<-data.frame(d$id)
coordinates(idd_sp)<-d_utm@coords

# ポイント間の距離を計算する
distance<-gDistance(idd_sp,byid=TRUE)

# データフレームに変換・行と列に名前をつける・csv ファイルに書き出し
distance<-data.frame(distance)
colnames(distance)<-d$id
rownames(distance)<-d$id
write.csv(distance,"distance.csv")
```

計算結果は以下のような matrix で出力される。
![image](https://qiita-image-store.s3.amazonaws.com/0/153729/1c605aec-8068-8d7b-5bd5-271f66bf7541.png)

#gWithinDistance
値に興味がない場合は、2 つのポイントがある距離より離れているかどうかということのみ判定することもできる。
gDistance のかわりに gWithinDistance を使う。

```R:gWithinDistance
# ポイント間の距離が dist (m) 以内かどうかを判定する
# 下の場合は 200 m
wdistance<-gWithinDistance(idd_sp,dist=200,byid=TRUE)
```

計算結果は以下のような matrix で出力される。
![image](https://qiita-image-store.s3.amazonaws.com/0/153729/7a693889-f207-9cbb-0694-ca36357ba2c8.png)

欲しい情報をここからどのように抽出していくかはあとで考える。

#参考にしたページ
rgeos
https://cran.r-project.org/web/packages/rgeos/rgeos.pdf
Outgoing WebHooksとFunction Appの連携をした話

##やったこと
SlackのOutgoing WebhooksをAzureのFunction Appを使って実現しようと試みて失敗(?)した．
###参考にしたサイト様
http://blog.xin9le.net/entry/2016/04/01/042452
http://qiita.com/chike0905/items/58222a99be460f325ab8


##Azureでの操作
- Function Appを作成する．
- 新しい関数からテンプレートの選択を開き，GenericWebHook-CSharpを選択する．


![quii01.PNG](https://qiita-image-store.s3.amazonaws.com/0/161850/e7de15e5-aa20-a326-6987-c4bce3319741.png)


- 関数名を適当に決めて，作成ボタンを押す．
- 自動でテンプレートが生成される．


![quii02.PNG](https://qiita-image-store.s3.amazonaws.com/0/161850/3d4bab66-8305-5990-96ab-b8b7ff5fb19d.png)


- 適当に書き換える．(今回はbotを起動させたユーザー名を答えるようにした)


```csharp:run.csx
    string jsonContent = await req.Content.ReadAsStringAsync();
    dynamic data = JsonConvert.DeserializeObject(jsonContent);

    return req.CreateResponse(HttpStatusCode.OK, new {
        text = $"Hello {data.user_name}!"
    });
```

- ログに Compilation succeeded. と出たらエラーなくコンパイルに成功したことになる．
- コードを書いているエディタの上に関数のURLがあるのでそれをコピーしておく．
- 左の関数リストにある「統合」をクリックし，HTTP trigger(req)のモードをStandardに変更する．(なぜかWebHookだと動かない)


![quii03.PNG](https://qiita-image-store.s3.amazonaws.com/0/161850/6206e755-58cd-bfb3-9217-3a65607a8509.png)

##Slackでの操作
Outgoing WebHooksの詳しい使い方はURLを参考にしてほしい．
http://qiita.com/chike0905/items/58222a99be460f325ab8

先ほどコピーした関数のURLを画像のURL(s)へペーストする．
![quii04.PNG](https://qiita-image-store.s3.amazonaws.com/0/161850/a18fadc8-f92d-cb2c-c2b3-f7f12b5495fe.png)

##いざ運用
Slackでbotを起動させる言葉をポストしてみる．

.
.
.

動かない．

##なんで？
Function Appのログを見てみると，

Exception while executing function: Functions.(関数の名前). Newtonsoft.Json: Error parsing boolean value. Path '', line 1, position 1.

と出力されている．
つまり，Jsonをパースするときにエラーが起こってプログラムが止まったらしい．

そこでデバッグでJsonの内容をログに出力してみた．
するとSlackからのデータ形式が，

![quii05.PNG](https://qiita-image-store.s3.amazonaws.com/0/161850/16420491-bc33-3f12-283c-eb43d3cc3293.png)

このデータを&区切りにした形だった．(そらエラーも起こりますわ)

##まとめ
SlackからWebHookが飛んでくるというものだったので，てっきりC#のNewtonsoft.jsonでデシリアライズできると思い込んで苦労した．
とりあえずの対応として

- Slackからの情報を使わないbotにする(つまり，デシリアライズしない)
- Slackからの情報を&でSplitして強引に運用する

としているが，正直かっこよくないので改善したい．
vagrant起動までの最短メモ

#VirtualBoxとVagrantをDL
OSに合ったVirtualBoxをダウンロードしてインストール
https://www.virtualbox.org/wiki/Downloads

OSに合ったVagrantをダウンロードしてインストール
https://www.vagrantup.com/downloads.html

#設定

boxファイルをDLする
```vagrant box add {VM名} {boxファイルダウンロードURL}```

ubuntu14.4
https://github.com/kraksoft/vagrant-box-ubuntu/releases/download/14.04/ubuntu-14.04-amd64.box
cent os
vagrant box add centos6-7 https://github.com/CommanderK5/packer-centos-template/releases/download/0.6.7/vagrant-centos-6.7.box
その他
http://www.vagrantbox.es/

DLされたか確認
```vagrant box list```

初期化
```vagrant init　[listで確認したOSのバージョン]```

#vagrant起動
```vagrant up```

ssh接続
```vagrant ssh```


起動完了

#エラーが出た場合

```
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'base' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Box file was not detected as metadata. Adding it directly...
==> default: Adding box 'base' (v0) for provider: virtualbox
    default: Downloading: base
An error occurred while downloading the remote file. The error
message, if any, is reproduced below. Please fix this error and try
again.

Couldn't open file /Users/***/vagrant/base
```

initが間違ってる可能性が高い。
一度消して再度入れ直す。
```rm Vagrantfile```
```vagrant init CentOS7```
```vagrant up```

#vagrantコマンド一覧
```
vagrant box add {VM名} {boxファイルダウンロードURL}	box追加
vagrant box list	利用可能box一覧確認
vagrant box remove {box名}	boxの削除
vagrant init	vagrant 初期化(Vagrantfileの作成)
vagrant up	vagrant 起動
vagrant ssh	vagrant ログイン
vagrant halt	vagrant 終了
vagrant reload	vagrant リロード(halt + up)
vagrant destroy	vagrant 破棄
```

#参考
http://qiita.com/Esfahan/items/41c4469f28f6011ab33b
https://inexio.jp/20150707-944/
http://qiita.com/croissant1028/items/1cd808dd8cc2b27044ef
matplotlib入門

gnuplotしか使ってこなかった自分がmatplotlibを使い始めたので覚書。
必要最低限の使い方をまとめる。

```py3
import numpy as np
import matplotlib.pyplot as plt
```

必要なモジュールのインポートが上のように行なわれているとして話を進める。

# データ点をプロットする

```py3
x = [1,2,3,4]
y = [5,6,7,8]
plt.plot(x, y, 'o-', label="my data") # plot ... w lp title "my data"
plt.xlabel("X")         # set xlabel "X"
plt.ylabel("Y")         # set ylabel "Y"
plt.legend(loc='best')  # set key
plt.show()
```

![image](https://qiita-image-store.s3.amazonaws.com/0/28792/37f136e5-fb4e-8507-2b45-52f02a10f8e8.png)

コメントに記載されているのは対応するgnuplotコマンド。

`plot()`の第３引数は、データの表示フォーマット。'o'が丸いマーカーを表し、'-'が線のタイプを表している。

`plt.legend`の引数として`loc='best'`を指定しておくと凡例の場所をよしなに選んでくれる。デフォルトでbestを選んでおけば良さそう。

## 複数のシリーズのプロット

```py3
x = [1,2,3,4]
y1 = [5,6,7,8]
y2 = [4,2,8,6]

plt.plot(x, y1, 'o-', label='y1')  # plot ....
plt.plot(x, y2, 'o-', label='y2')  # replot ...
plt.legend(loc='best')             # set key
plt.show()
```

![image](https://qiita-image-store.s3.amazonaws.com/0/28792/9900ff1c-a42f-29ef-1af3-cffee96f0234.png)

`plot`を複数回呼ぶとどんどんプロットが重ねられていく。`show()`を呼ぶ時に初めて描画される。

# 関数をプロットする

関数を与えてそのままプロットすることはできないので、データ点を自分で作る必要がある。
`np.arange`を使うのがイディオム。

```py3
x = np.arange(-3.0, 3.0, 0.01)
y = np.sin(x) * np.exp( -x)
plt.plot(x, y, '-')
plt.show()
```

![image](https://qiita-image-store.s3.amazonaws.com/0/28792/847228c1-9f43-b49d-2457-6f3e441929a1.png)

# ログスケールにする

```py3
x = np.arange( -3.0, 3.0, 0.01 )
y = np.exp(-x) * np.cos(x)*np.cos(x)
plt.plot(x, y, '-')
plt.yscale('log')
plt.show()
```

![image](https://qiita-image-store.s3.amazonaws.com/0/28792/17e9ae0b-ad31-d22e-bde2-ae9e158b02a4.png)

linear scaleにしたい場合は例えば `plt.xscale('linear')` というように書く。

# ファイルからデータを読む

例えば以下のようなファイルがあるとして

```txt:test.dat
1 2 4
3 4 9
5 6 2
7 8 4
```

これをプロットするには

```py3
# "cols", "names", "delimiter" arguments are mandatory.
plt.plotfile('test.dat', cols=(0,1), names=('x','y'), delimiter=' ', marker='o', linestyle='--')
plt.show()
```

とする。`delimeter`, `names`, `cols`を省略すると上手くいかない。
特に`names`が無いと、最初の１行がヘッダ行だと解釈されてしまうので１行分のデータがなくなってしまう。

![image](https://qiita-image-store.s3.amazonaws.com/0/28792/17ac45cf-3fb1-0036-c3a0-c503ce6c70b5.png)

またはnumpyを使ってデータを読む

```py3
np.loadtxt("test.dat", comments='#', delimiter=' ')
plt.plot( dat[:,0]/1000, dat[:,1], 'o-' )
```

## 複数列の結果のプロット

```py3
names = ('x','y1','y2')
plt.plotfile('test.dat', cols=(0,1), names=names, delimiter=' ', label="y1")
plt.plotfile('test.dat', cols=(0,2), names=names, delimiter=' ', label="y2", newfig=False)
plt.legend(loc='best')
plt.show()
```

![image](https://qiita-image-store.s3.amazonaws.com/0/28792/e07e6481-3a7d-5e80-60c2-912657d4fad0.png)

または同様に`numpy#loadtxt`を使う

# ファイルに書き出す

```py3
plt.figure()     # bufferのクリア
x = [1,2,3,4]
y = [5,6,7,8]
plt.plot(x, y, 'o-', label="my data")
plt.xlabel("X")
plt.ylabel("Y")
plt.legend(loc='best')
plt.savefig('plot.png')
```

![image](https://qiita-image-store.s3.amazonaws.com/0/28792/88800553-95fe-7d1f-eaea-e929d59f76ae.png)

`savefig( filename )` メソッドを使う。ファイル名の拡張子に応じて適切にフォーマットを切り替えてくれる。便利！
EPSやPDFも書き出せる。
SparkでJSONからDatasetを作成する際にスキーマを設定する

SparkでDatasetを作成する際、JSONを読み込んでからモデル定義をcase classで指定すると、整数が標準でLongになっているといったことが原因で例外が発生することがある。

```scala
import org.apache.spark.sql.SparkSession

val ss = SparkSession.builder.getOrCreate
val rdd = sc.parallelize(Seq("""{"i":1}"""))

val ds = ss.read.json(rdd)
ds.schema
// => org.apache.spark.sql.types.StructType = StructType(StructField(i,LongType,true))

case class C(i: Int)
ds.as[C]
// => org.apache.spark.sql.AnalysisException: Cannot up cast `i` from bigint to int as it may truncate
//    The type path of the target object is:
//    - field (class: "scala.Int", name: "i")
//    - root class: "C"
//    You can either add an explicit cast to the input data or choose a higher precision type of the field in the target object;
//    at org.apache.spark.sql.catalyst.analysis.Analyzer$ResolveUpCast$.org$apache$spark$sql$catalyst$analysis$Analyzer$ResolveUpCast$$fail(Analyzer.scala:2016)
//    ...

case class D(i: Long)
ds.as[D]
// => org.apache.spark.sql.Dataset[D] = [i: bigint]
```

次のように予めスキーマを設定しておくと、最初からモデル定義に従ってJSONを読み込んでくれる。

```scala
case class C(i: Int)
val schema = ScalaReflection.schemaFor[C].dataType.asInstanceOf[StructType]

val ds = ss.read.schema(schema).json(rdd)
ds.schema
// => org.apache.spark.sql.types.StructType = StructType(StructField(i,IntegerType,false))

ds.as[C]
// => org.apache.spark.sql.Dataset[C] = [i: int]
```

モデル定義ごとにスキーマを作るのが面倒なら、次のようなメソッドを作っておくと便利。

```scala
def readJsonAs[Model <: Product : TypeTag](rdd: RDD[String])(implicit ss: SparkSession): Dataset[Model] = {
  val schema = ScalaReflection.schemaFor[Model].dataType.asInstanceOf[StructType]
  ss.read.schema(schema).json(rdd).as[Model]
}

val ds = readJsonAs[C](rdd)
```
DockerでFTPサーバーやSFTPサーバーをたてるのーと

* Docker 1.13.0
* FTP
    * https://github.com/stilliard/docker-pure-ftpd
* SFTP
    * https://github.com/atmoz/sftp

# 前提

開発環境としてFTPやSFTPが手元に欲しい。運用するわけではない。

# FTP

https://github.com/stilliard/docker-pure-ftpd

pure-ftpdを使うらしい。
READMEに書いてある通り。

## 起動

```
docker run -d --name ftpd_server -p 21:21 -p 30000-30009:30000-30009 -e "PUBLICHOST=localhost" stilliard/pure-ftpd:hardened
```

## ユーザー作成

1. `docker exec`で動いてるサーバーに入って
2. `pure-pw`でユーザー追加
3. パスワードが対話モードで聞かれるので入れる

こんな感じ。

```
% docker exec -it ftpd_server /bin/bash
root@df9198f8f9be:/# pure-pw useradd bob -f /etc/pure-ftpd/passwd/pureftpd.passwd -m -u ftpuser -d /home/ftpusers/bob
Password: 
Enter it again: 
root@df9198f8f9be:/# 
```

bobで接続するとFTPの `/` はコンテナ内の `/home/ftpusers/bob` になる。

## 接続

パッシブモードで。アクティブモードでは接続できない。
`ftp`でなら以下の通り。

```
ftp -p localhost
```

# SFTP

https://github.com/atmoz/sftp

READMEに書いてある通り。

## 起動およびユーザー作成

```
docker run -p 22:22 -d atmoz/sftp foo:pass:::upload
```

ユーザーが `foo` 、パスワードが `pass` で作成される。
fooで接続するとSFTPの `/` はコンテナ内の `/home/foo` になる。
書き込めるのは `/home/foo/upload` だけ。

SSHキー使うのとかはREADME参照。

## 接続

`sftp`でなら以下の通り。

```
sftp foo@localhost
```

sshは拒否される。

```
% ssh foo@localhost
foo@localhost's password: 
Could not chdir to home directory /home/foo: No such file or directory
This service allows sftp connections only.
Connection to localhost closed.
```
npm versionでCordova config.xmlのversionも更新する

#動機
- Cordovaのconfig.xmlのversionは手で書き換える必要がありめんどくさい＆更新をよく忘れる（でGoogle Playのアップロード時とかに怒られる）
- 一方package.jsonのversionはCLI(`npm version`)で更新できる上、major/minor/patchの指定で自動的に採番してくれたりgitのtagを作ってくれたりと便利

というわけで`npm version`で一緒にconfig.xmlも更新できたらいいなと思って調べてみました。

#調べたこと

##npm側

[scripts | npm Documentation](https://docs.npmjs.com/misc/scripts)
npmには様々なタイミングでpackage.jsonのscriptsに書かれたコマンドを実行する機能があります。
`npm version`ではpreversion, version, postversionが実行されるようになっているので、ここに何かしらを書けばできそうな気がします。

これらの実行タイミングについては以下の記事が参考になりました。
[npm version, preversion, postversionの使い分け](http://qiita.com/htanjo/items/d16d8531bc22e0a43217)

preversion → package.json更新 → version → コミット&タグ → postversionという流れのようなので、**更新されたバージョン番号を使って別のファイルを更新または生成し、package.jsonと一緒にコミットしたい**という場合は**version**に書くのが適当なようです。

##Cordova側

version更新のためにconfig.xmlをいじる必要があるのですが、そんなときに便利なのがconfig.xmlの値を取得したり設定したりといったことができるcordova-commonパッケージの`ConfigParser`。
プラグインのフック（インストール後にconfig.xmlに設定を加えたりとか）などで使われているようです。

`setVersion()`という見事に今回の需要にマッチしたメソッドもあるので今回はこれを使用することにします。

#やってみる

実行した環境は以下の通り

- node.js v6.5.0
- npm v3.10.7
- cordova v6.5.0

##必要なものをインストール

```bash
$ npm i -D cordova-common
```

##config.xml更新スクリプト
```js:scripts/update_config_xml_version.js
var path = require('path');
var ConfigParser = require('cordova-common').ConfigParser;
var configXml = new ConfigParser(path.resolve(__dirname, '../config.xml'));
var packageJson = require(path.resolve(__dirname, '../package.json'));

configXml.setVersion(packageJson.version);
configXml.write(); // 上書き保存。setVersionだけではファイルは更新されない
```
config.xmlやpackage.jsonへのパスは置き場所に応じて適宜調整してください。

##npm-scripts
```json:package.json
{
  "scripts": {
    "version": "node scripts/update_config_xml_version.js && git add config.xml"
  }
}
```
スクリプト中でGit管理対象のファイルの更新/追加が行われる場合は`git add`をお忘れなく。

##実行
```bash
$ npm version major
v1.0.0

> project@1.0.0 version /path/to/project
> node scripts/update_config_xml_version.js && git add config.xml

$ cat config.xml | sed '2!d'
<widget id="com.example.project" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
```

できた！
anacondaにおけるnumpyやscipyのインポートエラーについて

# 環境とエラーについて
##### 環境
windows 8.1 64bit
Anacoanda 4.2.0 Python3.5 version 64bit

##### エラーについて
インストール時のチェックマークははずさず、普通にインストール完了後、NumpyやScipyをインポートすると
[anacondaでnumpyやscipyのインポートに失敗してしまうバグについて](http://qiita.com/YoshikawaMasashi/items/a0f80c5aa3c37b0025d6)
と、同様に失敗してしまった。

上記記事を参考にsystem32のmkl_intel_thread.dllを削除してみたがエラーは直らず。
ダメもとで再起動や再インストールを試したが相変わらずインポートは失敗する。


# 原因
参考記事と同様に[Dependency Walker](http://www.dependencywalker.com/)を用いて
"Anaconda3\Lib\site-packages\numpy\core\multiarray.pyd"を開いて確認すると
"windows\system32\mkl_intel_thread.dll"だけではなく
"windows\system32\mkl_core.dll"もどうやらだめらしい。

# 解決策
参考記事によればmkl_intel_thread.dllは"Anaconda3\Library\bin"にあり、
探してみるとmkl_core.dllも同じ場所に存在した。

そこで
"windows\system32\mkl_intel_thread.dll"
"windows\system32\mkl_core.dll"
以上2つのファイルを

"Anaconda3\Library\bin\mkl_intel_thread.dll"
"Anaconda3\Library\bin\mkl_core.dll"

で上書きする。

# 結果
当環境ではNumpy, Scipy 共にインポートに成功した。


# 所感
Anacondaは初心者にとって環境構築には便利だけど、なにかエラーが発生したとき、参考になるような（自分のレベルで理解できる）情報が少なく感じる。


# 追記

今日(2017/01/28)matplotlibをインポートしてみたら
"windows\system32\mkl_avx.dll"か"windows\system32\mkl_def.dll"でエラーが発生したらしく失敗した。

"Anaconda3\Library\bin\mkl_avx.dll"と"Anaconda3\Library\bin\mkl_def.dll"
の2つのファイルでsystem32の上記の2つのファイルを上書きするか、system32の方の2つを削除すれば解決した。

同様のエラーでは、問題のあるファイルを"Anaconda\Library\bin"フォルダ中の同名のファイルで上書きするか、system32の同名のファイルを削除すれば、anacondaの方のファイルを参照するようになるので解決するようだ。
Android OS4.4.2でWebViewを使っている画面でクラッシュする原因


# 現象
4.4.2限定で、WebViewを使っている画面でクラッシュする時がある。


``` スタックトレース
java.lang.NullPointerException
 at XXXX.MainActivity$9.onPageFinished(MainActivity.java:100)
 at com.android.webview.chromium.WebViewContentsClientAdapter.onPageFinished(WebViewContentsClientAdapter.java:449)
 at com.android.org.chromium.android_webview.AwContentsClient$AwWebContentsObserver$1.run(AwContentsClient.java:73)
 at android.os.Handler.handleCallback(Handler.java:733)
 at android.os.Handler.dispatchMessage(Handler.java:95)
 at android.os.Looper.loop(Looper.java:136)
 at android.app.ActivityThread.main(ActivityThread.java:5017)
 at java.lang.reflect.Method.invokeNative(Native Method)
 at java.lang.reflect.Method.invoke(Method.java:515)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
 at dalvik.system.NativeStart.main(Native Method)
```

# 原因
## 条件
 - OS:4.4.2(WebViewのバージョンが関係している？)
 - onPageFinished内でWebViewを参照している
 - WebViewがある画面に遷移後、WebViewの処理が終わる前に再び画面遷移する(アクティビティを保持しない設定中だとやりやすい)

## どこが悪さしている
素早く画面遷移したことで、ActivityのonPageFinishが走るころにはWebViewが無いことが原因


## 解決法
ActivityのonDestory()時にmyWebView.setWebViewClient(null)する

# まとめ
 - ほぼ4.4.2だけに現れるクラッシュ
 - WebViewClientにnullを入れれば防げる

# リンク
https://github.com/btmura/rbb/issues/288
youtube埋め込み動画をレスポンシブ対応させる

# youtube埋め込み動画をレスポンシブ対応させる

案件で、youtube埋め込み動画をレスポンシブ対応させるというのをやったので、めも。

[github](https://github.com/takehiro-takahashi/youtube-responsive)にソースはアップしている。
また、github pagesで公開したので、実際にどうなるかも確認いただけます。[Github Pages](https://takehiro-takahashi.github.io/youtube-responsive/)

## Source

```css
.VideoWrapper {
    max-width: 500px;
    width: 100%;
    margin: 0 auto;
}

.video2,.video3 {
    position: relative;
    width: 100%;
    padding-top: 56.25%;
    overflow: hidden;
}

.video2 > iframe,.video3 > iframe {
    width: 100% !important;
    height: 100% !important;
    position: absolute;
    top: 0;
    left: 0;
}
```

### まず、サイズを100%表示しないものから。
---
VideoWrapperで、iframeをもつVideo2を囲います。
ここで、サイズを調整してください。
この時のサイズが動画のサイズになります。

iframeをもつVideo2は100%にしておき、iframeも100%にしておくとよいです。


### 100%表示
---
サイズ調整を行っているVideoWrapperを外せばOK

## 自分用のメモで説明が雑なので、わからないとこがあればコメントお願いします。
Slickで複数カラムのOrderByしたい

# SQL

```sql
select * from "hoge" order by "a_id", "b_id"
```
みたいなことしたかった。

# Slick

単一のカラムの時はこう

```scala
hoges.sortBy(_.aID.asc)
```

最初は二つ並べればいいかと思ったんですが、明らかにダサいので別の方法を探しました。

```scala
hoges.sortBy(_.aID.asc).sortBy(_.bID.asc)
```

で、実はOrderはタプルにするとまとめられるらしいです。

```scala
hoges.sortBy(x => (x.aID.asc, x.bID.asc))
```

参考： http://slick.lightbend.com/doc/3.1.0/sql-to-slick.html#order-by
hexoをcircleci経由でdeployする時に気をつけること


# TD;LR
自分自身のブランチにhexo deployしないようにする。
さもないと設定ファイルが消える
例)
topic -> master -> (hexo deploy) -> gh-pages(公開用ブランチ)
もしくは topic -> develop -> (hexo deploy) -> master(公開用ブランチ)

# 経緯
- 最近nodejs書く機会が増えたので、nodejs製のブログシステムhexoを使ってみた。
- ついでに、masterにpushしたらCircleCI経由でGithub Pagesに公開されるように設定(よくあるやつ)
- そうしたら、hexoのGithub Pagesにdeployするコマンドが予想外の動きだったのでメモする

# 詳細

Hexoの使い方は日本語の記事がいくつかあるのでそちらを参照

- [Hexo でブログをつくるまで · dev.shikakun.com](http://dev.shikakun.com/post/hexo-init/)
- [所要時間3分!? Github PagesとHEXOで爆速ブログ構築してみよう！ | 株式会社LIG](https://liginc.co.jp/web/programming/server/104594)
- [Hexoで始めるお手軽な静的ブログ　-インストールと配備- - Qiita](http://qiita.com/in_silico_/items/7e6ed639c24142bdbd04)


__config.ymlでmasterブランチに公開するように設定し

```__config.yml
# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
  type: git
  repo: git@github.com:kkanazaw/kkanazaw.github.io.git
  branch: master
  ## ignore exchange
  skip_render: README.md
```

masterにpushした時に、circleciでhexo deployを実行するようにしていたとする

```circle.yml
machine:
  timezone:
    Asia/Tokyo
  node:
    version: 6.3.1

deployment:
    production:
      branch: develop
      commands:
        - git config --global user.email "hoge@example.com"
        - git config --global user.name "Circle CI"
        - git submodule init
        - git submodule update
        - ./node_modules/.bin/hexo clean
        - ./node_modules/.bin/hexo generate
        - ./node_modules/.bin/hexo deploy
```

![image](https://qiita-image-store.s3.amazonaws.com/0/107603/350097bf-7a36-60dd-8669-7f72f8cf2b32.png)

この状態で、masterにpushすると、1度目は記事生成が行われる。
しかし、確認するとディレクトリ直下の設定ファイルがごっそり消える。(たぶん見えてもいいファイルだけ残すようになってるだと思う)

![image](https://qiita-image-store.s3.amazonaws.com/0/107603/ba63f707-017d-97c9-1a4e-6158657f3408.png)

circle.ymlも消えているので、2回目以降のビルドは当然失敗する。
しかも、git push -f origin masterしているようで、git履歴も書き換わってしまう。

# 対策
公開用のブランチと記事のマスターは分けるようにする。
自分の場合、master公開ブランチに設定していたので、developブランチを新設した。
また、公開ブランチはビルドされないようにした。

```
topic -> develop -> (circleciでhexo deploy) -> master(公開用ブランチ)
```

```circle.yml
general:
  branches:
    ignore:
      - master
machine:
  timezone:
    Asia/Tokyo
  node:
    version: 6.3.1

deployment:
    production:
      branch: develop
      commands:
        - git config --global user.email "hoge@example.com"
        - git config --global user.name "Circle CI"
        - git submodule init
        - git submodule update
        - ./node_modules/.bin/hexo clean
        - ./node_modules/.bin/hexo generate
        - ./node_modules/.bin/hexo deploy

```

記事作成手順はこうなる。
1. developからトピックブランチつくって、記事を書く
2. developにプルリクエストする。
3. developにマージすると、circleciが走りhexo generagte;hexo delopy
4. masterブランチに生成ファイルpushされる


# 終わりに
生成したhtmlファイルだけ追加でpushしてくれるかと思っていたから、理解するまで時間がかかった。問答無用でgit push -fはワイルドすぎる。 
(もしかしたら設定で挙動変更できるかも)
Amazon Linux と Ubuntu に pyenv を入れて Python 3.6.0 の環境を作る方法

```
# Amazon Linux
yum install gcc gcc-c++ make git openssl-devel bzip2-devel zlib-devel readline-devel sqlite-devel

# Ubuntu
# apt-get install git gcc make openssl libssl-dev libbz2-dev libreadline-dev libsqlite3-dev

git clone https://github.com/yyuu/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="${HOME}/.pyenv"' >> ~/.bashrc
echo 'if [ -d "${PYENV_ROOT}" ]; then' >> ~/.bashrc
echo 'export PATH=${PYENV_ROOT}/bin:$PATH' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
echo 'fi' >> ~/.bashrc
source ~/.bashrc
pyenv install --list|grep 3.6
pyenv install 3.6.0
pyenv global 3.6.0
python --version
pip --version
```
ILMergeのオプション(internalize他)

ILMergeを使ってDLLファイルを結合することがあったので、そのときに触ったオプションについて記載します。

### 基本ケース

B.dllとC.dllを結合してA.dllを作成します。

```
ilmerge /out:A.dll B.dll C.dll
```

### オプション

#### /target

library、exe、winexeが使えます。
特にtarget指定しなくても、以下のDLL同士の結合は問題なくできました。
何かdllからexeとかに変更するときに指定するのかもしれません。

```
ilmerge /target:library /out:A.dll B.dll C.dll
```

#### /internalize[:filename]

publicのものをinternalにします。

```
ilmerge /internalize /out:A.dll B.dll C.dll D.dll
```

とすると、CとDはinternalになります。

```
ilmerge /internalize:exclude.txt /out:A.dll B.dll C.dll D.dll
```

とした場合、exclude.txtにNamespaceまたclassを記載して、internalにしないものを指定します。
例として、exclude.txtにC.dllのNamespaceを指定した場合は、internalになるのはD.dllだけになります。


#### /ndebug

指定することで、pdbファイルを同梱しないように設定できます。
デバッグ用途でない場合は指定しておけばよさげです。

### オプションのリスト

```
Usage: ilmerge [/lib:directory]* [/log[:filename]] [/keyfile:filename [/delaysign]] [/internalize[:filename]] 
[/t[arget]:(library|exe|winexe)] [/closed] [/ndebug] [/ver:version] [/copyattrs [/allowMultiple] [/keepFirst]]
[/xmldocs] [/attr:filename] [/targetplatform:<version>[,<platformdir>] | /v1 | /v1.1 | /v2 | /v4] 
[/useFullPublicKeyForReferences] [/wildcards] [/zeroPeKind] [/allowDup:type]* [/union] [/align:n]
 /out:filename <primary assembly> [<other assemblies>...]
```

### 参考

* [ILMergeの使い方 - Qiita](http://qiita.com/mkit0031/items/5edde5926217a11aca85)
* [ILMergeを使ったInternal化における注意](https://www.infoq.com/jp/news/2010/08/ILMerge)
* [Internalizing Assemblies with ILMerge](http://www.blackwasp.co.uk/ILMergeInternalize.aspx)
PostgreSQL9.6 レプリケーション設定

#はじめに
仕事の現場でアプリ開発を一生懸命やっていたら
「PostgreSQLはちゃんとレプリケーション構成にしてあるよね？」
と言われ「え？何それ？」と思った人のためにPostgreSQLのレプリケーション設定手順まとめました。

#レプリケーションについて
レプリケーションについて、とても簡単に説明します。

###同期/非同期について
**同期**
マスタDBの更新とスレーブDBの更新の両方が終わって処理完了とします。
**非同期**
マスタDBの更新が終わったら処理完了とします。スレーブDBの更新結果を待ちません。

###スタンバイ/ホットスタンバイについて
**スタンバイ**
スレーブDBにアクセスできません。
**ホットスタンバイ**
スレーブDBに対して参照処理を行うことができます。更新処理はできません。

今回は非同期レプリケーションでホットスタンバイの構成を構築します。

PostgreSQLのインストールと初期設定は以下参照
[CentOS7にPostgreSQL9.6とJava8とNginx1.10をインストール](http://qiita.com/nyao/items/6c2fcf858456ce4c746e)

#マスタDB側の設定
postgresql.confの以下の設定を変更します。

```/var/lib/pgsql/9.6/data/postgresql.conf

#外部のホストからアクセスを許可
listen_addresses = '*'

#WALレコードがディスク上に書き込まれるまで待たない。
synchronous_commit = off

#同期スタンバイサーバなし
#synchronous_standby_names = ''

#WALに出力される情報を指定
wal_level = replica

#wal_senderプロセスの最大数
max_wal_senders = 3

# スタンバイ中も参照を可能にする(スレーブの設定)
hot_standby = on
```
hot_standbyはスレーブの設定ですが、pg_basebackupを実行するとマスタの設定がスレーブにコピーされるため、マスタ側で先に設定しておきます。マスタDBではhot_standbyの設定は無視されます。

PostgreSQLに接続してレプリケーション用のユーザーを作成
`psql -U postgres`
`CREATE ROLE replication_user LOGIN REPLICATION PASSWORD 'xxxxxxxxx';`


pg_hba.confにレプリケーションの設定を追加します。
(スレーブのIPアドレス(xxx.xxx.xxx.xxx)からのレプリケーションを許可)

```/var/lib/pgsql/9.6/data/pg_hba.conf
host    replication     replication_user        xxx.xxx.xxx.xxx/32           md5
```

PostgreSQLを再起動
`sudo systemctl restart postgresql-9.6`

#スレーブDB側の設定
PostgreSQLを停止
`sudo systemctl stop postgresql-9.6`

postgresユーザーになる
`sudo su - postgres`

既存のデータベースクラスタ（データ保存領域）を削除
`rm -rf /var/lib/pgsql/9.6/data/*`

マスタDBからベースバックアップを取得(xxx.xxx.xxx.xxxはマスタDBのIPアドレス)
`pg_basebackup -h xxx.xxx.xxx.xxx -D ${PGDATA} -R --progress -U replication_user`
${PGDATA} 配下(普通は/var/lib/pgsql/9.6/data)に自動でrecovery.confが作成されます。

スレーブからマスタへの昇格はトリガーファイルを使用したいため、以下の設定を追加

```recovery.conf
trigger_file = '/tmp/trigger_file'
```

PostgreSQLを起動
`sudo systemctl start postgresql-9.6`

#レプリケーション動作確認
マスタDB側で以下のSQLを実行
`SELECT * FROM pg_stat_replication;`
内容については以下のURLを参照
http://www.postgresql.jp/document/9.6/html/monitoring-stats.html#pg-stat-replication-view

後はマスタDBを更新してスレーブDBに反映されているか確認してみてください。


#マスタ切り替え
スレーブ側に設定で追加したトリガーファイル(/tmp/trigger_file)を作成します。
スレーブ側が更新できることを確認してください。

スレーブをマスタに昇格させたあと、元のマスタをスレーブにするためには、元のマスタ側のデータベースクラスタを削除し、スレーブDBに対してpg_basebackupコマンドを実行してください。

また、スレーブをスレーブとして再使用する場合は一旦マスタDBを最新データに更新し、スレーブ側でデータベースクラスタの削除とpg_basebackupコマンドを再実行してください。

#最後に
アプリ開発の片手間でインフラの作業もよくやったほうではないでしょうか？
こんなに頑張っているのに、お小遣いは月1万円しかもらっていません！！
WordPress カスタムフィールドはSmart Custom Fieldsもおすすめ

#Smart Custom Fields
もともと、記事を投稿する人がカスタムフィールドのグループごと複製できたらいいなと導入しました。
Advanced Custom Fields　は有料アドオン対応していますが、こちらは無料でできます！

## 解決
Swift3+Playground でUITableViewController を表示する

「<a href="https://realm.io/jp/news/tryswift-chris-eidhof-table-view-controllers-swift/">SwiftらしいTable View Controller</a>」のコードが動かなかったので...

```bash:Swiftのバージョン
$ swift --version
Apple Swift version 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1)
Target: x86_64-apple-macosx10.9
```


<img alt="swift-playground-uitable-vc.png" src="https://qiita-image-store.s3.amazonaws.com/0/2883/b26e0945-f1d9-4ae9-aad2-f2896857cf1f.png">


```swift
import UIKit

struct Person{
    let name : String
}
let people = [
    Person(name:"たもり"),
    Person(name:"さんま"),
    Person(name:"たけし"),
]

final class MyTableViewController: UITableViewController {
    let items :[Person]
    init(items :[Person], style: UITableViewStyle) {
        self.items=items
        super.init(style:style)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell=UITableViewCell(style:.default,reuseIdentifier:nil)
        let item=items[indexPath.row]
        cell.textLabel?.text=item.name
        return cell
    }
}

let tableVC = MyTableViewController(items:people,style:.plain)

import PlaygroundSupport

PlaygroundPage.current.liveView = tableVC
PlaygroundPage.current.needsIndefiniteExecution = true
```

## ポイント

1. PG用の使用モジュールが変更。
    - 旧＞`import XCPlayground`
    - 新＞`import PlaygroundSupport`
2. overrideメソッド名が変更。
    - 旧＞`cellForRowAtIndexPath`
    - 新＞`cellForRowAt`
3. 定数値が小文字に変更。
    - 旧＞`.Plain`、`.Default`
    - 新＞`.plain`、`.default`
Dockerコンテナ内にsudoユーザを追加する

### 事の起こり

[re:dashセットアップ手順](http://qiita.com/ninneko/items/5dc1341e3d23db84f8df)
上記を見て、re:dashをdockerで動かしてみようかと手を動かした時に、
sudoユーザでインストールするようなプログラムだけど、
今まではdockerはrootでやっていたので、
いい機会なのでsudoユーザ作成についてまとめました。

### ゴール

+ 追加するsudoユーザ情報

ユーザ名 | ユーザが所属するグループ | ユーザのpassword
:-:|:-:|:-:
iganari | developer | hogehoge


### Dockerfile

+ ubuntu:16.04で構築しますが、他のOSでも基本的にいけると思います。
	+ 中身

```text:Dockerfile
FROM ubuntu:16.04
MAINTAINER iganari <iganari@qiita.com>

# apt update
RUN apt-get update
RUN apt-get install -y sudo

# add sudo user
RUN groupadd -g 1000 developer && \
    useradd  -g      developer -G sudo -m -s /bin/bash iganari && \
    echo 'iganari:hogehoge' | chpasswd

RUN echo 'Defaults visiblepw'             >> /etc/sudoers
RUN echo 'iganari ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

USER iganari
```


+ 実行コマンド

```text:cmd
# docker build --no-cache .
# docker tag $(docker images -q | head -1) sudo-test
# docker run --rm -it sudo-test /bin/bash

================
コンテナ内でsudo有りと無しで確認してみる

### sudo無し
iganari@4b6360fbafce:/$ apt-get update
W: chmod 0700 of directory /var/lib/apt/lists/partial failed - SetupAPTPartialDirectory (1: Operation not permitted)
E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)
E: Unable to lock directory /var/lib/apt/lists/
E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?


### sudo有り
iganari@4b6360fbafce:/$ sudo apt-get update
Hit:1 http://archive.ubuntu.com/ubuntu xenial InRelease
Hit:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease
Hit:3 http://archive.ubuntu.com/ubuntu xenial-security InRelease
Reading package lists... Done
```

以上で、sudoユーザが出来ました。

### ソース

Gistにも載せておきます。

+ Gist
    + [Dockerfile-sudo-test ](https://gist.github.com/iganari/621ecb2cf93e700bac5eb21a802636d8)

### 補足

ハマったポイントとしては
`echo 'Defaults visiblepw' >> /etc/sudoers`
これが見慣れなくてすこし調べました。

ちなみに、当初の目的であるredashを入れるところは別途構築中です…


### 参考
[dockerでsudoできるユーザを追加するdockerfile](http://qiita.com/kakkyz81/items/9ae90c4d28490dc09d6d)
[ssh で sudo 実行](http://fishrimper.blogspot.jp/2012/09/ssh-sudo.html)
[Jenkinsでsudo実行時のエラー](http://qiita.com/gozuqi/items/6ebb2e6a4d49dfeb080f)
rundeck2.6.xから2.7にアップグレードしたらログインできなくなった

# Upgrade Guideを読もう
http://rundeck.org/docs/upgrading/index.html

ログイン認証のためのクラス名が変わっているそうな。
`/etc/rundeck/jaas-loginmodule.conf`の中の`org.eclipse.jetty.plus.jaas.spi.PropertyFileLoginModule`を`org.eclipse.jetty.jaas.spi.PropertyFileLoginModule`に変更しよう。
lambda の Context オブジェクトのプロパティ

# 出典
[ここ](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/nodejs-prog-model-context.html)を単に表にしただけ（みづらかったので）

# Context オブジェクトのプロパティ (Node.js)

context オブジェクトは、更新が可能な次のプロパティを提供します。

|name|description|
|:--|:--|
|callbackWaitsForEmptyEventLoop|デフォルト値は True です。このプロパティはコールバックメソッドのデフォルト動作を変更する場合にのみ使用できます。デフォルトでは、コールバックは Node.js ランタイムのイベントループが空になるまで待機してから処理を停止し、呼び出し元に結果を返します。このプロパティを false に設定して、イベントループにイベントがある場合でも、callback が呼び出されたすぐ後に処理を停止するように AWS Lambda にリクエストできます。AWS Lambda は、Node.js イベントループ内の処理、任意の状態のデータおよびイベントを停止します (イベントループに残っているイベントは、Lambda 関数が次に呼び出され、AWS Lambda が停止された処理を使用することを選択したときに処理されます)。コールバックの詳細については、「コールバックパラメーターを使用する」を参照してください。

また、context オブジェクトはランタイム情報を取得するために使用できる次のプロパティを提供します。

## 関数自体について

|name|description|
|:--|:--|
|functionName|実行中の Lambda 関数の名前。|
|functionVersion|実行中の Lambda 関数のバージョン。エイリアスを使用して関数を呼び出した場合、function_version はエイリアスが指すバージョンになります。|
|invokedFunctionArn|この関数の呼び出しに使用された ARN。関数 ARN またはエイリアス ARN を指定できます。非修飾 ARN は $LATEST バージョンを実行し、エイリアスはそれが指定する関数のバージョンを実行します。|
|memoryLimitInMB|Lambda 関数に対して設定したメモリ制限 (MB 単位)。Lambda 関数の作成時にメモリ制限を設定します。後で変更できます。|
|awsRequestId|リクエストに関連付けられた AWS リクエスト ID。invoke メソッドを呼び出したクライアントに返される ID です。AWS Lambda が呼び出しを再試行する場合 (たとえば、Amazon Kinesis レコードを処理する Lambda 関数が例外をスローする状況)、リクエスト ID は同じままです。|

## ログについて

|name|description|
|:--|:--|
|logGroupName|Lambda 関数によって書き込まれたログがある CloudWatch ロググループの名前。|
|logStreamName|Lambda 関数によって書き込まれたログがある CloudWatch ロググループの名前。ログストリームは、Lambda 関数の呼び出しごとに変わる場合と、そうでない場合があります。Lambda 関数がログストリームを作成できない場合、この値は Null になります。これは、Lambda 関数に必要なアクセス権限を付与する実行ロールに、CloudWatch アクションのアクセス権限が含まれていない場合に発生することがあります。|

## 認証について

|name|description|
|:--|:--|
|identity|AWS Mobile SDK を通じて呼び出された場合の、Amazon Cognito ID プロバイダーについての情報。null とすることができます。
|identity.cognitoIdentityId|特定のモバイルプラットフォーム向けの正確な値については、AWS Mobile SDK for iOS Developer GuideのIdentity Context、およびAWS Mobile SDK for Android Developer GuideのIdentity Contextを参照してください。|
|identity.cognitoIdentityPoolId|同上|
|clientContext|AWS Mobile SDK を通じて呼び出されたクライアントアプリケーションとデバイスに関する情報。null とすることができます。
|clientContext.client.installation_id|clientContext を使用して、入手できます。
|clientContext.client.app_title|同上
|clientContext.client.app_version_name|同上
|clientContext.client.app_version_code|同上
|clientContext.client.app_package_name|同上
|clientContext.Custom|同上
|clientContext.env.platform_version|モバイルクライアントアプリケーションで設定されたカスタム値。
|clientContext.env.platform|同上
|clientContext.env.make|同上
|clientContext.env.model|同上
|clientContext.env.locale|同上
ターミナル上でGitHubに登録しているIssueを選択してブランチを切れるようにする

僕はIssueに対応させて、`feature/{issue番号}`でブランチを切るという作業をしているのですが、これの少し面倒なところが

* 一々GitHubにIssue番号を確認しに行かないといけない
* Issue番号を何らかの形で記憶しておかないといけない

というものですね。
これを解決しようと便利なコマンドを作りました。

![https://i.gyazo.com/0b00660ddc57a673fc76ab853084a6da.gif](https://i.gyazo.com/0b00660ddc57a673fc76ab853084a6da.gif)

コマンドを実行すると現在いるリポジトリのIssueがリスト表示され、その中から一つ選択すると`feature/{選択したissueの番号}`でブランチが切れます。

# 導入方法

事前に[HomeBrew](http://brew.sh/index_ja.html)をインストールしておいて下さい。

以下のパッケージをインストールします。

```bash:install_brew_packages
$ brew install hub
$ brew install peco
```

その後、以下のスクリプトを作成しパスの通ったところに置きましょう。実行権限を与えるのもお忘れなく。

```bash:git-checkout-issue
#!/bin/bash

hub issue | peco | sed -e "s/\].*//" | xargs -Inum git checkout -b feature/num

exit 0
```

これで完了です。`$ git-checkout-issue`と叩くだけで、簡単にIssueに対応したブランチが切れるようになります。`.gitconfig`にエイリアスを書いておくのもいいかもしれませんね。
是非活用して快適なgitライフをお過ごし下さい！
dockerでRailsサーバとMySQLサーバを別々にしてみた

Railsアプリの開発環境としてdockerを使っていたが、データベースサーバもローカルにほしいと思い、docker内にサーバを立てつつデータも永続化できるようにした。

# MySQLサーバのコンテナを起動する

まず、MySQLサーバのdockerコンテナを起動する。ついでにデータも永続化できるようにローカルに保存するディレクトリを作ってMySQLのコンテナでマウントして起動する。

（他のPCではやらなくてもできたので、データのコピーは不要）
~~下記コマンドでローカルのフォルダをマウントして、コンテナにある初期データをローカルに持ってくる。~~
~~（なんか他にいい方法があるような気もするので誰か教えてください。）~~


~~$ docker run -p 3306:3306  -v [MySQLのデータを保存するフォルダ]:/var/lib/mysql --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.6~~
~~（初めての場合、MySQLの公式からイメージをダウンロードしてくれる）~~
~~（mysql:5.6でバージョン指定しているが、指定しなくても大丈夫）~~

~~MySQLサーバのデータフォルダ（初期データ）をローカルにコピーする。~~

~~$ docker exec some-mysql -it bash~~
~~（以下、コンテナ内）~~
~~$ cp -r /var/lib/mysql/* /var/lib/mysql2~~
~~$ exit~~

~~同名のコンテナは起動できないので、ここで出てきたコンテナIDやコンテナ名を使って一度削除する。~~

~~$ dokcer ps -a~~
~~$ CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS                    NAMES~~
~~c53fbf671a88        mysql:5.6           "docker-entrypoint..."   9 minutes ago       Up 9 minutes                0.0.0.0:3306->3306/tcp   mysql-vm~~
~~$ docker stop c53fbf671a88~~
~~$ docker rm c53fbf671a88~~

~~dockerのMySQLコンテナを起動しなおす。~~

~~$ docker run -p 3306:3306  -v [MySQLのデータを保存するフォルダ]/var/lib/mysql --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.6~~

SequelとかMySQL Workbenchなどで、MySQLコンテナにアクセスして、データベースを登録する。
ちなみに、アクセスするときはrootアカウントでパスワードはMySQLコンテナ起動時に-eオプションで設定したやつ。

```
$ CREATE DATABASE app_production;
```

# RailsサーバのコンテナからMySQLコンテナに接続するように設定

Ruby on Rails用のdockerのコンテナを起動する

```
$ docker run -it -p 3000:3000 --link some-mysql:mysql-serv myrails/server
```

--linkオプションでコンテナ同士の通信ができるようになる。ちなみに使い方は「--link [MySQLのコンテナ名]:[Railsコンテナ内でのホスト名]」。

（ここからRailsコンテナでの作業）
railsのconfig/database.ymlにurl属性を追加する。

```
$ vi config/database.yml
# default: $default
#   adapter: mysql2
#   url: mysql2://root:my-secret-pw@mysql-serv:3306 ← 追記する
```

追記部分の書式は以下の通り。

```
url: mysql2://[アカウント]:[パスワード]@[--linkで指定した：の後ろの名前]:3306
```

これで、dockerのMySQLコンテナとつながるので、Railsアプリ用のデータベースを生成したり、サーバを起動したりできます。

```
$ rails db:migrate　←　データベースを生成
$ rails db:seed　←　テストデータを登録
$ rails server -b 0.0.0.0　←　Railsサーバを起動
```
つくばFOSS4Gもくもく会・CS立体図勉強会

#つくばFOSS4Gもくもく会・CS立体図勉強会
中身は、これから書きます。

開催日時　1/30（月）16:00-20:00（開場13:00- ) 
会場　吾妻交流センター(茨城県つくば市吾妻1－10－1)
https://goo.gl/4qY9Zl
JSON 2.0.2 conflict で activate できないことがある(2017年1月)

# 追記(2017-01-30)

ZabbixAPIの3.0.0がリリースされて、conflictの問題は解消された。
https://github.com/express42/zabbixapi/releases/tag/v3.0.0


# 概要

```
04:19:05        [2017-01-27T04:19:05+09:00] ERROR: zabbix_source[extract_zabbix_database] (/tmp/kitchen/cache/cookbooks/zabbix/providers/database_my_sql.rb line 61) had an error: Gem::ConflictError: Unable to activate zabbixapi-0.6.6, because json-2.0.2 conflicts with json (>= 1.6.0, ~> 1.6)
```

ある日 Jenkins からエラー通知がきた。
５００日くらい毎日実行していた test kitchen のテストが失敗したとのこと。
Zabbix 環境を作るもので、あまり大きな変化がないと思っていて、
何事が起こったのかと思って調べた。

# 結論

エラーメッセージにあるように。
zabbixapiのactivate時にエラーになるようだ。


zabbixapiには、すでに修正のPRがあった

* [#64 updated to json 2.0 by atheiman · Pull Request #65 · express42/zabbixapi](https://github.com/express42/zabbixapi/pull/65)

## インストールできるが、activate できないとはなんなのか？


手動では問題がなくinstallはできた。

```
gem install zabbixapi -v 0.6.6
```

activate するときが問題なのだろうけど、よくわからなかった。

Major version が違うからかなぁとか想像してみたけど。。。

この辺りは別に調べる必要がありそうだ。

# 調べたこと

他の事例もあるのか調べた。

## 他の事例

以下の検索ワードで調べたら

* [gem json 2.0.2 conflict - Google 検索](https://www.google.co.jp/search?q=gem+json+2.0.2+conflict)

これがヒットした。

* [JSON Conflict error with manually including JSON gem · Issue #105 · contentful/contentful.rb](https://github.com/contentful/contentful.rb/issues/105)

ここを調べてたら最後にこっちからもリンクされていた

* [Unable to activate twitter-5.16.0, because json-2.0.1 conflicts with json (~> 1.8) · Issue #784 · sferik/twitter](https://github.com/sferik/twitter/issues/784)

## json gem

json 2.0.2 自体は随分前にでていたようだ

* [json | RubyGems.org | your community gem host](https://rubygems.org/gems/json/versions/2.0.2)

```
2.0.3 - January 12, 2017 (136 KB)
2.0.3 - January 12, 2017 java (85 KB)
2.0.2 - July 26, 2016 java (85 KB)
2.0.2 - July 26, 2016 (136 KB)
2.0.1 - July 1, 2016 java (51 KB)
2.0.1 - July 1, 2016 (135 KB)
2.0.0 - July 1, 2016 (135 KB)
2.0.0 - July 1, 2016 java (51 KB)
1.8.6 - January 13, 2017 (141 KB)
1.8.6 - January 13, 2017 java (87.5 KB) 
```

1系もメンテナンスはつづいてるのかな。
1.8.6が、January 13, 2017 にでている。
WordPress 画像挿入方法

#WordPressで画像挿入する方法の整理

## 目次
- wp_get_attachment_image
- get_the_post_thumbnail

## wp_get_attachment_image()
- カスタムフィールドの画像オブジェクトなどを取得する

(参考)
[WordPress Codex - wp_get_attachment_image()]
(https://wpdocs.osdn.jp/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%82%BF%E3%82%B0/wp_get_attachment_image)

## get_the_post_thumbnail()
- アイキャッチ画像を取得する

(参考)
[WordPress Codex - get_the_post_thumbnail()](http://wpdocs.osdn.jp/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%82%BF%E3%82%B0/get_the_post_thumbnail)
Oracle text

#ctxsysユーザを作る必要がある。
```sql
SQL> @?/ctx/admin/catctx.sql mypwd DATA TEMP NOLOCK
```
>ここで、CTXSYSはctxsysユーザーのパスワード、SYSAUXはctxsysのデフォルトの表領域、TEMPは>ctxsysの一時表領域で、LOCK|NOLOCKはctxsysユーザーのアカウントをロックするかどうかを指定し>ます。

```sql

--以下はdbユーザで実行
begin
ctx_ddl.create_preference('preference_m_sku','BASIC_LEXER');
end;
/



BEGIN
CTX_DDL.create_preference('CTXSYS.DEFAULT_WORDLIST', 'BASIC_WORDLIST');
END;

--以下はctxsysユーザで実行する。
update dr$parameter
set par_value = 'CTXSYS.EMPTY_STOPLIST'
where par_value = 'CTXSYS.DEFAULT_STOPLIST'; 

BEGIN
CTX_DDL.create_preference('CTXSYS.DEFAULT_LEXER', 'BASIC_LEXER');
END;

COMMIT;

--以下はdbユーザで実行
create index I_M_SKU_CONTEXT1 on M_SKU(SKU_CD)
indextype is ctxsys.context
parameters ('lexer COM2.PREFERENCE_M_SKU');
```
遺伝的アルゴリズムxニューラルネットワーク（NeuroEvolution）でOpen AI Gymの山登りをさせた話

どうも、オリィ研究所（http://orylab.com/） の ryo_grid こと神林です。

今回は前回、Open AI Gymの二足歩行ロボを歩かせたNEATという手法で、他の課題も解けるか試してみようということで、パワー不足の車が振り子の要領で勢いをつけて山を登る、という課題を解かせてみます。

#前回のお話
前回は遺伝的アルゴリズムとニューラルネットワークを組み合わせた手法であるNEAT(NeuroEvolution of Augmenting Topologies)を用いて二足歩行ロボを歩かせました。

[遺伝的アルゴリズムxニューラルネットワーク（NeuroEvolution）でOpen AI Gymの二足歩行ロボを歩かせた話](http://qiita.com/ryo_grid/items/af60750659d1d7ffeef9)

ただ、パラメータが多数あり、課題ごとにチューニングしないと性能が出ないのではないかという点に疑問が残りました。
そこで、今回は上述の課題を同じプログラムを用いて解いてみることを試みました。

#今回の課題
![155f296e28d7f439c5f73151b0ebb4a5.png](https://qiita-image-store.s3.amazonaws.com/0/12325/53ccb44c-16c9-0f8d-e1c1-04d5a5b55ea6.png)

上の画像のような勾配の坂道を、前進・後退のできる車が移動して最終的に右上の旗のあるところを目指します。
しかし、この課題はやっかいなことに、車はパワー不足でただ前進し続けるだけでは右の山を登れないという設定になっています。そこで、右左に振り子のように移動をしながら振幅を大きくして山を登りきるような動作をしなくてはなりません。

制御プログラムには観測情報(Observe)として2つの数値が渡されます。これは本来、知らずとも強化学習のAIなら解けるべき(でないと、汎用性が無くなる)なのですが、ちょっとズルをして、Open AI Gymのソースコードを調べてみたところ、車の速度と位置を返していることが分かりました。

https://github.com/openai/gym/blob/master/gym/envs/classic_control/mountain_car.py

利得(Award)はテストプログラムを動作して観察していると、山を登りきっていない間は-1、登りきったタイミングでプラス数百という値を返しているようでした。

# 解く
さて、どう解くかなのですが、通常は状況に応じて利得の値が変化して返ってくるものなのですが、この課題だと山を登りきらない限りずっと-1が返ってくるので、結果として登れていない限り利得の累積値に差が出ず、遺伝的アルゴリズムにおける各個体間の優劣を決めることができません。そこで、ズルをして、上記で調べて分かった観測情報のうちの車の位置をいわば利得として用いることにしました。

各種パラメータは課題固有の数値（ネットワークのチューニングとかではなく）以外は変更せずに動作させました。

# 結果
<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr"><a href="https://t.co/8ynYU0p7wj">pic.twitter.com/8ynYU0p7wj</a></p>&mdash; ホクソryo_grid@86世代 (@ryo_grid) <a href="https://twitter.com/ryo_grid/status/824848975039598593">2017年1月27日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

https://gym.openai.com/evaluations/eval_ysDnHwZBTiDPej4743wBQ
＃ ソースコードや動作のさせ方等も載せてあります

解けました。
前回は学習に一日とかかかっていましたが、この課題は一・二分で解けてしまいました。
課題によって必要な時間というのも全然違うものなのですね。
また、遺伝的アルゴリズムやニューラルネットワークのパラメータは変化させずに、利用することができたので、さほどパラメータセンシティブではないということも分かりました。

次回は、これまでのプログラムの中身についてもう少し詳しく解説したいと思います。
以上です。