OmniAICreator/Qiita-1.07M huggingface dataset:
AndroidStudioでパッケージ名を変更する

## 追記
最近だと、このようなことをせずともUIの方から変更できるようです。
https://mashmorgan.hatenablog.com/entry/2018/06/06/160823

## 以前の記事
AndroidStudioでパッケージ名を変更するのは手順が多くて少し面倒です。
なので、Rubyでスクリプトを作って半自動化してみました。

※実行は、バックアップをとった上で自己責任でお願いします。

```rename_package.rb
require 'find'
require 'fileutils'
require 'tmpdir'

print "Path : "
path = gets.chop
Dir.chdir(path)
Dir.chdir("app")

# 旧パッケージ名の取得
str = File.read("src/main/AndroidManifest.xml")
old_name = str.slice(/package="(.+?)"/, 1)

puts "Old Package : #{old_name}"
print "New Package : "
new_name = gets.chop

# app 以下の全ファイルの置換
Find.find(".") {|path|
	if FileTest.file?(path) then
		str = File.read(path)

		if str.include?(old_name) then
			puts path
			f = File.open(path, "w")
			f.write(str.gsub(old_name, new_name))
			f.close
		end
	end
}

# ディレクトリ構造の変換
old_dir = old_name.gsub(".", "/")
new_dir = new_name.gsub(".", "/")

Dir.chdir("src/main/java")
Dir.mktmpdir() {|tmp_dir|
	FileUtils.mv(Dir.glob(old_dir + "/*"), tmp_dir)
	FileUtils.rm_r(old_dir.split("/")[0])
	FileUtils.mkdir_p(new_dir)
	FileUtils.mv(Dir.glob(tmp_dir + "/*"), new_dir)
}
```

参考ページ
http://qiita.com/nusa/items/413c8a131ebc451e80f8
Unicode, UTF-8, UTF-16

先日会社で PR 書くときに Unicode ってなんなんだっけ…？ UTF-8 と UTF-16 ってなんだ…？となってその場はごまかしたんですが、さすがにぼんやりとでもわかっておいた方がいいのかなと思って調べてみました。
おそらく間違っていたりするので、訂正などいただければ…
書くにあたって色々読んだんですが、 Unicode および文字コードは魔境ということがわかりました。

### Unicodeとは（はじめに）

> 符号化文字集合や文字符号化方式などを定めた、文字コードの業界規格
> Unicode - https://ja.wikipedia.org/wiki/Unicode

つまりどういうことかと言うと、(1)符号化文字集合 と (2)文字符号化方式 などを定めた文字コードの業界規格ということらしいです。
符号化文字集合というのは、あ、い、う、え………などの文字の単なる集合のことを指していて、文字符号化方式というのは文字の集合の一要素に対してコンピュータ上でどう表すか、みたいな表現方法です。
（この Wikipedia の説明もなんだか誤解を招きやすくなっていると思うのですが…）
Unicode というのは単なる文字集合のことを表していて、文字符号化方式に UTF-8 / UTF-16 などがある、というイメージです。

### Unicode の code point
code point というのは符号位置のことで、Unicode では、符号空間が 1 次元のため整数値がふられていて、特に Unicode スカラ値と言われます。`U+` のあとに続けて 16 進数の Unicode スカラ値を書きます。
たとえば、以下のような対応付けがされています。ASCII 文字コードの符号位置は、そのまま Unicode における符号位置と同じになっていました。

```
1 => U+0031
A => U+0041
あ => U+3042
```

ここで重要なのは、この code point が符号化形式ではないということで、これを元に計算した結果が実際の文字コード（表現方法）になります。その計算方式に UTF-8, UTF-16 などがあります。
Unicode スカラ値の範囲については、 `U+0000 - U+FFFF` が BMP の範囲になっており、それ以降の `U+10000 - U+10FFFF` は BMP 以外を表しています。追加の歴史については Wikipedia がよくまとまっています。（ https://ja.wikipedia.org/w/index.php?title=Unicode&action=edit&section=10#.E5.90.84.E3.83.90.E3.83.BC.E3.82.B8.E3.83.A7.E3.83.B3.E3.81.A8.E3.81.9D.E3.81.AE.E7.89.B9.E5.BE.B4 ）
最大値が `10FFFF` なのは、Unicode の符号空間が 21 ビットだからで、これ以降に文字を追加することはない、と（今のところ）言われています。
符号空間が 21 ビットなのは、国際標準である ISO/IEC 10646 に合わせており、この範囲内においては ISO/IEC 10646 と互換性があります。ISO/IEC 10646、最初は 31 ビットの文字空間があったんですが、色々あって 2006 年に正式に 21 ビット以降に文字を追加しないことになったらしいです。

### UTF-8
8 ビット符号単位の文字符号化形式です。符号単位というのは、「その文字符号化形式において、意味を持つ最短のビット数」のことを言い、UTF-8 においては 8 ビット = 1 バイトが意味を持つ最短のビット数です。
表現方法としては、ASCII と同じ部分は互換性のためにそのまま 1 バイトとして表現します。
2, 3, 4, 5, 6 バイトについては、1 バイト目の先頭に 1 がどれだけ続くかで、何バイトで文字を表現しているのかわかります。また、その後の各バイトの先頭には 10 が付くので、バイトの区切りがわかりやすくなっています。
(8/2 追記)5, 6バイトについては不正としてはじくような定義がなされました。（https://tools.ietf.org/html/rfc3629#section-4）

```
2バイト : 11xxxxxx 10xxxxxx
3バイト : 111xxxxx 10xxxxxx 10xxxxxx
...
```

みたいな感じ。
そして、残りのビットに変換対象の Unicode code point を 2 進表記したものを右づめで入れていきます。（なお、ディレクトリトラバーサルなどの対策のため、ある文字を表現する最も短いバイト数以外は不正なものとして弾かないといけないです。）
細かい変換方法は https://ja.wikipedia.org/wiki/UTF-8 を読むとよいです。
読むとわかるんですが、変換対象の文字によってバイト数が変動するので、ファイルサイズには優しいですが、なんかデコードめんどくさそうに感じます。

### UTF-16
16 ビット符号単位の文字符号化形式です。
Unicode code point が `U+0000 - U+FFFF` の範囲のものについては、1 文字 16 ビットのため、そのまま表現できます。（例： `あ = (Unicode code point) U+3042 = (UTF-16) \u3042` ）
それより大きい範囲については、サロゲートペアを使用します。
Unicode code point における `U+D800 - U+DBFF`（ハイサロゲート） と `U+DC00 - U+DFFF`（ローサロゲート） の 2 つを組み合わせて 1 文字を表現します。（イメージ的には二次元配列？）
これで、1024 * 1024 通りの文字を表現出来るようになります。
このため、Unicode code point において `U+D800 - U+DBFF, U+DC00 - U+DFFF` の範囲は定義されていません。（ 2 つ組み合わせてはじめて文字が表現できるため）
悪名高いサロゲートペアも詳細を知るとなんだそんなもんかという気持ちになりました。（16 ビットじゃ漢字とか全部入れられないよね）
文字数カウントでバグるとかはただバイト数をカウントするんじゃなくて、範囲も見ないといけないのかな。

#### UTF-16 BE / LE
UTF-16 ビッグ / リトルエンディアンの略称です。詳細はバイトオーダなどで調べると出てくると思います。

### UTF-32
32 ビット符号単位の文字符号化形式です。
32 ビット固定長のため、UTF-8, UTF-16 とくらべて文字によってサイズが可変しません。
ファイルサイズには優しくないですが、サイズが可変しないという点はとても良いと思います。が、どこで使うかはわかりません…
将来符号空間を 21 ビットから拡張する時にすごく役に立つとか…富豪プログラミングとか…？
Raspberry Pi3 Model B 初期設定のとき参考にしたもの

投稿のテストです。

▪️初期設定
https://www.amazon.co.jp/gp/product/B071ZMJ386/1982-22
https://www.amazon.co.jp/gp/product/B019IJPYVI/1982-22

▪️キーボード日本語入力（IMEの設定）
http://dekirukana-dekirukana.hatenablog.com/entry/2015/12/12/005537

▪️IPを固定化する
http://unskilled.site/raspberrypi3%E3%81%A7%E7%84%A1%E7%B7%9Alan%E5%86%85%E3%81%A7%E3%81%AEip%E3%82%92%E5%9B%BA%E5%AE%9A%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%EF%BC%92%E3%81%A4/

▪️SSHのリモート操作（CUI）
https://www.amazon.co.jp/gp/product/B071ZMJ386/1982-22

▪️リモートデスクトップ操作（GUI）（VNCの設定）
http://zonomasa.hatenablog.com/entry/raspberry_pi_vnc_ssh

▪️しゃべらせる（Open Talkの設定）
http://qiita.com/lutecia16v/items/8d220885082e40ace252

▪️サーバー化（ApacheとCGIの設定）
http://qiita.com/aryoa/items/2c28b466e911a3dd101d

▪️というかたぶんこの本を買えばあるていどいろんな設定がすんなりできる気がします
https://www.amazon.co.jp/dp/B0721WG731/1982-22
複数のサーバーに公開鍵を設定する・削除するツール

小ネタです。

