OmniAICreator/Qiita-1.07M huggingface dataset:
MariaDB Galera Clusterでマルチマスタレプリケーションの際のwsrep_auto_increment_controlについて

# はじめに
MariaDB Galera Clusterでマルチマスタレプリケーションをキメているみなさんこんにちは。

マルチマスタの場合、クラスタを構成する各ノードで衝突が起きないようにGaleraがイイ感じにしてくれてるわけですが、AUTO_INCREMENTもイイ感じにしてくれているようです。

# AUTO_INCREMENT
そもそもAUTO_INCREMENTって何という方は前回記事を書きましたのでご参照ください。

[MariaDBのAUTO_INCREMENTについて](https://qiita.com/tk117/items/51e000070a15a829434a)

上記の記事にも書いていますが、マルチマスタの場合、クラスタサイズ分のINCREMENTを設定し、OFFSETは1ずつズラす必要があります。

# wsrep_auto_increment_control
そこで登場するのがこのパラメータです。

[wsrep-auto-increment-control - Galera Cluster Documentation](http://galeracluster.com/documentation-webpages/mysqlwsrepoptions.html#wsrep-auto-increment-control)

まさにクラスタ内のAUTO_INCREMENTで使う値をイイ感じにしてくれると書いてますね！

Galera用語で言うところのPrimary Componentsに接続しているノードの数にincrementとoffsetを調節してくれます。これによって2つのノードが同じincrementの値を使う可能性を下げてくれます。

defaultでONのパラメタなので、特に気にする必要はないですが、シングルマスタの場合は明示的にOFFにしてもいいかもしれません。

# 値を確認してみる
検証環境で実際に確認してみました。以下、3ノードのクラスタです。

```
[root@mariadb1 ~]# mysql -u root -e "SHOW STATUS LIKE 'wsrep_cluster_size'" 
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 3     |
+--------------------+-------+

[root@mariadb1 ~]# mysql -uroot -e "SHOW VARIABLES LIKE '%auto_inc%';"
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| auto_increment_increment     | 3     |
| auto_increment_offset        | 2     |
| wsrep_auto_increment_control | ON    |
+------------------------------+-------+

[root@mariadb2 ~]# mysql -uroot -e "SHOW VARIABLES LIKE '%auto_inc%';"
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| auto_increment_increment     | 3     |
| auto_increment_offset        | 3     |
| wsrep_auto_increment_control | ON    |
+------------------------------+-------+

[root@mariadb3 ~]# mysql -uroot -e "SHOW VARIABLES LIKE '%auto_inc%';"
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| auto_increment_increment     | 3     |
| auto_increment_offset        | 1     |
| wsrep_auto_increment_control | ON    |
+------------------------------+-------+
```

incrementはクラスタサイズになっていて、offsetはちゃんとズレてますね！

# おわりに
逆にマルチマスタじゃないひとのほうが気を付けるべきパラメータでしたね。

### 参考
* [Auto increments in Galera](https://mariadb.org/auto-increments-in-galera/)
* [MariaDBでGalera Clusterを構成する(CentOS 7使用)](https://orebibou.com/2016/02/mariadbでgalera-clusterを構成するcentos-7使用/) ... 構築メモで、wsrep_auto_increment_controlはOFFにしている。マルチマスタで使うかどうかは明示していない。
* [MariaDB Galera Cluster での AUTO_INCREMENT の扱いについて](https://blog.neoflow.jp/oss/mariadb-galera-cluster/2408/) ... IDがINTだと枯渇しちゃうから気を付けようねという記事。確かに。
* [Multi-Valued INSERTs, AUTO_INCREMENT & Percona XtraDB Cluster](https://www.percona.com/blog/2014/09/09/multi-valued-inserts-auto_increment-and-percona-xtradb-cluster/) ... マルチマスタの場合、PK重複でレプリケーションが壊れてしまう例を示す。master-slave構成ではもっとも高いINCREMENTはmasterが持つべきであり、その構成の場合slaveはwsrep_auto_increment_controlをOFFにすべきと指摘している
jMeter 2.13のインストール （mac）with BlazeMeter Step-by-step Debugger

# 作業ディレクトリの作成
```
REF_DIR="お好みの場所をフルパスでどうぞ"
sudo mkdir -p ${REF_DIR}
```
  
# 作業ディレクトリに移動
```
cd ${REF_DIR}
```
  
# JMeter version 2.13ダウンロード
```
wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-2.13.tgz
```
  
# ダウンロードしたデータを解凍
```
tar xvzf apache-jmeter-2.13.tgz
```
 
# /binの下にjmaterコマンドのシンボリックリンクを設置する
```
ln -s ${REF_DIR}/apache-jmeter-2.13/bin/jmeter /usr/local/bin/jmeter
```

# jMeter Plugins Managerのインストール
# 「 https://jmeter-plugins.org/wiki/PluginsManager/ 」からjarファイルをダウンロードして設置
```
cp ~/Downloads/jmeter-plugins-manager-0.19.jar ${REF_DIR}/apache-jmeter-2.13/lib/ext/.
```

# プロキシを通して実行（負荷テスト対象へのアクセスがプロキシ必須な場合）
```
jmeter -H <host> -P <port>
```

# 起動後、「オプション」 > 「Plugins Manager」と移動。
# 「Available Plugins」タブから「BlazeMeter Step-by-step Debugger」をインストールして再起動
# 再起動後に「実行」から「step-by-step debug debugger」が選択できるようになる

# 参考資料
https://www.blazemeter.com/blog/step-step-debugger-jmeter-it%E2%80%99s-not-dream-anymore
Guard使用時にNo such file or directoryエラーが発生した場合

Ruby on Railsチュートリアルの第3章の[3.6.2 Guardによるテストの自動化](https://railstutorial.jp/chapters/static_pages?version=5.1#sec-guard)の際に以下のエラーが発生しました。

```bash
No such file or directory - bin/rails test test/controllers/static_pages_controller_test.rb test/test_helper.rb
```


そこで色々調べたところ、いくつかのサイトではGuardfileの冒頭の部分から「spring: "bin/rails test"」を削除すれば動くとありました。

確かにこれでも動きましたが、そもそもこの操作をしてしまったらその前で言及している
> この行ではGuardからSpringサーバーを使って読み込み時間を短縮しています (SpringはRailsの機能の１つです)。

を無視してしまっているのではないかと思ったのです。
とはいえ、該当の部分に原因があるのは明らかなので色々と試したところ、**"bin/rails test"**の部分をコンソールからコマンドで実行するときと同様に**”rails test”**に修正したところ問題なく動きました。

```ruby:guardfile
# Guardのマッチング規則を定義
guard :minitest, spring: "rails test", all_on_start: false do
  watch(%r{^test/(.*)/?(.*)_test\.rb$})
```

おそらくこの修正ならば言及されていたSpringサーバーの機能を使いつつ、問題なく動かせるのではと思います。

ただ、コンソールからは**"bin/rails test"**とコマンドを打っても問題なく動くので、bundleを通して実行する場合は”bin/rails”に上手くパスが通っていないのかなと思います…（もしかしたらチュートリアルで言及されていたGuardとSpringが相互に作用するバグのせいなのかもしれません。）

ここのあたりの原因は自分でも探りきれていないので、どなたか知見のある方がいましたら教えていただけると助かります。
Kotlin コード規約（ Naming rules ）

[公式](http://kotlinlang.org/docs/reference/coding-conventions.html)の和訳（意訳）です．

- [IDEでスタイルを設定する, ソースコード構成](https://qiita.com/hmiyado/items/2531be40b3369173a2cd)
- 命名規約(この記事)
- [フォーマット 前半](https://qiita.com/hmiyado/items/2ad86df1d0cb842beee6)
- [フォーマット 後半](https://qiita.com/hmiyado/items/4667994ea71fe4c76484)
- [ドキュメントコメント，冗長な記述を避ける](https://qiita.com/hmiyado/items/05cae7df64d6d0138594)
- [慣用表現の使用](https://qiita.com/hmiyado/items/94792e428e5993bc8fc6)
- [ライブラリのコード規約](https://qiita.com/hmiyado/items/f1e84c7870b8a5864a7b)

# 命名規則

Kotlin の命名規約はシンプルだ。

パッケージ名は常に小文字で，アンダースコアを使用しない（`org.example.myproject`）．
一般に，複数の単語を使うことは非推奨である．
しかし，どうしても複数の単語を使う必要がある場合，単に複数の単語をつないでもよいし、それらの単語をキャメルケースでつないでもよい（`org.example.myProject`）．

クラスとオブジェクトの名前は大文字から始まるキャメルケースを用いる．

```kotlin
open class DeclarationProcessor { ... }

object EmptyDeclarationProcessor : DeclarationProcessor { ... }
```

## 関数名

関数，プロパティ，ローカル変数の名前は小文字から始まるキャメルケースを用いる．
アンダースコアは使用しない．

```kotlin
fun processDeclarations() { ... }
var declarationCount = ...
```

例外：クラスのインスタンスを作成するためのファクトリ関数は生成するクラスと同じ名前を用いてもよい．

```kotlin
abstract class Foo { ... }

class FooImpl : Foo { ... }

fun Foo(): Foo { return FooImpl(...) }
```

### テストに用いるメソッドの名前

テストでは（テストの中**だけ**では），バックスティックで囲んだ空白を含むメソッド名を使ってもよい．
（そのようなメソッド名は現在Androidランタイムではサポートされていないことに留意されたい）．
また，アンダースコアを含む名前も使ってもよい．

```kotlin
class MyTestCase {
  @Test fun `ensure everything works`() {
  }

  @Test fun ensureEverythinsWorks_onAndroid() {
  }
}
```

## プロパティ名

定数（`const`を付したプロパティや，保持しているプロパティも含めて完全に不変なデータを保持しカスタムゲッターを用いないトップレベル宣言またはオブジェクトの`val`プロパティ）の名前はアンダースコアで区切った大文字の名前を用いる．

```kotlin
const val MAX_COUNT = 8
val USER_NAME_FIXED = "UserName"
```

振る舞いを持っていたり可変なデータを保持するトップレベル宣言またはオブジェクトのプロパティの名前は普通のキャメルケースを用いる．

```kotlin
val mutableCollection: MutableSet<String> = HashSet()
```

シングルトンオブジェクトの参照を保持するプロパティには`object`宣言をしたものと同様の名前を用いる．

```kotlin
val PersonComparator: Comparator<Person> = ...
```

enum 定数に対しては大文字をアンダースコアで区切った名前（`enum class Color { RED, GREEN }`）を使ってもよいし，大文字から始まるキャメルケースの名前を使ってもよい．
使用用途によって使い分ける．

### バッキングプロパティの名前

概念的には同一だが，片方は public API で，もう片方はその詳細な実装であるような2つのプロパティがクラス内にあるとき， private なプロパティの名前は先頭にアンダースコアをつける．

```kotlin
class C {
  private val _elementList = mutableListOf<Element>()

  val elementList: List<Element>
    get() = _elementList
}
```

## いい名前をつける

クラス名はそのクラスが_何であるか_を説明する名詞または名詞句にする．
たとえば， `List` `PersonReader`など．

メソッド名はそのメソッドが_何をするか_を言い表す動詞または動詞句にする．
たとえば，`close` `readPersons` など．
その名前はメソッドがオブジェクトを変更するのか新しいオブジェクトを返すのか示すようなものにすべきである．
たとえば，`sort`はコレクションを変更してソートするのに対し，`sorted`はソート済みのコレクションのコピーを返す．

名前は目的が何であるか明確になるようつける．
名前に意味のない単語（`Manager`,`Wrapper`など）を使用しないようにする．

名前の一部に略語を使う場合，その略語が2文字のときはそれらを大文字にする（`IOStream`）．
略語が長いときは最初の文字を大文字にする（`HttpInputStream`）.
DiscordのBotにSplatoon2のステージ情報を教えてもらう

Splatoon2のステージ情報を取得するDiscordのBotを作りました。

* ステージ情報の取得は[Spla2 API](https://spla2.yuu26.com/)
* Botの作成には[discordrb](https://github.com/meew0/discordrb)
* HTTP通信には[Faraday](https://github.com/lostisland/faraday)

をそれぞれ使わせていただきました。

# 作ったもの

現在のステージ情報と次のステージ情報を教えてくれるBotです。
今回は`.stg`という発言に反応して教えてもらうようにしました。

イメージはこんな感じ。
やってることはSpla2 APIを叩いて、返ってきたものをちょっと加工してメッセージとして送信させているだけです。

<img width="670" alt="スクリーンショット 2018-01-18 22.43.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/222294/0da5254e-a32b-0c6c-71d7-ec36d6314f24.png">

# 導入とか

Botの登録やdiscordrbのインストールの仕方、簡単なBotの作り方は省略します。

# ソースコード

ソースコードはこんな感じ。
`'User-Agent'`のところはそれぞれご自身について書き換えてください。
形式は問わないとのことです。

> **Spla2 API**
>プログラムに組み込む際は、User-Agent をなるべく設定してください。
形式は問いませんが、連絡先が分かる形式だと嬉しいです。
（例: Ikabot/1.0 (twitter @m_on_yu) IkaGirl/2.0 (+https://example.com/) など）

```ruby:bot.rb
require 'faraday'
require 'json'

bot = Discordrb::Commands::CommandBot.new token: '自分のトークン', client_id: 自分のクライアントID, prefix: '.'

times = [['現在', 'now'], ['次', 'next']]
rules = [['レギュラーマッチ', 'regular'], ['ガチマッチ', 'gachi'], ['リーグマッチ', 'league']]

bot.command(:stg) do |event|
  message = times.inject('') do |msg, (time_ja, time_en)|
    msg + "#{time_ja}のステージ情報\n" +
    rules.reduce("```\n") do |detail, (rule_ja, rule_en)|
      detail + "#{rule_ja} : #{call_splat_api(rule_en, time_en)}\n"
    end + '```'
  end
  event.send_message(message)
end

def self.call_splat_api(rule, time)
  conn = Faraday.new('https://spla2.yuu26.com')
  response = conn.get do |req|
    req.url "/#{rule}/#{time}"
    req.headers['User-Agent'] = 'Roboty (Twitter: @otuhs_d)'
  end
  if response.success?
    result = JSON.parse(response.body)['result'][0]
    result['maps'].inject("#{result['rule']}\n") { |msg, map| msg + "* #{map}\n" }
  else
      '情報の取得に失敗しました'
  end
end

bot.run
```

Gemfileに`gem 'faraday'`の追加も忘れずに。

```ruby:Gemfile
gem 'discordrb'
gem 'faraday'
```

# おわりに

Spla2 APIではサーモンランの情報も提供されているので、同様にして作ってみてはいかがでしょうか。
Botを常時動かしたい場合は

* [Docker上でDiscordのBotを動かす](https://qiita.com/otuhs_d/items/679a429d64ad5166bddb)
* [Google App Engineにサードパーティパッケージをインストールする](https://qiita.com/otuhs_d/items/2cb2d798303041387475)

を一例にどうぞ（ダイレクトマーケティング）
AWSでbazelをインストールする方法

## 0. 環境

OS: Amazon Linux AMI 2017.09.1
　　t2.micro

## 1. ソースをダウンロード

```
$ wget https://github.com/bazelbuild/bazel/releases/download/0.9.0/bazel-0.9.0-dist.zip
$ unzip bazel-0.9.0-dist.zip
```

最新のバージョンは
https://github.com/bazelbuild/bazel/releases
で探してください。
2018/1/18現在は0.9.0

## 2. コンパイル

### 2.1 JDK

コンパイルに必要なJDKをインストール。
1.8.0が必要らしい。

```
$ sudo yum -y install java-1.8.0-openjdk-devel
```

デフォルトでは1.7.0が設定されているので1.8.0に変えます

```
$ sudo alternatives --config java
2 プログラムがあり 'java' を提供します。
 
  選択       コマンド
-----------------------------------------------
*+ 1           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
   2           /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.25-0.b18.4.amzn1.x86_64/jre/bin/java
 
Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:
```

`2`と入力してEnter

java -versionで1.8.0になったことを確認します。

```
$ java -version
openjdk version "1.8.0_151"
OpenJDK Runtime Environment (build 1.8.0_151-b12)
OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)
```

### 2.2 bazel

```
sudo ./compile.sh
```

でコンパイル
※ **t2.micro**の場合は以下の2つのエラーが出るはずなので、先に対策しておくとよいと思います。

---
トラブルシューティング
①もし`java.lang.OutOfMemoryError: Java heap space`がでたら、この記事を参照してください。
->[ソースからbazelをコンパイルする時に"java.lang.OutOfMemoryError: Java heap space"というエラーが出たときの対処法](https://qiita.com/shinochin/items/7cefdb6b9b4daa452f08)

②もし`g++: error trying to exec 'cc1plus': execvp: No such file or directory`というエラーがでたら、

```
sudo yum install gcc-c++
```

でgcc-c++をインストールすればOK

---

最後に、コンパイルされたbazelをパスが通っている/usr/binに移動します。

```
$ sudo cp output/bazel /usr/bin/
```

最後に、bazelにパスが通っていることが確認できたら終わりです。

```
$ which bazel
/usr/bin/bazel
```

お疲れ様でした！
kerasでword2vecを構築

# 目標
word2vecをgensimのword2vecを使わずにkerasで実装する。

# word2vecの概要
word2vecとはニューラルネットワークを使用して単語を分散表現にする方法である。
分散表現とはベクトル化することである。単語は今までBagOfWordで扱われることが多い。ベクトル化することで、単語間の距離を測ることができる。つまり単語間の類似度を知ることができる。

この類似度というのは意味的な類似度を表している。なぜかというと、分散表現にする際に、「わたしは〇〇に行きたい。」といった文があった時に、〇〇に入る言葉はそれぞれ意味が近いという仮定を置いているからである。この仮定のおかげで、教師なしデータでも学習ができるようになっている。この仮定はあっているかもしれないが、もっと良い仮定を思いつけばより良い分散表現が得られそう。

# word2vecの理論
word2vecを実装する際に考えなければならないのは、ニューラルネットの構造と、入力データである。
ニューラルネットの構造に関しては、基本的にはなんでも良いと考えている。というよりも、色々ありすぎてまだ何が良いのかわかっていないというのが本当のところである。

word2vecにも色々な種類がある。
・CBoW
・skip gram
・Globe (厳密にはword2vecとは違う？)
これらの違いはうまく説明できない。

ただ、CBowとskip gramは反対の意味らしい。
ここにCBoWとskipgramの違いについて述べられている記事を載せておく。
> https://qiita.com/To_Murakami/items/6bd5638689166ec4821c

今回はskip gramの方を実装していく。

# 実装

## 使用するデータ
歌詞テキストを10,000件ほど集めた。

## データの読み込み
```python
def text2doc(text):
    results = tagger.parse(text).split('\n')
    doc = [result.token
        for result in map(MecabResult, results)
        if not result.POS[0] in ['記号', '助詞', '助動詞', None]]
    return doc

docs = [text2doc(song['lyric'], 'mecab') for song in list(db.songs.find())]
```
これを実行すると、

```
['わたしは犬になりたい', ...]
>> [['わたし', '犬', 'なり'], ... ]
```
といった感じになります。これはword2vecを利用できるライブラリのgensimのdocsと同じ形式である。

## 辞書の作成
```python
dic = Dictionary(docs)
dic.id2token = {val:key for key, val in dic.token2id.items()}
dic.filter_extremes(no_below=3, no_above=0.3)
```
これは単語をidに変換させるためである。filter_extremesでは頻度3以下の語と、全体の0.3以上を占める語を削除している。


## 学習データの作成
```python
x = np.zeros((len(dic),len(dic)))
for i in range(len(dic)):
    x[i][i] = 1
```
この処理では、ニューラルネットにinputする時の、データを作成している。len(dic) x len(dic)の対角成分のみ1の行列である。

```python
window_size = 3
y = np.zeros((len(dic), len(dic)))
for doc in docs:
    for i, word in enumerate(doc):
        _id = dic.token2id.get(word, None)
        for j in range(window_size*2+1):
            k = i-window_size+j 
            if k >= 0 and len(doc) >k:
                target_id = dic.token2id.get(doc[k], None)
                if target_id and _id and k != i:
                    y[_id][target_id] += 1
            else:
                pass
```
_id : 現在注目している単語
target_id : _idの周辺からwindow_size内にある単語のid
をさしていて、y[_id][target_id] += 1で、単語の共起回数を数え上げている。

## modelの構築
```python
hidden_num = 200
hidden_layer = 2
from keras.layers import Dense, Activation
model = keras.models.Sequential()
model.add(Dense(hidden_num, input_dim = len(dic)))
model.add(Dense(hidden_num , activation='relu', input_dim=100))
model.add(Dense(len(dic), activation='sigmoid'))

model.compile(optimizer='sgd', loss='mse')
```

## modelの学習
```python
model.fit(x, y, epochs=1, batch_size=32)
```

# 疑問・課題
・gloveの概要
[バッドノウハウ]webプログラミング初学者がAWS Cloud9でPython3を使う

**この記事は、AWS cloud9上で'python'コマンドでpython3を動かそうとした記録です。
結果的には'python3'のまま運用することにしましたのでこの手順は不要になりました。**

#この記事を書こうと思ったきっかけ

ローカルに環境を用意しなくても開発が始められるという統合開発環境(IDE)Cloud9を始めてみようと思いましたが、ネットで調べてもAWS版のcloud9がリリースされる前の情報が多く、いろいろと戸惑ったこともありましたので記事を書くことにしました。

#これまでのあらすじ

Cloud9のenvironmentを立ち上げるところまでできました。
[webプログラミング初学者がAWS Cloud9を使い始める](https://qiita.com/h008/items/b3ed1b27820bc117dcd9)

#なぜPython3なのか。
やっぱり3>2でしょ。
大きいことは正義だ。新しいことは正義だ。

#Python3を使う
参考にさせていただきました。
[Cloud9でpython3を動かす時にやっておきたいこと](https://qiita.com/hahifu/items/6c808a72b1474500acd6)

##Preferencesパネルを開く
下のいずれかの方法でPreferenceを開く。

- 画面左上「AWS Cloud9」メニューから「Preferences」
- 画面右上の歯車アイコンクリック
- ショートカットキー[Ctrl]+[,]

「PROJECT SETTINGS」→「Python Support」「Python Version」を"Python 3"に切り替えます。
![スクリーンショット 2018-01-18 22.05.32.png](https://qiita-image-store.s3.amazonaws.com/0/125664/dfc0a292-202c-7108-9280-f3828e3fe1c6.png)

##pythonのバージョンを確認してみる

```
ec2-user:~/environment $ python --version
Python 2.7.12
ec2-user:~/environment $ readlink -f /usr/bin/python
/usr/bin/python2.7
ec2-user:~/environment $ pip --version
pip 9.0.1 from /usr/lib/python2.7/dist-packages (python 2.7)
```
##リンクを張り替える方法はダメ。
参考にしたサイトにならい、下記の方法でリンクを張り替えてみたけど失敗。

```
ec2-user:~/environment $ sudo mv /usr/bin/python /usr/bin/python2
ec2-user:~/environment $ sudo ln -s /usr/bin/python3 /usr/bin/python
ec2-user:~/environment $ python --version
Python 2.7.12
```

#.bashrcのaliasが原因？

```
ec2-user:~/environment $ cat ~/.bashrc
# .bashrc

（略）

# User specific aliases and functions
alias python=python27
```

viで下記に書き換える。

```
alias python=python36
```
.bashrcを再読込してpythonのバージョンを確認

```
ec2-user:~/environment $ source ~/.bashrc
function
ec2-user:~/environment $ python --version
Python 3.6.2
```

無事Python3が読み込まれました。
念のためpipのバージョンも確認

```
ec2-user:~/environment $ python -m pip -V
pip 9.0.1 from /usr/lib/python3.6/dist-packages (python 3.6)
```

#ネットにあった情報と違っていて戸惑った点まとめ


- python3をデフォルトにするにはリンク書き換えではなく.bashrcのaliasを書き換える。
Electron + CoffeeScript + Hyperapp でアプリを作った話

## fingerなくなった？

昨年末頃にウチではシステム切り替えがあったのだが、それまで管理者がユーザー確認するために使っていたfinger[^1]が使えなくなったことに切り替え後に気付いた。fingerを使えるようにしていたサーバーの各サービスを他サーバーに分散して移して行ったため、そのサーバー自体をリプレース対象から外していたのが真実だ。誰だ、この仕様を決めたのは、オレだよ。

ということで、急遽LDAPサーバーから簡易にユーザーを検索するためのツールを作ることになってできたのが下記のツールだ。

https://github.com/raccy/dareda

半分趣味、半分仕事なので、年末年始の間にコソコソ作っていたことは秘密だ(こんなOSSを見つけたので、これを使いましょうスタンスなので…)。なお、使い方のドキュメントなど一切作ってないが、需要があったら作る。

## ツールを作るにあたって

サーバーを用意するのは面倒だったので、独立して使えるデスクトップアプリにした。まずは、容量がデカイこと以外に問題が少ないElectronをアプリのベースに採用することにした。

Electronと言えばJavaScriptでロジックを作れることが利点だ。といってもAltJSを使わない理由は無い。もちろんここはCoffeeScriptだ。

最後に、フレームワークをどうするかだ。何も使わずにDOM操作を書いていくのは少し辛い。で、年末Hyperappの記事がQiitaにいくつか上がっていたのをみて「これだ！」と勘違いしたわけだ。ということで、Hyperappを使うことにした。

## TypeScript + React + Reduxと比べて

実はElectron + TypeScript + React + Reduxという組合せで作りかけていたアプリがある。必要性が無くなったこともあって未完成なのだが、そのとき得た見地から今回を比較して述べたいと思う。

### TypeScript vs CoffeeScript

もし、主要なIDEにおける静的型付き言語並の補完を望むのであれば、TypeScriptは有力な選択肢だ。エディタ上で型チェックをしてエラーを指摘してくれるのも大きい。試行回数が大幅に減るだろう。だが、小規模においては如何せん面倒と言わざるを得ない。いざやろうとしても、型定義ファイルが古い、間違いがある、用意されていない、というのも少なくない。どこかで`any`を使用したり、無理矢理キャストさぜるを得ないことも多々あった。

だが、TypeScriptへの不満はそんなことでは無い。一番の問題はECMAScriptの拡張に過ぎないと言うことだ。ECMAScriptの仕様ははっきり言っていいものではない。歴史的ないろいろの無理なところがES2015+になっても無くなったわけでない。むしろ、カオスさが増したと思えるぐらいだ。TypeScriptはそんなECMAScriptに静的型を足しただけだ。それ自体は良い事だと思うのだが、基にした物がどうしようも無いと思っている。これなら、C#をJavaScriptに変換するような形で作った方が良かったのでは無いかと思っている。

ということで、ECMAScriptの呪縛から逃れるために、CoffeeScriptに戻ってきた。CoffeeScriptがどうなのかはこれを読んでいる読者には今更なので説明しなくても良いだろう。

CoffeeScriptだと型が無いでは無いか？と言う人が居るかも知れない。それは間違っている。最新版ではCoffeeScript + Flowという手段が使えるのだ。ただ、**CoffeeScript + Flowで自動型チェックの環境をどう作れば良いのかよくわからない**ので今回は断念した。いつか挑戦したいと思っている。

ああ、最後に一応言っておくけど、ご存じの通りCoffeeScriptはJSX表記に対応しているので、ReactとかHyperappを使うのに特に問題はない。

### React + Redux vs Hyperapp

React + Reduxを作っていても思ったことは「でかい」だ。枠がでかすぎて、いろいろなことを仕込まなければならない。アレもコレも何でも一つ一つ準備しなくてはならない。はっきり言って面倒だ。そして、いろいろと組合せを自動的に処理しようとしたときは、いくつかのライブラリに頼る必要が出てくる。確かにそれらは便利なのだが、より複雑さが増しているような気がした。

巨大なプログラムを構造を崩さずに組み立てるというのであれば、React + Reduxの構成は便利なのかも知れない。しかし、小規模ではそこまでの機能は要らないのだ。Reactの機能は多すぎるし、Reduxがしてくれることは最低限すぎて副作用すら単独では扱えない。なんとも痛し痒しな組合せのような気がする。

そんなときに知ったのがHyperappだった。ライブラリが小さい事は重要では無い、必要な機能だけある事が重要なのだ。Hyperappは余りにも単純すぎるが、単純であるが故に、どうすれば良いのかが見えてくる。規模が大きくなるとわからないが、小さい内は十分見通しが良いアプリが作れる。

今回はそれほど大きい物でなかったこともあって、マッチしていたと思っている。JSX表記も使えるし、基本的な流れはReact + Reduxとそれほど変わらないため、学習コストもほぼ0だった。ドキュメントがまだ少なく、細かいところで迷うところはあったけど、そもそも出来ることが少ないので、それほど苦労することも無かった。

## 何か作ることはやはり楽しい

CoffeeScript v2がでてから何か完成品[^2]を作ると言うこともしてなかったし、ごく一部で話題になっていたHyperappを試すことが出来たので、今回の経験はとてもためになったと思っている。またCoffeeScript + Flow環境をどう用意するか、Hyperappでコンポーネント毎に分割して作って行くときはどうまとめるべきなのか、といった課題も出てきたので、今後研究していきたいと思う。まぁ、どちらもお勧めかと言われると、**微妙**って感じだが。

[^1]: ローカルユーザーを検索するコマンド。OS(pam)がLDAPを見に行っているシステム内なら、LDAP上のユーザーも検索できる。

[^2]: あのツールはあれで完成なのかというツッコミはしないでくれ。動けば良いのだよ、動けば。
Homebrew(cask)でJava7をインストール

以前はcaskで`java7`をインストールできたけど、
Oracleの該当DLページがログイン必須(Oracleアカウント)になったことにより、使えなくなってます。

https://github.com/caskroom/homebrew-versions/issues/3902

代替策としてはOpenJDKの`zulu7`。こっちはcaskでインストール可能。

```bash
brew cask install caskroom/versions/zulu7
```

Java SE 7で！という制約がなければ、こちらで。
QemuでWindows10を物理パーティションから起動する

- linuxとWindows10のdual boot
- linux/QemuでWindows10を物理パーティションからboot
- パフォーマンスは素晴らしくはないが，office等のちょっとした作業をするには十分

# 早速．．

## 環境
Linux : 4.13.16-2-MANJARO
Qemu : version 2.11.0

私のSSDは以下のようになっております．

```
$ sudo fdisk -l

Device     Boot     Start       End   Sectors   Size Id Type
/dev/sda1  *         2048   1026047   1024000   500M  7 HPFS/NTFS/exFAT
/dev/sda2         1026048 710952959 709926912 338.5G  7 HPFS/NTFS/exFAT
/dev/sda3       710952960 712982527   2029568   991M 27 Hidden NTFS WinRE
/dev/sda4       712984440 975128575 262144136   125G  5 Extended
/dev/sda5       712986488 729370623  16384136   7.8G 82 Linux swap / Solaris
/dev/sda6       729372672 975128575 245755904 117.2G 83 Linux

```

この```/dev/sda1```がwindowsのシステムパーティションですね
```/dev/sda2```はwindowsのブートパーティションです
なお私はUEFIよりレガシーブートのほうが好きなのでこのような構成になっています．

この状態で

```
sudo qemu-system-x86_64 -enable-kvm -hda /dev/sda
```

これで動きます．(UEFI環境の方は```-bios OVMF.fd```とかが必要かも?)
お好みでオプションを加えることでより使いやすくなるかと

いろいろな記事を参考にさせていただきましたが，これが一番シンプルかな?
loopデバイスを使ったり，Virtualboxを使ったり．．


# 注意
- バックアップを取ってからやりましょう
  - ストレージ周りになるため適当にいじっていると壊れます．(私は Windows10のシステムパーティションを破壊したらしく，Windowsを壊しました．．)

# 参考
https://www.linuxquestions.org/questions/linux-virtualization-and-cloud-90/qemu-kvm-on-a-real-partition-947162/
https://lejenome.github.io/post/boot-physical-windows-inside-qemu-guest-machine
homebrew コミット履歴を調べる（tig コマンド利用）

こんにちは。
homebrew の各 formula のコミット履歴を表示・調べて見ました（```tig``` コマンド利用）。

```console
$ brew install tig
$ (cd /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core; tig)
```

![tig.png](https://qiita-image-store.s3.amazonaws.com/0/54617/2c93c7ed-84b1-52d6-4bfa-bdb9adfe8787.png)
APIで複数通貨のレートを効率よく完全自動でデータベースに登録する方法！　メンテナンスも簡単！

#概要
以前の記事[seed.rbの使い方　railsでAPIから取得したjsonデータをDBに自動登録](https://qiita.com/Hijiri-K/items/53ff9a985d0d0978e2fb)では、currencylayerのAPIを利用して一つの通貨を基に複数の通貨のレートを取得し登録したが、今回はそれを複数の通貨を基にしたレートを取得し、さらに通貨が増えても簡単にメンテナンスできるように改良した。


#コード
前回の記事で書いたコードは通貨を変更するときは、URLの編集が必要であった。
また、USDJPYとJPYUSDといった変換先が逆転するデータも登録する場合、新たにURLを書かなくてはいけなかった。
今回のコードでは、eachを2回組み込むことで、完全自動で変換先が逆転したデータまで登録できる。
また、通貨を追加する際にも、sourcesの配列に追加するだけで、メンテナンスも簡単である。

```rb:sample.rb
ENV["SSL_CERT_FILE"] = "app/controllers/cacert.pem"
      require 'open-uri'
      sources = ["USD","JPY","EUR","CNY","KRW","THB"]
      currencies = sources.join(',')#配列を文字列に変換
      sources.each do |source| #変換元（source）を順番に繰り返す。
          res = open('https://apilayer.net/api/live?access_key=アクセスコード&currencies=' + currencies + '&source=' + source + '&format=1')
          code, message = res.status # res.status => ["200", "OK"]
          if code == '200'
            result = ActiveSupport::JSON.decode res.read
            @result = result['quotes'] #返ってきたjsonデータをrubyの配列に変換
            @result.each do |key, value| #jsonの通貨ごとに登録を繰り返す。
               rate = Exchange.find_or_create_by(currency: key)
               rate.update(currency: key, rate: value)
            end
          else
            puts "Error!! #{code} #{message}"
          end
        end
      end
```

#感想
かなりきれいに実装できたので良かった（うれしかったので記事にしました。笑）
eachの使い方などがパッと思いつくようになり、エンジニアの思考回路に近づいた気がする。
今度は、これをheroku上で毎朝定期的に実行するような実装をする予定。
[JavaScript] Mapと連想配列の相互変換 - 深い階層も変換

[[JavaScript] Mapと連想配列の相互変換
](https://qiita.com/mktoho-n/items/6b96674c9c7ba542d2be) の続きです。

せっかく作ったので、連想配列の値が連想配列だったりとか、Mapの要素がMapだった場合にも変換できるように修正してみました。

# 使い方
```js
let object = {id: 1, name: 'mk'}

let map = objectToMap(object) // -> Map {'id' => 1, 'name' => 'mk'}

mapToObject(map) // -> {id: 1, name: 'mk'}
```
2つめの引数に`{deep:true}`を渡すと、ディープな変換をします。

```js
let object = {id: 1, name: 'mk', profile: {
  blood: 'O', like: 'カレー', address: {
    pref: 'Tokyo', city: 'Yoyogi'}}}

let map = objectToMap(object, {deep: true})
// -> Map {'id' => 1, 'name' => 'mk', 'profile' => Map {
//      'blood' => 'O', 'like' => 'カレー', 'address' => Map {
//        'pref' => 'Tokyo', 'city' => 'Yoyogi' } } }

mapToObject(map, {deep: true})
// -> {id: 1, name: 'mk', profile: {
//      blood: 'O', like: 'カレー', address: {
//        pref: 'Tokyo', city: 'Yoyogi'} } }
```


# ソースコード

```js:map_object_convert.js
'use strict'

const mapToObject = (map, {deep = false} = {}) =>
  [...map].reduce((l, [k, v]) =>
    Object.assign(l, {[k]: deep && isMap(v) ? mapToObject(v, {deep}) : v}), {})

const objectToMap = (object, {deep = false} = {}) =>
  new Map(Object.entries(object).map(([k, v]) =>
    [k, deep && isObject(v) ? objectToMap(v, {deep}) : v]))

const is = constructor =>
  something =>
    something !== undefined &&
    something !== null &&
    something.constructor === constructor

const isObject = is(Object)

const isMap = is(Map)

export {mapToObject, objectToMap}

```
【PixiJS】ポインター・マウス座標取得【相対・絶対】

# 1. 相対座標取得

HTML, CSS でキャンバスのサイズを拡大縮小したときに、相対的な座標を取得する方法です。
特定の `PIXI.DisplayObject` に対する相対位置を知りたいときにも有効です。

## 1.1. event から取得

`.on('click', listener)` などのイベントリスナー内で使うことを仮定。

```javascript
const listener = (event) => {
    const position = event.data.getLocalPosition(event.currentTarget);
};
```

`event.currentTarget` の代わりに具体的な `PIXI.DisplayObject` を指定することも可。

参考「[[pixi.js] MagicLight (4) ～Sprite, TouchEvent～ | にゃあプロジェクト](http://blog.project-nya.jp/2058)」


## 1.2. event を使わずに取得

Ticker で取得するときなどに使用？

```javascript
// app: PIXI.Application
// displayObject: PIXI.DisplayObject

const position = app.renderer.plugins.interaction.mouse.getLocalPosition(displayObject);
```

`renderer.plugins.interaction.mouse` の中身は `event.data` と同じく `PIXI.interaction.InteractionData` です。

参考「[PIXI.interaction.InteractionData - PixiJS API Documentation](http://pixijs.download/dev/docs/PIXI.interaction.InteractionData.html)」
参考「[PIXI.CanvasRenderer - PixiJS API Documentation](http://pixijs.download/dev/docs/PIXI.CanvasRenderer.html)」
参考「[PIXI.WebGLRenderer - PixiJS API Documentation](http://pixijs.download/dev/docs/PIXI.WebGLRenderer.html)」


# 2. 絶対位置を取得

キャンバスの拡大縮小に関わらない座標が取得できます。

```javascript
// app: PIXI.Application

app.renderer.plugins.interaction.mouse.global.x
app.renderer.plugins.interaction.mouse.global.y
```

参考「[Pixi.jsでマウスクリックなどのインタラクティブ性をつける - code snippets](http://miffysora.wikidot.com/pixijs-interactive)」


# 3. 廃止

最新バージョンでは廃止されて使えない方法なのですが、検索すると出てくるので一応書いておきます。

```javascript
// stage: PIXI.Stage

stage.getMousePosition()
```

参考「[簡単アニメーション！Pixi.jsを触ってみる！（6）インタラクションに挑戦！(のつづき) - Qiita](https://qiita.com/tadfmac/items/8b392608124a00c792ec)」

v3 で廃止されたようです。
CodeIQ「進捗ヴェリーグッドマーク」問題に参加しました

[CodeIQ「進捗ヴェリーグッドマーク」問題](https://codeiq.jp/q/3526)の公開が終了したということで、自分の解答を公開したいと思います。なおCodeIQはそのサービスの都合上、解答の公開は基本的にNG。ただ[今回は出題者の@tbpgrさんの許可が出ている](https://twitter.com/tbpgr/status/953643033991438336)ということもあり、解答を公開しています。

```csharp:Program.cs
using System;
using System.Linq;

public class Program
{
    public static void Main(string[] args)
    {
        var n = int.Parse(Console.ReadLine());
        var ans = Draw(n);
        Console.WriteLine(ans);
    }

    public static string Draw(int n)
    {
        if (n % 2 == 0)
        {
            return "invalid";
        }

        var matrix = Enumerable.Range(0, n).Select(i => Enumerable.Repeat(".", n).ToList()).ToList();
        foreach (var i in Enumerable.Range(0, n))
        {
            var j = i / 2;
            matrix[i][j] = matrix[i][n - j - 1] =  "v";
        }


        return string.Join(System.Environment.NewLine, matrix.Select(row => string.Join("", row)));
    }
}
```

まずは二次元配列を文字列`.`で初期化したあと、適当な要素を文字列部分で`v`で上書きする――というシンプルなロジックになっています。もう少しC#らしい書き方があるような気もしますが、C#初心者としては満足な出来上がりです。

次にテストコード。かなり雑、というかコピペで作った感満載(´・ω・｀) 正直なところNUnitがよくわかっておらず、雰囲気で使っている面は多々あります。鍛錬が足りぬ(´・ω・｀)

```csharp:ProgramTest.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Tests
{
    [TestClass()]
    public class ProgramTests
    {
        [TestMethod()]
        public void DrawTest1()
        {
            Assert.AreEqual("v", Program.Draw(1));
        }

        [TestMethod()]
        public void DrawTest2()
        {
            Assert.AreEqual("invalid", Program.Draw(2));
        }

        [TestMethod()]
        public void DrawTest3()
        {
            var expected = "v.v?v.v?.v.".Replace("?", System.Environment.NewLine);
            Assert.AreEqual(expected, Program.Draw(3));
        }

        [TestMethod()]
        public void DrawTest5()
        {

            var expected = "v...v?v...v?.v.v.?.v.v.?..v..".Replace("?", System.Environment.NewLine);
            Assert.AreEqual(expected, Program.Draw(5));
        }
    }
}
```

関連リンク:

- https://codeiq.jp/q/3526
- https://twitter.com/tbpgr/status/953643033991438336
- http://tbpgr.hatenablog.com/entry/2018/01/17/235711
- https://togetter.com/li/1184198
管理者権限でbatを実行したい時にやッた事

# はじめに
管理者権限が必要なコマンドや領域をbatで弄りたいけど困った時に
ユーザーがマニュアルを読まず、右クリックしてくれない現場の時に
なんかいろいろ面倒になった時に
そんな時に使える管理者権限でのbat実行

ただし、powershellとユーザーへの管理者権限付与が必要です。

##管理者権限への昇格方法

```bat
powershell start-process 実行対象 -verb runas
```

batの中でpowershellと最初に入れるとpowershellのコマンドが使えます。
それを使って、新しいプロセスを管理者権限で実行しようというわけです。

簡単な解説
powershell ぱわーしぇる
start-process　新しいプロセス立ち上げよう
実行対象　立ち上げたい対象
-verb runas 管理者で実行する

##想定の構成

Cドラの直下にシステム用のディレクトリを作成してもらう必要が出てしまいました。

ダウンロードしたbatを実行してもらい、作成して貰いましょう

Kick.bat
main.bat
が有るとします。

Kick.batには

```bat:Kick.bat
powershell start-process main.bat -verb runas
```

main.batには

```bat:main.bat
mkdir c:\temp_SYS
```

としてkick.batを実行してもらうと管理者権限が必要なCドラの直下にディレクトリ作ったり出来る訳ですね。

##でも、2つもbat必要とか微妙だよね
2つのbatとかユーザーが押してくれないしダウンロードさせる時とかに面倒じゃない？

大変そう思います。大方どっちを実行すれば良いのかと問い合わせが来そうです。

そんな訳で、batを一つにまとめてしまいましょう。

ついでにちゃんと成否を判定してダメだったユーザーにはヘルプへ問い合わせを促しましょう。
そんな感じで処理を盛り込み、batの中でbatを生成する様にして一つにまとめたのがこちらです。



```bat:main.bat
@echo off

rem 日時を取得する
set now_date=%DATE: =0%
	set now_date=%now_date:~0,4%%now_date:~5,2%%now_date:~8,2%

set now_time=%time: =0%
	set now_time=%now_time:~0,2%%now_time:~3,2%%now_time:~6,2%

set now_dt=%now_date%%now_time%

rem 場所の移動する
cd /d "%~dp0"

rem 実行したい処理をセットする
set syori_1=mkdir c:\temp_SYS

rem エラーが起きた時の為にエラーレベルを出力する
set syori_err_l=echo %%errorlevel%%

rem セットしたコマンドをbatに出力する
echo %syori_1% >syori.bat
echo %syori_err_l% ^>"%~dp0"err_%now_dt%.log >>syori.bat

rem powershellで管理者権限で出来たbatを実行する
powershell start-process syori.bat -verb runas

rem 処理が終わるまでちょい待つ
@ping localhost -n 5 > nul

rem 出力されたエラーレベルを取得する
set /p err_l_get=<./err_%now_dt%.log

rem エラーレベルで処理の成否を判定
if %err_l_get% == 0 (
	echo 処理完了!!!
) else (
    echo 処理エラー　ヘルプに問い合わせて
	goto err_go
)

rem 使い終わったbatとlogを消す
del syori.bat

del err_%now_dt%.log

echo キーボードをどれか押すと閉じる

@pause  > nul

exit


:err_go
rem  エラー時の処理

rem 使い終わったbatを消す
del syori.bat

echo キーボードをどれか押すと閉じる

@pause > nul

exit


```


##おわり
何処かで誰かの役に立てばいいなぁ
Hibernate Validator の @Email を使ってはいけない？

*有名な話だったらゴメンよ！*

Hibernate Validator 先生はめっちゃ便利なわけですが、ある日こんなことが。

「おい！ hoge@+gmail.com とか入力されてメール送信系が例外吐いてんぞ！ 誰だバリデーションしてねえ馬鹿は！？」

~~まずそんな馬鹿な作りにしたやつは誰だ。~~
この時、Hibernate Validator のバージョンは 5.2.2 Final でした。なんで最新じゃないのかって？ 知るもんかい。

# なお何ら問題なくバリデーションされていた模様
どこを見ても @Validated は付いています。あれ？ と思って hoge@!@#$%^&()_+ とかやると……引っかかる。動いてるよなー。
ってことは**こいつドメイン部の+通しちまうんじゃねえか！！**

# なお最新版
5.2.2 で存在した EmailValidator は 最新版 (2018/01/17) では @Deprecated 。では現行はどうなんでしょう？
https://github.com/hibernate/hibernate-validator/blob/7c0afb18cc83aab5e73827a6659af23970dd26f5/engine/src/main/java/org/hibernate/validator/internal/constraintvalidators/bv/EmailValidator.java
ありゃ、見当たらない。Abstract の方でしょうか。

https://github.com/hibernate/hibernate-validator/blob/35ba4c157e81ce6a54e8717418d2718d384ed144/engine/src/main/java/org/hibernate/validator/internal/constraintvalidators/AbstractEmailValidator.java

```java
DomainNameUtil.isValidEmailDomainAddress( domainPart );
```

ほうほう、DomainNameUtil 。

https://github.com/hibernate/hibernate-validator/blob/911efbad82d0c81e2ae4aa8b5b412865ed6bd127/engine/src/main/java/org/hibernate/validator/internal/util/DomainNameUtil.java

```java
private static final String DOMAIN_CHARS_WITHOUT_DASH = "[a-z\u0080-\uFFFF0-9!#$%&'*+/=?^_`{|}~]";
private static final String DOMAIN_LABEL = "(" + DOMAIN_CHARS_WITHOUT_DASH + "-*)*" + DOMAIN_CHARS_WITHOUT_DASH + "+";
private static final String DOMAIN = DOMAIN_LABEL + "+(\\." + DOMAIN_LABEL + "+)*";
```

**ﾃﾞﾃﾞﾄﾞﾝ!!(絶望)**
……これは参ったなあ。ドメインは RFC1035 ベースで見たほうがいいんじゃないの？って Issue を書くべきかしら。

# じゃあ何使えばいいのよ？
Apache commons-validator が割といいらしいっすよ[^1]。
……もっとも、日本語アドレス (Gmailとかは対応してるらしい) みたいなキワモノまで使えるかは試してませんが。

# commons-validator ってアノテーションでついてたっけ？
ついてません。さくっとこんな感じで書きませう。

```java

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE,  ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {CommonsEmailValidator.class})
@Documented
@ReportAsSingleViolation
public @interface Email {

    String message() default "{org.hibernate.validator.constraints.Email.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface List {
        Email[] value();
    }
}

public class CommonsEmailValidator implements ConstraintValidator<Email, String> {

    @Override
    public void initialize(Email email) {
        // nothing to do
    }

    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        if( s == null || s.isEmpty() ) return true;
        return EmailValidator.getInstance(false).isValid(s);
    }
}
```


[^1]: https://stackoverflow.com/questions/624581/what-is-the-best-java-email-address-validation-method
【Qt】QCommandLineParserを使う

簡単なUDP受信アプリケーションのIPアドレスとポートをコマンドラインで設定できるようにしました。

-aまたは--addressでIPアドレスを、-pまたは--portでポート番号を設定できます。
何も設定しない場合は、デフォルト値（IPアドレス:0.0.0.0, ポート番号:45454）が使われます。
また、addHelpOption()で、-hしたときのヘルプを勝手に作ってくれます。
今回は実装していないですが、不正なオプション指定も簡単に検出できます。

```cpp
#include <QCoreApplication>
#include <QtCore/QCommandLineParser>
#include <QtCore/QDebug>

int main(int argc, char *argv[]) {
  QCoreApplication app(argc, argv);
  QCoreApplication::setApplicationName("udp_receiver");
  QCoreApplication::setApplicationVersion("1.0");

  QCommandLineParser parser;
  parser.setApplicationDescription("Receive UDP datagram.");
  parser.addHelpOption();
  parser.addVersionOption();
  parser.addOptions({
      {{"a", "address"}, 
        QCoreApplication::translate("main", "Host address. Default: 0.0.0.0"),
        QCoreApplication::translate("main", "address"),
        QCoreApplication::translate("main", "0.0.0.0")},
      {{"p", "port"}, 
        QCoreApplication::translate("main", "Port. Default: 45454"),
        QCoreApplication::translate("main", "port"),
        QCoreApplication::translate("main", "45454")}
  });

  parser.process(app);
  const QString addr = parser.value("address");
  const quint16 port = parser.value("port").toUInt();
  qDebug() << "UDP receiver starts" << addr << "(" << port << ")";

  // 以下、UDPレシーバのコードは省略

  return app.exec();
}
```

```
./udp_receiver -h
Usage: ./udp_receiver/release/udp_receiver [options]
Receive UDP datagram.

Options:
  -h, --help               Displays this help.
  -v, --version            Displays version information.
  -a, --address <address>  Host address. Default: 0.0.0.0
  -p, --port <port>        Port. Default: 45454
```

```
./udp_receiver
UDP receiver starts  "0.0.0.0" ( 45454 ) #デフォルト値
```

```
./udp_receiver -a 192.168.1.3 -p 8888
UDP receiver starts  "192.168.1.3" ( 8888 ) #設定値
```

便利です♪
結局 "メールアドレスの規格" ってどこ？

メールアドレスの "規格" を探すと、おっそろしーことに未だ "RFC822を参照せよ" 、という文言を見かける。マジか。お前それいつの何の資料かわかって言ってんの？
(一応擁護すると、未だ "STD 11" はRFC822を参照している[^1] - それはそれとして822を参照すること自体が不適切なのには変わりないんだが - ので、これについてはIETFもちょっと悪い気はする)

# 2系統の定義
メールアドレスの規格を調べる時混乱する要因の一つが、定義そのものが複数系統存在することだ。
こういうと「？」な感じなのだが、要するに「メールアドレスの規格」だけを定義するものはそもそも存在しない。
ムリもない話で、メールアドレスだけ存在しても周辺の伝送機構がなければなんにもならんのだ。住所とポストだけ整備しても郵便サービスがなければ手紙は届かんのである。

## RFC822 系統
いわゆる「電子メールメッセージのデータ形式」の定義である。まだ3桁なあたりが時代を感じさせる。2018/01/16現在の最新はRFC5322で、標準となったのは822ながら、実はこの更に元ネタ (?) としてRFC733が存在する。
読めばわかるが、ARPANETのような懐かしい通り越して大多数の人間が「なにそれ」となりそうな単語が頻出する (気になったらとりあえず "カッコウはコンピュータに卵を産む" を読めばいいと思うよ。かくいう筆者もアレで知ったクチ) 。

これによるメールアドレスの定義はそれはもうドエラいガバガバっぷりを発揮しており、下手すると "もう /[@]/(= @ が含まれていればvalid) でいいじゃないか" とすら言われるほど[^2]である。

### Q. 何故こんなガバガバ定義なのか？
A. 「電子メールメッセージのデータ形式」の定義だから。
要するに、このRFCは「なんやかんやして受け取ったメッセージはこういうふうに解釈せえよ」と "受け取った者 (大抵は受信者のメーラー・ソフトウェア) に対して" 言っているのだ。

特に初期の定義は黎明期も黎明期のものである。いわゆる "メールアドレス" っぽい部分には人名が入り込んだりしていた。
よく見るこういうやつだ:

```
hoge@hogefuga.com <hogefuga>
```

こういうのを受け付けるようにするとどうあがいたってそりゃガバる。
そもそも目的が「受け取ったものの解釈法」なので、根本的にこれを「メールアドレスの規格」として参照することそのものが論外である[^3]。

## RFC821 系統
SMTPという単語を聞いたことはあるだろうか。これはRFC772の提案物が821で標準化されたもので、2018/01/16現在の最新はRFC5321である。

SMTPは Simple Mail Transfar Protocol の略で、大雑把に言うとメールを送信する時の作法と送信系システムの規定である。
一般的には "SMTPサーバ" という形で聞く機会が (比較的) 多いはずだ。SMTPサーバはSMTPに従ってメールを送信する際それを受け付けてくれるサーバのことで、郵便でいうとそこらへんの郵便局に相当する。現実と異なり出しに行くのは通信一つで済むので、ポストに相当するものは存在しないと考えていい。

さて、先程 "受け取ったものの解釈法" の規定を "メールアドレスの規格" として扱うのは論外だと記述した。ではどこを使うべきか？ 無論 "メールアドレスを実際に使う側" の規定である。
既に大体察していると思うが、SMTPはまさにその "使う側" に他ならない。郵便局の人たちが読めないような書き方で郵便番号と住所と名前を書いても手紙が届かないように、SMTPサーバが解釈できないようなアドレスへメールを送れと言われても送りようがないのだ。必然的にRFC821系の最新を満たすのが望ましい。

……ただし、こうやっていろいろと掘っていくと最終的にかなりややこしい話になってくる。
(たとえば @ の前は quoted-string が利用可能である、とか……)
最終的には「RFCに意図的に違反した」バリデーションにならざるをえない、というのは珍しい話ではない。

# 結論
(少なくとも2018/01/16現在では) RFC5321を出来る限りそれっぽく満たすのがよい、ということになる。
……もちろんこれが死ぬほどややこしいのは言うまでもない。特にIPリテラルなどはほとんど無理ゲーに近い。
結局は input[type="email"] よろしく 
```/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/```
のような単純化した正規表現を使うとかそういう方向に倒すことが多くなるだろう。しかし、こういうものの裏にこういった資料群と葛藤があることは把握して然るべきである。
……あとは言うまでも無いが、まともに使えるライブラリがあるならそっちを使うべきだ。

# 参考
http://www.nslabs.jp/email-address-regular-expression.rhtml
http://srgia.com/docs/rfc5321j.html
http://srgia.com/docs/rfc1035j.html
https://www.w3.org/TR/html53/sec-forms.html#valid-e-mail-address

[^1]: http://d.hatena.ne.jp/kazu-yamamoto/20080107/1199679405 によると、 IETF的には "標準" へわざわざ育て上げるメリットもないという認識があるらしくほったらかしらしい。まあわからんでもない、普通なら最新のRFCを優先する。
[^2]: http://d.hatena.ne.jp/shidho/20090320/p1 記事自体は「お馬鹿な "使える正規表現まとめ" へのツッコミ集」である。あまりにお粗末な正規表現まとめが乱立していたため主語が大きくなり、主語が大きくなった結果クソリプが山ほど付いて大荒れになった。
[^3]: http://jbpe.tripod.com/rfcj/rfc-822.j.sjis.txt ではこう訳されている: "この標準は、「電子メール」の枠組み内で、コンピューター利用者の間で送信されるテキストメッセージ用の構文を特定します。" つまりアドレスの定義はおまけ以下だ。822を参照すること自体が不適切なのには変わりない、というのはこういうこと。
Google Speech API + Python で音声をテキスト変換する


# Python install

```bash

# Pythonのバージョン管理ソフトのインストール
$ brew install pyenv
$ echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
$ echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
$ source ~/.bashrc

# インストール可能なバージョンの確認
$ pyenv install -l

# 2系インストール
$ pyenv install 2.7.14

# 3系インストール
$ pyenv install 3.6.3

# デフォルトバージョンの指定(python python2, python3)
$ pyenv global 2.7.13 3.6.1

# Virtualenv install（環境管理用）
$ pip install virtualenv

```


# Google Cloud Speech API　有効化

1. Google アカウントを準備する
2. GCP コンソールにログインする
3. GCP のプロジェクトを作成・選択する
4. google speech aipを有効化する
  1. メニューボタンの「APIとサービス」 -> 「ダッシュボード」をクリック
  2. ページ上部の「APIとサービスの有効化」をクリック
  3. 検索窓で「speech」と入力し、「Google Cloud Speech API」を選択
  4. 「有効にする」をクリック
5. 認証キーの取得
  1. メニューボタンの「APIとサービス」 -> 「認証情報」をクリック
  2. 「認証情報を作成」 -> 「サービスアカウントキー」をクリック
  3. サービスアカウントの選択でspeech-apiを選択する
  4. キータイプはjsonを選択する
  5. 作成をクリック



### 参考サイト

- プロジェクトを作成、管理する  
  https://cloud.google.com/resource-manager/docs/creating-managing-projects?hl=ja
- Speech API クイックスタート  
  https://cloud.google.com/speech/docs/getting-started?hl=ja

# gcloud（SDK）install

```bash
$ curl https://sdk.cloud.google.com | bash
$ exec -l $SHELL
$ gcloud init

# ブラウザを利用したログイン
$ gcloud auth login
```
**-TODO-**
GCP のサービスアカウントキーを取得し環境変数の設定が必要か検証が必要

```bash
# Google Cloud Speech APIの 5.認証キーの取得 でダウンロードしたjsonファイルを指定
$ export GOOGLE_APPLICATION_CREDENTIALS=<path_to_service_account_file>
```
サービスアカウントキー取得の参考サイト
http://blog.a-know.me/entry/2016/09/18/212947

サービスアカウントキーとは
https://cloud.google.com/speech/docs/common/auth?hl=ja
https://cloud.google.com/iam/docs/creating-managing-service-account-keys?hl=ja
https://cloud.google.com/iam/docs/understanding-service-accounts?hl=ja



# Python 非ストリーミングおよびストリーミング音声認識サンプルの実行

#### 参考サイト
https://cloud.google.com/speech/docs/samples?hl=ja

```bash
# サンプルファイル取得
$ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
$ cd python-docs-samples/speech/cloud-client

# 環境構築
$ brew install portaudio
$ pyenv local 2.7.14
$ virtualenv env
$ source env/bin/activate
$ pip install -r requirements.txt
$ pip install pyaudio
```

```bash
# ストリーミングで音声変換
$ python transcribe_streaming_mic.py
```
注）変換は言語が英語のため、日本語に変換したい場合は178行目あたりの`language_code = 'en-US'`を`language_code = 'ja-JP'`と変換する必要がある。
babelのAPIを使ってtransformを色々試してみる。

# この記事は？

実用的ではないのですが、
babelを色々試す過程で、babelのtransformなどのAPIを使ってコード変換を書いてみたので、勉強ログとして残しておきます。
なお、変換するコード自体は**ES2015以前の書き方**で書いています。

# 実装した内容について

実装した機能はES2015で書かれた``input.js``を変換して``output.js``にするというもの。

このコード(input.js)が、

```javascript
const hello = (str) => {
  console.log("Hello ", str);
}

hello("world");

```

このように変換されます。
(output.js)

```javascript
"use strict";

var hello = function hello(str) {
  console.log("Hello ", str);
};

hello("world");

```

# 依存関係

``package.json``内の依存関係は下記のとおりです。

```json

  "dependencies": {
    "babel-core": "^6.26.0",
    "babel-preset-env": "^1.6.1"
  }
  
```


# babel.transformを使用したコード変換

```javascript
const babel = require('babel-core');
const fs = require('fs');

const CHAR_CODE = 'utf-8';

const options = {"presets": ["env"]}

const inputFile = './input.js'
const outputFile = './output.js'

function readFile(path) {
  return fs.readFileSync(path, CHAR_CODE);
}

function compile(input, output) {
  const code = readFile(input);
  const newCode = babel.transform(code, options).code
  fs.writeFileSync(output, newCode);
  console.log("*** compile success!! ***");
  console.log(input, "----->", output)
}

compile(inputFile, outputFile)
```

# babel.transformFileを使用したコード変換

```javascript
const babel = require('babel-core')
const fs = require('fs')

const options = {"presets": ["env"]}

const inputFile = './input.js'
const outputFile = './output.js'

function compile(inputFile, outputFile) {
  babel.transformFile(inputFile,options, function(err, result) {
    fs.writeFileSync(outputFile, result.code);
    console.log("*** compile success!! ***");
    console.log(inputFile, "----->", outputFile)
  });
}

compile(inputFile, outputFile)

```

# babel.transformFileSyncを使用したコード変換

```javascript
const babel = require('babel-core')
const fs = require('fs')

const options = {"presets": ["env"]}

const inputFile = './input.js'
const outputFile = './output.js'

function compile(intputFile, outputFile) {
  fs.writeFileSync(outputFile, babel.transformFileSync(inputFile, options).code)
  console.log("*** compile success!! ***");
  console.log(inputFile, "----->", outputFile)
}

compile(inputFile, outputFile);

```

# babel.transformFromAstを使用したコード変換

```javascript
const fs = require('fs')
const babylon = require('babylon')
const babel = require('babel-core')

const CHAR_CODE = "utf-8";

const inputFile = "./input.js";
const outputFile = "./output.js";
const options = {"presets": ["env"]}

function readFile(path) {
  return fs.readFileSync(path, CHAR_CODE);
}

function compile(inputFile, outputFile) {
  const code = readFile(inputFile);
  const ast = babylon.parse(code);
  const newCode = babel.transformFromAst(ast, code, options).code;
  fs.writeFileSync(outputFile, newCode)
  console.log("*** compile success!! ***");
  console.log(inputFile, "----->", outputFile)
}

compile(inputFile, outputFile);
```

以上です。
普段何も考えずに使っているbabelのコード変換ですが、こうやってちょっとした処理を自分で書いてみると少しだけ身近になったような気分になりますね。

# 参照

[Babel - API](https://babeljs.io/docs/usage/api/)
identity の使いみち

「Functional Interfaceやらなんやらが便利なのはなんとなくわかってきたんだ。でも、この "identity" ってやつは何に使うんだ？ そのまま返すだけの関数を返すって一体何がしたいのさ？」
なんて言われたので、超今更なメモ。

*注: 調査検証が雑です。マサカリ歓迎*

```
// こんなクラスがあるとして
@Data
class Obj {
    private int id;
    private String data;
}

// List になってたとする
List<Obj> list = <some>;

// key:id, value:obj のマップを生成 (※もっとマシな手がありそうな気はする)
Map<Integer, Obj> map = list.stream().collect(Collectors.toMap(obj::getId, Function.identity()));
```

Functional Interface は「操作そのもの」を受け取るためのインターフェイスだ。ありとあらゆる操作をシグニチャでそれっぽく処置してくれる。
しかし、これをバンバン使って物を書いていくと「いやいやそのままでいいんだ！何もせんでくれ！」ってことはなくもない。そういう時に identity が役に立つ。

もちろん同じことは lambda で o -> o とか書いても出来るが、しかし、全く同じとは行かない。
lambda の実体は無名ローカルクラスだというのは有名な話だが、つまり使えば使うほどクラスとインスタンスが増える。ということは多少とは言え負荷がかかる。
 (そりゃそうだよな、引数として渡せるってことはオブジェクトとしての実体があるってことだ) 

一方 (JVM実装次第かもしれないが) identity は常に同一のインスタンスを返すそうだ:
https://stackoverflow.com/questions/28032827/java-8-lambdas-function-identity-or-t-t
確かに、確実に一発で終わるなら lambda でさらっと書いてもまあ困らない。しかし、基本的に Function.identity なり UnaryOperator.identity なりを使っておいたほうがうっかり無駄インスタンスを量産しなくて安心できる利点がある。ちょっとタイプ数と import が増えるのはまあ許してやろう。

# 「ところで identity ってなんだ？」
identity = 恒等。メソッド identity は恒等関数を返す。
恒等関数は「渡された引数を返す関数」で、関数の結合における単位元。つまり、 (本来は文脈の示す領域によるが、あくまで感覚的には) 数字の1みたいなもの。
NotificationCenterとFuture

**この記事は落書きです**

### Future
Futureを使うと簡単になるのではという問題に直面したので、Futureというものを自分で作りながらお勉強しています。

今のところこんな感じのインターフェイスになっています。

```swift
class Future<T> {
  init(_ queue: DispatchQueue = default, _ block: @escaping () throws -> T)
  
  @discardableResult
  func onSucces(_ block: @escaping (T) -> Void) -> Self
  @discardableResult
  func onFailure(_ bloc: @escaping (Error) -> Void) -> Self

  func success(_ value: T)
  func failure(_ error: Error)

  func map<U>(_ transform: @escaping (T) throws -> U) -> Future<U>
  func flatMap<U>(_ transform: @escaping (T) -> Future<U>) -> Future<U>
}
```
バカなのでPromiseの必要性が分からないため混ざってます。

### Notification
上のFutureをもとに*Notificationを受けると値が確定するFuture*がもらえるものを作りました。

```swift
extension NotificationCenter {

  // block: 戻り値がFutureの値となる。
  //        例外が投げられると投げられたエラーでFutureが確定する。
  //        戻り値がnilの時はNotificationの監視を継続する。
  func future<T>(forName name: Notificaion.Name,
                 object: Any?,
                 queue: OperationQueue?,
                 block: @escaping (Notification) throws -> T?) {

    let future = Future<T>()

    weak var token: NSObjectProtocol?
    token = addObserver(forName: name, object: object, queue: queue) { notification in
      do {
        guard let value = try block(notification) else { return }
        future.success(value)
      } catch {
         future.failure(error)
      }
      token.map(self.removeObserver)
   }

   return future
}
トランジスタ技術2017年11月号の特集のESP32をやってみた

この記事の要約
スマホからwifi経由でマイコンにアクセスしマイコンのI/OにつながれたLEDをON/OFFさせる

正月休みにトランジスタ技術2017年11月号の特集のESP32をやってみた
本の内容通りに配線し、ソースコードをダウンロードし、ESP32にファームウェアを書き込んだ
シリアルモニタを起動しIPアドレスを確認しようとしたが問題が起きた。シリアルモニタを起動しても何も表示されなかった。ネットで調べた結果ESP32評価ボードの「EN」ボタンを押した
するとシリアルモニタにIPアドレスが表示された
本には書かれていない内容である
ひとつ勉強になった
そしてスマホのブラウザを立ち上げ、表示されたIPアドレスをURL欄に入力した
本の内容通りのが画面が一瞬表示されたがエラー画面に切り替わった
パソコンからも同様の現象になった
スマホはAndroid6.0でyahooブラウザを使用した
ソースコードの検証はせずにネットで調べてみた
そうすると本の内容とは違っているが同じようなことをやっている人のサイトを見つけた
そのホームページに紹介されているソースコードをコピペしESP32に書き込んだ
スマホのブラウザからIPアドレスを入力するとホームページ通りの画面が表示されLEDをON/OFFすることが出来た

感想
話が脱線するが中国のメーカに先を越された。中国マジでカッコイイ
日本はダメだ