OmniAICreator/Qiita-1.07M huggingface dataset:
TensorFlowでニューラル会話モデル

[以前の記事](http://qiita.com/yoh_okuno/items/50e7dccfb6ebfa8a7238)ではTensorFlowを使って英語から日本語に翻訳するニューラル翻訳モデルを訓練しましたが、今回は最近のチャットボットブームに乗っかって（？）、ニューラル会話モデルを訓練してみました。

# 環境
環境は以前の記事と同じですが、今回はAWSのスポットインスタンスを使うことでコスト削減を図りました。

- TensorFlow 0.9
- AWS g2.2xlarge spot instance
- Ubuntu Server 14.04
- Python 3.5

# データ
ニューラル会話モデルを訓練するためには、発言とその発言に対する返信のテキストデータが必要になります。ここでは[Twitterのリプライを収集スクリプト](https://gist.github.com/yohokuno/37269d09d37f18a70c9ec867b442ac52)を書き、1.3Mほどのツイートと返信先のペアを収集しました。ツイートからユーザ名、ハッシュタグ、URLは削除され、例えば次のようなペアが得られます。

| 返信先ツイート | ツイート |
|:-:|:-:|
| じょーは買ったの？  | 発売日に買ったわ！^ ^  |
| ある(ﾉｼ 'ω')ﾉｼ ﾊﾞﾝﾊﾞﾝ  |  (ヾﾉ´°ω°)ﾅｲﾅｲ |


あとは以前と同じように単語分割と訓練データの分割を行います。

- MeCab 0.996とunidic 2.1.2を用いた単語分割
- 訓練データ99%とテストデータ1%のランダム分割

# 訓練
ニューラル会話モデルはニューラル翻訳と同じエンコーダ・デコーダモデルを使うため、今回はTensorFlowの機械翻訳のチュートリアルのスクリプトをそのまま使います。会話の場合、返信中の単語が元の発言の単語に対応するとは限らないためアテンション付きのモデルが妥当かどうかは疑問の余地が残りますが、このあたりは今後の課題としたいと思います。パラメータは前回と同じくニューロン数が512でレイヤー数は2、語彙数は返信元と返信先の両方とも40,000に設定しました。

```
% python translate.py --data_dir data/ \
    --train_dir model/ \
    --size=512 --num_layers=2
```

2日ほど待つと200kステップが完了し、パープレキシティは2.8まで下がりました。

```
global step 207200 learning rate 0.0612 step-time 0.50 perplexity 2.86
  eval: bucket 0 perplexity 393.02
  eval: bucket 1 perplexity 1015.13
  eval: bucket 2 perplexity 295.72
  eval: bucket 3 perplexity 148.09
```

今回はスポットインスタンスを使ったため、GPUインスタンスにかかった費用は$30くらいで済みました。

# テスト
会話は翻訳よりも自由度が高いので自動評価は難しいと考えられますが、うまくいった例を見るとそこそこ賢いような気がします。

![chatbot twitter.png](https://qiita-image-store.s3.amazonaws.com/0/23665/44996435-b67e-1fde-cb09-fa0d4e93fdf5.png)

しかし、うまくいかなかった例も多くあるのでなんとも言えません。

![Screen Shot 2016-09-02 at 17.32.37.png](https://qiita-image-store.s3.amazonaws.com/0/23665/67bc2ab4-73da-8fc9-8875-5be34af50373.png)

# 感想
機械翻訳では翻訳文の意味は原文と同じである必要がありましたが、会話では意味的にも複数の正解が許されるので翻訳よりも易しいと言えるかもしれません。一方でちゃんとした学習に必要な語彙数やベクターサイズが大きく、特に日本語だと形態素解析の粒度が細かすぎて単語ベクトルがまとまった意味を捉えられていないように思えます。また応用について考えてみると、以下のような課題があると思いました。

- ビジネスになりそうなテクニカルサポートや電子コマースなどのでは致命的な間違いが許されないので使いづらい
- オンラインゲームなどの娯楽目的では発言に一貫性がないためキャラクター性を付与するのが難しい

ニューラル会話モデルは人間のような会話ができる事を目的関数にしていますが、人間らしさよりもタスクの完遂を優先する場合やユーザーを楽しませることを目標にする場合は工夫が必要であるように思いました。ただし、GMailのスマートリプライやiPhoneキーボードのQuickTypeの予測変換ように、入力の補助をするといった応用は比較的すぐに実現すると考えられます。
FFmpeg->AVFrame(Audio)->AVAudioEngine再生のやり方。+ Accelerateフレームワークの能力も借ります。

###2016.09.05
- オディオの**AVFrame**の**linesize**や**nb_samples**についてAVAudioPCMBufferの設定値をもっと精密にやり直しました。


```

let audioContext: UnsafeMutablePointer<AVCodecContext>

// プレイするサウンドの基本設定
let audioFormat: AVAudioFormat(
    commonFormat: .pcmFormatFloat32, 
    sampleRate: Double(audioContext.pointee.sample_rate),
    channels: 2, // サウンドシステムのoutputチャンネルを超えたらクラッシューが発生されます。
    interleaved: false)

let audioEngine = AVAudioEngine()
let audioPlayer = AVAudioPlayerNode()

// オディオエンジンにプレイヤーを付けます。
engine.attach(audioPlayer)
// オディオエンジンの基本出力ノードにプレイヤーを連結します。
engine.connect(audioPlayer, to: engine.mainMixerNode, format: audioFormat)

engine.prepare()

try! engine.start()

audioPlayer.play()
...
// ディコードされたAVFrameをAVAudioPCMBufferに格納します。
let frame: AVFrame

// frameCapacityはframeに配置されているfloatデータの個数を計算し渡します。
let pcmBuffer = AVAudioPCMBuffer(
    pcmFormat: audioFormat, 
    frameCapacity: AVAudioFrameCount(frame.linesize.0 / MemoryLayout<Float>.size))
// frameLengthは実際のaudioのfloatデータの個数を渡します。
// バーファーの長さとsamplesの個数は同じ場合も違う場合もあります。
pcmBuffer.frameLength = frame.nb_samples // AVAudioFileを利用する場合は自動に設定されるところですが、その以外は直接やります。

// ファファーに設定したformatでかくチャンネルのデータのメモリが配置されます。
//　普通はステレオで2個になります。
let channels = buffer.floatChannelData! 
let leftOutputChannel: UnsafeMutablePointer<UnsafeMutablePointer<Float>> = channels[0]
let rightOutputChannel: UnsafeMutablePointer<UnsafeMutablePointer<Float>> = channels[1]

// frameのデータタイプは常にUInt8なのでFloatに変えます。
let leftAudioBuffer: UnsafeMutablePointer<Float> = frame.data.0!.withMemoryRebound(to: Float.self, capacity: Int(pcmBuffer.frameLength)){$0}
let rightAudioBuffer: UnsafeMutablePointer<Float> = frame.data.1!.withMemoryRebound(to: Float.self, capacity: Int(pcmBuffer.frameLength)){$0}

// leftAudioBufferの内容をAccelerateの関数を利用し複写します。
cblas_scopy(Int32(pcmBuffer.frameLength), leftAudioBuffer, 1, channels[0], 1)
cblas_scopy(Int32(pcmBuffer.frameLength), rightAudioBuffer, 1, channels[1], 1)

// オディオのデータが2チャンネル以上を持つ場合、ここでは5.1chのオディオだと仮定します。
// 出力のチャンネルは二つなので余るデータはAccelerateの関数を使って既存のデータに加えます。
let lbuf1 = frame.data.2!.withMemoryRebound(to: Float.self, capacity: Int(buffer.frameLength)){$0}
let rbuf1 = frame.data.3!.withMemoryRebound(to: Float.self, capacity: Int(buffer.frameLength)){$0}
let lbuf2 = frame.data.4!.withMemoryRebound(to: Float.self, capacity: Int(buffer.frameLength)){$0}
let rbuf2 = frame.data.5!.withMemoryRebound(to: Float.self, capacity: Int(buffer.frameLength)){$0}

vDSP_vadd(channels[0], 1, lbuf1, 1, channels[0], 1, vDSP_Length(buffer.frameLength))
vDSP_vadd(channels[1], 1, rbuf1, 1, channels[1], 1, vDSP_Length(buffer.frameLength))
vDSP_vadd(channels[0], 1, lbuf2, 1, channels[0], 1, vDSP_Length(buffer.frameLength))
vDSP_vadd(channels[1], 1, rbuf2, 1, channels[1], 1, vDSP_Length(buffer.frameLength))

//最後に作ったオディオのbufferをAVAudioPlayerNodeに入れます。
audioPlayer.scheduleBuffer(pcmBuffer, completionHandler: nil)

```

で、サウンドの再生が可能になります。
[postgres]大容量メモリかつOSがRHEL(CentOS)6系をお使いの方、THPのdefragは止めた方が良いですよ

# 概要
とある日、postgresが稼働しているサーバのリプレースを行ったところ、
CPUのsysがスパイクしてpostgresが数十秒ほど処理不可となり、ひどい目にあったという話です。
※この環境はCentOS6.8で、postgresは9.4でも8.2でも同現象が発生しました

原因は"THP(Transparent Huge Page)"というOSの機能に関連したdefrag(compaction alloc)処理により、CPUリソースが枯渇したためでした。

![SYSmax.png](https://qiita-image-store.s3.amazonaws.com/0/120707/478f1ea8-9c7e-08ac-a9f1-ef826d85a063.png)


検証したところ、以下の状況が重なるとsysスパイク現象が起きてしまう様です。

* サーバの搭載メモリが大きい(たとえば200GB以上)
* 継続的にトランザクションが発生する
* THPが有効である(OSのデフォルトで有効)

# THP(Transparent Huge Page)のざっくり説明
通常4KBのページを2MBという大きな単位で扱うことで、
ページ管理コストを削減し、効率改善による性能向上を図ることが目的の機能。
Postgresの場合手動でHugePageを指定できるが、THPはOSが動的(トランスペアレント)にHugePageを割り当てる。


# 対策
```
オンラインでTHPのデフラグを停止する
# echo madvise > /sys/kernel/mm/transparent_hugepage/defrag

永続的にTHPのデフラグを停止する(もっとスマートな方法がありそう...）
# vi /etc/rc.local
echo madvise > /sys/kernel/mm/transparent_hugepage/defrag を追記
```

# 調査方法
```
■ 現行設定確認
# cat /sys/kernel/mm/transparent_hugepage/defrag
⇒alwayであれば対象

■ あれ？sys高いなと思ったときに打つ
# perf top
⇒以下のように出たらすぐにTHPのdefrag設定を見直しましょう
～～～
Samples: 2M of event 'cycles', Event count (approx.): 908733026153
  42.59%  [kernel]                  [k] compaction_alloc　　←★これ (圧縮_再配置)
   8.09%  [kernel]                  [k] __reset_isolation_suitable
   2.32%  [kernel]                  [k] compact_zone
   ...
～～～
```
 
# 起きたこと
1. CPU使用率のsysが張り付く
* postgresの処理が止まる
* postgresのプロセスが大量生成(セッションが処理されないので）
* PG-REX構成だったのでpacemakerによるF/Oが発生、また発生、またまた発生....

# 参考：THPにまつわるDB界隈の情報
調べてみると、THPに関してデータベース界隈で情報が見つかりました。個人のまとめとして記載させて頂きます。
### ・ガチャピン先生こと 小崎資広 大先生のTHPに関するまとめ
http://mkosaki.blog46.fc2.com/blog-entry-1291.html
### ・RHEL6マニュアル
「THP はデータベースのワークロードには推奨されません」
https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Performance_Tuning_Guide/s-memory-transhuge.html
### ・Postgresの主要開発者Mr.Robert Haasの記事
「(意訳)CPUのSYSが高負荷になる場合、THPを無効化を推奨している」
http://rhaas.blogspot.jp/2014/03/back-from-lsfmm-and-collab.html
### ・NTT Data社の大規模環境postgresでの事例
「THPを無効にすることによりCPUのsys高騰が解消した」
http://www.slideshare.net/hadoopxnttdata/ntt-data-postgresql
※エンジニア魂を揺さぶって頂ける素晴らしいスライド
### ・Oracleマニュアル
「パフォーマンスの問題を回避するために、透過的なHugePagesはすべてのOracle Databaseサーバーで無効にすることをお薦めします」
https://docs.oracle.com/cd/E57425_01/121/CWLIN/memry.htm#CHDFBJAH
### ・MySQLでの事例
「(意訳)THPはOSの”問題”として劇的な効果を見せた……OFFにしたので安定した」
http://developer.okta.com/blog/2015/05/22/tcmalloc/
※デフォルトのglibc mallocではなく、チューニングでTCMallocを採用したケースのようです
### ・MongoDB
「(意訳)THPは良いものだがDB処理ではひどい状況になることがある、MongoDBでベストパフォーマンスを保証したければOFFにするべきだ」
https://docs.mongodb.org/manual/tutorial/transparent-huge-pages/
### Hadoop
「(意訳)THPはHadoopの処理に深刻なダメージを与える可能性がある」
http://www.cloudera.com/documentation/enterprise/5-2-x/topics/cdh_admin_performance.html

# 最後に
THPの思想・機能はとても素晴らしいものと考えています。
実際にバイナリデータを多用するトランザクションをpgbenchで負荷がけしたところ、THP有効時とTHP無効時ではCPUのSYSの上がり方が有効時の方が抑えられる結果を得られました。(defrag発生時はsysがスパイクしてしまいますが)

その一方で、OSのバージョンアップを機にデフォルトで有効になったという点で、SYSスパイクトラップとしてその機能を体験してしまったことは、個人として残念な結果でした。。
Ruby で do ~ while xxx の条件文を使いたい

Rubyには条件文を最後に持ってくる `do ~ while xxx` がないので、同等のこと使いたい

### do ... end while はダメ

"ruby  で do while をつかいたい"で検索してみると `begin ~ end while xxx`が紹介されてるんですがこれはMatzによって既にrejectされてるらしいです。

### loop break if を使いましょう

```.rb
loop do 
  # some code here
  break if <condition>
end 
```

な書き方が推奨らしいです。詳しく知りたい人は参照を見てください。

### 参照

http://stackoverflow.com/questions/136793/is-there-a-do-while-loop-in-ruby
Google Spreadsheetでのなんちゃって表結合（How to make Query SQL JOIN of two tables with Google Spreadsheet）

# はじめに
Google Spreadsheet には`query`というsqlライクな表アクセスができる便利な関数があって感動したのですが、表の結合方法が検索しても見つからなかったのでメモをしておきます。
他の難民の方の助けになれば嬉しいです。

タイトルに英語も加えたのは検索でヒットしやすくするため
（ほらエンジニアって英語でググるでしょ？）


# 表の結合方法
もっと良い方法があるかもですが、一応これで結合できました。
セルの範囲をセミコロン(;)で区切ると縦方向に結合
カンマ(,)で区切ると横方向に結合できます。

```
# 縦方向に結合
{C7:D9;C13:D15}
```

```
# 横方向に結合
{C7:D9,C13:D15}
```


![図1.png](https://qiita-image-store.s3.amazonaws.com/0/64854/0e784c2a-957a-7ab8-1215-4470b79dcabe.png)





# 余談ですが
Excelの場合、条件に合致したレコードのみを抜き出すにはオートフィルタを使う以外は`countif`などをうまく使って該当レコードのみをピックアップするしかなく、やりたいことはシンプルなのに複雑な関数が必要になります。

[All About: 関数で条件を満たす複数のデータを表から取り出す方法](http://allabout.co.jp/gm/gc/297817/) 


Google spreadsheet なら下みたいな感じで一発でいけます。
しかも分かりやすい！

```javascript
=query( A2:C8,"
  select A, B, C 
  where A = 'ZONY'
  AND B = 'デスクトップPC1'
  AND C  148500
")
```
Retinaディスプレイ MacのWindows(bootcamp)上でoF開発するときに描画解像度おかしくなる問題

## PCスペック（関係ありそうなところのみ）
- Macbook Pro 15 inch Retina display
    - GPU: GeForce GT 650M
    - OS: Windows 10 Pro (Bootcamp)

## 起きたこと
1. Macbook Pro 15 inch (Retina) にBootcampでWindows 10 を入れて使用
2. openFrameworksでアプリケーション作成
3. Windows上での 疑似解像度 とoF上の 描画解像度 が合わない
    - Windowsの画面設定でテキストやアプリケーションの表示倍率を200%を指定。
        - 15 inch Retinaの表示解像度は最大 2560x1600
        - だから見た目上の画面サイズは 1280x800 になる
    - oFのウィンドウサイズを1280x800の数値で指定すると、画面の4分の一の大きさになる。要は半分の大きさに描画される。
    - oFはWindowsの画面サイズではなくグラボから渡される？ディスプレイサイズ情報を見て描画してるのかー
4. てことで直す

## 解決方法の一つ
プログラムで2倍の大きさに描画する、のではなく、グラボの設定を変えて出力解像度を1280x800にする

1. NVIDIA Control Panel を開く
    - 前述した環境なら、プリインストールされているはず。
2. Dsplay -> Change Resolution -> Choose the resolution. から解像度を変更
    - 今回は1280x800に変更
3. Apply
4. 想定通りのサイズで表示される
postgresでメジャーバージョンを跨いでダウングレードが出来た話(ver9.4⇒ver8.2)

# 概要
一般的に、postgresのバージョンアップは一方通行(accelerator)と言われています。
アップグレードは以下の通りとても簡単にできるのですが、不可逆であることが通説です。
```
■バージョンアップ：pg_dumpall -h 古いバージョン | psql -h 新しいバージョン
■バージョンダウン：pg_dumpall -h 新しいバージョン | psql -h 古いバージョン　←大変たくさん警告が出ます。もちろんキチンと戻りません
```

本記事では、準備をしておけばpostgresのダウングレードを"出来る/出来た"ことを共有したいと思います。
postgresをバージョンアップして暫く運用していたが、止む無く戻さざるを得ない状況でのノウハウです。
※私の場合ではpostgre9.4⇒postgres8.2へ下げられました

# 本記事の対象読者
* これからpostgresをバージョンアップしようとされている方
* とりあえずpostgresのVersion上げてみたら散々な結果になった方（レアケースとは思います）
* postgresマスター(どうぞ、私の間違いを正してください）

# 手順概要
* 事前
  1. バージョンアップ前環境のスキーマ定義をダンプしておく(pg_dumpall -s)
  * バージョンアップ後環境でDDLを実行した場合は、それをメモっておく
* リストア時
  1. バージョンアップ前環境のスキーマダンプをcreate系ファイルとalter系ファイルに分割
  * バージョンアップ後のDDLをcreate系ファイル、alter系ファイルへ手動で反映
  * 前バージョンのDBへcreate系ファイルでスキーマをリストア(psql -f create系ファイル)
  * 新バージョンのDBの設定を変更(bytea_output = 'hex' ⇒ 'escape')
  * 新バージョンのDBからデータだけリストア(pg_dumpall -a -h 前バージョンDB)
  * 前バージョンのDBへalter系ファイルで外部キー制約などをリストア(psql -f alter系ファイル)

# 実際の手順
## バージョンアップ前
1. バージョンアップ前環境のスキーマ定義をダンプしておく(pg_dumpall -s)  
```
pg_dumpall -s > 前バージョンのスキーマダンプ
```

## リストア時
1.バージョンアップ前環境のスキーマダンプをcreate系ファイルとalter系ファイルに分割

```
TGTFILE=前バージョンのスキーマダンプ
awk -v DATE=`date +%Y%m%d%H%M%S` 'BEGIN{FILE = "pg_dump_create_"DATE }{
  if(($0 ~ /^\\connect|^SET/)){print $0 >> "pg_dump_create_"DATE ; print $0 >> "pg_dump_alter_"DATE}
  if(($1 ~ /^--/)){FILE = "pg_dump_create_"DATE ; next}
  if(($1 ~ /^CREATE/)){FILE = "pg_dump_create_"DATE}
  if(($0 ~ /ALTER TABLE ONLY/)){FILE = "pg_dump_alter_"DATE}
  {print $0 >> FILE}
}' ${TGTFILE}
※create系ファイル"pg_dump_create_日時"と、
　alter系ファイル"pg_dump_alter_日時"の2個のファイルを作成しています
```

 2.バージョンアップ後のDDLをcreate系ファイル、alter系ファイルへ手動で反映
※ここは手動（ハートウォーミング)でやるしかないです...  
 3.前バージョンのDBへcreate系ファイルでスキーマをリストア(psql -f create系ファイル)
```/前バージョン/bin/psql -h 前バージョンのDB -f create系ファイル
```

4.新バージョンのDBのバイナリデータ型の設定を変更(bytea_output = 'hex' ⇒ 'escape')

```
vi /新しいバージョン/DB領域/postgres.conf
#bytea_output = 'hex'
↓
bytea_output = 'escape'
```

 5.新バージョンのDBからデータだけリストア(pg_dumpall -a -h 前バージョンDB)
```/新しいバージョン/bin/pg_dumpall -a -h バージョンアップ後DB | /前バージョン/bin/psql -h 前バージョンDB
```

6.前バージョンのDBへalter系ファイルで外部キー制約などをリストア
```/前バージョン/bin/psql -h 前バージョンのDB -f alter系ファイル
```
## 補足
* スキーマダンプをcreate系とalter系に分ける理由は、外部キー制約によってpg_dumpallで直接データをリストアできないためです
* 経験的に画像ファイル(jpgなど)のラージオブジェクトのデータはver9⇒ver8で戻せませんでした。どうしても戻す必要がある場合、実ファイルを手動でDBへinsertし直す必要があります
* ver9⇒ver8へ戻す場合"ERROR:  unrecognized configuration parameter "lock_timeout"は無視してよいです

# 最後に
postgresのダウングレードは、公式にはサポートされていません。
しかし、プロダクション環境で片道切符しか用意しないというのは心臓によくありません。
ぜひ事前にリストア検証を行って頂き、少しでも安心材料を増やしてアップグレードに挑んで頂ければと存じます。
Kibana5.0.0-alpha5 & Elasticsearch5.0.0-alpha5でCSVインポートするまで(Mac)

- Elasticsearch5.0.0-alpha5
- Kibana5.0.0-alpha5

CSVインポート機能はalpha4から追加されている

## java
java -versionで無かったら or バージョンが低かったらインストール
[Java SE Development Kit 8 Downloads](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)
ver 1.8以上必要

![スクリーンショット 2016-09-02 23.19.55.png](https://qiita-image-store.s3.amazonaws.com/0/95469/2933168f-3b40-151c-51a3-d0b1732b1751.png)
Accept License Agreementを選択して、Mac OS Xのdmgをダウンロード & 解凍 & インストール

## elasticsearch
ダウンロード
[Elasticsearch 5.0.0-alpha5 download](https://www.elastic.co/downloads/elasticsearch)
リファレンス
[Elasticsearch Reference: 5.0.0-alpha5](https://www.elastic.co/guide/en/elasticsearch/reference/master/index.html)

5.0.0-alpha5バージョンをダウンロード(tar.gzがおすすめ?) & 解凍して好きなディレクトリに置く

```bash
cd elasticsearch-5.0.0-alpha5

# 起動コマンド
bin/elasticsearch
```

[http://localhost:9200/](http://localhost:9200/)にアクセスして
![スクリーンショット 2016-09-02 23.28.22.png](https://qiita-image-store.s3.amazonaws.com/0/95469/daa485e3-fb39-6474-139b-8fe99595f570.png)
みたいになってればOK


## kibana
ダウンロード
[Kibana 5.0.0-alpha5 download](https://www.elastic.co/downloads/kibana)
設定
[Setting Up Kibana](https://www.elastic.co/guide/en/kibana/5.0/setup.html)
リファレンス
[Kibana Reference: 5.0.0-alpha5](https://www.elastic.co/guide/en/kibana/5.0/index.html)

5.0.0-alpha5バージョンをダウンロード & 解凍して好きなディレクトリに置く

config/kibana.ymlの

```yaml:config/kibana.yml
# elasticsearch.url: "http://localhost:9200"
```
をコメントアウト --> これしなくてもelasticsearchと連携できたのでデフォルトでポート9200を見てるっぽい

```bash
cd kibana-5.0.0-alpha5-darwin-x86_64

# 起動コマンド
bin/kibana
```
[http://localhost:5601/](http://localhost:5601/)にアクセス

## CSVインポート
[http://localhost:5601/](http://localhost:5601/)にアクセスするとこのような画面になる

![4d837d1b-4cc0-4ffd-8bb6-7efcd974ddf4.png](https://qiita-image-store.s3.amazonaws.com/0/95469/d7ccce63-472e-f873-f3f2-a41916886b95.png)


左のバーから「Management」 --> 「Upload CSV」かトップページの「Upload CSV」を選択

![b5344049-17f0-0faa-59f6-0d11c71340d3.png](https://qiita-image-store.s3.amazonaws.com/0/95469/82a4e8f9-6393-3152-072e-a0ca07c7e74b.png)


このへんから[http://k-db.com/](http://k-db.com/)てきとうなCSVを探してアップロード。
**UTF-8じゃないと文字化けするので注意する(Shift_JISだと文字化けする)**

![3469ff42-5e68-68ee-edd6-a52101dc54f4.png](https://qiita-image-store.s3.amazonaws.com/0/95469/63c45d35-bfe1-2b4d-bd0e-4ab1e15fa3b3.png)


表示されたら「Next」ボタンで次へ

![8332fb9f-1102-f25f-c402-2e3065701a2d.png](https://qiita-image-store.s3.amazonaws.com/0/95469/93d67e05-e57a-ba55-4b3f-58ccce927650.png)



左上のindex nameを入力して「save」する

![34153d5f-97b4-f49f-875e-0e621b45e5b5.png](https://qiita-image-store.s3.amazonaws.com/0/95469/d9837152-07a1-456c-e27a-0c0f427f56ce.png)



Created XXXX documents!がでればインポート完了。

![5fa96a6e-44ad-3c66-922e-0ff1a2a4b466.png](https://qiita-image-store.s3.amazonaws.com/0/95469/46e3810a-348b-0600-fb21-d98ddf0dc822.png)


ちゃんと入ってる

## まとめ
kibanaってバージョン上がるたびにUIのデザイン変わるよね！！
Xcode8がすぐ固まる場合の対処方法

Xcode8をインストールしてから頻繁にXcode8がフリーズするようになったので、対処方法メモです。
環境はmacOS Sierra(10.12)、Xcode8.0(8A218a)です。

* Xcodeを起動している場合は終了します
* システム環境設定を開きます
* セキュリティとプライバシー > プライバシー > 連絡先をクリックして、Xcodeのチェックを外します。

<img width="662" alt="pref.png" src="https://qiita-image-store.s3.amazonaws.com/0/5699/8a967caf-af2a-c02b-9ed8-71050d1f91e8.png">

以上！
MA2016 myThings〜はじめてのIoT〜に参加したよ〜

## myThings利用によるサービス開発

```
株式会社リクルートホールディングス：伴野さん
講師：ヤフージャパン　山本さん
```

### myThingsのサービス

* [myThings](https://mythings.yahoo.co.jp/) (Android/iOS) 
* [myThingsDeveloper](https://mythings-developers.yahoo.co.jp/)

## myThingsの基本機能について

```
○○が××ばつだったら
△△を■■する
```

など、iOS/Androidアプリ上でGUIベースで簡単に自分専用アプリが作れるスグレモノ！

現在対応しているプロダクト（API/アプリ)は約50アプリ

## 本日のやることIoTデバイスのプロトタイピングを始めよう

* myThingsを使用してIoTを始めてみよう
* myThingsを使ったアイディアソン

[myThingsハンズオンの参考資料](http://goo.gl/BHN5u2)

## 覚えていただく用語について

```
○○が××だったら   <=トリガー
△△を■■する      <=アクション
```

○○ △△はチャンネルの位置付け

### myThings IoTの基本セット
・Raspberry Pi2 ModelB
・ブレッドボード
・USBシリアルアダプター

### myThingsの基本動作
・トリガーは15minの定期間隔のポーリングで実施される（または手動実行も可能）
・アクションはwebsocketやポーリングなどで実施が可能

### クラウドサービスIDCFとも連携できるよ！？

IDCFチャンネルでできることはカスタムイベント・トリガーを作ることが可能です。

```
Twitter <--- myThings ----> Aaction <-----raspi(データを送信）
```

### 今日実装すること

○○が××だったら、IDCDのアクションに通知を送る
RaspiでIDCFのアクションを監視して、通知が来てたらLEDを光らせる

Raspiで温度をセンシングして27度以上だったらIDCFのトリガーに通知を送る
IDCFのトリガーに通知が来たら△△を■■する

詳細はこちらー [【myThingsハンズオン】○○が☓☓だったら、LEDを光らせよう](http://qiita.com/yamamotomanabu/items/4818906490b0b0d12236)

やってみた

![IMG_4393.JPG](https://qiita-image-store.s3.amazonaws.com/0/93976/ce279bed-d144-db66-b36f-0c255e277b44.jpeg)


### myThingsDeveloper機能について

何はともあれ、登録してみよう [myThingsDeveloper](https://mythings-developers.yahoo.co.jp/)


カスタムトリガーについて・・・自身でトリガーを作成することが可能。トリガー元となるデバイスやプログラムでトリガーイベントを発動させることが可能

作成例
お米がなくなったら自動的にカートに追加する（○○が××だったらを自作）

例：自作デバイスでお米残量をキャッチ => LOHACOでカートに追加（合わせてTweetする）

<img width="872" alt="カスタムトリガー.png" src="https://qiita-image-store.s3.amazonaws.com/0/93976/a1877d82-20a0-ccad-21a5-5f9080d13519.png">


カスタムアクションについて・・・自身でアクションを作成することが可能。トリガーからキャッチするイベントをデバイスまたはイベントプログラムを実行することができる

例：ヤフーの天気で雨だった場合に特定のURL（API）にリクエストを送り、取得したJsonから今日の天気をホームページに反映させる

```
ヤフーから天気情報をjson形式でキャッチ
それらをURLに対してPostしてごにょごにょできる
```

### アイディアソンタイム

15分という短い中、2チームに分かれてアイディアソンを実施しました。

![IMG_4394.JPG](https://qiita-image-store.s3.amazonaws.com/0/93976/2fd39eff-cd51-e8d7-05c8-8656295b2fe2.jpeg)

ピザ食べながら :smile: 

チーム：ナハx4

```
・毎月の食費上限をzaimに登録
・好きなレシピをcookpadから取り出し（トリガー）、WEBショッピングにて自動的に食材を購入（アクション）
・zaimの食費上限値を超えていなければ（トリガー）、Facebookに今月達成の記事投稿を行う（アクション）
```

![IMG_4395.JPG](https://qiita-image-store.s3.amazonaws.com/0/93976/14dfb63f-cb2a-7c9d-3c16-5bf258b29982.jpeg)

チーム：沖縄野球Aチーム

```
・筋トレの回数をAppleWatchで回数をカウント（トリガー）
・規定回数以上の筋トレが完了したら、デバイスプロジェクションマッピングを作動させる（アクション）
```

![IMG_4397.JPG](https://qiita-image-store.s3.amazonaws.com/0/93976/fd0ec77d-fb7d-fcbb-0174-2518184d3148.jpeg)

## 参加してみて

* myThingsを触ってみて、既存アプリでもノンプログラマでも簡単に自作アプリが作れること
* myThingsDeveloperを利用することにより、更に高度なサービスの開発を作ることが可能となる


## お疲れしたー！

![集合写真.jpg](https://qiita-image-store.s3.amazonaws.com/0/93976/9d51df8a-ddcc-7c71-f02d-4aed75cc459c.jpeg)


## 10/1,2にMA2016沖縄予選があるよ！

是非是非ご参加を〜
[MA2016 沖縄 KDDIウェブコミュニケーションズ、日本マイクロソフト、ぐるなび〜](https://mashupawards.doorkeeper.jp/events/51864)
ActiveAdminのCSVダウンロードをカスタマイズする


[ActiveAdmin](https://github.com/activeadmin/activeadmin)のリソースのindexには、モデルの全データをCSVダウンロードするボタンがついてくるが、行や列を絞ったCSVをダウンロードするボタンを追加してみる。（結果的には、CSVを一行ずつ組み立てるだけ）

```Ruby
ActiveAdmin.register Klass do
  before_filter :skip_sidebar!
  
  collection_action :download_report, method: :get do
    query = Klass.get_query
    csv_data = CSV.generate do |csv|
      csv << %w{col1 col2}
      query.each do |row|
        csv << [row.col1, row.col2]
      end
    end
    send_data csv_data, type: 'text/csv; header=present', disposition: 'attachment; filename=file.csv'
  end

  action_item only: :index do
    link_to 'download report', params.merge(action: :download_report)
  end

  index download_links: false do
    # ...
  end
end
```

# 参考
以下をコピーして修正した

- https://codedump.io/share/JdwI3J2Knkx/1/active-admin-csv-export-custom-query-scoped
The server quit without updating PID file → mysql起動コマンドのsudo忘れでした

mysqlが起動せずに四苦八苦していました。それで、__いつもの__ディレクトリの権限やプロセス周りを疑っていたのですが、今回は凡ミスでした。

エラー。

```bash
$ mysql.server start
ERROR! The server quit without updating PID file
```

sudoをつけて解決。

```bash
$ sudo mysql.server start
Starting MySQL
... SUCCESS!
```



#### いつもお世話になっている記事

- [mysqlが起動できなくなった（Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)）
](http://qiita.com/carotene512/items/e00076fe3990b9178cc0)
- [mysqlを起動しようとしたらPIDファイルがnot foundで起動できないのを解決する話
](http://qiita.com/YamKenta/items/a33499a7db7946a43381)
テーブルのカラム名をプログラム中に取得したい。

PHP5.6
SQL文を動的に組み立てたい時などに。

```
class Db
{
  // ・・・

  private $pdo; // PDOインスタンス必要

  public function getColumnNames($table_name)
  {
    $sql = "SELECT * FROM {$table_name} LIMIT 0";
    $stmt = $this->pdo->query($sql);
    for ($i = 0; $i < $stmt->columnCount(); $i++):
      $column_names[] = $stmt->getColumnMeta($i)['name'];
    endfor;

    return $column_names;
  }

  // ・・・
}
```
RubyでAPIを叩く(#1 DigitalOcean SDK編)

RubyでクラウドサービスのAPIを叩くノウハウは、ネット上にも結構載っています。
**「SDKでいいんじゃね？」**というご意見もごもっともです。AWSをはじめ大抵のパブリッククラウドはRuby用のSDKを備えているのですが、ニフティクラウドのように途中で[提供を終了](http://cloud.nifty.com/cs/catalog/cloud_news/catalog_140226001680_1.htm)してしまったり、ドコとは言いませんが恐ろしいことに全くSDKを提供していない恐ろしいパブリッククラウドも世の中にはあります。

いい加減、自分でリクエストを作ってcurlを叩く生活にも疲れたので、RubyでAPIを叩くラッパーを作ってみたいと思い立ちました。SDKを提供していない素敵クラウドについてはちょっと書けないので、たまたま自分が契約している[DigitalOcean](http://www.digitaloean.com)を練習台にしてみます。

## まずは普通にSDKを使ってみよう

DigitalOceanには公式Ruby用SDK([DropletKit](https://github.com/digitalocean/droplet_kit))があります。
gemで普通に突っ込めばいいや、と思いましたが、怒られました。

`gem install droplet_kit`
とすると、`ERROR:  Error installing droplet_kit: activesupport requires Ruby version >= 2.2.2.`と怒られます。私が使っているEl CapitanのRubyは2.0…orz。

いささか面倒くささを感じながらもrbenvでRubyのバージョンを2.3.1にします。
今度は入った。

DigitalOceanのサイトからトークンを取っておき、まずは簡単なアクセスをしてみます。

```ruby:doclient.rb
require 'droplet_kit'

token = '取得したトークン'
client = DropletKit::Client.new(access_token: "#{token}")
droplets = client.droplets.all
droplets.each do |droplet|
  p droplet
end
```

droplet.allで取ってきた場合、eachにしないと駄目みたいです。
こういう出力になります。

```
<DropletKit::Droplet {:@id=>26530455, :@name=>"centos-512mb-sgp1-01", :@memory=>512, :@vcpus=>1, :@disk=>20, :@locked=>false, :@created_at=>"2016-09-22T11:49:56Z", :@status=>"active", :@backup_ids=>[], :@snapshot_ids=>[], :@action_ids=>nil, :@features=>["virtio"], :@region=><DropletKit::Region {:@slug=>"sgp1", :@name=>"Singapore 1", :@sizes=>["512mb", "1gb", "2gb"], :@available=>true, :@features=>["private_networking", "backups", "ipv6", "metadata"]}>, :@image=><DropletKit::Image {:@id=>19779752, :@name=>"6.8 x64", :@distribution=>"CentOS", :@slug=>"centos-6-x64", :@public=>true, :@regions=>["nyc1", "sfo1", "nyc2", "ams2", "sgp1", "lon1", "nyc3", "ams3", "fra1", "tor1", "sfo2", "blr1"], :@type=>"snapshot"}>, :@networks=>#<struct DropletKit::NetworkHash v4=[#<struct DropletKit::Network ip_address="(グローバルIP)", netmask="255.255.192.0", gateway="（グローバルIP)", type="public", cidr=nil>], v6=[]>, :@kernel=>nil, :@size_slug=>"512mb", :@tags=>[], :@names=>nil, :@volumes=>nil, :@ssh_keys=>nil, :@backups=>nil, :@size=>nil, :@ipv6=>nil, :@user_data=>nil, :@private_networking=>nil}>
```

Dropletを2つ起動していれば、2つ分の情報が出力されます(貼り付けませんが)。

DropletのIDが分かっていれば、削除も簡単です。

```ruby:del_droplet.rb
require 'droplet_kit'

token = '取得したトークン'
id = '対象のID'
client = DropletKit::Client.new(access_token: "#{token}")

client.droplets.delete(id: "#{id}")
```

Dropletの削除はtagからでもできる(droplets.delete_for_tag)のですが、それ以外の操作全般には結局IDが必要なので、早めに操作対象のIDを取得しておくに越したことはないようです。

最後に、順序は逆っぽいですがDropletの作成。

```ruby:create_droplet.rb
require 'droplet_kit'

token = '取得したトークン'

client = DropletKit::Client.new(access_token: "#{token}")
droplet = DropletKit::Droplet.new(
  name: "test",
  region: "sgp1",
  size: "512mb",
  image: "ubuntu-14-04-x64",
  ipv6: false
)

client.droplets.create(droplet)
```

ほぼAPIサンプルのままですが、これだけで適当なDropletがすぐ作成できます(パラメータはもっとありますし、SSH鍵も指定してないので上記では不完全です)。

## 結論:SDKは

やっぱり楽ですね:-)。
自分でURLを叩いて行こうとすると、今回droplet_kitが裏でやってくれていることを全部面倒見ないといけないわけです…。

こんな便利なライブラリがある以上、DigitalOceanであえてRubyから直接APIを叩く理由なんてほとんどないわけですが、そこは修行の一環ということで、次回から徐々にAPIにアクセスしていきたいと思います。
electronメモ

electron書くときの自分用メモ。

**********************************************************************
雑多なメモ。

・参考URL
　・入門
　　　https://ics.media/tutorial-electron
　・node.jsのインストール
　　　http://qiita.com/seibe/items/36cef7df85fe2cefa3ea
　・menuをレンダラープロセスから作る。
　　　https://github.com/electron/electron/blob/master/docs-translations/jp/api/menu.md
　・ローカルファイルの読み書き
　　　https://ics.media/entry/8401/2
　　　http://programmer-jobs.blogspot.jp/2016/06/electron-save-file.html

・electronはnode.jsを使った技術。
　起動方法は以下。
　・electronをグローバルにインストールし、以下のコマンドで実行することも
　　ある。
　　　npm install electron-prebuilt -g
　　　electron ./
　　　(サンプルはhttps://ics.media/entry/7298/2)
　・package.jsonを書いてnpmで以下のコマンドにより実行することもある。
　　　npm install && npm start
　　　(サンプルはhttps://github.com/electron/electron-quick-start)
　　結局はnpm startでelectron ./を実行するような設定がpackage.jsonに
　　書いてあるだけ。

・electronにはメインプロセスとレンダラープロセスがある。
　　http://developers.mobage.jp/blog/electron-security

　メインプロセスが親玉で、レンダラープロセスの起動や右クリックメニューの表示を担当。

　レンダラープロセスがchromium上で動いているプロセスで表示画面の処理を担当。

　レンダラーからメニューの登録をする場合、
　レンダラープロセスからメインプロセス内の機能を呼び出すためremoteを使う。

・ubuntuへのnode.jsインストール。
　apt-getでインストールするものは古いので以下の方法をとる。
　　http://qiita.com/seibe/items/36cef7df85fe2cefa3ea

**********************************************************************
[Electron] BrowserWindow の proxy ユーザ認証方法

ユーザ認証が必要な proxy 環境下で Electron の BrowserWindow を使った時に、ユーザ認証を行う方法のメモです。

ログイン認証が発生した時にコールバック関数にユーザ名とパスワードを指定して呼び出すことで、 proxy のユーザ認証を行うことができます。

```js
var electron = require('electron');
var app = electron.app;
var BrowserWindow = electron.BrowserWindow;

// ログイン認証が発生した時に呼び出される処理
app.on('login', function(event, webContents, request, authInfo, callback) {
    event.preventDefault();
    // コールバック関数にユーザ名とパスワードを指定して呼び出す
    callback(username, password);
});
```
Vim-railsの:Rserverコマンドがバックグラウンドで起動してくれない件の解決策


Vimのrails用プラグイン「[tpope/vim\-rails: rails\.vim: Ruby on Rails power tools](https://github.com/tpope/vim-rails)」は、数々の便利な機能が利用できるプラグインですが、開発用サーバー（コマンドラインで`$ rails server`して起動するやつ）をVim上から、`:Rserver`でバックグラウンドで起動してくれるというのがあります。

しかし、これが私の環境（MacVim on Mac）だと、どうもうまくいかずフォアグラウンドでしか起動してくれません。


# 解決策
Vim上で`:Rserver -d`（デーモンとして起動する）

# 終了するには
Vim上で`:Rserver! -d`（デーモンを終了する）


# 余談
まぁ、普通にコンソールの別プロセスというか別タブで普通に起動すればいいんですけどね。


# 参考リンク
 - [tpope/vim\-rails: rails\.vim: Ruby on Rails power tools](https://github.com/tpope/vim-rails)
 - [vim\-rails よく使いそうなやつ \- Qiita](http://qiita.com/bibio/items/ac3f0cb8e7949b2ce56c)
Node.js アプリで Babel の ES2015 を利用する（babel-register）


新しめの Node.js なら ES2015(ES6) のシンタックスをかなりサポートしていますが（参考：[Node.js ES2015/ES6 support](http://node.green/)）、例えば stage 段階の機能を個別に取り込んだり等、利用する機能を自分でコントロールしたい場合。

> `babel-node` で起動すればよいという話もありますが、production 環境で使うべきでないと公式に書いてある（参考：[CLI · Babel](https://babeljs.io/docs/usage/cli/)）ので。ただ今回の `barel-register` を利用する方法だと起動に少し時間がかかります（各 JS ファイルを読み込むタイミングで Babel 変換するので）。

### 前提となる私の環境

> OS：`OS X 10.11.5（El Capitan）`
> Node：`6.2.1`
> npm：`3.10.7`

まず `babel-register` と `babel-preset-es2015` を npm コマンドでプロジェクトに導入します。

```sh:
$ npm install -S babel-register babel-preset-es2015
```

また今回はプラグインを導入する例として、現在(2016.09.22)ではまだ stage 段階である [class properties を有効にするプラグイン](https://babeljs.io/docs/plugins/transform-class-properties/) を導入してみます。

```sh:
$ npm install -S babel-plugin-transform-class-properties
```

`.babelrc` において、`presets` に `babel-preset-es2015` を、プラグインに `babel-plugin-transform-class-properties` を指定します。

```json:.babelrc
{
  "presets": ["es2015"],
  "plugins": [
    "transform-class-properties"
  ]
}
```

確認用のプログラムを作り試してみます。`class-properties` を利用した `Porson.js` を定義して `export` し、

```javascript:Person.js
class Person {
  name = 'Yamada'

  hello() {
    console.log(`Hello! ${this.name} san.`)
  }
}

export default Person
```

今回のアプリの起点となる `app.js` で `import` します。

```javascript:app.js
import Person from './Person'

const person = new Person() // インスタンス化
person.hello() // メソッドを呼び出し
```

あとは、任意の Node.js アプリを次のように起動するだけです。

```sh:
$ node -r babel-register ./app.js
```

![スクリーンショット 2016-09-23 15.14.39.png](https://qiita-image-store.s3.amazonaws.com/0/35733/f6080cff-e92d-e4d8-2122-e57e979c1130.png "スクリーンショット 2016-09-23 15.14.39.png")

> `-r` オプションでプリロードに `babel-register` を指定しています。これによりプリロードした以降に読み込む JavaScript は自動で Babel 変換がされます。

WebStorm 等で起動する場合は、次のように `Run/Debug Configurations` の設定で `Node parameters` に `-r babel-register` を指定すればよいです。

![debug-sample.png](https://qiita-image-store.s3.amazonaws.com/0/35733/9c0bc3b8-8fd9-94b8-dc29-07a7f366a567.png "debug-sample.png")

> 上記のように WebStorm から起動する場合はブレークポイントを設定してデバッグすることが可能になります。特に別途、ソースマップを出力する必要はありません。

## ほか

起動する際に毎回 `-r babel-register` を指定するのは面倒なので、npm scripts を定義しておくと良いと思います。例として今回の `package.json` は次のようになります。

```json:package.json
{
  "name": "es2015-node-app",
  "version": "0.0.1",
  "scripts": {
    "start": "node -r babel-register ./app.js"
  },
  "dependencies": {
    "babel-plugin-transform-class-properties": "^6.11.5",
    "babel-preset-es2015": "^6.14.0",
    "babel-register": "^6.14.0"
  }
}
```

この例だと `$ npm start` でアプリを起動することができます。

ソースコード全体は GitHub に置いておきます。
⇒ https://github.com/hkusu/es2015-nodejs-example
brew update: /usr/local 権限周りの問題＝更新で解消

### 環境
- MacBook (Retina, 12-inch, Early 2015)
- **macOS** Sierra（バージョン10.12）

### not writable エラーで `brew update` できない

macOS Sierra（バージョン10.12）へ更新したついでに `brew update` を行ってみると

```console
$ brew update
Error: The /usr/local directory is not writable.
Even if this directory was writable when you installed Homebrew, other
software may change permissions on this directory. Some versions of the
"InstantOn" component of Airfoil are known to do this.

You should probably change the ownership and permissions of /usr/local
back to your user account.
  sudo chown -R $(whoami):admin /usr/local
```

- `/usr/local` が not writable なので更新できません
- ownership と permission　を変更してみては

と表示される。

### ownership を変更してから `brew update`

指示通り、以下のように実施すると更新できた：

```console
$ sudo chown -R $(whoami):admin /usr/local
$ brew update
Checking out files: 100% (3753/3753), done.
==> Migrating Homebrew to v0.9.9
remote: Counting objects: 923, done.
remote: Compressing objects: 100% (814/814), done.
remote: Total 923 (delta 228), reused 511 (delta 85), pack-reused 0
Receiving objects: 100% (923/923), 670.29 KiB | 589.00 KiB/s, done.
Resolving deltas: 100% (228/228), completed with 156 local objects.
From https://github.com/Homebrew/brew
 + eb4538c...bbed724 master     -> origin/master  (forced update)
HEAD is now at bbed724 Merge pull request #1078 from ilovezfs/cmake-weak-symbols
==> Homebrew has enabled anonymous aggregate user behaviour analytics
Read the analytics documentation (and how to opt-out) here:
  https://git.io/brew-analytics
==> Tapping homebrew/core
Cloning into '/usr/local/Library/Taps/homebrew/homebrew-core'...
remote: Counting objects: 3725, done.
remote: Compressing objects: 100% (3617/3617), done.
remote: Total 3725 (delta 15), reused 1247 (delta 0), pack-reused 0
Receiving objects: 100% (3725/3725), 2.91 MiB | 517.00 KiB/s, done.
Resolving deltas: 100% (15/15), done.
Checking connectivity... done.
Tapped 3604 formulae (3,752 files, 9M)
Already up-to-date.
==> Migrating HOMEBREW_REPOSITORY (please wait)...
==> Migrated HOMEBREW_REPOSITORY to /usr/local/Homebrew!
Homebrew no longer needs to have ownership of /usr/local. If you wish you can
return /usr/local to its default ownership with:
  sudo chown root:wheel /usr/local
```

表示されたメッセージ末尾に以下があるのに気づいた：

- '/usr/local' に対する ownership はもう不要です
- 必要なら初期値に戻してもいいですよ

### ownership を初期値に戻してから `brew update`

```console
$ sudo chown root:wheel /usr/local
$ brew update
Already up-to-date.
```

その通り、初期値に戻して再度 `brew update` しても更新完了するようになっている。

更新後のバージョンは下記の通り

```console
$ brew --version
Homebrew >1.0.0 (no git repository)
Homebrew/homebrew-core (git revision 7ae6; last commit 2016-09-22)
```

以下のやりとりの通り、わりと最近のissue（opened this issue 5 days ago on 2016/09/22）で対処されたようだ

[/usr/local/Homebrew migration tracking issue #987](https://github.com/Homebrew/brew/issues/987)

### 補足
- git 版は使っていませんが、おそらく同じ挙動を得られると思います
- 新規インストールであれば、この対処が済んだバージョンをインストールするので、ownership 変更はそもそも不要と思います
rsync --link-dest はランサムウェア対策バックアップに相性がよい

###rsync --link-destオプション
***
コピーを作成する際に--link-destで指定したディレクトリにコピー元と同じファイルがあればコピー先に新たにファイルをコピーする代わりに--link-destにあるファイルからハードリンクを生成する。
###rsync --link-destを使用したインクリメンタルバックアップのよさ
***
差分バックアップ相当のバックアップ時間とディスク消費なのに作成される実体はフルバックアップそのものとなること。取得したバックアップ世代全てがフルバックアップなのでこのバックアップはいつの差分で、いつのフルバックアップの上にリストアすべきなのか、考える必要がない。
###ランサムウェア感染時
***
ランサムウェア感染PCからのアクセスによりファイルサーバ上の一部フォルダのファイルが暗号化されてしまった場合、気付かずに放置しておくと暗号化されたファイルがバックアップされてしまう。しかしインクリメンタルバックアップによってそれ以前のバックアップが暗号化ファイルで上書きされることはない。被害に気付くまでの期間を考慮した世代数分のインクリメンタルバックアップ履歴を確保しておけばよい。
###ランサムウェア感染後の復旧
***
ファイルサーババックアップの各世代を読み込み専用で公開しておけば、エンドユーザが自ら暗号化前の世代を見つけてリストアできる。各世代ともフルバックアップなので直観的な操作が可能。読み込み専用なのでランサムウェアに暗号化されることもない。
###世代ローテーション
***
バックアップの全ての世代がフルバックアップなので、単純に古い世代のディレクトリから削除すればよい。
###--link-dest指定先ディレクトリ
***
常に1世代前（直近）のバックアップディレクトリを指定すればハードリンクされる効率が高い。
###インクリメンタルバックアップの典型パターン
***
ログローテーションと同じ感覚で例えばこんな感じ。

```
rm -rf backup_dir.4
mv backup_dir.3 backup_dir.4
mv backup_dir.2 backup_dir.3
mv backup_dir.1 backup_dir.2
mv backup_dir.0 backup_dir.1
mv backup_dir backup_dir.0
rsync -a --link-dest ../backup_dir.0/ source_dir/ backup_dir
```

###制限事項
***
ファイルサーバ自身のランサムウェア感染には無力(Linuxに感染するランサムウェアもあるので）。

###参考
***
[書籍:オライリー Linuxサーバ Hacks](https://www.oreilly.co.jp/books/487311151X/)
デスクトップキャプチャについて

#やったこと　2016/9/22

VisualStudio2015 baseclasses.sln にてstrmbasd.libの生成を確認
Pushsource.slnのプロジェクトをビルド。strmbasd.libがリンクできていることは確認

ただし、strmbasd.libの中で標準関数(labs(),memcmp(),memcpy(),memset())の実体がないと言われてエラーになっているのが現状。
　=> 原因として、Dxライブラリが古い？
　　=> DXライブラリの最新版を入手。C:\DxLib フォルダ以下に展開

Pushsource.slnのプロジェクトのプロパティに、以下の変更を反映
　・ 「C/C++」の「全般」タグの「追加のインクルードディレクトリ」および「リンカー」の「全般」タグの「追加のライブラリディレクトリ」に、以下の絶対パスを追加
 　c:\DxLib_VC\プロジェクトに追加すべきファイル_VC用

試してみたが、問題解決せず......

インクルードファイルの中身を見る時は以下に格納されている
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include

仕方がないので、上手くシンボル解決ができているプロジェクトからPushsource.slnのプロジェクトに対して、「リンカー」→「入力」タブ→「追加の依存ファイル」の設定をコピーして、strmbasd.lib(Releaseモードのときはstrmbase.lib)を追加。
　=> 多くのシンボル未解決問題は、ひとまず解消
　=> Pushsource.defに、未定義シンボルが2個残っている模様

上手くシンボル解決できているプロジェクトと、うまくいかないプロジェクトで、ソースファイルの前処理結果(*.i)を取って比較してみた。
　=> 両者とも、memcmpのプロトタイプ宣言もできており、呼び出すコードも問題なさそうであった。
　=> なのに、何故片方は未解決と言われるのか？
　　=>　さらに調べたところ、うまくいかないほうは「リンカー」=>「入力」タブ=>「すべての既定のライブラリの無視」が「はい(つまり、無視する)」になっていた。
　　=> これを取ったところ、memcmpやmemcpyなどで出ていたシンボル未解決のリンクエラーは解消。
　　=> まだ少しだけエラーあり。_imp_timeGetTime()と_imp_timeSetEvent()が未解決と言われる。
macOS SierraにしたらcordovaでiOSにデプロイするとエラーになる

# 具体的な症状

iPhoneの実機にインストールされるが、以下のようなエラーが出力され、アプリが起動しない。

```shell-session
(lldb)     run
Traceback (most recent call last):
  File "/tmp/6E404B4D-DAFC-4EF2-8EFF-06E51BCCDA7C/fruitstrap_5af0fd7f146e954c1a4e425e5218b7c1ba3cc65b.py", line 36, in run_command
    lldb.target.Launch(lldb.SBLaunchInfo(shlex.split(args[1] and args[1] or '')), error)
IndexError: list index out of range
(lldb)     safequit

Application has not been launched

Error: Error code 1 for command: ios-deploy with args: --justlaunch,--no-wifi,-d,-b,/Users/junichi/work/cordova/cmdtest/platforms/ios/build/device/CmdTest.app
```

# 対応策

- [Xcode 8 error code 1 on launch (ios10) and can’t run](https://forum.ionicframework.com/t/xcode-8-error-code-1-on-launch-ios10-and-cant-run/63412)

どうやら、Xcodeが原因の模様。新しいios-deployを入れることで無事解決。

```shell-session
npm install -g ios-deploy
```

# 関連記事

- [iOSでもCordovaプラグインを作ってmrubyを動かした](https://abrakatabura.hatenablog.com/entry/2016/10/08/072147)
- [cordovaのプラグインを作ってkindle fireでmrubyを動かしてみた](https://abrakatabura.hatenablog.com/entry/2016/09/21/070123)
- [High Sierraに2台のMacをアップデートした](https://abrakatabura.hatenablog.com/entry/2017/10/01/184010)
コの字アクリルパイプでケースを作ってみる

電子工作で小型化したので、今度はそれを入れるケースを作ります。

![P9220161.JPG](https://qiita-image-store.s3.amazonaws.com/0/129898/95eb78a5-4979-c89b-cc09-750373804caf.jpeg)

↑を入れる、こんなケースです。

<img width="320" alt="13179466_886020358190060_5104419328309150467_n.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/129898/80eddd7a-23c6-26be-8abc-cfcf8b75acfe.jpeg">

材料は、コの字のアクリル・パイプと、台座になります。

# LEDスティック

8個のLEDスティックを2つ連結しています。

![P9220162.JPG](https://qiita-image-store.s3.amazonaws.com/0/129898/e83d85c0-827f-9419-aefe-37d6f9fd52d1.jpeg)


# アクリル・パイプ

3mm の透明アクリル板を組み合わせたアクリル・パイプを使います。
断面はこんな感じです。東急ハンズで入手しました。

![pipe.png](https://qiita-image-store.s3.amazonaws.com/0/129898/7834a554-ecbb-c542-9552-a15d1d16ad3c.png)

長さが長かったので、155mm にカットしてもらっています。

# 台座

台座はこんな感じです。

![P9220163.JPG](https://qiita-image-store.s3.amazonaws.com/0/129898/30d11415-5953-588b-13dd-1eab5066e272.jpeg)

3D CAD で設計して、DMM.make で 3D プリントしました。
素材はナイロンです。

Autodesk の 123D という 3D CAD ソフトを使って作りました。
とても簡単な機能だけしか使ってません。

まず、長方形を作ります。
アクリル・パイプが 20x26x155 なので、底に 4mm、両端に 3mm に縁をつけて、24mm x 26mm x 161 mm の長方形にします。

![3Dmodel1.png](https://qiita-image-store.s3.amazonaws.com/0/129898/4daa6b1a-2c2f-6e08-fa0c-0cba03f19f57.png)

次に、アクリル・パイプをハメる部分を削ります。

![3Dmodel2.png](https://qiita-image-store.s3.amazonaws.com/0/129898/693bd9a0-0aeb-d7fe-518f-3cfdc3536302.png)

基板部分が LED より少し低くなるので、基板を置く部分を少し下げていきます。
基板は 20mm x 46mm くらいなので、この大きさで 2mm 下げます。

![3Dmodel3.png](https://qiita-image-store.s3.amazonaws.com/0/129898/0d18065d-5b9d-2aa2-62d1-582450171598.png)

さらに、アクリル・パイプを支える部分を 3mmx3mmx109mm で盛り上げて作ります。

![3Dmodel4.png](https://qiita-image-store.s3.amazonaws.com/0/129898/f7b4d729-1efe-c985-f689-10a913844552.png)

スティック LED のウラがはんだ付けで盛り上がってるので、これを避けて支えとする部分を1m の高さで作っていきます。

![3Dmodel5.png](https://qiita-image-store.s3.amazonaws.com/0/129898/4df41c36-989e-f782-9e62-ef906a65d8e9.png)

最後に、USB を挿すための口を作って終了。

![3Dmodel6.png](https://qiita-image-store.s3.amazonaws.com/0/129898/a3bbd022-e5e5-66db-a91f-23ce8a938c59.png)

届いた台座にアクリルパイプを合わせてみると、ぴったりハマりました :sparkles: 

![P5080015.JPG](https://qiita-image-store.s3.amazonaws.com/0/129898/773471bf-212c-b101-dc17-83155d8790e0.jpeg)


LED スティックが左右にズレてしまうのが反省点です :sweat_drops:
Ansible Tower を Vagrant で構築する

# ●1. はじめに

AnsibleにWeb GUIツール等を付加する「[Ansible Tower](https://www.ansible.com/tower)」を構築するには、
大きく分けて以下の3つの方法があります。

   1.   普通に自前のLinuxにインストールして構築
   2.   VagrantでLinuxごと構築
   3.   AWSのAMIを利用して構築

今回は比較的手軽な「2. VagrantでLinuxごと構築」をやってみたいと思います。

- 環境
    - Windows 10
    - VirtualBox 5.1.6
    - Vagrant 1.8.5

# ●2. Vangrant側操作
``` text
vagrant init ansible/tower
vagrant up --provider virtualbox
```
[3 WAYS TO TRY TOWER FREE](https://www.ansible.com/tower-trial)を参考にしました。

ネットワーク環境にもよりますが、完了まで数分間かかります。

# ●3. 仮想OS側操作

前項のVagrant側操作で `Waiting for machine to boot. This may take a few minutes...`
というログがでたあたりから、VirutalBoxの管理画面で、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/124069/8bf4de3e-7b54-437d-87c3-966c1cd6b99d.png)

のように新しい仮想マシンができているのが確認できるので
`表示`でコンソールを開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/124069/cfcd5f32-977b-7921-1dad-406ff4fcafc1.png)
ログインプロンプトになっていたら、ユーザ名、パスワードともに「vagrant」でログインします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/124069/689f0a3c-bc63-4a58-9906-42750b710f12.png)


仮想マシンはREHL7の64bit環境です。

# ●4.  Ansible Towerへのログイン
前項のOSログイン時に表示されたURL（https://~）、Username、Password
でログインします。
※私の環境固有かもしれませんが、URLのIPアドレス部分は仮想マシンに実際は割り当たっていなかったので、「ip addr show」で表示されたホストオンリーアダプタ側のアドレスに読み替えました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/124069/4043c367-643e-3abd-1312-53bccf66f339.png)


ログインすると、ライセンス（トライアル版あり）取得と、ライセンスファイル設定の
手順が表示されるので、それぞれ対応して`SUBMIT`ボタンをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/124069/2724a71a-9e33-8756-9804-591bc87f947b.png)

ログイン後画面の一例です。（すでに多少設定された状態です）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/124069/a26a2331-8062-e367-a1fd-bd4747408e19.png)


なお、同梱されているAnsbileのバージョンは2.1.1でした。（2016/09/22現在）

```
[vagrant@localhost ~]$ ansible --version
ansible 2.1.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
```

このように、お試しであればVagrantで構築するのもよいのではないでしょうか。

以上です。
minimagick 没有　imagelist 

https://rmagick.github.io/ilist.html

minimagick 没有  imagelist

https://github.com/minimagick/minimagick/issues/144

https://github.com/mperham/sidekiq/wiki/Problems-and-Troubleshooting　

rmagick不是线程安全的

https://github.com/minimagick/minimagick/search?q=imagelist&type=Issues&utf8=%E2%9C%93
STIのtypeカラムにintegerを使う


integerを使いたくなったのでやってみた。

# 通常のSTI

```ruby
class Message < ActiveRecord::Base
end

class WarningMessage < Message
end

class ErrorMessage < Message
end
```

こんな感じにしておくと、`messages`テーブルの`type`カラム

- `Message`
- `WarningMessage`
- `ErrorMessage`

という文字列が格納される。

# typeをintegerにしたSTI

```ruby
class Message < ActiveRecord::Base
  TYPE_VALUE = 0

  class << self
    def find_sti_class(type)
      case type
      when WarningMessage::TYPE_VALUE
        WarningMessage
      when ErrorMessage::TYPE_VALUE
        ErrorMessage
      else
        self
      end
    end
    
    def sti_name
      case self
      when WarningMessage
        WarningMessage::TYPE_VALUE
      when ErrorMessage
        ErrorMessage::TYPE_VALUE
      else
        self::TYPE_VALUE
      end
    end 
  end
end

class WarningMessage < Message
  TYPE_VALUE = 1
end

class ErrorMessage < Message
  TYPE_VALUE = 2
end
```

こんな感じで、`find_sti_class`と`sti_name`を変更するとintegerで扱える。

子クラスの情報を知る必要があるのが少しイケていない点ではあるけど…。

## gemにしてみた

毎回書くのが面倒なので、gemにしてみた。

[sti_type_customizable](https://github.com/taka0125/sti_type_customizable)

これを使うと

```ruby
class Message < ActiveRecord::Base
  include StiTypeCustomizable
  self.sti_type_value = 0
  sti_child_classes [WarningMessage, ErrorMessage]
end

class WarningMessage < Message
  self.sti_type_value = 1
end

class ErrorMessage < Message
  self.sti_type_value = 2
end
```

と書くことができる。
systemctl用にserviceを追加したのに反映されなかったとき

### 状況
/usr/lib/systemd/systemにサービスを追加して、systemctl startをしようとしても呼ばれなかった。


### やったこと
・systemctl enable　からの　systemctl start

本当に登録されていないのか試す意味でsystemctl enableを試すと、正常にシンボリックリンクが作成された。

あれ？と思ってもう一度systemctl startをすると何故か起動できた。

なので、もしstartができなかったら enable からの start を試して見るべし。
windowの高さを変更してもデザインが崩れない方法

CSSでbox大きさを%で指定すると、windowを拡大・縮小した時に縦横比がかわって形が崩れてしまう場合があります。でもpxで指定するのはいやだ。
そんなときに役に立つ方法を教えてもらったのでメモしておきます。

#padding-topをつかって縦横比を保つ
padding-topを%で指定した時、基準となる長さは親要素のwidthです。

縦横比を崩したくない時はまずwidthとpadding-topを指定したboxを用意し、そのなかで作業を行えばよいです。

## 親boxの高さをheightで指定した時
```css:index.css
    hoge{
      position: relative;
      width: 40%;
      height: 40%;
      background-color: purple;
    }
```
#### windowの大きさが1150px*750pxのとき
![スクリーンショット 2016-09-22 20.34.04.png](https://qiita-image-store.s3.amazonaws.com/0/141150/4acce009-6dcd-6fe7-5448-ce8ac2deab7b.png)

#### windowの大きさが1150px*550pxのとき
![スクリーンショット 2016-09-22 20.34.30.png](https://qiita-image-store.s3.amazonaws.com/0/141150/c2d81a81-7feb-fe56-289c-3fa79acab5b1.png)
windowの高さを変更するとboxのかたちが少し変わっていますね。

## 親boxの高さをpadding-topで指定した時
```css:index.css
    hoge{
      position: relative;
      width: 40%;
      padding-top: 40%;
      background-color: purple;
    }
```
#### windowの大きさが1150px*750pxのとき
![スクリーンショット 2016-09-22 20.35.05.png](https://qiita-image-store.s3.amazonaws.com/0/141150/2581cfa3-e46a-ce18-5946-b12146b859b7.png)

#### windowの大きさが1150px*550pxのとき
![スクリーンショット 2016-09-22 20.34.52.png](https://qiita-image-store.s3.amazonaws.com/0/141150/3baf916c-a18f-8710-50f5-915c9b301593.png)

高さを変えても正方形が保たれていますね。
このように、windowの高さを変更しても縦横比が変わらないので、
このなかで作業をすれば高さの変更によるデザインの崩れが起きずに中身の拡大・縮小をすることができます。
子要素にはpositionをabsoluteに設定しておくのを忘れずに！
Visual StudioからMySQLにアクセス

#インストール

- Connector/Net (ADO.NET driver for MySQL)
  https://dev.mysql.com/downloads/connector/net/

- MySql.Data
  Nugetからインストール。MySQLにアクセスするメソッドが実装されている。

- MySQL for Visual Studio
  https://dev.mysql.com/downloads/windows/visualstudio/
  Visual Studioと連携させるために必要。
  データソースの選択に"MySQL Database"が表示されるようになる。
![connector_net_datasource.PNG](https://qiita-image-store.s3.amazonaws.com/0/64683/75db1fe4-8ba4-cd1b-e75d-87185498fa3e.png)

###実施環境
- Visual Studio Community 2015 Update3
- mysql-connector-net-6.9.9.msi
- MySql.Data v6.9.9
- mysql-for-visualstudio-1.2.6.msi


#Visual Studioからサーバー内のテーブルを見る
テーブルからデータの取得ができる。

1. [表示]メニュー - サーバーエクスプローラーを選択
2. サーバーエクスプローラー - データ接続を右クリック
3. 接続の追加をクリック
4. データソース接続のための情報を入力
MFCのリストコントロールのスクロール位置指定について

#リストコントロールのスクロール
リストコントロールで表示されるスクロールバーは中々曲者であり、いつまで経っても思い通りになってくれない。
MSDNの嘘翻訳じゃ意味が全く分からないので、実験した。
MFC的解法を探したので記述する。

##解：Scroll関数
CListCtrlのScroll()は、相対位置指定である。現在のスクロールバーのつまみの位置から上下にどれだけ移動するかピクセル単位で指定する。
しかし、移動量はRowの高さの倍数でなければならない。端数は考慮されない。
よって、行高さを求め、現在位置を特定し、目的行までの相対行数を求め、相対座標に変換してScrollする。
リストコントロールの基準位置は表示されている最上部の行なので、特定行を中央に表示したい場合などはオフセットするべし。

なお、0行から始まっているので注意。

```cpp
//CListCtrl m_list;
	CRect rc;
	m_list.GetItemRect(0, &rc, LVIR_BOUNDS);//行高さ
	int index = m_list.GetTopIndex();//現在行
	int offset = rc.Height() * (10 - index);//10行へオフセット計算
	CSize cs;
	cs.cx = 0;
	cs.cy = offset;
	if (offset) {
		m_list.Scroll(cs);
	}

```

##駄目だった例
###GetScrollInfo,SetScrollInfo
GetScrollInfoはそれほど悪くない。SetScrollInfoも動作はするが、スクロールバーだけが移動して、リストコントロールの中身は何も移動しない。
スクロールバーを制御してもメッセージが飛ばないのだろう。
App Store と Google Play の ASO 基礎

iOS (iPhone/iPad) のストア App Store と Android のストア Google Play はストアに同じような情報をセットするが、それぞれの検索エンジンのアルゴリズムが異なるため、ASO 対策も異なる。

この記事では、ユーザーが入力する情報のなかで ASO に影響を与える変数をそれぞれまとめる。

なお、App Store も Google Play も検索アルゴリズムは日々アップデートされているので、以下に書いた情報が今後正しい情報である保障はない。以下の情報は過去一年以内に私が調査した結果から得られた知見である。

詳細は元記事にて＞[App Store と Google Play の ASO 基礎](http://monopocket.net/blog/aso/basic/)
rmagick and tempfile

```bash
vagrant@precise64:~/data$ pry
[1] pry(main)> require 'rmagick'
=> true
[2] pry(main)> a = Magick::ImageList.new("./1.jpg")
=> [./1.jpg JPEG 1920x1080 1920x1080+0+0 DirectClass 8-bit 288kb]
scene=0
[3] pry(main)> b = Tempfile.new("1.pdf")
=> #<File:/tmp/1.pdf20160922-5244-1cnwi16>
[4] pry(main)> b.write a.to_blob
=> 311811
[5] pry(main)> exit
```

https://rmagick.github.io/ilist.html#to_blob
[macOS]Text To Speech

<p>今回は、以前のアプリをSwift化するだけの内容だ。</p>

<p>テキストの内容を読み上げるが、それにディレイをかける。</p>

<pre><code>import Cocoa
import AudioUnit
import AudioToolbox
import CoreAudioKit
 
class ViewController: NSViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        demo()
    }
    
    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }
    
    var auGraph: AUGraph? = nil
    
    func demo() {
        var inputNode: AUNode = 0
        var effectNode: AUNode = 0
        var outputNode: AUNode = 0
        
        NewAUGraph(&auGraph);
        
        var	cd = AudioComponentDescription()
        cd.componentType = kAudioUnitType_Generator
        cd.componentSubType = kAudioUnitSubType_SpeechSynthesis
        cd.componentManufacturer = kAudioUnitManufacturer_Apple
        cd.componentFlags = 0
        cd.componentFlagsMask = 0
        
        AUGraphAddNode(auGraph!, &cd, &inputNode)
        
        cd.componentType = kAudioUnitType_Effect
        cd.componentSubType = kAudioUnitSubType_Delay
        AUGraphAddNode(auGraph!, &cd, &effectNode)
        
        cd.componentType = kAudioUnitType_Output
        cd.componentSubType = kAudioUnitSubType_DefaultOutput
        AUGraphAddNode(auGraph!, &cd, &outputNode)
        
        AUGraphConnectNodeInput(auGraph!, inputNode, 0, effectNode, 0)
        AUGraphConnectNodeInput(auGraph!, effectNode, 0, outputNode, 0)
        
        AUGraphOpen(auGraph!)
        AUGraphInitialize(auGraph!)
        
        var generateAudioUnit: AudioUnit? = nil
        AUGraphNodeInfo(auGraph!, inputNode, nil, &generateAudioUnit)
        var channel: SpeechChannel? = nil
        var sz: UInt32 = UInt32(MemoryLayout<SpeechChannel>.size)
        AudioUnitGetProperty(generateAudioUnit!, kAudioUnitProperty_SpeechChannel, kAudioUnitScope_Global, 0, &channel, &sz)
        
        AUGraphStart(auGraph!)
        
        SpeakCFString(channel!, "Nice to meet you. It's nice to see you! Nice meeting you. I'm pleased to meet you. Please say hello to your family. I look forward to seeing you again. Yes. Let's get together soon." as NSString, nil)
    }
    
    func dispose() {
        AUGraphStop(auGraph!)
        AUGraphUninitialize(auGraph!)
        AUGraphClose(auGraph!)
        DisposeAUGraph(auGraph!)
        auGraph = nil
    }
}
</code></pre>

関連情報
<a href="http://www.bitz.co.jp/weblog/?date=20120225">[Mac]談話と特殊効果（Text-to-Speech）</a><br />
<a href="https://github.com/murakami/TextToSpeech">https://github.com/murakami/TextToSpeech</a><br />

【Cocoa練習帳】
<a href="http://www.bitz.co.jp/weblog/">http://www.bitz.co.jp/weblog/</a><br />
<a href="http://ameblo.jp/bitz/">http://ameblo.jp/bitz/</a>（ミラー・サイト）<br />
<a href="https://t.co/6P3h2jtbRk</a>note<br />