公開鍵を設定するには`ssh-copy-id`というコマンドがありますが、複数サーバーに同時には設定できません。
また設定されている公開鍵の削除は出来ません。
これをできるツールを見つけました。

# 複数サーバーへの公開鍵設定・削除ツール
ssh-copy-id.rb
https://github.com/junegunn/ssh-copy-id.rb
## インストール
```
gem install ssh-copy-id.rb
```

## 使い方
### 複数サーバーで同時に公開鍵を登録
```
ssh-copy-id.rb -i ~/.ssh/id_rsa.pub vagrant@192.168.33.20 vagrant@192.168.33.30 vagrant@192.168.33.40
```

### 複数サーバーで同時に公開鍵を削除
```
ssh-remove-id.rb -i ~/.ssh/id_rsa.pub vagrant@192.168.33.20 vagrant@192.168.33.30 vagrant@192.168.33.40
```

ただしこのgemはGithub上で Unmaintained と書いてありますのでこの点は注意してください。
2017/1にコミットがあるので完全に放置ではないと思いますが。

----
※以下は戯言です。

しかし、もっと融通がきくツールがほしいですね。
入退社やプロジェクトへの参加・離脱とかで、複数人の個人の公開鍵を複数サーバーで管理しなければならない場面ってありそうです。

例えばこんなツールがあれば。。

- 管理用のユーザーでリモートのサーバーにsshログイン
- sudoで特定ユーザーになる
- その特定のユーザーに公開鍵を設定 or 削除
- そのユーザーのauthrized_keyを取得
- 設定・削除の前後のdiffを参照
- これを複数サーバーに同時に実行

とかができればいいのですが。

さらに進めて、鍵も集中管理して

 - コードで行うMySQLのアカウント管理
  - http://techlife.cookpad.com/entry/2015/04/10/122651

と似たようなことができれば。

少し似たようなところではこんな記事も見つけました。

 - ぼくのかんがえたさいきょうの(?)SSH鍵運用管理方法
  - http://qiita.com/tasaki-i3/items/b2b8250864cd6819f223
VagrantfileでCPUの数を設定する

実行環境がVirtualBoxの場合にVagrantfileでゲストVMのCPU数を設定する方法。他。

# 環境

- macOS Sierra
- Vagrant 1.9.7
- VirtualBox 5.1.26

# Vagrantfile

```ruby
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.synced_folder ".", "/vagrant", type: "virtualbox"

  config.vm.provider "virtualbox" do |vb|
    # 割り当てるメモリー(MB)
    vb.memory = 512
    # CPUの数
    vb.cpus = 1
    # I/O APICの有効化
    vb.customize ["modifyvm", :id, "--ioapic", "on"]
  end
end
```

# 参考

