OmniAICreator/Qiita-1.07M huggingface dataset:
個人的mastodonの出来事(技術編)

# 何の話か
結果的に中規模インスタンス(一応某リストで上位100以内にはいっているから現状間違ってないはず)を4台立てることになったので、その経緯とかそこで知ったこととか書きます。

# 得られた知見
総括として、

- 100-300人程度であればDBあたりはまだネックにならずメモリが真っ先に悲鳴をあげた(1GBしかない場合)
- 100人超えると何もいじってないt2.microだときつい
- 300人超えたくらいでもt2.smallでとりあえずスペック的には動く

ただし、金銭的な都合でRDSやElastiCache、複数EC2による冗長構成などをとっていないために、インスタンスサイズを変更する時など絶対にサービスが止まるので、そこは今回妥協しています。
また、CloudFrontやS3を使うこともできるのですがこちらも金銭的事情と今の所なんとかなっているので使ってないです。

環境としては

- mailにmailgun
- SSL証明書にLet's Encrypt
- サーバーはだいたいAWS
- 最低限のメトリクス監視はmackerel

です。

# mastodonをはじめたところ
4/12に多分Twitterでみかけてmastodonを始めた。現mstdn.jpインスタンスでアカウントを作りました。
しばらく楽しくやってたのですが、どんどん人が増えるのでコンセンプト的には分散させたほうがいいよなーという思いとか、mastodonで知り合った人にボドゲインスタンスほしいって言われたとか、この勢いなら人くるんじゃね？という企みとかそういうのがあって立てようかなと考え始めました。
結果、4/12は見送ったものの、4/13にmstdn.jpが不安定なこともあり分散する流れになるだろうと判断してそれなら急ごうとその夜から構築を開始することにしました。

# 1台目 tablegame.mstdn.cloud
どうせAWSとか使うと金銭的に維持できないと思い、家にあったサーバーを流用することに。
帰りにLANカードとバカHUBを買って帰宅。
マシン構成としては

- ubuntu 14.04 LTS
- CPU: Sempron 145
- RAM: 4GB

と非常に貧弱ながらも、ジャンルがニッチなのでこれで試そうと突っ込みました。
ちなみに、Dockerは使っておらず、理由としてはDockerにそこまで明るくないので死活監視とかDB周りをいじる必要が出た時にうまく弄れる自信がなかったためです。

構築で苦労したことは、LANとFletsのPPPoE直の物理インタフェース2本構成になったので、そのroutingとかiptablesわすれたとかその辺です。
また、設定を間違えたままresorceをbuildしたところ、アプリの設定など以外の動的に変わる部分(メインのタイムラインですね)が何も表示されない事態に陥り、そこで困ったりしました。
消してrebuildしたら治りましたが。
あとは、ubuntu 14.04なのでデフォルトのdaemon化する設定が使えず、現状nohupで動かしています。streamのnodeがよく落ちるのでそこだけpythonで監視して落ちてれば再起動するスクリプトをcronで回すという手荒い対応です。

結果として現在300人弱ですが、快適に動いています。

# 2台目 socialgame.mstdn.cloud
思ったよりうまく動いて、昼休みに先輩と喋っていた勢いで2台目を作りました。
こちらはジャンル的に人が集まる可能性もあったので、AWSを使って、でもまずは最小構成でということでt2.microにすべて載せる構成で作りました。

こちらはUbuntu 16.04なので公式ドキュメント通りに構築しました。(ただしこちらも非Dockerで)

ちゃんと動いたのは良かったものの、その日の夜にメモリを使いきりswapし始めた途端にアクセスさえ困難な状況に。
この時、sshで入れない状況だったのですが公式ドキュメント通りに作っていたのが功をなし、AWSコンソールから直接停止、インスタンスサイズアップで難を逃れました。

結果t2.small一台で現状300人超えたくらいですが、快適に動いています。

# 3台目, 4台目
2台目を参考に構築しました。4台目のR18可能なソシャゲインスタンス構築の話についてはできれば別の記事で書きます。

# 技術的タスク

- バージョンアップが早いのでバージョンアップをどう実施していくか。
- SSL証明書の更新やLet's Encryptについてもっと知る
- mailgunが一部制限かかっているのでそれの対応

# 最後に
タスク整理とかもあったので書いてみたんですが、これ、得られる情報ありますかね。。。
とりあえずお一人様や100人未満のインスタンスなら多分t2.microで動くと思うので無料枠でお試しとかするといいですよ、くらいかもしれないです。

# 追記 2017/04/20
次はストレージがネックになりました。
8GBだと、300人くらいのインスタンスだと5日くらいで死にました。
VMware Horizon 一定時間を経過するとセッションが切断される

#概要
Horizon 環境で Connection Server の接続に LoadBalancer を使用している場合、
一定時間を経過するとセッションが切断される場合があります。

#詳細
Horizon Client と Connection Server が下記グローバル設定の『ユーザーの強制切断』に設定された時間の、1/3の時間毎にヘルスチェックのためハートビート通信をおこないます。この際にHorizon Clientが初回接続時に接続した Connection Server とは別の Connection Server へハートビート通信を行った場合はセッションの切断処理が行われます。