- [Configuration - VirtualBox Provider - Vagrant by HashiCorp](https://www.vagrantup.com/docs/virtualbox/configuration.html#vboxmanage-customizations)
ちょっとずつ読むドメイン駆動設計 第一部 ドメインモデルを機能させる 序章2

# ドメイン、ドメインモデルとは何か

> ユーザがプログラムを適用するこの対象領域が、ソフトウェアのドメインである。
(第一部 序章 より)


ドメインとは、プログラムを適用する対象領域。

> ドメインモデルとは特定の図ではなく、図が伝えようとしている考え方である。これはドメインエキスパートの頭のなかにある単なる知識ではなく、その知識が厳密に構成され、選び抜かれて抽象化されたものだ。(同上)

"[モデルとは](http://qiita.com/YasuhiroKimesawa/items/386b43d684518656fd10)"、"ドメインとは"、"ドメインモデルとは"と分けて読むとよくわかりますね。

ビジネスの問題を解決するために、プログラムを適用する対象領域について、ドメインエキスパートの知識を選別し、抽象化させたもの。と言うことですね。

このことは、ビジネス全般を知らなくても良いということではなく、選別するためには幅広くドメインの知識は知っていないといけないということを意味していると思います。
そこからいかに、知識を選別し、抽象化することができるか。
よいドメインモデルを構築するために必要なことですね。

幅広く知り、学び、選別・抽象化する力をつける。
【備忘録】JetBrains製IDEを使用するための自分用Preferences【随時更新】

# 環境
Mac OS X

# Preferences
## Theme
Appearance & Behavior > Appearance のThemeを"Darcula"に変更

## Color Scheme
Editor > Color Scheme のSchemeを"Darcula"に変更

## Keymap
Keymap のKeymapを"Mac OS X 10.5+"に変更
（"Mac OS X"だと補完候補を^N、^Pで選択できない）

## スペースの表示する
Editor > General > Appearance のShow whitespacesにチェックを入れる

## 非アクティブ時にファイルを自動保存しない
Appearance & Behavior > System Settings のSave files on frame deactivationのチェックを外す

## 起動時に前回開いていたプロジェクトを開かない
Appearance & Behavior > System Settings のReopen last project on startupのチェックを外す

## ファイル変更時にタブにアスタリスクを表示する
Editor > General > Editor Tabs のMark modified tabs with asteriskにチェックを入れる

## 補完候補表示時の初期選択を強調する
Editor > General > Code Completion のInsert selected variant by typing dot, space, etc.にチェックを入れる
（本来の設定内容の意味合いとは違う気がする）

## 保存時に空白行のスペースを削除する
Editor > General のStrip trailing spaces on Saveを"Modified Lines"に変更

## Plugin
- IdeaVim - vim操作を可能にする

## インデント設定
Editor > Code Style > C# のTabs, Indents, Alignmentタブの以下の設定を変更。
・Align Similar Code in Columns > Fields and constants をチェック
・Align Similar Code in Columns > End comments をチェック

## (CLion) 中括弧の開始位置を次の行にする
Editor > Code Style > C/C++ の Wrapping and BracesタブにあるBraces placementの項目を全て"Next line"に変更

```
class Foo {
}
```

↓ こうなる

```
class Foo
{
}
```

## (CLion) 文の途中で改行したときに4スペース分のインデントにする
Editor > Code Style > C/C++ の Tabs and IndentsタブにあるContinuation indentを4に変更

## (CLion) elseを次の行にする
Editor > Code Style > C/C++ の Wrapping and Bracesタブにある'if()' statementの'else' on new lineにチェックを入れる

```
if (...)
{
} else {
}
```

↓ こうなる

```
if (...)
{
}
else
{
}
```
【Ubuntu】キーボードのログを取得する

# キーボードロガー

自分が打ったキーボードのログが欲しい時ってありますよね（ないか）。
そんな時におすすめなのが、「[logkeys](http://manpages.ubuntu.com/manpages/xenial/man8/logkeys.8.html)」です。

## １　インストール

インストールは簡単で、以下の１行で入ります。

```bash
sudo apt-get install logkeys
```

## 2　使用するための設定

インストールは簡単ですが、使うにはいろいろと設定が必要です。

### 2.1 キーボードのイベント情報の取得

以下のコマンドを打つと、ターミナルに入力デバイスの設定一覧が表示されます。

```bash
cat /proc/bus/input/devices
```

表示される設定一覧です（とても長いのでキーボード部分のみ掲載）。

```bash
I: Bus=0003 Vendor=04d9 Product=1818 Version=0110
N: Name="USB Keyboard"
P: Phys=usb-0000:00:14.0-12/input1
S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb1/1-12/1-12:1.1/0003:$4D9:1818.0006/input/input8
U: Uniq=
H: Handlers=kbd event8 
B: PROP=0
B: EV=13
B: KEY=300a010802000 0 0 1078002044000 603878d801d6e9 1e0000000000$0 0
B: MSC=10
```

上記の設定で必要なのは、`Handlers=kbd event8`のイベント番号です。

### 2.2　キーボードマップのインストール

次に、使っているキーボードが日本語対応のキーボードなのか、英字キーボードなのかという
キーボードマップ情報を取得する必要があるので、キードードマップのインストールをします。

```bash
 sudo apt-get install console-data
```

すると以下の設定画面が立ち上がりますので、設定をしていきます。

![Screenshot from 2017-08-20 21-09-47.jpg](https://qiita-image-store.s3.amazonaws.com/0/104675/f2628fb9-0778-da95-5d36-b75aa7894d8f.jpeg)

[了解]を選択します。


![Screenshot from 2017-08-20 21-10-20.jpg](https://qiita-image-store.s3.amazonaws.com/0/104675/439ee7b4-ea27-d21c-f67b-153622e45efb.jpeg)

[完全なリストからキーマップを選択]

![Screenshot from 2017-08-20 21-10-44.jpg](https://qiita-image-store.s3.amazonaws.com/0/104675/721f5914-0b14-9a3e-fdb5-5583aacb775b.jpeg)

日本語キーボードを使用しているのならば、上記の設定を選択します。

もし、インストールの際に、設定を取り消してしまったり、設定を間違えた場合は、以下のコマンドで同じ設定ができます

```bash
sudo dpkg-reconfigure console-data
```

## 3　キーロガーを使用する

ここまでの設定でキーロガーが起動できるようになります。
ここからは使用方法を書いていきます。

### 3.1 キーロガーの起動

以下のコマンドで起動します。

```bash
sudo logkeys -s -o ~/logtest.txt -d /dev/input/event8
```

+ `-s` がスタート
+ `-o` がログデータ出力先ファイル
+ `-d` が入力デバイスの情報

入力デバイスの情報には、上記の `cat /proc/bus/input/devices` で調べたイベント番号を入れてください。
起動したあとは、入力したコマンドなどがログファイルに出力され続けます。

### 3.2 キーロガーの終了

以下のコマンドでキーロガーを止めることができます。

```bash
sudo logkeys -k
```

### 3.3 ログの確認

ログの確認はsudo権限でしか確認できないので、`sudo`でテキストエディタを起動します。

```bash
sudo vi logtest.txt 
```

テキストファイルの中身は以下のようになります。

```
Logging started ...

2017-08-20 22:29:51+0900 > sudo apt-get update
2017-08-20 22:30:07+0900 > sudo log<Tab>k<Tab>-k
2017-08-20 22:30:21+0900 > 

Logging stopped at 2017-08-20 22:30:21+0900
```

以上です。

# 参考サイト
[1] [コンソールでのキーボード設定](https://wiki.archlinuxjp.org/index.php/%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E3%81%A7%E3%81%AE%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E8%A8%AD%E5%AE%9A)
[2] [Ubuntuにキーマップをインストールする](http://linux.just4fun.biz/?Ubuntu/%E3%82%AD%E3%83%BC%E3%83%9E%E3%83%83%E3%83%97%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%96%B9%E6%B3%95)
Goで管理画面を作る

# 管理画面を作ろう

GoでLINEbotを作った。

その時の記事はこちら。
[LINE Messenger APIで作った機能](http://qiita.com/courage-liberty/items/62bdd2f3b731c665ee50)

色々やっていると
やっぱり管理画面が必要になって来る。

そこで、管理画面もGoで作ってみた。

---

# 大体の構成

WebサーバはGoのFWでGinを使うことにした。

ORMはgorm。

デザインは面倒なのでbootstrap。

管理画面なので
きちんとセッション管理を入れたい。

API毎にセッションチェックを
しないといけないので
共通ロジックにしてうまいことやりたい。

ということで、早速チャレンジ。

---

# セッション管理

Ginには標準でセッション管理があるらしい。
折角なのでやってみたが、なぜか失敗。

ログイン時にセッションIDを作って
次のアクセスでチェックしてみたが
なぜかSession not foundに・・・

しばらく粘ったができないので
一旦Goのレシーバで実装することにした。

---

# まずはセッション登録

ログインした時にセッションIDを発行し
レシーバ内に保存。

セッションIDは適当なロジックで作成。

作ったIDはクエリパラメータに設定し
以降のアクセスでチェックする。

有効時間を決めて
長くアクセスがない場合には
タイムアウトするようにした。

```
type Session struct {
	session map[string]int64
}

func (session *Session) CreateSession() (key string) {
	key = sessionKey()
	session.session[key] = sessionTime()
	return
}

func (session *Session) CheckSession(key string) (ok bool) {
	if ok = time.Now().Unix() <= session.session[key]; ok {
		session.session[key] = sessionTime()
		return
	}
	delete(session.session, key)
	return
}
```

---

# チェックは共通ロジックで

セッションチェックは
どのページでもする必要があるので
全てに入れるのではなく
共通でチェックできるように
専用のHandlerを作った。

```
func (ms *Botman) SessionHandler(f gin.HandlerFunc) gin.HandlerFunc {
	return func(g *gin.Context) {
		if !ms.session.CheckSession(g.Query(SESSION)) {
			log.Errorf("Session not found: %s", g.Request.URL)
			ms.errorResult(g, http.StatusInternalServerError, errorMessage(SESSION))
			return
		}
		f(g)
		return
	}
}
```

---

# 次にGinのHandler設定部

ハンドラ設定する段階で
共通のセッション管理Handlerを被せる。

セッションチェックしたい場合は
SessionHandlerを被せて登録すればOK。

```
func HandlerSettings(ctx *system.Ctx) {
	ms := NewBotman(ctx)

	server := gin.Default()
	bm := server.Group(BASEPATH)
	{
		bm.Static(fmt.Sprintf("/%s", PUBLIC), "public")
		bm.GET(fmt.Sprintf("/%s", PING), func(c *gin.Context) {
			c.JSON(http.StatusOK, gin.H{
				CODE: http.StatusOK,
				MSG:  "pong",
			})
		})
		bm.GET(fmt.Sprintf("/%s", LOGIN), ms.LoginGetHandler)
		bm.POST(fmt.Sprintf("/%s", LOGIN), ms.LoginPostHandler)
		bm.GET(fmt.Sprintf("/%s", REPORT), ms.SessionHandler(ms.ReportGetHandler))
		bm.GET(fmt.Sprintf("/%s", CONTENT), ms.SessionHandler(ms.ContentGetHandler))
		bm.POST(fmt.Sprintf("/%s", CONTENT), ms.SessionHandler(ms.ContentPostHandler))
		bm.GET(fmt.Sprintf("/%s", MESSAGE), ms.SessionHandler(ms.MessageGetHandler))
		bm.GET(fmt.Sprintf("/%s", LINELOGIN), ms.LineloginGetHandler)
	}

	server.Run(":{{.Port番号}}")
	return
}
```

---

# 最後に

ただHandlerを被せれば良いだけなので
何も気にしないでページを増やせる (^＿^)

だいぶ楽になった。
これでセッション管理はOK。

Ginのセッション管理が
使えなかったことだけが残念。

途中まではうまく行っていた気がしたが
なぜか登録したセッションが
次のアクセスで見れなくなってしまう・・・

そんな事象に心当たりのある方は
是非教えてください！
[クイズ]javascriptと仲良くなるための一歩　第３４話「関数スコープ」

#問題

##第1問

```js
var i = 1;
for(i=0; i<10; i++){
}
i //=> ?
```

##第２問

```js
var i = 1;
for(var i=0; i<10; i++){
}
i //=> ?
```

##第３問

```js
for(var i=0; i<10; i++){
}
i //=> ?
```

:mouse:
:cow:
:tiger:
:rabbit:
:dragon_face:
:snake:
:horse:
:sheep:
:monkey_face:
:bird:
:dog:
:boar:
:mouse:
:cow:
:tiger:
:rabbit:
:dragon_face:
:snake:
:horse:
:sheep:
:monkey_face:
:bird:
:dog:
:boar:

#答え

##第1問

```js
var i = 1;
for(i=0; i<10; i++){
}
i //=> 10
```

##第２問

```js
var i = 1;
for(var i=0; i<10; i++){
}
i //=> 10
```

##第３問

```js
for(var i=0; i<10; i++){
}
i //=> 10
```
KVM ホストを Prometheus と Grafana で可視化

[Prometheus](https://prometheus.io/) は最近 Docker / Kubernetes 関連でよく目にしますが、さまざまな [exporter](https://prometheus.io/docs/instrumenting/exporters/) があるため Docker に限らず使えます。サーバーのメトリクスを収集するにはオフィシャル exporter である [node_exporter](https://github.com/prometheus/node_exporter) が使えます。これを Grafana で可視化するには「[Node Exporter Fullby idealista](https://grafana.com/dashboards/1860)」がなかなか良いです。

Grafana の Dashboard は「[Grafana Dashboards - discover and share dashboards for Grafana. | Grafana Labs](https://grafana.com/dashboards?dataSource=prometheus)」で公開されているものから検索できます。これを自分の環境に合わせて書き換えてみることから始めるのが入りやすいです。

node_exporter ではブロックデバイスごと、ネットワークデバイスごとの IO の情報が取得できるため、KVM ゲスト単位の情報もデバイス名からたどればわかるのですがかなり面倒です。

そこで、3rd party 製ですが [libvirt_exporter](https://github.com/kumina/libvirt_exporter) を使うことでドメイン（ゲスト）名でそれぞれのメトリクスを取得、表示することができます。（バイナリは配布されていないので go での build が必要です）

負荷が上がってるのはどのゲストの影響かな？ていうのがわかりやすくなります。

![dashboard_kvm-host.png](https://qiita-image-store.s3.amazonaws.com/0/8739/1aa2d542-1c27-1d4e-1ae4-16099d72c879.png)

この Dashboard は [kvm-host-dashboard.json](https://gist.github.com/yteraoka/04005dfe55dc9492149f7dbc9fafe0f8) で試せます。

## 関連ドキュメント

* [Prometheus + Grafana + cAdvisor で Docker container のリソースモニタリング](https://blog.1q77.com/2017/01/docker-container-resource-monitoring-using-prometheus-and-grafana-and-cadvisor/)
* [Prometheus の Service Discovery](https://blog.1q77.com/2017/01/service-discovery-of-prometheus/)
PostgreSQLでテーブルを作成する際に指定できないテーブル名について

PostgreSQLを使ってデータベースを作成する際に以下のように設定しようとしたところ、構文エラーが発生しました。

```postgres:PostgreSQL
create table user (
id text primary key,
pass text not null
);
```

スペルミスをしている様子もなく、原因が分からずあれこれ探していたところ、テーブル名として、`user`は使用できないようです。

PostgreSQLではその他にもテーブル名として使用できないものがいくつかあるようなので、調べておく必要があるかもしれませんね。
（そもそも、テーブル名にsをつける癖を身に付けるほうが先か・・。）


**参考サイト**
stackoverflow: Cannot create a database table named 'user' in PostgreSQL
https://stackoverflow.com/questions/22256124/cannot-create-a-database-table-named-user-in-postgresql

PostgreSQL: Appendix C. SQL Key Words
https://www.postgresql.org/docs/9.3/static/sql-keywords-appendix.html
bat+PowerShellでファイル一覧を取得（ファイルサイズ、タイムスタンプ、フルパス）

軽く探したところ、TSVかつファイルサイズを取得できるものが見つからなかったので、
作りました。

用途に応じてscriptを書き換えて利用することを想定しています。
例えば、出力カラムの並び変更や増減は、1行書き換えるだけでできます。

[PowerShellコードをbat内に書いて実行しています](http://qiita.com/cd01/items/82829ba0ec0f59e1b04d)が、深い意味はありません。

```ps1:listDir.bat
@powershell -NoProfile -ExecutionPolicy Unrestricted "$s=[scriptblock]::create((gc \"%~f0\"|?{$_.readcount -gt 1})-join\"`n\");&$s" %*&goto:eof
#
# ファイル一覧取得
#
#   出力項目
#     ファイル名、ファイルサイズ、更新日付、フルパスディレクトリ名 （属性、親ディレクトリ名、拡張子、フルパス も出力可。コメントアウトしてあります）
#   参考
#     http://qiita.com/yjnk/items/a69920748e96272bfd10
#   引数
#     パターン1
#       引数指定なし ※リダイレクトするとSJISで出力できる。パターン2も同様
#     パターン2
#       <検索場所>
#     パターン3
#       <検索場所> <出力TSVファイル名> ※BOMありUTF-8で出力される
#   注意
#     引数はシングルクォート「'」で囲むのが安全です。囲まない場合、例えば 「(重要)」 というディレクトリを検索しようとしたときにエラーになります。

Param($inname, $outname)
$enc="UTF8"

if ($outname) {
    $null | Out-File $outname -Encoding $enc # 空ファイル作成
}
$List=Get-ChildItem $inname -Recurse -File | Select-Object Fullname #-File のかわりに -Directory を指定するとディレクトリのみ取得。指定しないとファイルとディレクトリを取得
foreach($Row in $List)
{
    $fullname=$Row.FullName
    #$property=Get-ItemProperty $fullname # 指定するファイル名が [.txt だとエラー、 [重要].txt だと失敗してnullが返却されてしまう
    $property=Get-ItemProperty -LiteralPath $fullname
    $name=$property.Name
    $extension=$property.Extension
    $timestamp=$property.LastWriteTime
    $length=$property.Length
    $attributes=$property.Attributes

    if ($fullname) {
        # フルパスからフルパスディレクトリ名を算出
        $dir_fullpath=$(Split-Path $fullname -Parent)
        # フルパスディレクトリ名からディレクトリ名を算出
        $dir=$(Split-Path $dir_fullpath -Leaf)
    } else {
        "ERROR : fullname null [" + $Row + "]"
        continue
    }
    # 更新日付の整形
    if ($timestamp) {
        $timestamp=$timestamp.ToString('yyyy/MM/dd HH:mm:ss')
    } else {
        "ERROR : timestamp null [" + $Row + "]"
        continue
    }

    # 1行出力
    $str="$name`t$length`t$timestamp`t$dir_fullpath"
    #$str="$name`t$length`t$timestamp`t$dir_fullpath`t$attributes`t$dir`t$extension`t$fullname`t" # 全カラムの出力テスト用 & テンプレート
    #$str="$length" # ファイルサイズ出力テスト用
    if ($outname) {
        $str | Out-File $outname -Append -Encoding $enc # ファイルへ
    } else {
        $str # 標準出力へ
    }
}
```

# 関連情報
[PowerShellでディレクトリのファイル一覧とタイムスタンプを取得する](http://qiita.com/yjnk/items/a69920748e96272bfd10)
【MySQL】基本操作

# MySQLの基本操作
## 起動、作業準備
開発環境に接続(自分の場合はVM)
1　ディレクトリ移動

```
cd [directory]
```
2　MySQL起動、ログイン

```
mysql -u [user_name] -p
```
ユーザ未作成の場合はroot権限でログイン

```
mysql -u root
```
3　DB一覧

```
show databases;
```
4　DB選択

```
use [database];
```

#作業ユーザ作成と権限付与
1　新規ユーザ作成(root権限)

```
create user [user_name]@localhost identified by '[password]';
```

2　権限付与()

```
grant all to [database].* to [username]@localhost;
```

>参考：ドットインストール「MySQL入門」http://dotinstall.com/lessons/basic_mysql_v3
Macbook AirにDebian9をインストールしてトラブったところ。

Macbook Air (OS X)をDebian9 Strechとのデュアルブートにしましたので、インストール方法をまとめました。一番トラブったのは、Wi-Fiの設定です。たまたまEthernetのアダプターがあったのでWi-Fiドライバをインストールすることができましたが、なかったらインストールできませんでした。注意してください。
ここでは、インストール、Wi-Fiドライバ、キーボード、Node.js/Node-REDのインストールまでを行います。
GUIは、Raspberry Piと同じLXDEがおすすめです。ストレスがなくとっても使いやすいです。

## 1.インストール方法
参考になるサイト
Ubuntuのインストールですが、こちらが参考になります。
[http://ottan.xyz/el-capitan-ubuntu-dual-boot-4020/](http://ottan.xyz/el-capitan-ubuntu-dual-boot-4020/)

[こちら](http://cdimage.debian.or.jp/)のサイトの「 PC/サーバー用DVDイメージ (64ビット)」をダウンロードし、ダウンロードしたisoファイルをubuntuのisoファイルの代わりにUSBメモリに書き込みを行い、あとはubuntuと同じようにインストールします。

```
sudo dd if=debian-9.1.0-amd64-DVD-1.iso of=/dev/rdisk2 bs=1m
```

## 2.Wi-Fiドライバのインストール
### 2-1.source.listの編集
apt-getするサーバーのリスト`/etc/apt/source.list`を次のように編集します。

```/etc/apt/sources.list
deb http://deb.debian.org/debian stretch main contrib non-free
deb-src http://deb.debian.org/debian stretch main contrib non-free

deb http://deb.debian.org/debian stretch-updates main contrib non-free
deb-src http://deb.debian.org/debian stretch-updates main contrib non-free

deb http://security.debian.org/ stretch/updates main contrib non-free
deb-src http://security.debian.org/ stretch/updates main contrib non-free
```

### 2-1.カーネルの更新
```
apt-get update && apt-get upgrade && apt-get dist-upgrade
```

### 2-2.broadcom-sta-dkmsを削除
```
apt-get remove broadcom-sta-dkms
```
### 2-3.Wi-Fiのドライバをインストール
```
apt-get install linux-image-$(uname -r|sed 's,[^-]*-[^-]*-,,') linux-headers-$(uname -r|sed 's,[^-]*-[^-]*-,,') broadcom-sta-dkms
modprobe -r b44 b43 b43legacy ssb brcmsmac bcma
modprobe wl
```

## 3. キーボードの設定
「英数」「かな」キーの設定をするだけで使用できています。
### 3-1.設定方法
設定 --> Setting Hot Keyを起動します。
![setting.png](https://qiita-image-store.s3.amazonaws.com/0/136933/be4b1baf-2cca-a390-5b93-baaa72428bbf.png)
起動したら、[全体] オンの編集を押して設定画面を開きます。
![setting_key.png](https://qiita-image-store.s3.amazonaws.com/0/136933/1c6994c0-3784-ab60-8e55-fa57a7bcd667.png)
取得を押して、「かな」キーを押して、「追加」ボタンを押します。

同様に[全体]オフの編集画面を開き、「英数」キーを登録して「OK」を押します。

## 4.Node.jsとNode-REDのインストール
### 4-1.curlのインストール
```
sudo apt install curl
```
### 4-2.node 6をインストールする設定
node 4.x系はインストールできないようです。

```
$ curl -sL https://deb.nodesource.com/setup_6.x | sudo bash -
```
### 4-3.nodejsをインストールする。
```
$ sudo apt install nodejs
```
### 4-4.Nodeのバージョンを確認
``` 
$ node --version 
> v6.11.0
```
### 4-5.npmのバージョンを確認
```
$ npm version 
> { npm: '3.10.10',
>   ares: '1.10.1-DEV',
>   http_parser: '2.7.0',
>   icu: '56.1',
>   modules: '48',
>   node: '6.11.0',
>   openssl: '1.0.2k',
>   uv: '1.11.0',
>   v8: '5.1.281.102',
>   zlib: '1.2.11' }
```
### 4-6. Node-REDのインストール
次のコマンドでインストールできます。
詳細は[こちら](https://nodered.jp/docs/getting-started/installation)を参照してください。

```
sudo npm install -g --unsafe-perm node-red
```
Bashにgitのブランチ名を表示


私用でCloud9を利用する機会があり，その中でgitのブランチ名がターミナル上に表示する機能があり非常に有用だと思ったのでMacに導入したのでメモがわりに記載．
便利な機能だが使っている人あまり見ないので，色々な人が記載しているが整理してまとめたメモみたいなものbrewの使用を前提としている．

## Bashのオートコンプリート機能導入

まずはbrewを利用してBashのオートコンプリート機能を導入する．以下のコマンドでgit以外の様々なコマンドに関するオートコンプリート機能がBashに導入される．

```
brew install bash-completion
```

インストールが終了したら.bash_profileに以下をechoコマンドで追記することによりオートコンプリート機能の導入は完了．

```
echo "[ -f /usr/local/etc/bash_completion ] && . /usr/local/etc/bash_completion" >> ~/.bash_profile
```

## Gitのオートコンプリート機能導入

次にgitに関するオートコンプリート機能を導入する．brewでgitを入れる方法もあるみたいだが，個人的にいらないものが色々ついてくる気がするのでオートコンプリート機能のみを下記コマンドでインストールする．

```
curl -o "/usr/local/etc/bash_completion.d/git-completion.bash" https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash
```

これに対するパーミッションを下記コマンドで設定してオートコンプリート機能の導入は完了．

```
sudo chmod 755 /usr/local/etc/bash_completion.d/git-completion.bash
```

## Gitのブランチ名を表示

最後にgitの現在使っているブランチ名を表示する機能を導入する．まず以下のコマンドでgitの状態をプロンプトに表示する機能をインストールする．

```
curl -o "/usr/local/etc/bash_completion.d/git-prompt.sh" https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh
```

前節と同様にしてファイルのパーミッションを以下のように変更して完了．

```
sudo chmod 755 /usr/local/etc/bash_completion.d/git-prompt.sh
```

最後に.bash_profileにヒアドキュメント機能を利用して，下記のように追記することでGitのブランチ名を表示するという目的は達成である．

```
cat <<EOF >> ~/.bash_profile
> if type __git_ps1 > /dev/null 2>&1 ; then
>   PROMPT_COMMAND="__git_ps1 '\h:\W \u' '\\\$ '; $PROMPT_COMMAND"
>   GIT_PS1_SHOWDIRTYSTATE=true
>   GIT_PS1_SHOWSTASHSTATE=true
>   GIT_PS1_SHOWUNTRACKEDFILES=true
>   GIT_PS1_SHOWUPSTREAM="auto"
>   GIT_PS1_SHOWCOLORHINTS=true
> fi
> EOF
```

PROMPT_COMMANDの部分がターミナルに表示されるブランチ名などの接頭辞部分なので適宣調整することで好みの形式にすることが可能．
Emacsのインデント機能 (indent-rigidly) のキーバインド改善

## `f` と `b` でもインデントできるようにする

リージョン範囲をインデントする `C-x C-i (indent-rigidly)` のキーバインドはなぜか矢印キーです。ホームポジションから楽に押せないキーはあってないようなものなので、これじゃせっかくの便利機能を使うことができません。なので次のようにキーバインドを追加します。

```el
(when (boundp 'indent-rigidly-map)
  ;; 矢印ではなく f b で簡単にインデントできるようにする
  (define-key indent-rigidly-map (kbd "f") 'indent-rigidly-right-to-tab-stop)
  (define-key indent-rigidly-map (kbd "b") 'indent-rigidly-left-to-tab-stop)

  ;; 1文字ずつインデントする方は滅多に使わないので shift 付きにする
  (define-key indent-rigidly-map (kbd "F") 'indent-rigidly-right)
  (define-key indent-rigidly-map (kbd "B") 'indent-rigidly-left)

  ;; C-x C-i を2連続でタイプした場合は使用頻度が高い右タブインデントに割り当て
  (define-key indent-rigidly-map (kbd "C-x TAB") 'indent-rigidly-right-to-tab-stop)

  ;; vi ライクなキーバインドにしたいときは h l を使うのもいいかも
  ;; (define-key indent-rigidly-map (kbd "l") 'indent-rigidly-right-to-tab-stop)
  ;; (define-key indent-rigidly-map (kbd "h") 'indent-rigidly-left-to-tab-stop)
  )
```

当初は shift 付きの場合だけ大きく移動するのが無難かと思いましたが、よく使う機能ほど簡単にしたかったので to-tab-stop の方を f b に割り当てています。

## slim-mode で indent-rigidly を使ったときのタブ幅を直す

上の設定をしても slim-mode ではインデントが 8 も移動してしまってぜんぜん嬉しくありません。これを直します。slim-indent-offset が 2 なので、これを tab-width に設定しています。

```el
(require 'slim-mode)
(add-hook 'slim-mode-hook
          '(lambda ()
             ;; C-x C-i からの左右インデント幅を slim-mode のインデント幅に合わせる
             (setq tab-width slim-indent-offset))))
```

これで `C-x C-i f` のときのインデント幅が 2 になります。

# 参考
https://github.com/clear-code/emacs.d/blob/master/init.el#L53
opencvによるカスケード分類器作成

#はじめに
このサイト(https://www.pro-s.co.jp/engineerblog/opencv/post_6202.html)
にやり方は書いてあるんだけど、色々躓いたのでメモとして書いておく。
環境はwin10です。

---
1.opencv2.4.13を入手してインストール。
（opencv3以降はcreatesamplesやtraincascadeが入っていない。サポートが無くなったのかな？）

2.createsamplesで正解画像を用意するときは、できるだけ縮小させておく。
（traincascadeでNG画像を正解画像のサイズに縮小させるため、小さくないと学習効率が悪い） 

3.traincascadeで使うNG画像のリストはフルパスで記入。じゃないとエラーが出る。

4.traincascadeで使うNG画像のリストは改行コードはLF。じゃないとエラーが出る。

##余談
traincascadeのエラーメッセージが超分かりづらいです。
でもまあ途中でエラーで止まっても、とりあえずカスケードファイルは使えるので良しとしとこうかな。
golangの日付のフォーマット指定


golangで時間をフォーマット指定した文字列に変換する時には
%Yといったような制御文字で表すのではなくて
"2006/1/2 15:04:05"という決まった日付に対して、出力例を与えるような形になっている。
(ちなみに、この日以外の指定は受け付けないので注意。)

出力内容がそのままかかれるので
ソースを読むときには、分かりやすいといえばわかりやすいかも。

goreで出力どんな感じになるのか確認してみた。

```go
gore> :import time

gore> date := time.Date(2017, 8, 20, 23, 39, 45, 0, time.Local)
time.Time{sec:63638836785, nsec:0, loc:(*time.Location)(0x51a8c0)}

gore> date.Format("2006/1/2 15:04:05")
"2017/8/20 23:39:45"

gore> date.Format("2006/1/2 3:04:05 pm")
"2017/8/20 11:39:45 pm"

gore> date.Format("2006/Jan/2 03:04:05 pm")
"2017/Aug/20 11:39:45 pm"

gore> date.Format("2006/January/2 03:04:05 PM")
"2017/August/20 11:39:45 PM"

gore> date.Format("20060102150405")
"20170820233945"

gore> date.Format("2006010230405")
"20170820113945"

gore> date.Format("20060102030405")
"20170820113945"

gore> date.Format("060102")
"170820"

```

Janと書けば月の出力が英語になるし
15ではなく3と書けばAM/PMを区別するといった具合になっている。
あと、03なのか3なのかで0で埋めるかどうかも設定できているみたい。
年の下二桁もちゃんと指定できるのね。

ちなみに、日付はアメリカの時間書き方の順番で1,2,3,4,5,6と並べているため
1月2日 15時04分05秒 2006年という形になっているとの事

参考
[Golangでの日付のフォーマット指定の方法について](http://qiita.com/sotayamashita/items/c8782420391c108e3cac)
[Goのtimeパッケージのリファレンスタイム（2006年1月2日）は何の日？](http://qiita.com/ruiu/items/5936b4c3bd6eb487c182)
Object Change Notificationの設定しようとしてはまってしまった時の話


@sinmetal 氏の [OCN設定](http://qiita.com/sinmetal/items/0438203034a0cb448448) を見ながら設定してたんだけどうまくいかない上に探してもジャストな答えが見つからなかったのでメモ。
たぶんこんな設定してる人いないだろうけどメモ。

## 状況

- OCNの通知先はGAE
- GAEのデフォルトアカウントの設定済み
- 自分のappspotドメインの設定済み
- `gsutil notification watchbucket` の実行で401エラー

出力はこんな感じです。

```
Watching bucket gs://xxx/ with application URL https://xxxx.appspot.com/gcs/notify ...
ServiceException: 401 Unauthorized WebHook callback channel: https://xxxx.appspot.com/gcs/notify
```

## 答え

gsutilの方の認証情報が自分のになってました。
gsutilの設定記事はあとで書こうと思ったけどイマイチ需要ないかなと思ってお蔵入りしたときに`gsutil config`で設定した認証情報のままにしてたため、401になってました。
あーあ。
あと、gcloudコマンドの方の設定でもgcloudの認証情報を使わないでgsutilコマンド側の認証を使うって設定をONにしてました。

`gcloud config set pass_credentials_to_gsutil true`

## 何したか

1. `pass_credentials_to_gsutil`を`unset`する。
2. `$HOME/.boto`の`gs_oauth2_refresh_token`をコメントアウトする。
3. `gcloud config set account` でGAEのサービスアカウントに切り替える。
4. もう一回`watchbucket`する。


## 今回の事で得られた教訓

`gcloud config set pass_credentials_to_gsutil` + `gsutil config` するときは自分のワークスペースでやらない方がいいかな。
というか認証は共有しといた方がいいな。
UnityのImport PackageにAssetsが表示されない場合の解決策[Standard Assetsダウンロード済]

# 症状
Standard Assetsはダウンロード済みなのにUnityのImport Packageに表示されない。
(http://tsubakit1.hateblo.jp/entry/2015/06/26/232958 これはStandard Assetsダウンロードされていない場合なので、今回のケースではこれで対処できない…)

# 正しくない動作(今回の問題点)
![スクリーンショット 2017-08-20 20.28.56.png](https://qiita-image-store.s3.amazonaws.com/0/150728/da11efc7-cfde-cfb3-705b-436b6ae2ca95.png)
# 正常動作
![スクリーンショット 2017-08-20 20.22.12.png](https://qiita-image-store.s3.amazonaws.com/0/150728/0b6be5d8-8dd2-14e1-3359-4b4fee996186.png)


# 前提
- Standard Assetsはダウンロード済み
- UnityのImport Packageに表示されない (Custom Packageのみしか表示されない)


# 調査
UnityのImport PackegeにStandard Assetsがデフォルト表示されるためには、Standard AssetsフォルダがUnityのアプリケーションと同ディレクトリ内にある必要があり、そうでないと正しく参照されないようです。

### 正しい状態
eg) アプリケーションフォルダ配下のUnityフォルダ
→ Unityフォルダ内にUnityアプリがいる状態
![スクリーンショット 2017-08-20 20.11.59.png](https://qiita-image-store.s3.amazonaws.com/0/150728/ec9c48bd-e7ed-5663-b465-37762c71147a.png)

### 正しくない状態
eg) Unityフォルダ
→ Unityフォルダ内にUnityアプリがいない状態
![スクリーンショット 2017-08-20 20.16.10.png](https://qiita-image-store.s3.amazonaws.com/0/150728/34568d99-7c56-6781-4777-6d33de785132.png)


# 対処
Unityのアップデートをした際に、アプリやフォルダがうまく配置されていなかったようです。

おそらくアプリケーションフォルダにUnityフォルダがあるので、Unityのアプリケーションを移動させるだけで、参照がうまくできるようになり、Import Packageに表示されるようになります。(Unity起動中の場合はUnityを再起動)

![スクリーンショット 2017-08-20 20.41.18.png](https://qiita-image-store.s3.amazonaws.com/0/150728/21d5d2f1-4947-c5b9-c1c7-84898ae4813a.png)



## Standard Assets自体がダウンロードされていない場合
Standard Assets自体がダウンロードされていない場合は、https://unity3d.com/jp/get-unity/update の「インストーラーをダウンロード」の下の 「追加ダウンロード」から「標準アセット」からダウンロード。ダウンロードしたパッケージをインストール。
(もしStandard Assetsのinstall先がUnityアプリが入っているUnityフォルダ内になっていなかった場合、参照しているUnityフォルダ内に移動させること)
Go言語でシンプルに構造体⇔バイナリの相互変換

構造体をサクッとバイナリに変換したい！

そんなときは[encoding/binary](https://golang.org/pkg/encoding/binary/)パッケージを使います。


## 構造体→バイナリ
[binary.Write](https://golang.org/pkg/encoding/binary/#Write)メソッドに構造体を渡すと上から順番にフィールドが並んだバイナリになります。

```go
package main

import (
	"encoding/binary"
	"encoding/hex"
	"os"
)

type A struct {
	Int32Field int32
	ByteField byte
}

func main() {
	// 構造体つくる
	a := A{Int32Field: 0x123456, ByteField: 0xFF}

	stdoutDumper := hex.Dumper(os.Stdout)
	defer stdoutDumper.Close()

	// 構造体をバイナリにする
	binary.Write(stdoutDumper, binary.LittleEndian, &a)
}
```

出力

```
00000000  56 34 12 00 ff                                    |V4...|
```

https://play.golang.org/p/AJy78r6qTO


## バイナリ→構造体
[binary.Read](https://golang.org/pkg/encoding/binary/#Read)メソッドにバイナリと受けの構造体を渡すと、構造体に復元できます。

```go
package main

import (
	"encoding/binary"
	"bytes"
	"fmt"
)

type A struct {
	Int32Field int32
	ByteField byte
}

func main() {
	// 構造体つくる
	a := A{}

	// バイナリを構造体aに入れる
	bin := []byte("\x56\x34\x12\x00\xFF")
	reader := bytes.NewReader(bin)
	binary.Read(reader, binary.LittleEndian, &a)

	fmt.Printf("a: %v\n", a)
}
```

出力

```
a: {1193046 255}
```

https://play.golang.org/p/JP0ySnszNN

## 注意点

### ポインタやスライスなどを含む場合
binary.Read/Write ではポインタやスライスなどの複雑な型のフィールドは扱えません。

そのような複雑なものについては、[gob](https://golang.org/pkg/encoding/gob/)や[protobuf](https://github.com/golang/protobuf)を検討すると良いかもしれません
【Swift4】（国際化対応） Localizable.stringsを言語を指定して取得する


[前回の投稿](http://qiita.com/moons-k/items/25e9049a1115408b737d)は、Int型に対してLanguageProtocolを適用しましたが、String型に適用しLocalizable.stringsから言語してして文字列を取得する機能を実装してみました。

```Swift
// プロトコル
protocol LanguageProtocol

// プロトコル・エクステンション
extension LanguageProtocol

// 言語別のクラス
final class Language<Base>
```
は前回と同様です。（そもそもこの記述を様々なクラスに適用できるのがこの手法の素敵な点です）
以下のようにString型のextensionを記述します。

```Swift
extension String: LanguageProtocol { }

// 関数の実装
extension Language where Base == String
{
    // 多言語文字列
    var localized: String
    {
//        // 無理やりだけど言語コードを取り出す。ja_JPのja部分。
//        // identifierは、String.en.xxxx, String.ja.xxxxのen、jaで切り替わる
//        let array = identifier.components(separatedBy: "_")
//        guard array.count > 0 else { return self.base }
//        // Localizable.stringsのパスを取得する。
//        var path: String? = Bundle.main.path(forResource: "Localizable", ofType: "strings", inDirectory: nil, forLocalization: array[0])
        
        let languageCode = Locale(identifier: identifier).languageCode ?? identifier
        var path: String? = Bundle.main.path(forResource: "Localizable", ofType: "strings", inDirectory: nil, forLocalization: languageCode)
        if path == nil
        {
            // en、jaで指定された言語がない場合は、Baseを採用する。
            path = Bundle.main.path(forResource: "Localizable", ofType: "strings", inDirectory: nil, forLocalization: "Base")
        }
        guard let _path = path else { return self.base }
        
        // ファイル名はいらないので削除してディレクトリー情報だけにする。
        let path2: String = _path.deletingLastPathComponent
        
        // Bundle作成に渡すのはディレクトリー情報だけ。
        let bundle: Bundle? = Bundle(path: path2)
        guard let _bundle = bundle else { return self.base }
        // ファイル名を指定していないので、DefaultのLocalizable.stringsを読み込む。
        return NSLocalizedString(self.base, bundle: _bundle, comment: self.base)
    }
}
```

これで

```Swift
        XCTAssertEqual("多言語化".en.localized, "Multilingualization")
        XCTAssertEqual("多言語化".ja.localized, "多言語化")
```
のような形で呼び出せるようになります。
iPhoneの設定に拠らないで言語を選択できるようになりました。
enの部分をjaに切り替えると結果は日本語に切り替わります。


ちなみに、

```Swift
let path2: String = _path.deletingLastPathComponent
```

の部分は、下記のextensionを利用します。

```Swift
extension String
{
    private var url: URL?
    {
        return URL(string: self)
    }

    public var deletingLastPathComponent: String
    {
        guard let _url = url else { return self}
        return _url.deletingLastPathComponent().path
    }
}
```
parameterized使ってみた

#parameterized
Pythonのユニットテストの補助ライブラリー的なもの。
同じメソッドに対して違う値でテストしたいときに、わざわざ違うテストメソッドを書かなくてすむようにできる。

unittest、pytest、noseなどに対応している。
unittest、pytestで多少書き方が異なる。

自分はunittestしか使ったことないので、unittestのでの使い方。

#install
```py3
pip install parameterized
```

#usage
##テスト対象のコード
ただの足し算。

```py3
def add(a, b):
    return a + b
```

##テストコード

```py3
import unittest
from parameterized import parameterized


class TestAdd1(unittest.TestCase):

    @parameterized.expand([
        (2, 3, 5),
        (1, 1, 2),
        (3, -1, 2)
    ])

    def test_add(self, a, b, exp):
        self.assertEqual(add(a, b), exp)
```
a、b、expにそれぞれ、値がわたってくる。
キーワード引数に対応させたい場合は以下。param関数を使う。

```py3
import unittest
from parameterized import parameterized, param


class TestAdd2(unittest.TestCase):

    @parameterized.expand([
        param(2, -2),
        param(1, -1),
        param(3, -1, exp=2)
    ])

    def test_add(self, a, b, exp=0):
        self.assertEqual(add(a, b), exp)

```
【iOS】UIKit Frameworkのクラスのsubviewを調べて取得する方法

例)UISearchBar

# subviewから取得する

UISearchBarのsubviewはUIViewですが、そのsubviewにはImageViewとTextFieldのクラスがあります。

```swift
for subview in searchBar.subviews {
    for subview2 in subview.subviews {
        print(subview2)
    }    
}
```

[コンソールの出力]
![SearchBarSubview.png](https://qiita-image-store.s3.amazonaws.com/0/194104/b155d312-192a-1e00-283a-96b4aebb9140.png)

クラス名は、
UISearchBarBackground -> ImageView
UISearchBarTextField -> TextField

となります。

UISearchBarTextField等は、通常時に利用できるクラスではないので、

```swift
if subview2.isKind(of: UITextField.self) {
            
}
```

のように取得はできません。

そのためNSClassFromStringを利用して、取得します。
以下の２種類の方法はどちらでも取得できます。

```swift
for subview in searchBar.subviews {
    for subview2 in subview.subviews {
        print(subview2)
        if subview2.isKind(of: NSClassFromString("UISearchBarBackground")!) {
            
        }
    }    
}
```

```swift
for subview in searchBar.subviews {
    for subview2 in subview.subviews {
        print(subview2)
        if NSStringFromClass(type(of: subview2)) == "UISearchBarBackground" {
            
        }
    }    
}
```

あとは、キャストして利用するだけです。

```swift
if subview2.isKind(of: NSClassFromString("UISearchBarTextField")!) {
    let textField = subview2 as! UITextField
    textField.backgroundColor = UIColor.blue
}
```

# value(forKey: )を利用して取得する

同様にpropertyで設定されていればvalue(forKey: )を利用して取得することもできます。

```swift
let textField = searchBar.value(forKey: "_searchField") as! UITextField

textField.backgroundColor = UIColor.blue
```

どちらの方法でも特に問題ありません。
ibusが起動しない時の対処

Fedora KDE 26 で表示は始めから日本語表示だったが、日本語入力ができなくて困っていた。

```bash
sudo dnf install ibus-mozc
```
でibusやmozcなどいろいろインストールされた。
その後再起動してもibusが起動しなかった。

普段使っているシェルのプロファイルに

```
export GTK_IM_MODULE=ibus
export XMODIFIERS=@im=ibus
export QT_IM_MODULE=ibus
exec ibus-daemon -dx &
```
を追加しシェルを再起動。
するとパネルの右の方に黄色いアイコンが表示されるようになり、IMEの切り替えができるようになった。

その後も使えるときと使えない時がある。根本的解決はしていないみたい。
設定の起動と終了→自動起動でプログラムを追加->ターミナルで実行にチェック
`ibus-daemon -r -d -x`と書いてOK、で再起動。
うまくいったっぽい。
# 参考
- [Fedora 20 KDE をインストールした際にやったこと](http://ksmzn.hatenablog.com/entry/fedora_kde_20_config_japanese)
- [Ubuntu 12.04 LTS 日本語変換IBus を自動起動させる](http://pc.casey.jp/archives/153902376)
横浜市のごみ分別AIで使われているチャットボット Repl-AI でできること・その２（表現ゆらぎ吸収）

Repl-AI は，ユーザー入力のゆらぎを吸収する機能がある．

* 辞書（予め設定したワードを，特定のワードに変換する機能）
* 曖昧一致（類似ワードかどうかを自動推定してマッチングする機能）
* 部分一致（入力内に含まれていればマッチングする機能）

新規登録などはこちら ↓
[横浜市のごみ分別AIで使われているチャットボット Repl-AI でできること・その１（新規登録・サンプルシナリオ・カスタマイズ）](http://qiita.com/tanakaworld/items/80bcb6f559d7a0ac94a9) 

# 辞書

辞書機能は，予め設定したワードを特定のワードに変換する機能で，[システムでも吸収できない表現のゆらぎを吸収させるために用いる](https://repl-ai.jp/#docs/tutorial/dictionary)．

例えば，あいさつ系のワードだったらボットがあいさつで返すケース．
普通に作成すると，あいさつに該当するワードを全て `ユーザー発話BOX` に入力する必要がある．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31862/880d2ef9-94cd-42ee-d698-74e4a33b89a7.png)

このシナリオは辞書を用いると，次のように設定できる．

## 辞書作成

ボット毎に設定する．
ボット一覧ページの `ユーザー辞書` から設定ページへ遷移．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31862/4b83f065-6ee5-d143-0417-e2be4331306d.png)

`代表単語` と それに集約する単語を登録する．
ここでは先程 `ユーザー発話BOX` に設定していたワードを設定する．
`代表単語に吸収する単語` にマッチした場合，ボットは `代表単語` として認識するようになる．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31862/941a63c1-94bf-ef2e-ad9c-672783b9776c.png)

## シナリオに辞書を適用

`代表単語` だけシナリオに設定して，シミュレータで対話してみる．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31862/b45ebf8f-aed6-e43d-ac21-bd53d3d215e9.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/31862/a8a9c3a9-4b3b-3213-a57a-3ed9a1f93dc9.png)

## 表記ブレにも使える

ユーザーは，かな文字やカタカナ，漢字，アルファベットで入力してくるかわからない．
それぞれに対応できるように辞書を拡張する．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31862/04997411-4b24-ffa8-95a5-53f0bdb792d5.png)




# 曖昧一致

> 入力した発話の概念を解釈し、似たような言葉にもマッチングするようにできる機能です。この機能を利用することで、ユーザの発話の揺らぎを自動的に吸収してくれるようになります。 [「曖昧一致」機能について](https://repl-ai.jp/#docs/tutorial/speech)

類似ワードかどうかを自動推定してマッチングする機能．
実際に `曖昧一致` を有効にして，マッチしたワードをまとめてみた．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31862/8282c904-fc34-bfd5-db6c-63ac5e75f271.png)


|入力したワード|マッチしたワード|マッチしなかったワード|
|:-:|:-:|:-:|
|はい|はい，うん，うむ．そう，イエス|イェス，そうです，おっけー，OK，よい|
|いいえ|いいえ，のー，ノー，|だめ，ダメ，NG，ちがう，違う，のう，脳|
|犬|犬，イヌ，いぬ|いっぬ，イッヌ，🐶，🐩|
|猫|猫，ネコ，ねこ|ねっこ，根子，根っこ|
|旦那|旦那，夫，だんな，ダンナ，檀那|おっと，オット|
|妻|妻，嫁，褄，都万，つま|よめ，お嫁さん，ツマ，都万|
|家族|家族，かぞく，華族，ファミリー，ファミリ|カゾク，ふぁみりー，ふぁみり，ファミリーマート|

`読み` にしたときに入力したワードの読みと同じになる単語・漢字だとマッチする模様．
`家族` →　`ファミリー` のように英語のアルファベット読みのケースもマッチすることがわかった．
（ちなみに `ファミリーマート` だとマッチしないw）


# 部分一致

入力の一部に，設定した文字列が含まれている場合にマッチしてくれるようになる．

> 部分一致のチェックをつけると、設定したキーワードが実際のユーザー発話内に含まれていれば、それを見つけて反応してくれます。[「部分一致」機能について](https://repl-ai.jp/#docs/tutorial/speech)

入力文字列が「こんにちは」の場合は，文章のどこかに「こんにちは」が含まれていればマッチしたと判断される．
内部的には，ワイルドカードを用いたマッチングをしている模様．

```
こんにちは
*こんにちは
こんにちは*
*こんにちは*
```

# 関連記事

- [横浜市のごみ分別AIで使われているチャットボット Repl-AI でできること・その１（新規登録・サンプルシナリオ・カスタマイズ）](http://qiita.com/tanakaworld/items/80bcb6f559d7a0ac94a9)
【iOS】UISearchBarのbackgroundカラーを変更する

検索バーでよく利用するUISearchBarを自分で指定したbackgroundカラーにカスタマイズする方法です。

単純に、以下のように記述するとなぜか反映されません。

```swift
searchBar.backgroundColor = UIColor.yellow
```

![changeBackground.png](https://qiita-image-store.s3.amazonaws.com/0/194104/264266b0-65b5-3caa-bb26-303a22897a3f.png)


また、barTintColorを変更するとbackgroundカラーは変更されますが、borderは残ったままになります。

```swift
searchBar.barTintColor = UIColor.yellow
```

![barTintColor.png](https://qiita-image-store.s3.amazonaws.com/0/194104/553adca2-4af9-15e6-e556-1b6453bcbd7e.png)


そこで色々調べてみたところ、UISearchBarにはbackgroundImageが設定されているというのがわかりました。
UISearchBarBackgroundという、独自のクラスのようです。

そのため、このbackgroundImageを削除してみると無事にbackgroundColorをカスタマイズすることができました。

```swift
let barImageView = searchBar.value(forKey: "_background") as! UIImageView
barImageView.removeFromSuperview()

searchBar.backgroundColor = UIColor.yellow
```

![removeImage.png](https://qiita-image-store.s3.amazonaws.com/0/194104/f7b71938-9fa0-413b-5303-412048716e53.png)

同様に　"value(forKey: )"　を利用すればTextFieldの取得もできます。

```swift
let textField = searchBar.value(forKey: "_searchField") as! UITextField

textField.backgroundColor = UIColor.blue
```

![textField.png](https://qiita-image-store.s3.amazonaws.com/0/194104/60ac21f2-063f-261f-e26a-d55c676cdb2f.png)

textFieldを取得すれば後は、textFieldの設定を変更してカスタマイズすることができます。

ちなみにこのkeyはデバッグで内容を知ることができます。

![searchBarKey.png](https://qiita-image-store.s3.amazonaws.com/0/194104/fff27015-053f-dfff-3b65-1187935eb779.png)
OracleLinuxにJenkinsをインストールする

#OpenJDKをインストールする
    # yum install java-1.8.0-openjdk

#Javaのバージョン確認
    # java -version
#公開鍵をインポートする
    # sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo
    # sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
#yumでインストール    
    # yum install jenkins
#jenkinsを起動する
    # service jenkins start
#ポートの変更
    # vi /etc/sysconfig/jenkins
    -----
    JENKINS_PORT="8082"
    -----
#jenkins の状態を確認
    # service jenkins status
    ● jenkins.service - LSB: Jenkins Automation Server
    Loaded: loaded (/etc/rc.d/init.d/jenkins; bad; vendor preset: disabled)
    Active: active (exited) since Mon 2017-08-21 06:12:52 JST; 6s ago
    Docs: man:systemd-sysv-generator(8)
    Process: 13748 ExecStart=/etc/rc.d/init.d/jenkins start (code=exited, 
    status=0/SUCCESS)
fisherman によるキーバインド設定を制御する方法がわからない

前置き
----

[fisherman](https://github.com/fisherman/fisherman) を使うと、プラグインがもつキーバインド設定(`key_bindings.fish` の中身)が `fish_user_key_bindings` 関数にコピーされる。このとき、プラグイン由来ではない自分で書き加えたキーバインド設定があれば、それは `fish_user_key_bindings` 関数の先頭に移動される。


悩み
----

`C-f` も `C-t` も勝手にバインドされると困る。


試行錯誤
----

### 余計な設定をするプラグインは使わない

最終手段。

### ローカルのプラグイン

プラグインになっていれば、(たぶん)プラグイン名の辞書順で並んで `fish_user_key_bindings` にコピーされるので、適当に後ろに並ぶような名前のプラグインを作れば解決しそう。

`fisher <path>` でプラグインを追加した時は期待通りの結果を得られたが、 `fisher up` した時に上に持って行かれた。残念。ローカルプラグインは、なぜ `fishfile` に追加されないのか。

### gist のプラグイン

ローカルがダメなら gist でどうかと試した結果、だいたい期待通りの結果を得られた。が、gist に含めたファイルを `key_bindings.fish` のみとした結果、gist の名前が `key_bindings` となり、プラグイン名も `key_bindings` として管理される結果に。

k より後に並ぶ名前のプラグインをどうしたものか。

### GitHub リポジトリのプラグイン

そこまでしたくない。

### fish 自体の何かズバリな仕組み

知りたい。

### fisher がコピーしたやつは無視

関数上部にへばりつく挙動を前提に、自分で書く設定の最後を `return` にしてしまう案。プラグインが追加する関数にバインドしたいものがあれば、自分でコピペする。

```sh:~/.config/fish/functions/fish_user_key_bindings.fish
function fish_user_key_bindings
    bind \cf 'forward-char'
    bind -M insert \cf 'forward-char'

    return
    ...
    ### fzf ###
end
```

正直、色々めんどくさくなってこれで良い気がしている。


まとめ
----

fisherman なんて使わなければ良い気がしている。とはいえ、スニペット共有リポジトリ的な観点からは便利そう。

プラグイン定義のキーバインドを手軽に on/off する良い感じの方法を知りたい。
OpenCV3.3で動画ファイルのリードができない(Ubuntu16.04)

OpenCVでは、ビデオキャプチャからの動画入力が、カメラであろうと動画ファイルであろうと同じように扱えるはず。

```
##!/usr/bin/python
# -*- coding: utf-8 -*-

import cv2

cap = cv2.VideoCapture('2017_0706_082809_003.MOV')

while(cap.isOpened()):
    ret,frame = cap.read()
    print("ret=",ret)
    gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

    cv2.imshow('frame',gray)
    if cv2.waitKey(1)&0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
```
ところが、
#
```
Failed to query video capabilities: Invalid argument
libv4l2: error getting capabilities: Invalid argument
VIDEOIO ERROR: V4L: device 2017_0717_114442_006.MOV: Unable to query number of channels
```
となり読み込めない。C++で記述しても同様なので、バインディングの問題ではなさそう。

#環境
Ubuntu Linux 16.04
OpenCV 3.3.0
Python は2.7系

#調査
OpenCVをソースから再コンパイル。そもそもコーデックがちゃんと入っているのかを見ると、FFMPEGもGStreamerも入っていない。。
```
--   Video I/O:
--     DC1394 1.x:                  NO
--     DC1394 2.x:                  NO
--     FFMPEG:                      NO
--       avcodec:                   NO
--       avformat:                  NO
--       avutil:                    NO
--       swscale:                   NO
--       avresample:                NO
--     GStreamer:                   NO
```

#解決策
根本的にはFFMPEGをcmakeの時に見つけられていないことが原因と思われる。が、これの直し方がよくわからない。代わりに、gstreamerで試してみると、なぜかうまく行った。

```
sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
cmake  (略) ..
make & make install
```
```
--   Video I/O:
--     DC1394 1.x:                  NO
--     DC1394 2.x:                  NO
--     FFMPEG:                      NO
--       avcodec:                   NO
--       avformat:                  NO
--       avutil:                    NO
--       swscale:                   NO
--       avresample:                NO
--     GStreamer:                   
--       base:                      YES (ver 1.8.3)
--       video:                     YES (ver 1.8.3)
--       app:                       YES (ver 1.8.3)
--       riff:                      YES (ver 1.8.3)
--       pbutils:                   YES (ver 1.8.3)
```


#
JavaScript Classのpropertyとmethodを列挙する

色々参考にしてclassのメソッドとプロパティを列挙する方法を調べてみました。
作ってみたけど結局使わないような。
まだまだ不備があるかもしれません。

```javascript:javascript
class First {
  constructor() {
    this.dataFirst = "first";
  }
  funcFirst() {
    console.log("funcFirst");
  }
  static staticFuncFirst() {
  	console.log("static funcFirst")
  }
}

class Second extends First {
  constructor() {
    super();
    this.dataSecond = "second";
  }
  funcSecond() {
    console.log("funcSecond");
  }
  static staticFuncSecond() {
  	console.log("static funcSecond")
  }
}

class Third extends Second {
  constructor() {
    super();
    this.dataThird = "third";
  }
  funcThird() {
    console.log("funcThird");
  }
  static staticFuncThird() {
  	console.log("static funcThird")
  }
}

function getAllMethodNames(object) {
  let methods = new Set();

  //Objectオブジェクトにまでたどるとobj.__proto__はnull。もしくはOwnPropertyNamesに__proto__が出てくる
  for(let obj = Object.getPrototypeOf(object); obj !== null && obj.__proto__ !== null; obj = Object.getPrototypeOf(obj)) {
    let names = Object.getOwnPropertyNames(obj)
  	names.forEach((x) => methods.add(x));
  }
  return methods;
}

function getAllStaticMethodNames(className) {
  let methods = new Set();

  //typeof __proto__ が"function"の間はユーザが定義したclass。"object"になるとObjectオブジェクト
  for(let obj = className; obj !== null && typeof obj.__proto__ === "function"; obj = Object.getPrototypeOf(obj)) {
  	let names = Object.getOwnPropertyNames(obj)
    names = names.filter((prop) => { return typeof obj[prop] === "function"; });
    names.forEach((k) => methods.add(k));
  }
  return methods;
}

function getAllPropertyNames(object) {
  let properties = new Set();

  for(let obj = object; obj !== null && typeof obj.__proto__ !== null; obj = Object.getPrototypeOf(obj)) {
  	let names = Object.keys(obj)
    names.forEach((k) => properties.add(k));
  }
  return properties;
}

let first = new First();
let second = new Second();
let third = new Third();

console.log(getAllPropertyNames(first));
console.log(getAllMethodNames(first));
console.log(getAllStaticMethodNames(First));
console.log(getAllPropertyNames(second));
console.log(getAllMethodNames(second));
console.log(getAllStaticMethodNames(Second));
console.log(getAllPropertyNames(third));
console.log(getAllMethodNames(third));
console.log(getAllStaticMethodNames(Third));
```
【Python】二段階認証設定しているgmailからメール送信

## gmailでアプリパスワードを設定する
https://support.google.com/accounts/answer/185833?hl=ja
こちらから設定するだけ。
16桁のアプリ専用パスワードが手に入る。

## メールの送信サンプルコード

```py
# -*- coding: utf-8 -*-

import smtplib
from email.mime.text import MIMEText

if __name__ == '__main__':
    to_addr = 'hoge@to.com'
    from_addr = 'fuga@from.com'
    mail_id = from_addr
    # 取得した16桁パスワードを入力する
    mail_pass = 'wwwwxxxxyyyyzzzz'

    message = MIMEText('Hello')
    message['Subject'] = 'Hello'
    message['From'] = from_addr
    message['To'] = to_addr

    sender = smtplib.SMTP_SSL('smtp.gmail.com')
    sender.login(mail_id, mail_pass)
    sender.sendmail(from_addr, to_addr, message.as_string())
    sender.quit()
```