『ユーザーの強制切断』を [なし] の設定とした場合も、6.6時間毎にハートビート通信をおこないます。
![image](https://qiita-image-store.s3.amazonaws.com/0/169431/feeeac5f-5420-b5a4-4270-1d0c4cbaa14d.png)


#対応策
LoadBalancer（②）側のセッション保持時間を『ユーザーの強制切断』で指定されている1/3以上の時間に設定する。
Horizon Administrator（①） で『ユーザの強制切断』を[なし] の設定とした場合も6.6時間以上の時間にセッション保持時間を設定する。




![image](https://qiita-image-store.s3.amazonaws.com/0/169431/3a6d0a5f-4ada-6a78-4b61-0736b98c603c.png)
Mastodon APIをcurlで試してみる

ハマったところはアクセストークンの取得で、何故かログインできない感じでアクセストークンの取得がうまく行かなかったのですが、原因は`curl -H "Content-Type: application/json"`としてJSON形式でポストしなかったことにあったみたいです。

```bash
# add application
MASTODON_HOST=mstdn.syui.cf
CLIENT_NAME=mstdn-client
if [ ! -f ./client_id.json ];then
	WEBSITE=https://example.com
	curl -X POST -d "client_name=$CLIENT_NAME&redirect_uris=${REDIRECT_URIS:-urn:ietf:wg:oauth:2.0:oob}&scopes=${SCOPES:-read write follow}&website=$WEBSITE" -sS https://${MASTODON_HOST}/api/v1/apps >> ./client_id.json
fi

# get access token
json=`cat ./client_id.json`
CLIENT_ID=`echo $json|jq -r '.client_id'`
CLIENT_SECRET=`echo $json|jq -r '.client_secret'`
YOUR_EMAIL=mail+mastodon@gmail.com
YOUR_PASSWORD=passwd
curl -H "Content-Type: application/json" -X POST -Ss https://$MASTODON_HOST/oauth/token -d "{\"client_id\": \"$CLIENT_ID\", \"client_secret\": \"$CLIENT_SECRET\", \"grant_type\": \"password\", \"username\": \"$YOUR_EMAIL\", \"password\": \"$YOUR_PASSWORD\", \"scope\": \"read write follow\"}"

# use api
if [ ! -f ./access_token.json ];then
	curl -H "Content-Type: application/json" -X POST -Ss https://$MASTODON_HOST/oauth/token -d "{\"client_id\": \"$CLIENT_ID\", \"client_secret\": \"$CLIENT_SECRET\", \"grant_type\": \"password\", \"username\": \"$YOUR_EMAIL\", \"password\": \"$YOUR_PASSWORD\", \"scope\": \"read write follow\"}" >> access_token.json
fi

ACCESS_TOKEN=`cat ./access_token.json|jq -r '.access_token'`
curl -H "Authorization: Bearer $ACCESS_TOKEN" -sS https://$MASTODON_HOST/api/v1/timelines/home
```

Testing the API with cURL / https://github.com/tootsuite/documentation/blob/master/Using-the-API/Testing-with-cURL.md

mastodon api docs / https://github.com/tootsuite/documentation/tree/master/Using-the-API

2FA OFF / https://github.com/tootsuite/documentation/issues/72
Rubyを使ってWeather Undergroundから10日間の時別気温予報データを取得する

# はじめに

機械学習を使って電力需要予測をするという記事を公開しているのですが、予測に気温のデータが必要であることから、どうしても使い勝手が悪い。

[機械学習で電力需要を予測してみる パート2](http://qiita.com/mix_dvd/items/1f96f5202614dbea93e0)

ということで、未来の気温データを取得する方法を探していたらWeahter UndergroundというサイトのAPIで10日間分の時別の気温予報データが取得できることがわかったので、そのやり方をまとめます。

[Weather Underground](https://www.wunderground.com)

ちなみに、以下のサイトを参考にさせて頂きました。

[Google Weather APIがサービス終了して天気予報難民に -> 帰ってきたうみったー](http://nefo.hatenablog.com/entry/20120831/1346370232)

# データを取得してCSV形式で保存

東京都のデータを取得する例を以下に示します。

```rb:wu.rb
require 'open-uri'
require 'json'
require 'date'

uri = URI.parse('http://api.wunderground.com/api/[your API key]/hourly10day/lang:JP/q/Japan/Tokyo.json')

json_string = uri.read('r:binary').encode("UTF-8", invalid: :replace, undef: :replace)
parsed_json = JSON.parse(json_string)

temps = "MONTH,WEEK,HOUR,TEMP\n"

parsed_json["hourly_forecast"].each do |val|
  
  y = val["FCTTIME"]["year"].to_i
  m = val["FCTTIME"]["mon"].to_i
  d = val["FCTTIME"]["mday"].to_i
  h = val["FCTTIME"]["hour"].to_i
  
  t = DateTime.new(y,m,d,h,0)
  
  w = t.wday
  temp = val["temp"]["metric"]
  
  temps += "#{m},#{w},#{h},#{temp}\n"
  
end

File.open("tokyo.csv", "w") do |f| 
  f.puts(temps)
end
```

tokyo.csvの中身は以下のようになっています。

```
MONTH,WEEK,HOUR,TEMP
4,2,6,19
4,2,7,21
4,2,8,21
4,2,9,22
4,2,10,23
4,2,11,23
4,2,12,23
4,2,13,24
...
```

# 取得したデータで電力需要を予測

上述した電力需要予測の記事で示しているコードに以下を追記します。

```py3:
# データ読込
filename = "tokyo.csv"
df = pd.read_csv(filename)

# 入力データの取得
X = df.as_matrix().astype('float')

# 正規化
X_pred = scaler.transform(X)

# 予測
result = model.predict(X_pred)

# データフレームに追加
df["KW"] = result

# グラフ描画
df.KW.plot(figsize=(15, 3))
```

![Unknown.png](https://qiita-image-store.s3.amazonaws.com/0/114240/e0feff8a-ac99-0cf3-6eae-ce5075214041.png)


...この予測結果が正解か否かは、これから電力会社さんが公開して下さる電力使用実績データと比較しないとわからないですけどね(^_^;)
[java.io] Java文字列入力のまとめ (InputStream, Reader, Scanner)

最近、授業で Java を書くことになりました。
File, InputStream, FileReader, Scanner の関係がよくわからなかったのでまとめます。

この記事では、Java SE 1.8 を前提としています。
ただし、この記事は java.nio ではなく、古い java.io についてのまとめです。

コード中には、例外処理が書かれていませんが、ファイルを開くときには FileNotFoundException を、ファイルを読み書きするときには IOException を受け取れるようにしておく（または、さらに上のメソッドに投げる）必要があります。

ページの下の方にまとめの図があります。

#####java.io のリファレンス
https://docs.oracle.com/javase/jp/8/docs/api/java/io/package-summary.html


# File, FileDescriptor
- java.io.File <br />
  パスの抽象表現（パスの単なる表現で開いたファイルを保持したりはしていない）

  ```java
  File file = new File("file.txt"); // ファイル名から作れる
  ```
- java.io.FileDescriptor:
  開いたファイルを表す。ハンドルとして機能。

# InputStream
バイトを読み込むためのクラス

- java.io.InputStream 抽象クラス
   - java.io.FileInputStream: ファイルから InputStream を構築するためのクラス
  - java.io.FilterInputStream: InputStream を保持するためのクラス
     - java.io.BufferedInputStream: InputStream をバッファして自身も InputStream として見せる。

```java
// System.in は InputStream のインスタンス
InputStream sytemin = System.in;

// ファイルからストリームを作る
InputStream fileStream = new FileInputStream("file.txt");
// ストリームをバッファする
InputStream bufferedStream = new BufferedInputStream(fileStream); 

bufferedStream.close();
```

# Reader
InputStream'Reader' のように名前の最後に 'Reader' とついているクラスは、文字列ストリームを読み込むためのクラスです。

- java.io.Reader 抽象クラス
   - java.io.InputStreamReader: InputStream => Reader への橋渡し。文字セットを指定できる
   - java.io.FileReader: 簡易クラス (File, FileDescriptor, fileName で Reader 構築。文字エンコーディングは指定できない。)
   - java.io.BufferedReader: Reader クラスをバッファ

```java
// ファイルからバイトストリームを作る
InputStream fileStream1 = new FileInputStream("file1.txt");
// バイトストリームから文字列ストリームを作る
Reader reader1 = new InputStreamReader(fileStream1);

// ファイルからバイトストリームを作る
InputStream fileStream2 = new FileInputStream("file2.txt");
// 文字列ストリームを作る。文字列エンコードの指定
Reader reader2 = new InputStreamReader(fileStream2, "utf-8");

// 簡易クラスを使って、ファイルから Reader を直接作る
Reader reader3 = new FileReader("file3.txt");

// リーダーをバッファする
BufferedReader bufferedReader3 = new BufferedReader(reader3);
// BufferedReader には、テキスト行を読み込む readLine() がある
String line = bufferedReader3.readLine();

reader1.close();
reader2.close();
bufferedReader3.close();
```

# java.util.Scanner
テキストから int, long, boolean などのプリミティブ型や文字列を取得するスキャナー。
File クラスや、InputStream クラスから構築できる。文字列エンコーディングも指定できる。
区切り文字のマッチングを正則表現で指定できる。
詳しくは、https://docs.oracle.com/javase/jp/8/docs/api/java/util/Scanner.html

```java
// System.in から数値を読み込み
Scanner sc1 = new Scanner(System.in);
int i = sc1.nextInt();

// File から構築
Scanner sc2 = new Scanner(new File("file.txt"));

// Scanner sc2 = new Scanner("file.txt")); とはできない。
// このようにした場合、"file.txt" という文字列を読もうとしてしまう。

// 区切りをコンマに変更
sc2.useDelimiter(",");

// 区切りごとに１行ずつ表示
while (sc2.hasNext())
{
    String str = sc2.next();
    System.out.println(str);
}

// sc1.close();
sc2.close();

```

# 利用の関係を表した図
![java.io4.png](https://qiita-image-store.s3.amazonaws.com/0/147332/dd545a08-83f4-1a89-99de-cad930d85c54.png)

# 命名の法則
|クラス名|分解|意味|
|:--|:--|:--|
|FileInputStream|File-InputStream|File を InputStream に変換する。|
|InputStreamReader|InputStream-Reader|InputStream を Reader に変換する。|
|FileReader|File-Reader|File を Reader に変換する。|
CSS3のflexboxを使ってフッターを固定

Webサイトのレイアウトを作成するにはmargin: 0 auto;したりとややこしかったのですが、flexboxであればbootstrapなどのCSSフレームワークしか使った事がない自分が簡単に画面下にフッターを固定出来ました。

caniuse.comによると現在のflexboxの対応状況は最新バージョンのすべてのブラウザが対応しています ![Screenshot from 2017-04-17 00-00-57.png](https://qiita-image-store.s3.amazonaws.com/0/69351/8f5211c1-bb93-9cd8-afc4-b7f0a092fe10.png)

#画面下にフッターを固定
最終的にこのようにフッターを画面下に固定します
![-home-takasi-%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97-flexbox.html.png](https://qiita-image-store.s3.amazonaws.com/0/69351/1cbebed0-7e46-d0e0-feb1-bc7c48696008.png)

Htmlはこのようになります、シンプルです

```
<body>
	<div id="container">
		テキスト
	</div>
	<footer>
			<a href="">Contact Form</a>
			<a href="">その他</a>
	</footer>
</body>
```
次はcssです。flexboxを使用する事をブラウザに伝えるためにbody部分に`display: flex;`と記述します。縦軸方向に`flex-direction: colum;`センター寄せ`align-items: center;`します。そしてビュポートの高さの最小サイズを100%`min-height: 100vh;` にしてcontainerを膨らませて`flex-grow: 1;`フッターを画面下に押しやります

```
body{
	display: flex;
	align-items: center;
	min-height: 100vh;
	flex-direction: column;
}
#container{
	flex-grow: 1;
}
```

フッターの中身のリンクを均等に配置したいのでflexboxを宣言`display: flex;`してから`justify-content: space-around;`で均等に配置します。`width:100%;`で横幅いっぱいに広げて完成です。

```
footer{
	display: flex;
	justify-content: space-around;
	width: 100%;
}
```

これでレイアウトは完成です。後は見栄えを良くして最終的に以下のソースコードになりました。

```
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style type="text/css">
<!--
body{
	margin: 0;
	background-color: #f5f8fa;
	display: flex;
	align-items: center;
	min-height: 100vh;
	flex-direction: column;
}
#container{
	background-color: #fff;
	min-width:320px;
	flex-grow: 1;
}
footer{
	background-color: #000;
	display: flex;
	justify-content: space-around;
	width: 100%;

}
footer a{
	color: #fff;
	padding: 10px;
	text-align: center;
}
-->
</style>

</head>
<body>
	<div id="container">
		テキスト
	</div>
	<footer>
			<a href="">Contact Form</a>
			<a href="">その他</a>
	</footer>
</body>
</html>
```

#最後に
flexboxを使ってサイトを作成したのでもしよろしれば見てください
似ているタレントを画像検索するサイトです
http://talent.oldjpg.com/
なぜ私のredisはこんなにも遅かったのか

# RedisってKVSやしチョー早いんやろ？
と、そう思っていた時期が私にもありました。
Redisを利用する上で、適切に利用しないと性能が1/10以下に陥ってしまいます。
この記事では、redisの性能を発揮する実装と発揮できない実装で性能測定を行いました。

# 結論
最初に結論

Redisの読み書きはmget/msetなどの複数のデータを一度に読み書きするコマンドを用いることで本来の性能が発揮できる。
逆に単純に```for```を用いてget/setなどのコマンドで１件単位でループを回すと大きな性能劣化が発生する。

# 環境

python3で計測します。

redisはdockerで動かしました。

```
$ docker run --name redis -d -p 6379:6379 redis:3.2.8
$ redis-cli
127.0.0.1:6379> ping

```
redis-cliは別途インストールしたけれど、記事内ではこの疎通確認にしか使いません。

# 計測する

10000件のデータを書き込んで測定してみます。
条件を揃える目的で、データを書き込む前にflushdb()によってrediｓをきれいな状態にして計測します。
また、pythonのtimeitモジュールで1回の実行速度についてをまとめています。

## loopで1件づつ書いてみる
``` bash
$ cat forloop.py 
import timeit
code = '''
import redis
r = redis.StrictRedis()
r.flushdb()
for i in range(10000):
	r.set(i, i)
'''
print(timeit.timeit(code,number=1))
$ python forloop.py 
5.071391730001778
```
10000回の書き込みで約５sec。
1回あたり0.5msecですが遅いとまでは、この時点ではあまり思っていなかった…

## 100件づつ100回
10000件の書き込みするために、「１００件づつ１００回」の書き込みにまとめてみます。
redisのコマンドで言うと、setがmsetになります。

```
$ cat chunk.py 
import timeit
code = '''
import redis
r = redis.StrictRedis()
r.flushdb()
for i in range(100):
    kv = {str(j):j for j in range(i*100,(i+1)*100)}
    r.mset(kv)
'''
print(timeit.timeit(code,number=1))
seiket-mba2011:sandbox seiket$ python chunk.py 
0.2815354660015146
```

１００００件書くのに約0.28sec
１件あたり0.028msec
１件づつ書き込みの**10倍以上**早い。
ココまで違いが出るのか！！

## 10000件１発で書き込む

せっかくなので、10000件を、一気に書き込む

```
$ cat all.py 
import timeit
code = '''
import redis
r = redis.StrictRedis()
r.flushdb()
kv = {str(j):j for j in range(10000)}
r.mset(kv)
'''
print(timeit.timeit(code,number=1))
seiket-mba2011:sandbox seiket$ python all.py 
0.22943834099714877
```
更に高速化してますね。

# 測定結果とまとめ

redisへの書き込み速度はまとめて書くと圧倒的に速度に違いが出る。
10000件の書き込みについて以下のように違いが出た。

| 書き込み方法   |    1万件の書き込み所要時間（sec）|
|:-----|------------------:|
|１件ずつ10000回|5.071|
|100件ずつ100回|0.281|
|10000件ずつ1回|0.229|

上の表を見て分かるように、まとめてredisへの書き込みを行うことによって**１0倍以上の性能向上**（あるいは、**１件ずつ書くことによって1/10以下の性能劣化**）が発生する。
どちらかと言うと、**性能劣化**のほうが適切だとは思う。

記事内では触れてないが読み込みでも同様の傾向があるのでまとめて読み込むほうが性能面で圧倒的によい。
特に速度目当てでredisを使う場合に1件ごとアクセスするのは致命的に遅い。

# gist

計測に使ったソースコードは記事内と同一ですが以下にもおいてます。
https://gist.github.com/seiketkm/3ca7deb28e8b0579a6e443cc7f8f9f65
`git rebase -i` 時にfirst commitも編集対象に含めたい場合は `--root` オプションを使う

作ったばかりのリポジトリで作業中、first commitに別のコミットの内容を含めようと思って `git rebase -i` したところ一番最初のコミットを対象にした作業ができなかったため、どうすればよいか調べました。

## 結論

`--root` オプションを付与すればOKです。

## 状況

```
* 0ee5342 - (HEAD -> master) third commit (83 seconds ago) <kyo>
* 18ce4ba - second commit (2 minutes ago) <kyo>
* 1268ce4 - first commit (3 minutes ago) <kyo>
```

上記のようにcommitが3つある状態で `third commit` を `first commit` にsquashさせようと思い `git rebase -i HEAD~3` したところ、以下のようなエラーが出たと言うものです。

```
fatal: Needed a single revision
invalid upstream HEAD~3
```

## 対応

調べたところ `rebase` する際に `--root` オプションを付けると first commitから全てのcommitを対象することができるとのことだったので `git rebase -i --root` としたところ、無事first commitも含めて `rebase -i` することができました。

## 余談

rebase時には既にgithubにpush済だったため、first commitをいじったことでログが以下のようにローカルとリモートで全く別のツリーになりました（画像はSourceTreeによるもの）。普段中々見ることのない状況だったので非常に面白い体験でした。

<img width="720" alt="git-rebase-root.png" src="https://qiita-image-store.s3.amazonaws.com/0/18007/7833f0ee-a7af-4a3a-3471-13767f4bf8ed.png">



# 参考

- [First commit が git rebase -i できない問題 → git rebase -i --root でできる - 納豆には卵を入れる派です。 ](http://d.hatena.ne.jp/ken_c_lo/20130421/1366558065)
自治体サイト一覧

最終的には、自治体サイト一覧は wikidata で[メンテナンス](https://github.com/hkwi/lgjp_web)しているという話。

# 経緯

[自治体コード一覧](http://qiita.com/kwi/items/b20463da8a6cc645e7c6)で、自治体を網羅的に列挙することはできるようになった。今度はいわゆる公式ウェブサイト一覧が欲しい。

linkdata に[登録](http://linkdata.org/work/rdf1s2022i)もあるし、github で管理されている[例](https://github.com/codeforfukui/localgovjp)もあるけれど、基本的には手作業更新の様子。これを維持し続けるのは体力的に大変そう。

ウェブサーチ結果から自動的に抽出できないか一度試したこともあったけれど、上手くいかなかった。しばらくして wikipedia, wikidata 使えばいいような気がしてきた。

## dbpedia

wikipedia から直接クエリはできないので、dbpedia を使わせていただく。SPARQL エンドポイントは http://ja.dbpedia.org/sparql

```
SELECT ?code,?name,?homepage WHERE {
 ?s <http://dbpedia.org/ontology/areaCode> ?code ;
  <http://ja.dbpedia.org/property/name> ?name .
 OPTIONAL {
  ?s <http://xmlns.com/foaf/0.1/homepage> ?homepage .
 }
 FILTER regex(?code, "[0-9]{5}-[0-9]")
}
ORDER BY ?code
```

## wikidata

SPARQL エンドポイントは https://query.wikidata.org/

```
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?code ?name ?site WHERE {
 ?s wdt:P429 ?code ; # 全国地方公共団体コード
    rdfs:label ?name .
  OPTIONAL {
    ?s wdt:P856 ?site . # 公式サイト
  }
 FILTER ( lang(?name)="ja" )
 FILTER NOT EXISTS { ?s wdt:P31 wd:Q18663566 } # 分類 日本の廃止市町村
} order by ?code
```

wikidata であれば、私にも維持できそうな気がする。体力的に。サステナビリティ大事。

最新版のコード一覧と比較して差分が出たのは一件で、`042161` 富谷町から `044237` 富谷市への移行が、wikidata は追従できていませんでした。
これは……名称やコードを更新するべきか。
コード更新した。

一覧の[CSV](https://hkwi.github.io/lgjp_web/wd.csv)を travis で自動生成するようにした。

# 差分

さきほどの[福野さん](https://github.com/taisukef)作成の[一覧](https://github.com/codeforfukui/localgovjp/blob/gh-pages/localgovjp-utf8.csv)との差分は、自動ビルドするようにして、[こうなっている](https://github.com/hkwi/lgjp_web/blob/master/docs/codeforfukui.diff)。ここから先は目視確認が主軸になろうかと思う。

Wikidata の「公式サイト」URL は次の基準で揃えていっています

- 専用ホスト名がある場合はトップページであろう「/」を使った `http://example.jp/` の形に。
- lg.jp が使われている場合は優先する。
- https が使われていて、完全性がある（http との mixed-contents になっていない）場合は https 優先。
- 例えば `http://www.example.jp` から `http://www1.example.jp` にリダイレクトされる場合は、冗長構成設定の副作用だと推測されるので、`http://www.example.jp` を採用。
knife zeroをawsで扱う際にsshが切断されてしまう問題と解決策

# awsでknife zero convergeを使うと起きる問題

awsでknife zeroを使う場合、shellが長い間応答しないコマンドが走るとフリーズしてしまいます。具体的にはdokkuをインストールしようとしましたが、この辺でsshが応答しなくなり、Ctrl+Cでキルするしかなくなります。

```
Importing herokuish into docker (around 5 minutes)
```


# 原因
awsはsshで長い間通信されない場合にインフラ側で自動的にルーティングを切ってしまうようです。ssh-clientやsshdは生きていますが通信が通らないという状態に陥ります。

この状態を回避するために、~/.ssh/configに定期的に通信して切られないよう設定を追加するという方法が提案されています。
http://qiita.com/euno7/items/00ef56244b7b193d2455


しかし、knife zeroではこの方法が働きません。

# 解決策
knife zeroで~/.ssh/configが働かない課題には2つの要因があり、それらの解決策について解説します。

## knife sshでコンソールのssh_configが反映されていない
chefのソースコード上(chef/lib/chef/knife/ssh.rb)で、~/.ssh/configを読み込む処理がありますが、user,forward_agent,portくらいしか使われていませんでした。そこでServerAliveIntervalを働かせるように修正します。

https://github.com/kackyt/chef/pull/1/commits/8b6bfd586774b754108b0a1d03f9db21e8543553

## Net::SSH::Multiでkeepaliveパケットが流れない
これでうまくいったーと正直私も思いましたが上だけでは解決しませんでした。Net::SSHでは動作しますが、knife zero(knife ssh)ではNet::SSHから派生したNet::SSH:Multiというclassが使われています。これにはNet::SSHでは実装されているServerAliveIntervalに対応するkeepaliveパケットを送信する実装が入っていませんでした。そこでNet::SSH:MultiにNet::SSH同様の実装を追加しました。

https://github.com/kackyt/net-ssh-multi/commit/19c3efba675c61c50a6468f5200f7e52efdfcc04

これでようやくcookbookが長引いてもちゃんと処理が完了するようになりました。やったね。

# TODO
もろもろ落ち着いたらpull request書きます
Chatterに Twitterの検索結果(とか他いろいろ)を投稿する

# RSSを取得しChatter へ投稿
単純にTwitterの内容をSalesforceへ、という話なら、[Salesforce for Twitter and Facebook](https://appexchange.salesforce.com/listingDetail?listingId=a0N30000003HpEQEA0) を利用するのが一番手っ取り早いんですが、普通のレコードとして保持するのではなく、Chatterに投稿させたいなぁと思って調べた所、こんなものを見つけました。
[Chatter RSS](https://appexchangejp.salesforce.com/listingDetail?listingId=a0N30000003ITo8EAG&tab=r)

使い方に関しては、こちらの記事を参考にしました。
[AppExchange：Chatter RSS つかってみました](http://tyoshikawa1106.hatenablog.com/entry/2013/07/24/223530)
ただ、カスタム設定の登録は特に無くても動きました。(Version上がって仕様変わった？)

これでまず、外の情報を拾ってきてChatterに投稿する準備はできました。

# TwitterのRSSを取得
しかし、残念ながらTwitterのRSSは公式からは提供されていません。
そこで、Twitterの内容をRSS化してくれる別のサービスを利用します。
[QueryFeed](https://queryfeed.net/)

こちらの利用方法は、こちらの記事を参考にしました。
[「Queryfeed」を使ってTwitterのつぶやきをRSSリーダーで読む](http://wasure.net/queryfeed/)

なお、こちらのサイトはTLS1.0までしか対応していないようで、https通信ができなかったので、httpで接続しました。
まぁ、盗聴されて困るような情報やりとししないので問題ないかなと。

# Webの検索結果もRSSに
と、ここまでやって、じゃあとりあえずRSSに寄せてしまえば、大概のことはこれでChatterに投稿できるんじゃないかと思って、他のニュースサイトのRSSの取得を考えたんですが、特定キーワードの情報をかき集めるなら、Googleアラートを使うのが一番手っ取り早そうです。(その分ノイズも増えますが)

Google アラートの内容をRSSにする方法は、こちらの記事を参考にしました。
[GoogleアラートをRSSフィードで受信する](https://www.howtonote.jp/google-alert/index5.html)

# 最後に
今回は完全に有りものを組み合わせるだけのお話でしたが、まぁこういうのもクラウドらしいから、たまにはいいかなぁと。

Chatter RSSのソースはすべていじれるようなので、投稿の仕様で気になる部分は、ちょこちょこっと改造すればいいかなと思います。
Sidekiqでperform_asyncしてもRedisのキューに入らなくなってしまった話

## 現象
* ある日、突然、development環境で、Sidekiqのジョブがenqueueされなくなった・・・

## 原因
* Gemfile内で、`rspec-sidekiq`をdevelopment環境にも入れてしまっていたため。

```
group :development, :test do
  gem 'rspec-sidekiq'
end
```


## ここに書いてあった
* `rspec-sidekiq`の[FAQ & Troubleshooting](https://github.com/philostler/rspec-sidekiq/wiki/FAQ-&-Troubleshooting)にありました。

```
Sidekiq jobs will not be pushed to Redis but instead to a jobs array to enable testing.
```
* つまり`rspec-sidekiqを使うと、SidekiqはジョブをRedisにpushしないで、代わりにテスト用の配列に入れる`ということらしい

## 対応
* test環境だけに`rspec-sidekiq`入れました。

```
group :test do
  gem 'rspec-sidekiq'
end
```


## あとがき
* まあdevelopmentには入れる人いないでしょうけど、ひょんなことから`rspec-sidekiq`の中身が見れてよかったです。
AWS CloudSearch を使ってみて

# 何
- solrを直接使っていたが、CloudSearchを使う機会があったため、感想を列挙する

## Good
- サーバの準備や管理が楽

## Bad
- 形態素解析の辞書、シノニムは分析スキーマとしてアップロードしないといけない。jsonで数万点など膨大な量を上げようとすると、タイムアウトしたりする。
- 分析スキーマの変更や、インデックス定義の変更時、re-indexに時間がかかる。(数点のドキュメントでも30-40分)
- スキーマの一括インポートができない。jsonでのエクスポートはできる。
- filterやcharFilterがないため、インデックス時やクエリー時のどちらか、または両方でデータ変換する必要がある。
- CloudWatchのメトリックスが少なく、re-indexの状況などはわからない。（いつ終わるかわからない）
- ドキュメントの親子関係を表現できない。
- structuredクエリーパーサではあいまい検索ができない。luceneパーサを選べばできる。
- 複数のフィールドをORで検索している時、どのフィールドでヒットしたのかわかりづらい。(デバッグクエリーがない)
- ドキュメント一括削除がない。
- copyField定義が持てないため、形態素解析とNGRAMの両方のフィールドでインデックスしたいときに、コピーを自前で行う必要がある。
- 部分更新ができない（atomic updateがない)
error: src refspec master does not match anyが出る時（解決済み）

# 確認しよう

1. ちゃんとcommitしたかな？
2. branchの名前は合っているかな？

以下ポエム。

# 解決するまでの道程

GCEにフラットファイルCMSの[Grav](https://getgrav.org/)を入れてみました。
解凍したzipをFTPでアップロードするだけで動くのだ！　と言われて採用したのにGAEでは動かず[^1]…。結局、GCEに直接GitHubからクローンしてインストールしました。

[^1]: GAEではファイル書き込みがでできないため

フラットファイルなのでコンテンツ丸ごとgitで管理できます。とりあえずバックアップ代わりにGCPの非公開リポジトリにpushしようとしたらこんなエラーが出る。

>error: src refspec master does not match any.
error: failed to push some refs to 'https://source.developers.google.com/p/[project-ID]/r/[repo]'

ググると「commitしてないと出る」とか出てきますがcommitはしている。
何かコンフリクトしてるのかと思い、`-f`やリモートリポジトリの作り直しなどをやってみたが効果なし。

諦めずにググり続けた結果、以下のページに行き当たる。

[error: src refspec master does not match any](http://stackoverflow.com/questions/21264738/error-src-refspec-master-does-not-match-any)

これだ～～～～～～！！

確認したところ、GitHubのGravはmasterブランチではなくdevelopみたいな名前のブランチを採用していました…。
`git push google master`で頑張っていたので怒られていたみたいです。

それにしても、`error: incorrect branch`みたいなわかりやすいエラーが出てくれると助かるのだけど。
[Node.js] .yaml-tmLanguage を .tmLanguage に変換する (yamlからproperty listへの変換)

vscodeのシンタックスハイライトプラグイン用。
yamlからtmLanguageのシンタックスハイライト設定ファイル(property list)に変換する方法メモ

https://github.com/Microsoft/TypeScript-TmLanguage/blob/master/build/build.ts

Microsoft製のTypescriptのプラグインが `js-yaml` と `plist` を使っていたので参考にしました。

# 要求パッケージのインストール

```bash:packageのインストール
$ npm install --save-dev js-yaml plist
```

# 実装例

とはいってもjs-yamlで読み込んで、plistで書き出すだけです。

```js:build.js
const fs = require('fs');
const yaml = require('js-yaml'); 
const plist  = require('plist');

const inputYamlTMLanguageFile = "./syntaxes/diagram.yaml-tmLanguage";
const outputTMLanguageFile =  "./syntaxes/diagram.tmLanguage";

const yamlTMLanguageText = fs.readFileSync(inputYamlTMLanguageFile, "utf8");
const data = yaml.safeLoad(yamlTMLanguageText);

const tmLanguageText = plist.build(data);
fs.writeFileSync(outputTMLanguageFile, tmLanguageText, "utf8");
```

```bash:実行
$ node ./build.js
```
IDCFのオブジェクトストレージへawscliのsyncを使ってバックアップ

# はじめに

IDCFクラウドのオブジェクトストレージはAWSのS3との高い互換性を謳っています。
また、IDCFクラウドでもs3cmdよりawscliを使ったほうが性能が出るそうです(例えば[この記事](http://qiita.com/motty/items/d0ff4a947e1436a105bb))
awscliでバックアップする場合cpとsyncがあります。
バックアップ用途ではsyncのほうが使い勝手が良いです。
しかし、IDCFクラウドでsyncを使ってバックアップをしたよという記事は見かけません。
やってみたらできましたので手順を書いておきます。

# awscliのcpとsyncの違い

どうやるかだけ知りたい人は飛ばしてください。

cpは(ローカル|S3)から(ローカル|S3)へオブジェクトをコピーします。
一方、syncは再帰的に指定したディレクトリからS3へオブジェクトをコピーします。
syncは差分バックアップにも対応しています。
したがって、特定ディレクトリのバックアップを取りたいという場合にはsyncを使ったほうが良いです。

# バックアップの実装

まずはIDCFのWeb UIからオブジェクトストレージにAPIユーザを追加します。
APIキーとSecretキーは控えておきましょう。

その後、IDCFのWeb UIからバケットを作ります。
今回はcontents-backupというバケットを作成しました。

次にサーバ側での操作です。
まずはawscliを導入します。
pipが入っていなければ入れてください。

```
# pip install awscli
```

これでawscliが入ります。
次にバックアップを実行するユーザで下記コマンドを実行し
「AWS Access Key」と「AWS Secret Access Key」の入力を促されますので
先ほど控えたAPIキーとSecretキーを入れます。
その後の質問は特に答えずEnterで問題ないです。

```
$ aws configure
AWS Access Key ID [None]: myAPIKey
AWS Secret Access Key [None]: mySecretKey
```

設定がうまくいっているか確かめるために下記コマンドを実行します。

```
$ aws s3 --endpoint-url https://ds.jp-east.idcfcloud.com ls
2017-04-16 17:31:15 contents-backup
```

作成したバケット(この例だとcontents-backup)が表示されれば正常です。
"--endpoint-url"オプションはAPIのエンドポイントを指定します。
今回はIDCFクラウドの東日本リージョンを利用しているのでこのようなURLです。

次に実際にバックアップをしてみましょう。


```
$ aws --endpoint-url https://ds.jp-east.idcfcloud.com s3 sync contents/ s3://contents-backup/ --exact-timestamps --delete
```

"--exact-timestamps"オプションはタイムスタンプをみてアップロードするオプションです。
"--delete"オプションはバックアップ元にないファイルがバックアップ先にあれば削除するオプションです。
したがって、この例では下記の例では"contents/"というディレクトリを"contents-backup"バケットにタイムスタンプをみて更新のあったものだけバックアップして"contents/"にないファイルはcontents-backupから削除しています。

あとはこれをcron等に仕込めば自動バックアップの完成です。
WindowsからLinuxへの移行を楽にする

WindowsからLinuxへの移行を楽にするためのメモをまずは自分用に作成中です。

|用途 |Windows| Linux|memo |
|:--|:------:|:------:|:--|
|ファイルの比較| WinMerge | Meld|比較した結果を編集に反映する |
| SCP         | WinSCP | gFTP | GUIを使いながらファイルの転送をしたい。|
| SCP         | FileZilla |  FileZilla | GUIを使いながらファイルの転送をしたい。|
| serial 通信 | TeraTerm | screen|　|
| markdownのプレビューのあるエディタ | atom | atom, remarkable | |
|SVN client | TortoiseSVN| RabbitVCS| GUIでSVNを使うのに便利です。|
|Image viewerの例| irfanview | |  |
|Image viewerの例| ImageJ | ImageJ | | 
| エディタの例| Sakuraエディタ|nano | NanoはCUIで使う中では前提知識が不要　|
| エディタの例| |gedit | gedit　ubuntuなどで標準で入っている|
| エディタの例| |geany | ソースコードでハイライトをしてくれる |
| web Camera 用アプリケーション | | cheese| |
| 動画再生 | | VLC media player| |


必要なエディタの種類
・terminalしか使えない貧弱な環境でも使えるエディタ。
　日本語コードが混在していても扱えること
  改行コードが混在していてもOKであること。
　「メモ帳」は、Unixの改行コードを扱えない。
・terminalよりはましな環境で、ほぼ必ず入っていることが期待できて
　文字コードの問題を気にしなくてよいもので
　代表的なプログラミング言語の予約語はハイライト表示してくれるもの
・markdown記法を扱えて、文字コード・改行コードの問題なく扱えること。
　一見それらしい動作をするが、文字化けしで入力したテキストが失われるのは全体にダメ。
　
　仕様書をmarkdown記法でテキストベースで書く。
　そのような仕様書をソースコードのヘッダファイルのドキュメンテーションコメントに
　利用しやすくする。
  markdown 記法は、Redmineでも使えているし、Office365の webメールシステム上でも使えている。
　MicrosoftのSharePointで奇妙なことは、SharePoint上に置かれたテキストファイルは文字化けして読めないことが多いのに、markdown記法の*.md ファイルだと表示できるという点です

　ドキュメンテーションコストを下げることは、開発者の時間を確保する上で重要なことだ。

・統合環境に準じるほどプログラミングを支援する機能が充実しているエディタ
　vim, emacs

----
画像ファイルの一覧表示を楽にしたい
Geeqie
Shotwell

Thunar [Ubuntuで複数画像のリネームと回転を行う](https://がりはり.com/%E3%81%AD%E3%81%93/Ubuntu/Ubuntu%E3%81%A7%E8%A4%87%E6%95%B0%E7%94%BB%E5%83%8F%E3%81%AE%E3%83%AA%E3%83%8D%E3%83%BC%E3%83%A0%E3%81%A8%E5%9B%9E%E8%BB%A2%E3%82%92%E8%A1%8C%E3%81%86)
Serverless Step Functions v1.0をリリースしました

https://github.com/horike37/serverless-step-functions
Serverless FrameworkでAWS Step Functionsが使えるプラグインをβ版にて公開していましたが、この度、βを脱却して1.0をリリースしました。

## v1.0の機能
### serverless.ymlの設定

以下が serverless.ymlの記述例です。
`stateMachines`内で、`definition`にyamlにてState Languageを記述を行います。


```yaml:serverless.yml

custom:
  accountId: xxxxxxxx

functions:
  hellofunc:
    handler: handler.hello

stepFunctions:
  stateMachines:
    hellostepfunc1:
      events:
        - http:
          path: gofunction
          method: GET
      definition:
        Comment: "A Hello World example of the Amazon States Language using an AWS Lambda Function"
        StartAt: HelloWorld1
        States:
          HelloWorld1:
            Type: Task
            Resource: arn:aws:lambda:${opt:region}:${self:custom.accountId}:function:${self:service}-${opt:stage}-hello
            End: true
```
### トリガーイベントの対応
StateMachineをトリガーするイベントの設定は`events`内で行います。
現在はAPI Gatewayのイベントのみに対応しています。v1.0の段階では、Cors、Custom Authorizer, API Keyには対応できていないのですが、これらも順次対応予定です。

API Gatewayのイベントの記法は以下の通りです。これで、GETで/gofunctionにアクセスすることで、`hellostepfunc1`のStateMachineが起動するようになります。

```yaml:serverless.yml
stepFunctions:
  stateMachines:
    hellostepfunc1:
      events:
        - http:
          path: gofunction
          method: GET
      definition:
```


### デプロイ
今回で、`serverless deploy stepf`のコマンドは廃止され、デプロイはすべて`serverless deploy`を通して行う用になっています。

`serverless deploy`実行時に、serverless.ymlにStepFunctionsの記述が存在していれば、CloudFormationを通してデプロイが実行されます。

### コマンドラインからの実行
`serverless invoke stepf --name <your-statemachine>` で実行可能です。

## まとめ
というわけで、かなりシンプルな仕様になったと思います。以降はセマンティックバージョニングにも基いて互換性を保ちながらアップデートしていくことになります。

また、この機能はServerlessのコアに取り込むことも議論していましたが、結果、延期となってしまいました。
https://github.com/serverless/serverless/issues/3024

理由としては、ServerlessはAWSを含むマルチクラウドプロバイダーサポートを特徴としています。
Step FunctionsはAWS固有の機能です。こういったプロバイダー特有の機能は、イベントとFunctionからは切り分けてどのように管理していくのかを決めていく必要があるためです。(`x-aws-`といったベンダープレフィックスを付けるとか)

ただし、今回のリリースで決まった仕様は、ちゃんとした議論の結果でもあるので、コアに取り込まれることも大きく変わらないと思います。
それでは、良いStep Functionsライフを！
素人の言語処理100本ノック:93


[言語処理100本ノック 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)の挑戦記録です。環境はUbuntu 16.04 LTS ＋ Python 3.5.2 \:\: Anaconda 4.1.1 (64-bit)です。過去のノックの一覧は[こちら](http://qiita.com/segavvy/items/fb50ba8097d59475f760)からどうぞ。

## 第10章: ベクトル空間法 (II)
>第10章では，前章に引き続き単語ベクトルの学習に取り組む．

### 93. アナロジータスクの正解率の計算
>92で作ったデータを用い，各モデルのアナロジータスクの正解率を求めよ．

#### 出来上がったコード：

```python:main.py
# coding: utf-8
fname_input = 'family_out.txt'

with open(fname_input, 'rt') as data_file:

	# 1行ずつチェック
	correct = 0
	total = 0

	for line in data_file:
		cols = line.split(' ')
		total += 1
		if cols[3] == cols[4]:
			correct += 1

# 正解率表示
print('{} ({}/{})'.format(correct / total, correct, total))
```

#### 実行結果：

##### [問題85](http://qiita.com/segavvy/items/f1a7f3200c3b771e8568)の単語ベクトルに対する結果

```console:問題85の単語ベクトルに対する結果
0.03359683794466403 (17/506)
```

##### [問題90](http://qiita.com/segavvy/items/890d34a40991dd634cdf)の単語ベクトルに対する結果

```console:問題90の単語ベクトルに対する結果
0.09090909090909091 (46/506)
```

### アナロジータスクの正解率

やはりword2vecの方が優秀ですね。2倍以上の正解率です。ただword2vecでも9%なので、かなり低い感じです。単語ベクトルにない単語を不正解扱いしているのは、ちょっと厳しすぎたのかも。あと、使っているコーパスは1/100サンプリングのものなので、1/10サンプリングにするともう少し精度が上がるのかもしれませんね。

　
94本目のノックは以上です。誤りなどありましたら、ご指摘いただけますと幸いです。
<hr>

*実行結果には、[100本ノックで用いるコーパス・データ](http://www.cl.ecei.tohoku.ac.jp/nlp100/#data)で配布されているデータの一部が含まれます。この第10章で用いているコーパス・データのライセンスは[クリエイティブ・コモンズ 表示-継承 3.0 非移植](https://creativecommons.org/licenses/by-sa/3.0/legalcode)（[日本語訳](https://creativecommons.org/licenses/by-sa/3.0/deed.ja)）です。また、単語アナロジーの評価データは[Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0)で配布されているword2vecの一部です。*
プログラミング学習記録1日目

知らなかったこと、勘違いしていたことを中心に書き留める。

<h4>HTML & CSS</h4>
インライン要素 a span
ブロック要素 h1 p

box modelという概念
border padding margin

css : htmlのサイズ、色などを変更するのに使われる。デザイン要因

stylesheet.css：input textareaは .input .textareaとしない。そのまま

<h4>jQuery</h4>
classは何度でも使える、idは一度きり

stylesheet.cssでは　.class名　or #id名
idの方が高速処理が可能。よってid使用が推奨されている

hide()メソッド、show()メソッド ：property のdisplayをnone or blockにしているだけ



<h4>command line</h4>
touch : ファイル作成
cat : ファイル中身を表示
mkdir : ディレクトリ（フォルダ）作成

pwd : current directly の確認　point working directly

ls : directlyの中身表示（1階層下全てを表示と同意）　list

cd  : 通常移動　
cd ..　: １つ親のディレクトリへ移動
🌟移動は１つ下or上ずつしかできない
cdのみ : home directlyに設定しているところへ戻る

mv ファイル名(フォルダ名）　フォルダ名 ： ファイル（フォルダ）をフォルダへ移動
mv ファイル名　新しいファイル名　or mv フォルダ名　新しいフォルダ名　: 名前変更

🌟🌟頭文字 + tabキー　:　予測変換

cp ファイル名　新しいファイル名 or cp -r フォルダ名　新しいフォルダ名 : コピー
rm ファイル名 or rm -r フォルダ名 : 削除
↑キー　: 少し前のコマンドを選択できる


<h4>Git</h4>
git add ファイル名　: ファイル追加
git commit -m ”メッセージ” : ファイル記録　🌟-mの後にスペースがいる
git remote add リモート名　リモート先 ：リモートの登録　→
git push リモート名　master ： プッシュする（アップロード）→
git pull リモート名　master ： プルする（ダウンロード）

git status : 編集したファイルを確認できる
git diff : 編集内容を確認できる
git status : 編集したファイルをaddしたかどうか確認できる
git log : 過去のコミットメッセージ記録確認
git log -p : 過去の編集内容確認

今回は第一回だからこんなもの
今後はもっとMarkdownをうまく利用して見やすい形にしていきたい
PythonのStatsmodelsで重回帰分析を行う際に、定数項(y切片)を追加する

# はじめに
重回帰分析を行っていたところ、エクセルで算出した傾きやp値と、PythonのStatsmodelで算出した数値が異なり悩んでましたが、Statsmodelに定数項を追加してなかったことに気付きました・・・。

追加するにはStatsmodelの`add_const`と用いればよいようです。
[statsmodels.tools.tools.add_constant](http://statsmodels.sourceforge.net/devel/generated/statsmodels.tools.tools.add_constant.html)

# コード
```hoge.py
from statsmodels import api as sm

X = df[["height","width"]]
X = sm.add_constant(X)

y = df["weight"]

model = sm.OLS(y,X)
result = model.fit()

result.summary()
```

# さいごに
ありがとうございました。
yum update と yum upgradeの違い（ついでにDebianも）

## yum update
 * インストール済みのパッケージをアップデートする

## yum upgrade
 * `yum update --obsoletes`と同じ
    * `--obsoletes`は、パッケージの更新時にのみ有効なオプションで、不要になったパッケージの削除を自動で行う
        * 不要になったパッケージとは、例えばインストール済みのfooパッケージが今までbarパッケージを必要としていたが、fooのアップデートによってbarが不要になった場合


## 結局どっちもいっしょ
 * CentOSでは、/etc/yum.confに`obsoletes=1`と書いてあるため、デフォルトで`--obsoletes`が有効の状態
 * よって、`yum update`も`yum upgrade`も変わらない

##(おまけ)Debianでは
### apt-get update
 * パッケージのリストを更新する
 * インストールされているパッケージの更新は行わない

### apt-get upgrade
 * インストールされているパッケージを更新する. さきに`update`を実行しておく
 * ただし、更新によって新規にパッケージのインストールや削除が発生するような場合は、それを行わない
 * つまり、安全なアップデート

### apt-get dist-upgrade
 *  インストールされているパッケージを更新する.
 *  更新によって新規にパッケージのインストールや削除が発生するような場合、それらも実行する

## つまり
Redhat系(yum)とDebian(apt-get)では、updateとupgradeの意味合いが大きく異なる。

yumでは、`yum update`とするだけでOSのマイナーバージョンは上がるし、カーネルのアップデートも行われる。

## 疑問

プロダクション環境でDebianを運用したことがないので分からないのだが、パッケージ更新のベストプラクティスはどんな感じなんだろう。

Redhat系の場合、（私は）yum-cronをインストールして基本的には毎日パッケージの更新しつつ、kernelやミドルウェアはyum.confで更新対象から除外しています。
PHPのarray_pushとin_arrayの速度について

# はじめに
in_arrayを使うより、連想配列にしてissetとかで判定した方が早いよという会話を聞いたので、実際に速度を計測してどの程度の差があるのかを確認しました。
せっかくなので配列に値を入れる時にarray_pushを使って、こちらの計測も行います。


# array_pushと[] = の比較
まずはin_arrayで計測をするようの配列を準備したいので、配列に値を入れていきます。
その際にせっかくなので、array_pushで値を追加する場合と$array[] = 'hoge' みたいな形で追加する場合のパフォーマンスについて計測してみます。

```php
$array = [];

$start = microtime(true) * 1000;
for ($i = 0; $i < 10000; $i++) {
    array_push($array, $i);
}
$end = microtime(true) * 1000;

echo $end - $start; // 10.2802734375


$array2 = [];

$start = microtime(true) * 1000;
for ($i = 0; $i < 10000; $i++) {
    $array2[] = $i;
}
$end = microtime(true) * 1000;

echo $end - $start; // 3.06103515625
```

## 結果のまとめ
何度かやると上振れ下振れしますが、それぞれの差はあまり変わりませんでした。
だいたい3倍から4倍と行った印象です。

|   処理     |   実行速度     |
|:----------------:|:-----------------:|
|    array_push        |      10.2802734375         |
|    [] =        |      3.06103515625         |


# in_arrayとissetの比較
配列の準備ができたので、そこから値を検索するパフォーマンスの計測を行ってみます。

```php
// in_array
$start = microtime(true) * 1000;
in_array(5000, $array);
$end = microtime(true) * 1000;

echo $end - $start; // 0.123046875

// isset
$start = microtime(true) * 1000;
isset($array[5000]);
$end = microtime(true) * 1000;

echo $end - $start; // 0.0048828125
```

追加で似たような処理を行う組み込み関数も計測してみます。

```php
// array_search
$start = microtime(true) * 1000;
array_search(5000, $array);
$end = microtime(true) * 1000;

echo $end - $start; // 0.089111328125

// array_key_exists
$start = microtime(true) * 1000;
array_key_exists(5000, $array2);
$end = microtime(true) * 1000;

echo $end - $start; // 0.005859375
```

## 結果のまとめ

|    処理    |   実行速度     |
|:----------------:|:-----------------:|
|     in_array         |    0.123046875           |
|     array_search         |    0.089111328125           |
|    isset        |     0.0048828125        |
|     array_key_exists       |    0.005859375         |

単純に今回の比較ですとこのような差が出ました。(25倍くらい？)
そのためデータの件数が多い場合には、連想配列にしてissetでの判定ができないか試してみるは良さそうです。
MySQLで特定のテーブルをdumpする方法。

# はじめに
特定のテーブルを指定してdumpするには以下の方法で行えます。

```bash:コマンド
$ mysqldump -u<ユーザー> -p<パスワード> 【データベース】 【テーブル１】 【テーブル２】 ... --master-data --single-transaction > hogehoge.dump
```

データベースの後にテーブル名を並べれば良いのですが、数が増えてくると大変です。。。そんな時はテーブルリストを作成し、それを使ってdumpを行うと簡単になります。


# 実践
実際のデータベースを使って試してみます。
まずはrepltestというデータベースに以下のテーブルが存在します。

```bash:テーブル一覧
$ mysql -uroot repltest -e "show tables"
+--------------------+
| Tables_in_repltest |
+--------------------+
| hogehoge1          |
| hogehoge2          |
| hogehoge3          |
| hogehoge4          |
| hogehoge5          |
| test1              |
| test2              |
| test3              |
| test4              |
| test5              |
| user1              |
| user2              |
| user3              |
| user4              |
| user5              |
+--------------------+
```

ここで、hogeから始まるテーブルのみを抽出してみます。

```bash:hoge抽出
$ mysql -uroot repltest -N -e "show tables like 'hoge%'"
+-----------+
| hogehoge1 |
| hogehoge2 |
| hogehoge3 |
| hogehoge4 |
| hogehoge5 |
+-----------+
```

|オプション|内容|
|:------|:--|
|[-N, --skip-column-names](https://dev.mysql.com/doc/refman/5.6/ja/mysql-command-options.html#option_mysql_skip-column-names)|カラム名を表示しない|

これをテキストに書き出すと、

```bash:テキストへ書き出し
$ mysql -uroot -phogehoge repltest -N -e "show tables like 'hoge%'" > repltest.txt
```

```bash:表示
$ cat repltest.txt 
hogehoge1
hogehoge2
hogehoge3
hogehoge4
hogehoge5
```
このようにhogeから始まるテーブルのみ一覧としてリストできました。


あとはこのリストをcatコマンドを使いながらdumpすれば完了です。

```bash:dump
$ mysqldump -uroot -phogehoge repltest `cat ./repltest.txt` --master-data --single-transaction > repltest.dump
```


# おわりに
mysqldumpのオプションで `--ignore-table=<database>.<table>` があります。ですが複数テーブル除外したい場合は、その数だけ `--ignore-table=<database>.<table>` を並べないといけないデメリットがあります。
そんな場合は一旦dumpしたいテーブルをリストとして書き出し、そのリストを利用してdumpしてしまった方が簡単かもしれません。
【packagecloud】pythonのパッケージをpackagecloudで管理する

pythonのパッケージを[packagecloud](https://packagecloud.io/)で管理する方法。

# Wheelのビルド

`setuptools`を使ってwheelをビルドします。

パッケージの設定を`setup.py`に記述します。

```setup.py
from setuptools import setup, find_packages

setup(
    name='python_packagecloud_test',
    version='0.0.1',
    author='',
    author_email='',
    url='',
    license='See LICENSE.txt',
    description='',
    long_description=open('README.md').read(),
    packages=find_packages(),
    install_requires=[]
)
```

[wheel](http://pythonwheels.com/)をインストールし、ビルドします。

```bash
$ pip install wheel
$ python setup.py bdist_wheel
```

distディレクトリ下に`python_packagecloud_test-0.0.1-xxx-yyy.whl`というファイルがビルドされます。

# package_cloudコマンドのインストール

```
$ gem install package_cloud --no-ri --no-rdoc
```

# packagecloudのトークン

packagecloudでは以下の３つのトークンを使い分けるようです。

**Master Token**
[Master Token](https://packagecloud.io/docs#master_tokens)はRead Tokenを生成します。

**Read Token**
[Read Token](https://packagecloud.io/docs#read_tokens)は、レポジトリ毎の認証に使われるread-onlyのtokenです。Read Tokenはpackagecloudnの[インストールスクリプト](https://packagecloud.io/docs#install_repo)実行時に自動的に生成されます。

**API Token**
CIなどに埋め込んでレポジトリにpushするのに使われるトークン

# packagecloudへのpush

```bash
$ export PACKAGECLOUD_TOKEN=<API token>
$ echo "{\"url\":\"https://packagecloud.io\",\"token\":\"$PACKAGECLOUD_TOKEN\"}" > ~/.packagecloud
$ package_cloud push <username>/<reponame> dist/python_packagecloud_test-0.0.1-xxx-yyy.whl
```

# packagecloudからのインストール

## インストールスクリプトでインストール

```
$ curl -s https://<master-token>:@packagecloud.io/install/repositories/<username>/<reponame>/script.python.sh | bash
$ sudo pip install python-packagecloud-test==0.0.1
```

## `extra-index-url`指定でインストール

```
$ export PACKAGECLOUD_TOKEN=<read-token>
$ pip install python-packagecloud-test==0.0.1 --extra-index-url=https://$PACKAGECLOUD_TOKEN:@packagecloud.io/<username>/<reponame>/pypi/simple
or
$ pip install -r requirements.txt  --extra-index-url=https://$PACKAGECLOUD_TOKEN:@packagecloud.io/<username>/<reponame>/pypi/simple
```
Mastodonの単一Dockerイメージ作った

(https://instantodon.arukascloud.io で動かしてましたが今は止まってます）

arukas cloudだと一つのDockerイメージしか使えないので、単一イメージ作りました。脱docker-compose。
（とはいえarukas cloudで本格的な運用は推奨しません）

https://github.com/ymmtmdk/instantodon

見て貰えばわかるけどMastodonイメージをベースに愚直にredisとpostgresqlを起動するようにしただけ。
Railsも直に80にbindしてます。

環境変数さえ適切に設定すれば動くはず。
.env.production.sampleにある項目が必要な変数です。

シークレットの三つは
`ruby -r 'securerandom' -e 'puts SecureRandom.hex(64)'`

でそれなりに安全なのができるんじゃないかと。

メールは先日書いたGmailが楽。
http://qiita.com/ymmtmdk/items/aa0d300450d370a1eca0

取り急ぎ、以上となりますどうぞ宜しくお願い申し上げます。
Yahoo! JavaScriptマップAPI に 赤色立体地図 を表示する

![スクリーンショット 2017-04-17 21.42.59.png](https://qiita-image-store.s3.amazonaws.com/0/1830/69ea025c-d17c-7bd9-5ee2-4e8d12cec03f.png)
※ ヤフー地図に赤色立体地図を重ねる(飯能駅周辺)

## 概要
アジア航測株式会社の赤色立体地図が個人向けに無料公開されました(2017/4/5)
ヤフーの提供しているJavaScriptマップにレイヤーを重ね合わせて表示してみました。

 - [ブラタモリでもおなじみの「赤色立体地図」無料ダウンロード提供、日本全国から好きな地域を選択可 -INTERNET Watch](http://internet.watch.impress.co.jp/docs/news/1054902.html)
 - http://www.mapshop.co.jp/products/list.php?category_id=239

## タイルの準備

### ダウンロード
アジア航測のサイトよりGeoTIFF形式で地図が配布されているので、
表示したいエリアを選びダウンロードします。

 - http://www.mapshop.co.jp/products/list.php?category_id=239

### GeoTIFF形式とは
位置情報や地図の投影法などのメタデータが埋め込まれたtiff画像です。

 - https://ja.wikipedia.org/wiki/GeoTIFF

### タイルに切り出し
ヤフー、国土地理院タイル等のウェブ地図は、地図画像をタイルに分けて配布しています。

 - http://maps.gsi.go.jp/development/siyou.html#siyou-zm

### gdal2tile.py準備
OSXの場合は以下のサイトよりインストーラで導入できます。

 - http://www.gdal.org/gdal2tiles.html
 - https://developers.google.com/kml/articles/raster#install

パスが通っていなかったので、適宜設定します。

```
$ echo 'export PATH=/Library/Frameworks/GDAL.framework/Programs:$PATH' >> ~/.bash_profile
$ source ~/.bash_profile
```

コマンドが使えるようになったので切り出します。各種オプションはgdalのサイトに記載されています。
今回は東京周辺の画像を準備していたので5339.tifというファイル名です。
実行すると5339という名前のディレクトリが生成され、{z}/{x}/{y}.pngの階層でタイルが生成されます。

```
$ gdal2tiles.py 5339.tif
```

### タイルの基準点の変換
gdal2tiles.pyで切り出したタイル画像の基準点はTMS形式でタイルの右下を基準点に切り出しています。
Web地図はXYZ形式という左上を基準点にしているので変換が必要です。

 - [静岡市オルソ化航空写真 Tile Map Service の使い方 - Qiita](http://qiita.com/kudarisenmon/items/4d98894da058d34330bc)

tms2xyz.pyで画像の基準点を変換することができます。
以下のコマンドで5339_xyzディレクトリに出力されます。

```
$ curl -O https://raw.githubusercontent.com/smellman/creating_tiles_with_global_map_support_files/blob/master/2014/tms2xyz.py
$ python tms2xyz.py 5339 5339_xyz
```

## Yahoo! JavaScriptマップと重ねて表示する
タイル追加部分は、ローカルのファイルを参照するようにします。

```js
// 赤色立体地図レイヤーを定義
var layer = new Y.ImageTileLayer();
// YOLP地図向けに座標を変換
layer.getImageSrc = function(x, y, z) {
    function calc(x, y, z) {
        t = {};
        t.x = x;
        t.z = z - 1;
        t.y = Math.floor((y + 0.5) * -1 + Math.pow(2, t.z) / 2);
        return t;
    }
    var t = calc(x, y, z);
    return './5339_xyz/' + t.z + '/' + t.x + '/' + t.y + '.png';
}
// 透過を設定
layer.setOpacity(0.8);
// レイヤーを追加
map.addLayer(layer);
```
全体のコード

 - https://gist.github.com/ctyo/9d4ba4f761b18ce9245664624ee7e677

これで表示することができます。
アプリケーションIDはYahoo! ディベロッパーネットワークからは個別に取得します。




## 参考

 - タイル変換参考
  - [タイル地図がおもしろい- SlideShare](https://www.slideshare.net/kokogiko/ss-15067961)
 - Yahoo! JavaScriptマップ参考
  - [YOLP(地図):Yahoo! JavaScriptマップAPIサンプル - Yahoo!デベロッパーネットワーク](https://developer.yahoo.co.jp/sample/map/sample5.html)
  - [Yahoo! JavaScriptマップAPI に OpenStreetMap と地理院地図を表示する - Qiita](http://qiita.com/niwasawa/items/edc8f602ec05cd042a54)
  - [タイル画像を利用する - YOLP JavaScriptマップAPI サンプルコード](http://1st.geocities.jp/yjmapstaff/yolp/jsapi/cassette-tile.html)
PostgreSQL Studio on Docker

# 概要
PostgreSQLのWebUIツールは色々あります。
有名なのは、[phpPgAdmin](http://phppgadmin.sourceforge.net/doku.php)ですね。
もっと直感的に使えるのが、[PostgreSQL Studio](http://www.postgresqlstudio.org/)と言われています。
通常の[インストール手順](http://www.postgresqlstudio.org/support/documentation/supportdocumentationinstallation-guide/index.html)でも、十分簡単です。
ただ、Dockerで環境を作ることで、既存の環境を汚さず、試してみて、良さそうだったら、本番環境を作るって事をみなさんやられていると思います。
そこで、最低限必要なDockerfileを紹介します。

Dockerfileを作成するのも面倒な人用に、Docker Cloudにイメージをアップしましたので試して下さい。

```
$ docker run -d -p 80:8080 maedamikio/postgresql-studio
```

あとは、ブラウザで localhost を開いて、接続先のPostgreSQLの情報を入力して下さい!!!
![PostgreSQL_Studio.png](https://qiita-image-store.s3.amazonaws.com/0/68632/e06d2efd-bf87-ac0a-e887-18e86ed5fe99.png)

# 手順
かなり簡単なので、いきなりDockerfileを紹介します。

```
FROM ubuntu:latest

RUN apt-get update && apt-get install -y \
    openjdk-8-jdk \
    unzip \
    wget \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN wget http://downloads.postgresqlstudio.org/2.0/pgstudio_2.0-bin.zip
RUN unzip pgstudio_2.0-bin.zip

EXPOSE 8080

CMD /pgstudio_2.0-bin/bin/startup.sh && tail -f /dev/null
```

つまり、JavaがあればOKです。


# まとめ
実は、PostgreSQLへの接続時にバージョン等のチェックが行われています。
以下の通りで、例えばRedshiftへは接続出来ません。
ソースコード内のバージョンチェックの部分を無視する様に修正すればおそらく接続出来ると思います。
そんなに実害も無いような気がしますので、次の機会にチャレンジしたいと思います。

対応一覧
- PostgreSQL 9.5.x
- PostgreSQL 9.4.x
- PostgreSQL 9.3.x
- PostgreSQL 9.2.x
- Postgres-XL 9.2
- Postgres-XC 1.0.x
- Postgres-XC 1.1.x
- Postgres-XC 1.2.x
- vFabric Postgres
- Heroku Postgres
- Amazon RDS for PostgreSQL
ブラウザで簡単に ESNext デコレータを試す方法

[babel-standalone](https://www.npmjs.com/package/babel-standalone) を使うと、ビルド設定なしで、ブラウザ上で直接 [JS のデコレータ](http://qiita.com/mizchi/items/6bdf9d100f564a5c5b08)を試すことができます。

```html
<script src="https://unpkg.com/babel-standalone"></script>

<script type="text/babel" data-plugins="transform-decorators-legacy">
const myDecorator = (cls) => {
  cls.foo = 1
}

@myDecorator
class Foo {
}

alert(`Foo.foo=${Foo.foo}`) // => 1
</script>
```

ポイントは srcript タグの `src="text/babel"` と `data-plugins="transform-decorators-legacy"`. 以上の設定でブラウザ上で実行時に babel の transpile が decorators 入りで走るようになります。

# Codepen

Codepen でも、JS トランスパイルの設定を babel にすることでデコレータが使えるようになります。

[デモ](https://codepen.io/kt3k/pen/ybNZdV)
Rantly(property based testing tool)でテストデータ生成 - branch

Rantly#branch で複数のデータタイプからランダムにデータを生成できます

## <i class='fa fa-question-circle'></i> 関連記事
[tbpgr の rantly 関連記事](http://qiita.com/search?utf8=%E2%9C%93&q=user%3Atbpgr%20tag%3Arantly)

## <i class='fa fa-flask'></i> サンプル
```ruby
Rantly(5){ branch :integer , :string, :boolean}
# => [true, "VHxmI)", "^#E;,%", "5!aGIP", "qDx2Mf"]
Rantly(5){ branch :integer , :string, :boolean}
# => [-1665158384696428197, "y-,C2d", -1455156847361017947, "+`.g%)", false]
Rantly(5){ branch :integer , :string, :boolean}
# => [600450864974760975, -1001376245040046707, false, false, false]
```

## <i class="fa fa-book" style="font-size:1em;"></i> 外部資料
* [abargnesi/rantly](https://github.com/abargnesi/rantly)
bundle install時にRMagick 2.16.0がinstallできない

## 事象
MacでRailsの環境構築中にRMagick 2.16.0のinstallで失敗する

## 環境
Mac : sierra
Ruby: 2.3.1
ImageMagick : 7.0.5

## errorログ

```
$ bundle install --path vendor/bundle
・
・
・
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /rails_apps/vendor/bundle/ruby/2.3.0/gems/rmagick-2.16.0/ext/RMagick
/Users/myuser/.rbenv/versions/2.3.1/bin/ruby -r ./siteconf20170417-561-1rfccuu.rb extconf.rb
checking for clang... yes
checking for Magick-config... no
checking for pkg-config... yes
checking for outdated ImageMagick version (<= 6.4.9)... no
checking for presence of MagickWand API (ImageMagick version >= 6.9.0)... no
checking for Ruby version >= 1.8.5... yes
checking for stdint.h... yes
checking for sys/types.h... yes
checking for wand/MagickWand.h... no

Can't install RMagick 2.16.0. Can't find MagickWand.h.
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/Users/myuser/.rbenv/versions/2.3.1/bin/$(RUBY_BASE_NAME)

To see why this extension failed to compile, please check the mkmf.log which can be found here:

/rails_apps/vendor/bundle/ruby/2.3.0/extensions/x86_64-darwin-16/2.3.0-static/rmagick-2.16.0/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /rails_apps
/vendor/bundle/ruby/2.3.0/gems/rmagick-2.16.0 for inspection.
Results logged to /rails_apps
/rails_apps/vendor/bundle/ruby/2.3.0/extensions/x86_64-darwin-16/2.3.0-static/rmagick-2.16.0/gem_make.out

An error occurred while installing rmagick (2.16.0), and Bundler cannot continue.
Make sure that `gem install rmagick -v '2.16.0'` succeeds before bundling.
```

## 原因

``ImageMagick version >= 6.9.0)... no``
これが、マズい。
imagemagickが最新のhomebrewでは、7系がはいってしまうので、


## 対応
imagemagickをuninstallして
6系を遡ってbrew installしてあげればOK

```
$ brew uninstall imagemagick
$ brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/6f014f2b7f1f9e618fd5c0ae9c93befea671f8be/Formula/imagemagick.rb

Updating Homebrew...
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/imagemagick-6.9.7-3.sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring imagemagick-6.9.7-3.sierra.bottle.tar.gz
```

## 参考
http://stackoverflow.com/questions/42250292/rails-cant-install-rmagick-2-16-0-cant-find-magickwand-h