OmniAICreator/Qiita-1.07M huggingface dataset:
WWDC2017 Engineering For Testability要約とサンプルコード

# 背景

最近自分の中でテストを書くことに大してモチベーションが上がってきている。
理由は簡単に言うと以下の2点。
- 品質を担保したい
- 新機能を開発する時に既存のモノを壊していないことの保証が欲しい

そして、iOSでのテストに明るくなかったのでググっていたら以下の記事に出会った。
[A complete list of articles on Unit Testing with Swift from 2017](https://medium.com/flawless-app-stories/a-complete-list-of-articles-on-unit-testing-with-swift-from-2017-9be8f046ef25)

この中で紹介されているWWDC2017のセッション: [Engineering For Testability](https://developer.apple.com/videos/play/wwdc2017/414/) でコンセプトが非常によくまとめられていて勉強になった気はしたのだが、どうも腹落ちせず、サンプルプロジェクトを作り、[Githubにアップロードした](https://github.com/justin999/EngineeringForTestabilitySample)。

# ポイント
詳細はビデオ見てもらうこととして、以下かんたんにポイントをまとめておく。

## Testablity Techniques

テスト可能にするテクニックとして以下の2つがあげられている。
1. Protocols and parameterization
2. Separating logic and effects

1のProtocols and parameterizationはPreviewViewControllerで、2のSeparating logic and effectsはOnDiskCacheで説明されている。

これを見るとなぜ、単純に他のアプリを開く動作をするだけなら10行程で住む実装を、別クラスに分け、抽象化し、アプリコードだけ見ると複雑にみえる実装の理由がわかるはずだ。

## Scalable Test Code

このセクションでは、（発表者も変わり）スケーラブルなテストコードについて語られている。前半部分はテストしやすいアプリコードの書き方についてだったが、このパートはテストコードについての解説だ。

処理ごとに抽象化するテクニックに時間を割かれていたが、個人的に印象的だったのは最後のことば：

```
Important to consider even though it isn't shipping. 
Test code should support the evolution of your app. 
Coding principles in app code also apply to test code.

ユーザが使う動作させるコードではないが、テストは真剣に取り扱われるべき。
テストでアプリの発展をサポートするべきだ。
アプリコードでのコーディングプリンシプルはテストコードでも適用されるべきだ。
```

要は、テストコードは、縁の下の力持ちだけど、表のアプリコードと同じくらいとても大事だよ、ということですね。
仮想通貨の保有資産を定期的にメールで受け取る

## 経緯
・貯金通帳を眺めるのが好き
・せっかくだし遊びの範囲で仮想通貨買ってみたい

先人の方々は売買用のAPIなどを用いて自動化などをされているかと思いますが今回はあくまで現在の保有資産をみて「へー、ほーん」ってなるだけのものを作ります。

## 利用サービス
・Zaif Exchange API(https://corp.zaif.jp/api-docs/)
Zaifという仮想通貨取引所が提供しているRESTAPIです。
現在の仮想通貨の価格の取得を行います。

・GoogleAppsScript(https://developers.google.com/apps-script/)
Googleが提供しているサーバレスで動作するJavascriptベースのサービスです。
ここからZaifAPIを呼び出して現在の総資産を計算し、Gmail宛にメールを送ります。

## コード

```javascript:zaif.gs
//保有資産
xem = xxxx.xxxx
btc = xxxx.xxxx
mona= xxxx.xxxx
eth = xxxx.xxxx
zaif = xxxx.xxxx

//購入時金額
purchase_price_xem = 10
purchase_price_btc = 10
purchase_price_mona = 10
purchase_price_eth = 10
purchase_price_zaif = 10

///API URL
btc_url = "https://api.zaif.jp/api/1/ticker/btc_jpy"
xem_url = "https://api.zaif.jp/api/1/ticker/xem_jpy"
mona_url = "https://api.zaif.jp/api/1/ticker/mona_jpy"
eth_url = "https://api.zaif.jp/api/1/ticker/eth_jpy"

function calc_asset(asset, url, buy){
  res = UrlFetchApp.fetch(url)
  ticker = JSON.parse(res.getContentText())
  last = ticker['last'] * asset
  high = ticker['high'] * asset
  low = ticker['low'] * asset
  
  str = "    最新値            :" + last + "\n"
  str = str + "直近24時間最高値:" + high + "\n"
  str = str + "直近24時間最低値:" + low + "\n"
  return str
}

function myFunction() {
  mail_body = ""
  
  header = "* * * BTC * * *\n"
  body = calc_asset(btc, btc_url, purchase_price_btc)
  footer = "* * * * * * * * *\n\n\n"
  
  mail_body = header + body + footer

  header = "* * * XEM * * *\n"
  body = calc_asset(xem, xem_url, purchase_price_xem)
  footer = "* * * * * * * * *\n\n\n"
  mail_body = mail_body + header + body + footer

  header = "* * * ETH * * *\n"
  body = calc_asset(eth, eth_url, purchase_price_eth)
  footer = "* * * * * * * * *\n\n\n"
  mail_body = mail_body + header + body + footer

  header = "* * * MONA * * *\n"
  body = calc_asset(mona, mona_url, purchase_price_mona)
  footer = "* * * * * * * * *\n\n\n"  
  mail_body = mail_body + header + body + footer
  
  Logger.log(mail_body)
  MailApp.sendEmail('hogehoge@gmail.com', '仮想通貨保有資産のお知らせ', mail_body);
  
}
```

中身はすごくシンプルです。

```javascript
res = UrlFetchApp.fetch(url)
ticker = JSON.parse(res.getContentText())
```
UrlFetchApp.fetchで指定のURLにアクセスし、tickerの情報を取得します。

戻り値は下記のようになっているので
>JSONディクショナリを返します:
>>last – last price : 終値
>>high – last 24 hours price high : 過去24時間の高値
>>low – last 24 hours price low : 過去24時間の安値
>>vwap – last 24 hours volume weighted average price : 過去24時間の加重平均(詳細は下記)
>>volume – last 24 hours volume : 過去24時間の出来高
>>bid – highest buy order : 買気配値
>>ask – lowest sell order : 売気配値

現在持っている資産と終値や直近の高値などをかけ合わせた文章を作成し

```javascript:
MailApp.sendEmail('宛先', 'Title', 'Body');
```
でGmailへ送信します。

実行するとメールが送られてきます。
実際に送られてきたメールがこちら
<img width="356" alt="kasou.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/169001/e81c3101-8449-aa21-5ea2-c5ab3e32b6c4.png">

これを時間主導型でイベントトリガーを設定しておけば12時間毎に通知メールが届くようになります。

## 終わりに
拡張の候補として売買APIの追加やスプレッドシートの書き出しなどしてみても楽しいのではないかと思います。
web通帳よりも実際の通帳を見るほうがワクワクするのでエクセル送ったら通帳作ってくれるサービスとかないかなーとか考えながら書きました。

以上、最後までありがとうございました。
スクリーンのstandbyやsuspendをさせないようにする

プレゼンテーションで debian などの Linux デスクトップを使っているとき, 通常はxwindowを使っているだろう. そのときに, standby や suspend などで画面が off になってしまうと VGA への出力も止まってしまう場合がある. そういうことをさせないようにするには

```bash:画面をstandby,suspendさせない 
xset dpms 0 0 0
```

とする. 最初の数字が standby になるまでの秒数, 次の数字が suspend になるまでの秒数, 最後の数字が poweroff になるまでの秒数. すべてを 0 にしてしまえば, standby にも suspend にも poweroff にもならない. shell script にでもしておいて, 講演の時に script を起動させればよいだろう.
Linuxにおけるデスクトップエントリ(ショートカット)の作成の備忘録

デスクトップ環境によって作成する場所が違うっぽいので、自分用にメモ。<br>

Ubuntu Unity,GNOMEは`sudo vim ~/.local/share/applications/firefox.desktop`
MATE,cinnamon,KDE,LXDE,Xfceは`sudo vim /usr/share/applications/firefox.desktop`
に作成、保存してください。
特に権限付与などはしなくても問題なく起動を確認しました(GNOMEベース、cinnamonで確認)
以下ファイル内容です。

``` firefox.desktop
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=Firefox
Comment=Web Browser
Exec=/home/gn5r/firefox/firefox
Icon=/home/gn5r/ピクチャ/icon/firefox.png
Categories=Application;Network;WebBrowser;

Terminal=false
```

**Icon**をピクチャに保存している画像ファイルを割り当てているので、適宜書き換えて下さい。
(基本的には実行ファイルと同一ディレクトリに置いてある場合が多いです)
また、私のユーザー名が**gn5r**ですので、/home/**gn5r**/~となっていますが、ここは各自のユーザー名に変更してください。

なお、作成したデスクトップエントリを何かの理由で書き換えた場合`alt+F2→r`で更新しないと上書きが適用されない点も注意しておきたいです(よく自分が忘れてしまうため)

以上メモです。
2018/3/2(金)　一部表記修正
2018/3/19(月) 誤字、一部表記修正
GuestAdditionsをRunしようとしたらOopsダイアログ/Kali on VirtualBox

なぜかわからないが、Oopsなんたらかんたらというダイアログが出て、Runできなかった。

`/media/cdrom0`にGuestAdditionsがいるので

```Bash
mkdir /mnt/cdrom
cp -a /media/cdrom0 /mnt/cdrom
cd /mnt/cdrom
./autorun.sh
```
geometry > 論文 > 六角柱の表面のざらつきを考慮した形状モデル > Gaussian random surface | ADDAによる粒子の散乱特性

論文 (Open Access)
[Effects of surface roughness with two scales on light scattering by hexagonal ice crystals large compared to the wavelength: DDA results](http://www.sciencedirect.com/science/article/pii/S0022407316300802?_rdoc=1&_fmt=high&_origin=gateway&_docanchor=&md5=b8429449ccfc9c30159a5f9aeaa92ffb&dgcid=raven_sd_recommender_email)
by C.T. Collier, E. Hesse, L. Talor, Z. Ulanowski, A. Penttila, T. Nousiainen

氷雲などで見られる六角柱の粒子について、表面のざらつきを考慮した光散乱数値シミュレーションをしている。シミュレーションコードはADDAを使用している。

表面のざらつきはどのように再現しているかというと、Gaussian random surfaceという手法を用いている。
(ヘルシンキ大学のグループは別途、Muinonenらにより、Gaussian random sphereという非球形形状の生成手法の開発もしている。[こちら](https://wiki.helsinki.fi/display/PSR/SIRIS)のG-sphere）。

Fig.1に形状の紹介がされている。

- a. 展開図
- b. 端の三角形を折り曲げた状態。subfacetが伸びた状態
- c. bに加えてedge subfacets補正をした
- d. 一つのsubfacetを折りたたんだ状態
- e. 全部のsubfacetを折りたたんだ状態

Fig.2にSEMイメージがある。

Fig.3にはsurfaceの状態の紹介がある。overall profileの除去前と除去後、およびpower spectrum。

Fig.4には0.47 um-1より大きい波数を除いた結果。
Fig.5には0.47 um-1より小さい波数を除いた結果。

Fig.6はcrystal orientationsの例

Fig.7は使用座標系

Table.1はsize parameterおよび形状の変数との関連

Fig.8はPhase function(光がどの方向にどの強度で散乱されるかを表す)。左から右は粒子の方向を表す。上から下はsize parameterの違いを表す。線の違いにより、Smooth, One-scale rough, Two-scale roughの違いを表す。

Fig.9はphase functionの後方散乱部分。

Fig.10は方位角と散乱角の関係

Table.2はAsymmetry parameters

Fig.11は前方散乱の2D表示
Fig.12は後方散乱の2D表示

Fig.13はDegree of linear polarization。

Table 3. direct forward transmissionの変化(one-scale, two-scale rought crystals)

Fig.14 asymmetry parametersとsize parameter、roughnessの関係

Fig.15 二次元のinteisity patterns (size paramter:100)
機械学習論文読みメモ_112


[Neural SLAM](https://arxiv.org/abs/1706.09520)
エージェントが新しい環境を探索するにあたって有用となる、センサーデータからglobal mapの
表現獲得手法を提案する。
この手法を得るために、従来のSLAMを模擬し、soft attention basedで利用されるexternal memory構造を
新たに提案する。
このexternal memoryは環境内部の表現として用いられる。
これにより、完全微分可能なdeepnetがSLAMと似たような発展を見せるようになる。
この構造の利用でエージェントは新たな環境に対する強化学習的な探索が可能になる。

[Hindsight Experience Replay](https://arxiv.org/abs/1707.01495)
強化学習においてsparseなrewardに対する効率的な学習の実現は大きな課題の一つである。
この問題に対して本論ではHindsight Experience Replayと呼ばれる、sample efficientな手法を提案する。
この手法は任意のoff-policy手法へ適用可能で、implicit curriculum学習手法として見る事が出来る。
ここでは本来のゴールへ到達せずrewardが得られないパスが与えられたとしても、その最終状態がゴール
だと考えた時にそこへ到達するためのパスだと考える事ができ、学習への活用が可能になる。
この考え方はmulti-goal RLと関連している。

[Unsupervised Learning of Depth and Ego-Motion from Video](https://people.eecs.berkeley.edu/~tinghuiz/projects/SfMLearner/), CVPR2017
モノラルカメラのVideo sequenceより教師なしの深さ、モーション推定を行うための手法を提案する。
この手法はあるポーズとその画像から、近くのポーズとその画像への遷移を深さとポーズ推定の結果から
行うタスクを設定する事で学習する。
この学習は教師なしで行う事が可能である。
【MAYA】シェイプにマテリアルのアサインがあるか無いかを判断する(詳細版

[前回の記事](https://qiita.com/harayoki/items/9af90606167398bd8e68)でマテリアルのフェイスアサインがあるかないかを判別するコードを書きましたが、通常のオブジェクトアサインがあるかどうかの判定も合わせて、詳細な判定ができるようにコードを記述してみます。

##サクッと作ってみる

```python
def has_object_assign(shape):
    """
    シェイプにマテリアルのオブジェクトアサインがあるかどうか確認する

    :param shape: チェックするシェイプ
    :type shape: pymel.nodetypes.Shape
    :rtype: bool
    """
    instanceNumber = shape.instanceNumber()
    instObjGroup = shape.instObjGroups[instanceNumber]
    cons = pm.listConnections(instObjGroup, plugs=False)
    for con in cons:
        if con.type() == 'shadingEngine':
            return True
    return False
```
instObjGroupにSGのコネクションがあるかどうか調べているだけです。

これと前回の`has_face_assign`関数を組み合わせると、シェイプに何らかのマテリアルがアサインされているかがわかります。

```python
def has_any_assign(shape):
    """
    シェイプに何らかのマテリアルのオブジェクトアサインがあるかどうか確認する

    :param shape: チェックするシェイプ
    :type shape: pymel.nodetypes.Shape
    :rtype: bool
    """
    return has_face_assign(shape) or has_object_assign(shape)
```
処理に重複があるのと、そもそも重そうな処理判定なので、現実的なパフォーマンスが出るかはさておきですが。。

ところで、shapeには関連しているsetsを返すメソッドがあるので、

```python
def has_any_assign2(shape):
    set_list = shape.listSets()
    for s in set_list:
        if s.type() == 'shadingEngine':
            return True
    return False
```
何らかのマテリアルアサインがあるかどうかの判定は、こんな感じでもいけました。この処理でもちゃんとインスタンスの区別がされていました。

フェイスアサイン、オブジェクトアサインの判定もこんな感じでもっとスマートに判定できる方法がありそうな気もしますが、動くものを作って理解を進めているということで。。

## 動作検証

<img width="324" alt=" 2018-01-10 3.46.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/8302/3c37fd8b-30d6-4dd2-492f-4145c445fd73.png">
_下からpCube1,2,3,4,5,6_

```python
shape = pm.PyNode('pCube1|pCubeShape1')  # フェイスアサインのないインスタンスシェイプ
print(has_face_assign(shape)) # -> False
print(has_object_assign(shape)) # -> True
print(has_any_assign(shape)) # -> True
print(has_any_assign2(shape)) # -> True
print('')

shape = pm.PyNode('pCube2|pCubeShape1')  # フェイスアサインのあるインスタンスシェイプ
print(has_face_assign(shape)) # -> True
print(has_object_assign(shape)) # -> False
print(has_any_assign(shape)) # -> True
print(has_any_assign2(shape)) # -> True
print('')

shape = pm.PyNode('pCube3|pCubeShape3')  # インスタンスが存在しないフェイスアサインのないシェイプ
print(has_face_assign(shape)) # -> False
print(has_object_assign(shape)) # -> True
print(has_any_assign(shape)) # -> True
print(has_any_assign2(shape)) # -> True
print('')

shape = pm.PyNode('pCube4|pCubeShape4')  # インスタンスが存在しないフェイスアサインのあるシェイプ
print(has_face_assign(shape)) # -> True
print(has_object_assign(shape)) # -> False
print(has_any_assign(shape)) # -> True
print(has_any_assign2(shape)) # -> True
print('')

shape = pm.PyNode('pCube5|pCubeShape5')  # マテリアルが外れてしまったシェイプ
print(has_face_assign(shape)) # -> False
print(has_object_assign(shape)) # -> False
print(has_any_assign(shape)) # -> False
print(has_any_assign2(shape)) # -> False
print('')

shape = pm.PyNode('pCube6|pCubeShape6')  # 一部faceのマテリアルが外れてしまったシェイプ
print(has_face_assign(shape)) # -> True
print(has_object_assign(shape)) # -> False
print(has_any_assign(shape)) # -> True
print(has_any_assign2(shape)) # -> True
```
jsonファイルパーサParsonの使い方

# 目的
大学の課題としてjsonファイルから[年賀状等の宛名面を作成するプログラム](https://github.com/homedm/json2tex-address-letter)を書いた。
その時に使ったjsonパーサのparsonが思いのほか便利だったのでその使い方を忘れないうちにメモしておく。

具体的なサンプルは書いていないが上のプログラムのソースコードとparson.c, parson.hを読めばある程度使い方がわかると思います。

# jsonファイルのオープン
```c
JSON_Value piyo = json_parse_file("filename.json");
```
これでjsonファイルをJSON_Value型のroot_valueに読み込めます。

コメントを書いておけるhjson形式のファイルを読み込むときは
```c
json_parse_file_with_comments("filename.json")を使えばよいと思います。
```

# メンバーではない要素を取得する方法
```c
JSON_Object piyo = json_object(hoge);
JSON_Object piyo = json_object(hoge);
```
のようにすることでJSON_Object型の変数hogeの下にあるオブジェクトや文字列を取得できます。
以下のようなjsonファイルの時です。
```json
{
            "hogehoge"
}
```

# メンバーを指定して、値を取得する
```c
JSON_Object piyo = json_object_get_object(hoge, "fuga");
JSON_Object piyo = json_object_get_number(hoge, "fuga");
```
JSON_Object型の変数hogeに格納されているjsonオブジェクトの中でfugaという名前を持つメンバーの値を取得します。
値の型に応じて、最後の部分を変えます。

#配列の扱い
```c
JSON_Object piyo = json_array_get_object(hoge, n);
```
とすることでjsonの配列を代入しておいたhogeの中でn-1番目のオブジェクトを取得できる。
以下のようなときに
```c
JSON_Value hoge = json_parse_file("filename.json");
JSON_Object a = json_object(hoge);
```
JSON_Object b = json_array_get_string(a, 1);
とすることでfooを取得して、bに代入できる。
```json
{
    [
     "hoge",
     "foo",
     "fuga"
    ]
}
```

#日本語について
utf-8をサポートしており、日本語も扱えました。

#ドットで指定して値を得る
```c
JSON_Value piyo = json_object_dotget_string(hoge, key);
```
keyの部分にhoge以降の名前をドットで区切って渡すことで値を得ることができます。
下のような構造のjsonファイルの時に
```c
JSON_Value piyo = json_object_dotget_string(hoge, foo.first);
```
とすることでfooいかにあるfirstの値を得られます。
```json
{
    "foo":{
          "first": "nya",
          "second": "wan"
    }
    "fuga":{
          "first": "kerokero",
          "second": "mo"
    }
}
```
# 要素の追加
set, dotsetとある関数を使うとjsonに要素を追加できるようです。
ファイルへの書き込みまでやっているのかはわかりませんでした。

# 最後
parsonは要素の取得だけでなく、追加、削除までやれるらしいが今回はその機能までは調べなかった。
個人的にはドットで要素を指定できることが便利だと思います。

# 参考
[parson github repository](https://github.com/kgabis/parson)
[Parsonを使って，JSONのデータをCの構造体に変換する](http://kikd.hatenablog.com/entry/2017/08/07/003403)
Chromeで外部SD上のファイルに直接アクセスできない問題 on Android

　Androidスマホを使ってhtmlを作り、スマホからウェブページを更新する際、htmlファイルが外部sdカードの中に保存されているとうまくプレビューができない。Chromeでローカルファイルを見るにはアドレスバーに「file://」＋「ファイルの絶対パス」（例：`file:///storage/mywebpage/mypage.html`）を入力する。しかし、外部sdカードに入っているファイルはこの方法では見ることができない。Chromeには外部sdにアクセスする権限がないからである。

　解決方法としては3つある。1つ目はChromeに外部sdに対するアクセス権限を与えること。2つ目はファイルマネージャーを介してChromeで開くこと。3つ目は開きたいファイルを内部ストレージに移すことである。
　1つ目は理想的だが一筋縄ではいかない険しい道だ。2つ目は例えばASUSのファイルマネージャーを使うと外部sdの中のファイルもChromeで見ることができる。ただし例えばhtmlファイルを見るとき、cssファイルが反映されないという問題が起こる。となると3つ目の**「ファイルを内部ストレージに移す」が最も手っ取り早そう**である。特にスマホでウェブページを作りたい方は、外部sdではなく内部ストレージで作業した方がいいだろう。

##同様の報告
https://m.chiebukuro.yahoo.co.jp/detail/q14109504544
▲androidでSD内のhtmlファイルを標準ブラウザで読み込んだのですが、リンク先にアクセスできません。（Yahoo!知恵袋）

##関連リンク
https://play.google.com/store/apps/details?id=com.asus.filemanager
▲ASUS ファイルマネージャー
　ちなみにこれでSD上のhtmlを閲覧したとき、パスは次のようになった。`
content://com.asus.filemanager.OpenFileProvider/file/storage/DEA3-D49B/download/mywebpage.html`

http://d.hatena.ne.jp/m-kawato/touch/20120101/1325385031
▲SDカード上のHTMLファイルをAndroidのブラウザで開く

https://www.kanzaki.com/docs/html/htminfo-uri.html
▲URIとファイルディレクトリ

##補足
 **Yahoo!ファイルマネージャーでは**内部ストレージ・外部SDの**htmlファイルをcssが反映された状態で見ることができた**。
　ただし、htmlファイルを開くアプリがAndroidシステムのHTMLビューアしか選択肢がなく、Chromeでは見ることができなかった。

　Chromeの場合ローカルファイルやインデックスをブックマークに登録できて便利だが、最低閲覧できればよいという場合はYahoo!ファイルマネージャーを使うのもいいかもしれない。この辺はもう好みの問題だろう（）。

▼file://で表示したローカルファイルのインデックス
![Screenshot_20180110-163141_crop_720x584.jpg](https://qiita-image-store.s3.amazonaws.com/0/227618/68abac20-736a-bbfd-3cec-1231dba34f35.jpeg)
　ルート直下のディレクトリがsdcardとなっていますが、内部ストレージです。Androidの仕様らしい。

##環境
Android 6.0.1
ASUS_Z010DB
Chrome/63.0.3239.111
ASUSファイルマネージャー 2.2.0.199
HTMLビューア 6.0.1（Androidシステム）
Yahoo!ファイルマネージャー 1.5.11
flow gen-flow-filesを使って型定義ファイルを作成する

例えば、以下のようなファイルの場合。

index.js

```js
// @flow
'use strict';
module.exports = (input: string) => {
  const isExtendedLengthPath = /^\\\\\?\\/.test(input);
  const hasNonAscii = /[^\u0000-\u0080]+/.test(input);

  if (isExtendedLengthPath || hasNonAscii) {
    return input;
  }

  return input.replace(/\\/g, '/');
};
```

`flow gen-flow-files`を使って型定義を作成出来ます

```
$ flow gen-flow-files index.js > index.flow.js
$ cat index.flow.js
// @flow


declare module.exports: (input: string) => string;
```

help:

```
flow gen-flow-files --help
Usage (EXPERIMENTAL): flow gen-flow-files [OPTIONS] [FILE]

e.g. flow gen-flow-files ./src/foo.js > ./dist/foo.js.flow
```

単にコピーして`.flow`を付けてもいいですが、こちらの方がサイズが小さくなるのでいいですね。
しかしまだ`EXPERIMENTAL`なので注意が必要そうです。
EC2 RedisのMeltdown/Spectreパッチバージョン性能検証

Meltdownの脆弱性対応により軒並みサーバの性能が低下しているようです。
[MeltdownとかSpectreとか騒ぎがあったので、Amazon Aurora（MySQL互換）R4インスタンス再テスト（mysqlslap）](https://qiita.com/hmatsu47/items/656ebb6575c31bf1a90e)

自分はRedisを使い倒していることもあり、Redisでどの程度性能に影響がありそうかを実際に検証してみました。

## 環境

項目|OS|kernel version|redis version|インスタンスタイプ
---|---|--------------|------------|-------------
旧OS | Amazon Linux | 4.9.58-18.55.amzn1.x86_64 | v2.8.24 | c4.large
最新OS | Amazon Linux | 4.9.75-25.55.amzn1.x86_64 | v2.8.24 | c4.large

Redis少し古くてすみません…

## ベンチマークコマンド

バンドルされている`redis-benchmark`コマンドを利用して以下の軸で実行してみました。

```sh
# default
redis-benchmark
# setのみ100万回実行
redis-benchmark -t set -n 1000000 -r 100000000
# 100万個のランダム要素のリストを実行
redis-benchmark -r 1000000 -n 1000000 1 lpush mylist __rand_int__
# データサイズ1024byteで、3万リクエストを100クライアントで実行
redis-benchmark -d 1024 -n 30000 -r 30000 -c 100 -q
```

## ベンチマーク結果

フルの実行結果は以下を参照下さい。

- [パッチ適用前ベンチマーク結果](https://gist.github.com/toritori0318/c1638be83081a84550c7c2912c6630e0)
- [パッチ適用後ベンチマーク結果](https://gist.github.com/toritori0318/857375912eb052edd210e3a678cf7573)

### 結果抜粋

```sh
# データサイズ1024byteで、3万リクエストを100クライアントで実行
redis-benchmark -d 1024 -n 30000 -r 30000 -c 100 -q
```
このベンチマークがまんべんなく実行されているので比較してみましょう

コマンド | パッチ適用後(rps) | パッチ適用前(rps)| 性能比(%)
--------|-----------|---------|-----
PING_INLINE|                        103092.78  |123966.95|83.16
PING_BULK|                          101694.92  |121457.49|83.72
SET|                                98039.22   |111524.16|87.90
GET|                                97402.60   |116279.08|83.76
INCR|                               103448.28  |125000.00|82.75
LPUSH|                              100334.45  |126050.41|79.59
LPOP|                               97087.38   |119521.92|81.22
SADD|                               102739.73  |124481.33|82.53
SPOP|                               101351.35  |123966.95|81.75
LPUSH (needed to benchmark LRANGE)| 100671.14  |125523.02|80.20
LRANGE_100 (first 100 elements)|    8949.88    |9930.49|  90.12
LRANGE_300 (first 300 elements)|    2767.02    |2904.44|  95.26
LRANGE_500 (first 450 elements)|    1395.22    |1776.72|  78.52
LRANGE_600 (first 600 elements)|    1064.43    |1134.52|  93.82
MSET (10 keys)|                     38022.82   |43988.27| 86.43

パッチ適用後はやはり軒並み性能劣化しているようですね…
ちなみに何度か実行したり、別インスタンスで試してみても多少の上下はありましたが同じような結果になりました。

## まとめ

どこかで「10% - 20%落ち」というのは目にしましたが、実際にそんな感じでした。
割とキリキリの性能で使うことが多いのでだいぶ辛い ;q
Catch2 Supplying main() yourself

# これは何?

https://github.com/catchorg/Catch2/blob/master/docs/own-main.md の適当和訳。
ほとんど google 翻訳です、ハイ。

# main() を自前で作る

一番簡単な Catch の使い方は、Catch がユーザに用意している ```main()``` を、コマンドラインから制御する方法です。

*唯一つだけ*のソースコード中で、```#include "catch.hpp"``` の前に ```#define CATCH_CONFIG_MAIN``` を書くことで、実現できます。

しかし、時には main（）の独自のバージョンを書く必要があります。 代わりに ```#define CATCH_CONFIG_RUNNER``` を書くことでこれを行うことができます。 こうすると ```main()``` を普通に書くことができ、手動で Catch を呼び出すことができます。

今は柔軟性に富んでいますが、これを行うための 3つの料理法があります：

## Catch が args と config を完全に制御できるようにする

ただ単に Catch の前後に何らかの処理が必要な場合、これが一番簡単な選択肢です。

```c++
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"

int main( int argc, char* argv[] ) {
  // 全体の準備処理 ...

  int result = Catch::Session().run( argc, argv );

  // 全体の後始末処理 ...

  return result;
}
```

## 設定の変更

Catchにコマンドラインを処理させたいが、プログラムで設定を微調整したい場合は、次のどちらかの方法を利用できます

```c++
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"

int main( int argc, char* argv[] )
{
  Catch::Session session; // インスタンスの存在は1つだけ許されます
 
  // ここで session.configData() を記述するとデフォルト値を設定します
  // これが、デフォルト設定を行う良い方法です

  int returnCode = session.applyCommandLine( argc, argv );
  if( returnCode != 0 ) // Indicates a command line error
  	  return returnCode;
 
  // ここで session.configData() または session.Config() を記述すると
  // コマンドライン引数が覆ります(overrideされる)
  // あなたが必要と思う時だけ実施してください

  int numFailed = session.run();
  
  // numFailed は、下位8bit だけ使う Unix のため、 255 以下に切り詰められています
  // この切り詰めは実施済みですので、ここでは単に return します
  // また、ここで後始末処理を行うこともできます。
  return numFailed;
}
```

Config と ConfigData の定義を見て、それらであなたが何をできるかを知ってください。

config を完全に制御するには、単に ```applyCommandLine()``` の呼び出しを省略します。

## 独自のコマンドラインオプションを追加する

Catch には、 [Clara](https://github.com/philsquared/Clara) と呼ばれる強力なコマンドライン解析器が組み込まれています。
Catch2（およびClara 1.0）以降、Clara では _構成可能_ なオプションおよび引数パーサを記述できるため、Catch独自のコマンドラインオプションを拡張するのが容易になりました。

```c++
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"

int main( int argc, char* argv[] )
{
  Catch::Session session; // インスタンスは一つだけ許されます
  
  int height = 0; // あなたが設定できるいくつかのユーザー変数
  
  // Catch の上に新しいコマンドライン解析器を構築する
  auto cli 
    = session.cli() // Catch の複合コマンドライン解析器を取得する
    | Opt( height, "height" ) // 変数を新しいオプションにバインドします。
        ["-g"]["--height"]    // ヒント文字列を指定すると、
        ("how high?");        // ヘルプ出力の説明文字列に応答します。
        
  // 新しいコマンドライン解析器を Catch に渡して、それを使用します
  session.cli( cli ); 
  
  // Catch（Claraを使用）がコマンドラインを解析するようにする
  int returnCode = session.applyCommandLine( argc, argv );
  if( returnCode != 0 ) // コマンドラインエラー
  	return returnCode;

  // コマンドラインで設定すると、この時点で 'height' が設定されます
  if( height > 0 )
      std::cout << "height: " << height << std::endl;

  return session.run();
}
```

詳しくは [Clara documentation](https://github.com/philsquared/Clara/blob/master/README.md) をご覧ください。
デリゲートを使った時間計測用メソッド

コーディングや設計をしている時に、どんな書き方をすれば早いのかと思って、簡単に時間を測る事があります。

その際に、各処理の前後にStopwatchをStart、Stopと書き、掛かった時間を出力するのですが、
いちいち書くのめんどくさいなと思って、メソッドに纏めてみました。

# ソースコード

```c#

Stopwatch watch = new Stopwatch();

private void MeasurementClock(Action method)
{
    watch.Reset();
    watch.Start();

    // 計測するメソッド本体
    method();

    watch.Stop();

    // 計測メソッド名の取得
    string methodName = method.Method.Name;

    Console.WriteLine($@"メソッド名：{methodName}
                        計測時間：{watch.Elapsed.Milliseconds:n0}ミリ秒");
}


```



# 使い方例



```c#

using System;
using System.Diagnostics;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        /// <summary>
        /// メイン処理
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            var main = new Program();

            // ここで計測したいメソッド名を引数にして呼ぶ。
            main.MeasurementClock(main.StringBuilder);
            main.MeasurementClock(main.StringConcat);

        }

        Stopwatch watch = new Stopwatch();
        string Id = "Id0001";
        int loopCount = 10000;

        /// <summary>
        /// 計測用メソッド
        /// </summary>
        /// <param name="method"></param>
        private void MeasurementClock(Action method)
        {
            watch.Reset();
            watch.Start();

            // 計測するメソッド本体
            method();

            watch.Stop();

            // 計測メソッド名の取得
            string methodName = method.Method.Name;

            Console.WriteLine($@"メソッド名：{methodName}
                                計測時間：{watch.Elapsed.Milliseconds:n0}ミリ秒");
        }

        private void StringBuilder()
        {
            StringBuilder sb = new StringBuilder();
            string display = string.Empty;
            for ( int i = 0; i < loopCount; i++ )
            {
                sb.Append(Id)
                    .Append(Id)
                    .Append(Id)

                    .Append(i);
            }

            display = sb.ToString();
        }

        private void StringConcat()
        {
            string display = string.Empty;
            for ( int i = 0; i < loopCount; i++ )
            {
                display += Id + Id + Id + i;
            }
        }
    }
}


```
ちょっとずつ読むドメイン駆動設計 第四部 戦略的設計 第十五章 蒸留6 凝集されたメカニズム

# 前回までの第十五章

[コアドメイン1](https://qiita.com/YasuhiroKimesawa/items/899d1b3fd58ca91f525a)
[コアドメイン2](https://qiita.com/YasuhiroKimesawa/items/1aee3602d3aea1cb5b91)
[汎用サブドメイン](https://qiita.com/YasuhiroKimesawa/items/be23f3bd11626265f552)
[ドメインビジョン声明文](https://qiita.com/YasuhiroKimesawa/items/75e270b7d9a624823c1a)
[強調されたコア](https://qiita.com/YasuhiroKimesawa/items/9fdf325ab4cdb9e2286d)

# 凝集されたメカニズム

汎用サブドメインとはまた異なる、コアドメインと区別するもの。

「何が(what)」と「どのように(how)」を分離するのがカプセル化の仕組みですが、「どのように(how)」が肥大化し、複雑化することがあります。

問題を解決するためのアルゴリズムを提供するメソッドが大量に存在すると、問題を表現するメソッドがわかりづらくなります。

そこで、そのような**凝集された部分を抜き出す**ことで、残りが理解しやすくする。
これが、コアドメインを蒸留する手法の１つです。
凝集されたメカニズムはフレームワーク化すると使いやすくなります。

書籍の例では、組織図で用いられる[グラフ]のメカニズムをフレームワーク化していました。
注意する点としては、処理だけに焦点をしぼって、ドメインに関する部分を混ぜないようにすることです。

個人的に直近のプロジェクトで経験したところで、使えるなと思ったのは、elasticsearchでの検索に使用するモデルからelasticsearchのqueryを構築するためのメカニズムをフレームワーク化すること。

ここを素直に検索用のモデルを構築すると、書籍にあるような仕様オブジェクトのようなモデル(andモデルとかrangeモデルとか)を作ることになるのですが、そこをフレームワーク化することで、本質的な検索仕様が蒸留されるかもと思いました。

## 汎用サブドメインとの違い
汎用サブドメインはビジネスの中心であるドメインから離れてはいるけど、表現力豊かであるべきモデルです。
凝集されたメカニズムはドメインを表現するのではなく、あくまで「処理」の問題を解決するためにあります。

## 宣言的スタイルが大事に
コアドメインと凝集されたメカニズムを分離しやすくするためには、[第十章](https://qiita.com/YasuhiroKimesawa/items/988ed817de9aac785633)で読んだ意図の明白なインターフェースなどを活用した、しなやかな設計になっていることが大事です。

「何が(what)」と「どのように(how)」を分離するためのテクニックなので、何となくわかりますね。
pukiwikiからCrowiに移行する

# 目的
古くから使われているwikiソフトウェアである[pukiwiki](https://pukiwiki.osdn.jp/)のデータを、Markdownで書ける[Crowi](https://github.com/crowi/crowi)（またはその派生である[Crowi-plus](https://github.com/weseek/crowi-plus)）に移行したい

# 想定する環境
* Ubuntu16.04LTS
* pukiwiki 1.5.0
* Crowi-plus v2.3.2
    * [docker-compose版](https://github.com/weseek/crowi-plus-docker-compose)にしておくとデータ転送に途中で失敗しても復旧が簡単なのでオススメ

# 移行の流れ

1. pukiwikiのデータのファイル名をリネーム
2. (EUC-JP版の場合のみ)pukiwikiのデータ内の文字コードをUTF-8に変換
3. pukiwiki記法をMarkdown記法に変換
4. データをcrowiへ送信

以下、この流れに沿って具体的な作業を説明する

# pukiwikiのデータのファイル名をリネーム
* pukiwikiの`index.php`などが置かれているディレクトリへ移動する
* [こちらの記事](http://d.hatena.ne.jp/billiejoe/20090921/p1)にあるコードをlswiki.plとして保存
* bashで以下のコマンドを実行
    * `wiki`ディレクトリ配下にpukiwikiのデータファイルが格納されている
    * `wiki_mod`ディレクトリに変換したファイルが格納される

```
for file in $(ls wiki/*); do
  install -p -D $file wiki_mod/`./lswiki.pl -f euc-jp -s $file`
done
```

# (EUC-JP版の場合のみ)pukiwikiのデータ内の文字コードをUTF-8に変換
* 以下をbashで実行する

```
for file in $(find wiki_mod -type f); do
  iconv -f EUCJP -t UTF8 $file > $file.utf8;
  mv $file.utf8 $file;
done
```

# pukiwiki記法をMarkdown記法に変換
* [こちらの記事](https://qiita.com/yuki-takei/items/152e20f4421333ae8fd9)のコードから流用した以下のコマンドをbashで実行

```
find wiki_mod -type f | xargs sed -i -e 's/ \[#[0-9a-z]\+\]$//g' -e 's/^\*\*\*/###/g' -e 's/^\*\*/##/g' -e 's/^\*/#/g' -e 's/^---/    -/g' -e 's/^--/  -/g' -e 's/^\(\s*\)-\([^ ]\)/\1- \2/g' -e 's/^\(\s*\)+\([^ ]\)/\1+ \2/g' -e 's/&br;/<br>/g' -e 's/^#pre{*/```/g' -e 's/^}}*/```/g' -e 's/%%/~~/g' -e "s/^\#lsx/`echo -ne '\u0024'`lsx()/g"
```

# データをcrowiへ送信
* 以下のpythonスクリプトの`url`, `access_token`, `user_id`をそれぞれCrowiで設定されている適切なものに修正し、pythonで実行する

```python3
import requests
import os
import sys

url = 'http://example.com:3000/_api/pages.create'
pukiwiki_root = "wiki_mod"
access_token = "replace_with_your_access_token"
user_id = "your_id"

for root, dirs, names in os.walk(pukiwiki_root):
    for fn in names:
        fpath = os.path.join(root, fn)
        fn_base, ext = os.path.splitext(os.path.relpath(fpath,start=pukiwiki_root))
        body = u''
        with open(fpath, 'r') as f:
            body = f.read()

        data = {"access_token": access_token,
                "path": "/user/" + user_id + "/" + fn_base,
                "body": body}

        rsult = requests.request(method='post', url=url, data=data)
        if rsult.status_code != requests.codes.ok:
            print("Error! status code : " + str(rsult.status_code))
            sys.exit(1)
        print(rsult.text)
```

# 注意点
* pukiwikiにスペースが含まれるタイトルはファイル名の変換に失敗する
* CrowiのAPIの仕様は公開されていないため、将来的には変更される可能性がある
* 上記コードは無保証なので、データバックアップを取った上で自己責任でご利用ください

# まとめ
* ポイントとしては以下の3点
    * ファイル名、ファイル中の文字コードをUTF-8に変換する
    * pukiwiki記法をmarkdown記法へ変換する
    * CrowiのAPIを使ってpukiwikiのデータをCrowiに書き込む
[Swift]0.0の時は0、0.11の時は0.11にする

`0.0の時は0、0.11の時は0.11にする`

何が言いたいかというと、無駄な小数点以下の0は表示したくない。
暗号通貨の残高表示とか実装する時、物によっては小数点１８桁とかになるので
`0.000000000000000000 ETC`
とか表示したくない。

ぱっと思いつくのは`%,.18f`みたいなformatで文字列を作る方法だけど、Swiftの場合はNumberFormatを使う。

```swift
let formatter = NumberFormatter()
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 18
let balance = formatter.string(from: NSNumber(floatLiteral: balance)) ?? "0"
let symbol = "ETC"
"\(balance)\(symbol)" // 0ETC
```
備忘録　－　プロキシサーバーの話　－　その1（登場までの歴史）

年末年始に部屋の大掃除をしていたら、SoftWareDesignの2013年3月号が出てきた。
その中の特集ページに「プロキシサーバーの教科書」というのがあり、非常にためになったので自分なりのまとめと感想。
ついでにNATとかのまとめ。

例によって自分用備忘録。

深夜テンションでガサっと書いてたら長くなってしまったから何回かに分割する。
続きはそのうち書く。

##プロキシサーバー登場までの歴史
昔はインターネット上に存在するサーバーも少なく、そもそも現在のように一般に広く利用されていなかったので必要なかった。
当時は、LANに接続されているPCそれぞれがグローバルIPを持っていたらしい。
__信じらんねえ。__

###当時のインターネットユーザー
その当時の使用者は政府や企業の研究所、大学組織や軍隊に限られていたので、インターネットセキュリティも問題視されてなかったとか。
__逆に不正アクセスとか無かったんかな__
とか思ったけど、今ほど通信網が整備されてなかったからそんな心配なかったということ？

###一般公開後
んで、1993年に日本国内でインターネット接続サービスが一般に提供され、企業や個人が自分のホームページを公開し始め。
んでもって爆発的にインターネットに接続される端末が爆発的に増加し、この頃から不正アクセスとかが騒がれ始めたとか。

同時にIPv4のアドレス枯渇問題が心配され始めたらしい。
20年も枯渇問題に耐え続けてるってどうなん？

###ゲートウェイ&プライベートアドレス登場まで（プロキシはまだ）
上記2つの理由から外部と内部のネットワークを分ける必要が出てきて、1996年にRFC1918でプライベートアドレスが提案され、内外のネットワークを何かしらのゲートウェイで遮断&中継する技術が必要とされ。

IP的に遮断し、かつ中継するゲートウェイがNAT、ファイアウォール、HTTPプロキシサーバーだとか。

###んでNATってなんじゃい？という部分
NetWork Address Translation（ネットワークアドレス変換）
の略。読んで字のごとく。
最初期のNATはIPマスカレードと違って、ホントにアドレスを変換するだけだったらしい。

###IPマスカレードって？って話
NAPT（Network Address and Port Translation）とも言う。
つまりアドレスだけでなく、TCP/UDPのポートも変換する。
コイツのおかげで、LANにある複数の端末から同時にWANに接続できるというコト。

###んでファイアウォールとは？ざっくり説明。
内外のネットワークの境界に置く。ファイアウォールを通ろうとする通信を監視し、転送を許可しないパケットを破棄する。
ついでにネットワーク管理者に通報できる。

###プロキシサーバー登場（やっと）
が、NATとかは機械的な処理だけするのに対して、ファイアウォールはパケットの中身を確認したりログ取ったりを全部のパケットに対して行うから、ネットワークの遅延がヤバい。
んで規模がでっかくなるとファイアウォール自身の負荷がヤバい。

そこで登場したのが__プロキシサーバー__（やっと登場）。
パケットの中継とデータのキャッシュをプロキシサーバーによって行い、通信料を削減したりすることも目的だったとか。

##プロキシサーバーとは？
プロキシサーバーってなんぞや？というお話だけども、
「プロキシ」とは「代理」という意味の英語。つまり代理サーバー。
単にプロキシサーバーとだけ言う場合は、LANからのインターネット接続を代理で行うサーバーを指す(ことが多い)。

現在ではリバースプロキシというものが登場したので、それに対してフォワードプロキシと呼ぶ。

プロキシサーバーの機能とか、続きはそのうち。
アルゴリズム問題　B45　計算ドリル

#問題
小学校低学年向けの足し算と引き算の計算ドリルをつくりましょう。計算ドリルとして問題に重複があると計算力の訓練にならないため、足し算、引き算それぞれで重複が無いようにつくらなければなりません。必要な足し算と引き算の問題の数が与えられるので、それに従ってドリルを作成してください。


なお、その際問題に出てくる数値および解答はすべて 0 ~ 99 の整数になるようにします。
足し算も順番を変えたものは異なる問題とします (a ≠ b のとき "a + b =" と "b + a =" は異なる問題)。

例)
足し算 5 つ、引き算 3 つのドリルを作成 (入力例 1 に対応)

計算ドリルの例:

```
25 + 5 =
89 + 10 =
45 - 16 =
3 + 46 =
82 + 3 =
0 + 84 =
70 - 6 =
27 - 26 =

```
##条件
すべてのテストケースにおいて、以下の条件をみたします。

・0 ≦ M, N ≦ 5,050 (条件内で作成可能な足し算・引き算の最大数)
・M + N ≧ 1

#回答コード１（20点）

```rb:

input_lines = gets.split(" ")
tasizan = input_lines[0].to_i
hikizan = input_lines[1].to_i
cnt=-0

drill=[]
while cnt<tasizan
    kazu1 = rand(100)
    kazu2 = rand(100)
    next if kazu1+kazu2>99
    next if kazu1==kazu2
    drill.push("#{kazu1} + #{kazu2} =")
    cnt+=1
end

cnt=0
while cnt<hikizan
    kazu1 = rand(100)
    kazu2 = rand(100)
    next if kazu1 <= kazu2
    drill.push("#{kazu1} - #{kazu2} =")
    cnt+=1
end

drill.each{|i|
    puts i  
}
```
##解説
入力から足し算引き算それぞれ必要な出力数を取得してその回数ループする様に
while文をくみたてた。
Arrayのdrillは必要な式全てぶち込んでから最後にランダムで出力出来るようにと思って用意したけど結果的に時間を取りに行くために出力は添え字の順番でということになっている。（問題の回答としては問題無い）

randメソッドで引数に100を指定した事で0~99の数をランダムで返すがそれぞれのループに対して条件を設けている

足し算
→回答が100以上ならパス
→数字の被りはパス（減点対象）

引き算
→引かれる側が必ず大きい事

とした。結果20点。タイムは45分。

#回答コード２（訂正　90点）

```rb:



input_lines = gets.split(" ")
tasizan = input_lines[0].to_i
hikizan = input_lines[1].to_i
cnt=-0

drill=[]
while cnt<tasizan
    kazu1 = rand(100)
    kazu2 = rand(100)
    next if kazu1+kazu2>99
    next if drill.include?("#{kazu1} + #{kazu2} =")
    drill.push("#{kazu1} + #{kazu2} =")
    cnt+=1
end
cnt=0
while cnt<hikizan
    kazu1 = rand(100)
    kazu2 = rand(100)
    next if kazu1 <= kazu2
    next if drill.include?("#{kazu1} - #{kazu2} =")
    drill.push("#{kazu1} - #{kazu2} =")
    cnt+=1
end


    puts drill.sample(tasizan+hikizan)  
```

##解説
一回目の提出がたった２０点だった。

原因は同じ式の出力が行われたことであると考える。
drillにpuShする前に同じ式が無いかを確認するコードを加えて、
更に足し算引き算ランダムに出力される様にsampleメソッドを用いてみた。

”引数に整数を指定すると、その数だけ要素をランダムに取り出し配列で返します。要素の順番もランダムになります。”

結果ケース１０で何回やってもタイムオーバーになってしまうが90点。Bが遠い
Julia から C を呼び出す簡単なサンプル

# 本日は

JuliaからCの関数を呼び出すというお話です．
JuliaをPythonから，PythonからJuliaを呼び出すというのは結構楽っぽい．
ではJuliaからCを呼び出すのは・・・？


こちらの英語のブログを参考にしました．

[Julia calling C: A more minimal example](http://perfectionatic.org/?p=470)
# 環境
MacOSX で行なっています．

# 準備（Cのコードを準備）

二つのdoubleの値の平均を求めるという簡単なサンプルを用意します．

```c:calc_mean.c
double mean(double a, double b) {
    return (a + b) / 2;
}
```

これを共有ライブラリとしてビルドします:

```shell-session
$ gcc -shared -fPIC -o libmean.so calc_mean.c 
$ ls
calc_mean.c	libmean.so
```

# 呼び出す
ターミナルを開いてjuliaを起動します．

```julia
julia> cfunc=(x,y)->ccall((:mean,"libmean.so"),Float64,(Float64,Float64),x,y)
julia> cfunc(3.0,4.0)
3.5
```

やっていることは次の通りです．

1. mean関数をibmean.soから取り出して戻り値，引数の型情報を指定．
- 無名関数による `cfunc` を定義
- 呼び出し

期待通り３．５が得られましたね．

# 他にも

[Calling a C function from Julia and passing a 2D array as a pointer of pointers as argument　]
(https://stackoverflow.com/questions/33003174/calling-a-c-function-from-julia-and-passing-a-2d-array-as-a-pointer-of-pointers)

が参考になります．

# その他参考になりそうな場所

- https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/index.html
- https://github.com/JuliaLang/PackageCompiler.jl
My brew list


* インストールした理由がわからないのもありますが、一覧を出してみます。

```sh:brew.sh
#!/bin/sh -eu

for i in `brew list`; do
echo "1. "`brew info "${i}" | grep "${i}:"`
done
```

## インストール一覧

1. autoconf: stable 2.69 (bottled)
1. bash-completion: stable 1.3 (bottled)
1. clang-format: stable 2017-11-14 (bottled), HEAD
1. fswatch: stable 1.11.2 (bottled)
1. gcc: stable 7.2.0 (bottled), HEAD
1. gdbm: stable 1.14.1 (bottled)
1. gettext: stable 0.19.8.1 (bottled) [keg-only]
1. git: stable 2.15.1 (bottled), HEAD
1. gmp: stable 6.1.2 (bottled)
1. gnu-tar: stable 1.30 (bottled)
1. htop: stable 2.0.2, HEAD
1. isl: stable 0.18 (bottled), HEAD
1. libevent: stable 2.1.8 (bottled)
1. libidn2: stable 2.0.4 (bottled), HEAD
1. libmpc: stable 1.1.0 (bottled)
1. libunistring: stable 0.9.8 (bottled)
1. libyaml: stable 0.1.7 (bottled)
1. maven: stable 3.5.2
1. mpfr: stable 4.0.0 (bottled)
1. ncurses: stable 6.0 (bottled) [keg-only]
1. nkf: stable 2.1.4 (bottled)
1. openssl: stable 1.0.2n (bottled) [keg-only]
1. openssl@1.1: stable 1.1.0g (bottled) [keg-only]
1. pcre: stable 8.41 (bottled), HEAD
1. perl: stable 5.26.1 (bottled), HEAD
1. pkg-config: stable 0.29.2 (bottled)
1. postgresql: stable 10.1 (bottled), HEAD
1. pyenv: stable 1.2.1 (bottled), HEAD
1. python: stable 2.7.14 (bottled), HEAD
1. readline: stable 7.0.3 (bottled) [keg-only]
1. redis: stable 4.0.6 (bottled), HEAD
1. ruby: stable 2.5.0 (bottled), HEAD
1. sqlite: stable 3.21.0 (bottled) [keg-only]
1. tree: stable 1.7.0 (bottled)
1. uncrustify: stable 0.66.1 (bottled), HEAD
1. vim: stable 8.0.1400 (bottled), HEAD
1. wget: stable 1.19.2 (bottled), HEAD
1. zsh: stable 5.4.2 (bottled), HEAD
1. zsh-completions: stable 0.27.0, HEAD

## What does "keg-only" mean?

* [FAQ](https://github.com/Homebrew/brew/blob/master/docs/FAQ.md#what-does-keg-only-mean) に記載がありました。

> It means the formula is installed only into the Cellar; it is not linked
> into `/usr/local`. This means most tools will not find it. We don’t do
> this for stupid reasons. You can still link in the formula if you need
> to with `brew link`.

* kegとはビール樽という意味ですが、ここではインストールだけされていて/usr/localにはシンボリックリンクをつけてないパッケージのこと。…だそうです、コマンドではなくライブラリがこれにあたるようですね。
Alexaスキル「あまぞんちほーのラッキーさんのフレンズ紹介」を公開した

# アニメ『けものフレンズ』に登場するキャラクター、**ラッキービースト**(ラッキーさん)をAlexaで作成しました。

1月9日付けで、Alexaスキル「あまぞんちほーのラッキーさんのフレンズ紹介」が公開されました。

<img width="750" alt="ラッキーさん.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/155894/56c65574-34b2-7543-aed7-3256bce8274e.jpeg">

※　Echo Dotが光っている感じが、ラッキーさんが「検索中！ 検索中！」と頑張っている様に思われて、動画を撮りました。

## 動機
「CDを買ったりするアマゾンがAIスピーカーを出すんだ」とニュースを見て思いました。

そんな折、突然ひらめきました。

けものフレンズのCDを先行予約したりするAmazon
→　アマゾン　→　あまぞんちほー　
→　(内田彩さんの魅力ある声質をのぞくと)ラッキーさんの喋り方ってこんな感じ。 
→　プログラマー初心者の俺でも実装できそう！！

## 作成期間
去年2017年11月中旬に1度目の申請をしているので、約2か月です。

## 苦労した点
- Echo Dot の入手。
11月9日に招待リクエストを登録して12月1日まで購入できませんでした。

- [Alexaスキル開発トレーニングシリーズ 第1回 初めてのスキル開発](https://developer.amazon.com/ja/blogs/alexa/post/6e716e5c-55b0-445b-b936-9cfac4712e7b/training-1)を見ながら、実際に操作を試したのですが、実機がないからなのかブラウザ版でうまく反応しませんでした(原因は後述)。
- 認定に関するフィードバックを4回も受けた事。ドキュメントをしっかり理解できていなかったためです。また、ラッキーさんの雰囲気を活かしたくて次のように申請した際、「提示用に選ばれたサンプルフレーズは、現在、サポートされていない起動フレーズを使用しています。」との指摘をいただいたので修正しました。ですので、Alexaスキルの開発に挑戦される方は、起動フレーズのルールなど十分に読まれた方がいいです。
    - アレクサ、あまぞんちほーのラッキーさんを~~呼んできて~~。
    - アレクサ、あまぞんちほーのラッキーさんを~~連れてきて~~。

## ハンズオントレーニング
去年2017年12月16日 (土)にアマゾンジャパン合同会社大阪支社で開催された**Alexaハンズオントレーニング**に参加しました。
セットアップの手順から丁寧に教えていただきました。

特に、『「アマゾン　アプリ　開発者ポータル」のアカウント登録を、通常使っているAmazonアカウントのメールアドレスとパスワードを使いまわしていると、**何故か米国設定になって、**Alexaが正しく動かない』という貴重な情報を教えていただき大変助かりました。

この場合の回避方法は、「アマゾン　アプリ　開発者ポータル」のパスワードを変更する、です。ここから一気に道が開けました。

※　この件に関して、@toshimin氏が書かれた次の記事が詳しいので、是非読んでいただきたいです。
> [Alexa 開発者アカウントのハマりどころ](https://qiita.com/toshimin/items/3355a996008216dff741)

※※　公式ブログの方はこちらです。
> [Alexa 開発者アカウント作成時のハマりどころ](https://developer.amazon.com/ja/blogs/alexa/post/9f852a38-3a44-48bd-b78f-22050269d7c7/hamaridokoro)

正直JavaScriptの知識は必要なく、出来合いのコードを張り付けるだけでした。

しかし、開発者ポータルやAWSマネージメントコンソールにログインしてWebの記事だけで設定していくのって、初心者には、けっこう無理があったので、大変助かりました。

一緒に参加されている皆さんから大いに刺激を受けたり、専門スタッフの方に質問できて満足できたハンズオンでした。 2018年1月2月もあるようですので、是非参加してほしいです。

## 今後の展望
- 修正。一部のフレンズはちゃんと対応していますが、審査になかなか通らなくて、現状は基本的な処理をランダムで逃げています。フレンズの名称で呼びかけられたら、対応する説明を返答するように、コードを書き直したいです。
- Google Assistantアプリ「ぐーぐるちほーのラッキーさんのフレンズ紹介」は申請済みです。
- バージョンアップ
「サーバルちゃんに会える動物園はどこ？」などと質問されたら、最寄りの動物園を音声やホームカード機能で返答する機能を実装したいです。
- HomePod版
AppleのAIスピーカーHomePodは高すぎて買えそうにないのですが、「あっぷるちほーのラッキーさんのフレンズ紹介」も実現したいです。

## 著作権や個人情報
当該Alexaスキル「あまぞんちほーのラッキーさんのフレンズ紹介」は、けものフレンズ公式サイトが掲げている＜二次創作に関するガイドライン＞に則って作成した非公式スキルです。
また、位置情報などの個人情報は取得していません。
コンテナの起動時に ERROR: Service 'mysql' failed to build のエラー対応

## エラー内容

laradocを使って、コンテナを起動した際に、下記のようなエラーが出力

```bash
$ docker-compose up -d apache2 mysql
Building mysql
Step 1/10 : ARG MYSQL_VERSION=8.0
Step 2/10 : FROM mysql:${MYSQL_VERSION}
ERROR: Service 'mysql' failed to build: Get https://registry-1.docker.io/v2/library/mysql/manifests/8.0: unauthorized: incorrect username or password
```

## 対応

下記のコマンド実行後、再度コンテナを起動して解消

```bash
$ docker logout
```

途中、コマンド間違いとかしたので、何か仕掛かったのかもしれない。

***
参考サイト

* [Error unauthorized: incorrect username or password #1098](https://github.com/docker/hub-feedback/issues/1098)
Google Assistantに話しかけるだけでJenkinsでビルドする

### やること
Google HomeやAndroidスマホ等のGoogle Assistant搭載デバイスに「ビルドして」と話しかけるだけで、Jenkinsでビルドします。なお、各サービスどうしの連携は[IFTTT](https://ifttt.com/discover)を利用します。

### 前提
* Jenkinsの実行環境があること
* Google HomeやAndroidスマホ等のGoogle Assistant搭載デバイスがあること

### 構成1. IFTTTのWebhookから直接Jenkinsビルド

構成としては以下の通りです。IFTTTのWebhookにJenkinsのビルドリクエストを直接指定します。

![w.png](https://qiita-image-store.s3.amazonaws.com/0/23101/ced8d547-4969-35a4-7d93-461dc44b284a.png)

以下はIFTTTの設定です。左がGoogle Assistant、右がWebhooksになります。

![1515500488.jpg](https://qiita-image-store.s3.amazonaws.com/0/23101/b592b248-4334-6829-56eb-330beef669ff.jpeg)

上記設定により、Google HomeやAndroidスマホ等のGoogle Assistant搭載デバイスに
「ビルドして」と話しかけると（左の設定）、
「http://user:APIトークン@35.184.206.154//jenkins/job/test_build/build?token=testtoken 」 にアクセスし（右の設定）、ビルドが開始されます。


### 構成2. IFTTTのWebhook→FaaS→Jenkinsビルド

構成としては以下の通りです。IFTTTのWebhookにAWS LambdaやGCPのCloud Functionsのような[FaaS](http://www.itmedia.co.jp/enterprise/articles/1701/16/news026.html)を指定して、そこからJenkinsにビルドリクエストを送ります。ここでは、「[Google Cloud FunctionsからSlackへ通知を送る](https://qiita.com/NagaokaKenichi/items/fe2a04bef38bea632621)」で使ったFunctionを利用して行いました。この構成にすることで、コールバック処理を指定することも可能となります。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/23101/af071f43-6b61-70bf-3885-fe718f3d7cef.png)

IFTTTの設定は「構成1」と同じです。ただし、Webhook側はFaaSのURLを指定します。
Cloud Functions側のソースは以下のような感じです。

```index.js
const request = require('request');

exports.build= function build(req, res) {

	var headers = {
		'Content-Type':'text/plain'
	}

	var options = {
		url: 'http://user:APIトークン@35.184.206.154/jenkins/job/test_build/build?token=testtoken',
		method: 'GET',
		headers: headers
	}

	request(options, function (error, response, body) {
	　　// コールバック処理
	})

	res.status(200).send('Success');
};
```

```package.json
{
	"name": "sample-http",
	"version": "0.0.1",
	"dependencies": {
		"request": "^2.81.0"
	}
}
```

以上です。
実務で利用できるかどうかは別として、何かの参考になればと思います。

### 参考
Jenkinsのビルドジョブのリモート実行に関しては、以下を参考にしました。
https://tomokazu-kozuma.com/how-to-execute-jenkins-job-remotely/
http://symfoware.blog68.fc2.com/blog-entry-1902.html
UnityでVisualStudio2017のIntelliSenseが動作しなくなる問題を解決する


VisualStudio2017+Unity2017にしてから新しいC#スクリプトを作るとどうも(UnityEngineとかの)IntelliSenseが動作していない。
プログラムを再起動しても改善せず。作業にならんので解決方法を調べた。

[ここ](https://developercommunity.visualstudio.com/content/problem/130597/unity-intellisense-not-working-after-creating-new-1.html)にあった内容でいける模様。

1. [公式](https://www.visualstudio.com/downloads)からVS2017のインストーラ(vs_community_***.exe)をDL
2. インストーラを実行(しばらく待たされる)
3. 更新があると言ってきたので、とりあえず更新(これを書いている段階では15.5.2)
4. 「インストール済み」のVS Communityから、変更→「個別のコンポーネント」タブを選択
5. コードツールの「NuGetパッケージマネージャ」をチェック→変更

これで解決した。
webpack.mix.jsのソースファイルをglobのワイルドカードで指定する


Laravelのwebpack.mix.jsはwebpackを簡潔に書ける強力なツールですが、gulpfileのように標準でglobによるワイルドカード指定ができないので、ページによりjsやcssを分けようとするといちいちコンパイル元のソースを書き足していかないといけません（標準でglobがないのは通常のwebpackでも同じですが）。
それは面倒なので、globをインストールして使用してワイルドカードでファイル指定をするようにします。

```webpack.mix.js
const glob = require('glob');

// sassディレクトリ直下のscssファイルを全てコンパイル
glob.sync('resources/assets/sass/*.scss').map(function(file) {
  mix.sass(file, 'public/assets/css');
});

// jsファイルを連結・圧縮
mix.scripts(glob.sync('resources/assets/js/modules/vendors/*.js'), 'public/assets/js/vendors.js');
```

`glob.sync(pattern)`でファイルパスの文字列を要素にとる配列が返ってくるので、それをそれぞれコンパイルするか、配列を取れるmix.scriptsならそのまま引数にぶちこみます。
webpackに限らず基本的にいろいろなところで使えそうですね。glob便利。

## 参考サイト
[アセットのコンパイル(Laravel Mix) 5.4 Laravel](https://readouble.com/laravel/5.4/ja/mix.html)
[isaacs/node-glob: glob functionality for node.js](https://github.com/isaacs/node-glob)
modern.ie Windows10 を日本語化

ほぼ以下のとおり

http://na-tyan.com/archives/1821

> 1. ４つ窓（スタートメニュー）クリック
> 1. Settings クリック
> 1. Time & Language クリック
> 1. 左側の選択項目で Region & language クリック
> 1. ここで Country or region を Japan に変更
> 1. Languages には English があるので ＋ クリックで 日本語 の追加する
> 1. 日本語 クリックでダイアログが広がって Options をクリック
> 1. 当方の環境ではここで Search Windows Update 表示でしばらく待ち
> 1. Update が終わると Language options 下に Download が表示でクリック
> 1. Languages pack installed 表示でインストール完了（インストール状態がバーで表示された）
> 1. ← をクリックして前のウインドウ画面にする
> 1. 日本語 欄クリックで Set as primary クリック 再起動して既定値として設定される
> 1. 日本語表示の modern.IE for Windows10 へとなりました。

当方(Build 16299.rs3_release.170928-1534)では以下の違いがあった。
9の Windows Update の待ちはなかった。
12は Set as default 
ゴミ箱などの表示はそのまま
ペアリングしたBluetoothデバイスの「名前」を取得する方法

ペアリングしたデバイスは設定画面で名前を変えることができますよね。

![device.png](https://qiita-image-store.s3.amazonaws.com/0/94929/1abc815e-7772-2a27-d206-96db6defcafa.png)

どうしてもこの値が欲しかった。
[BluetoothDevice](https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html)を見ても、それらしいメソッドは見つかりません。
[getName()](https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#getName())というのがあったのですが、これは名前を変更する前のデフォルトの値が返ってきました。

Androidのソースを覗いてみると[getAlias()](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth/BluetoothDevice.java#883)を発見。
試してみると、ちゃんと取得できました。

ただし、`@hide`なメソッドなので使用する際は注意。

---

以下、リフレクションを使って`getAlias()`を呼び出すコード。

```java
private String getAlias(BluetoothDevice device) {
    try {
        Method getAlias = BluetoothDevice.class.getMethod("getAlias");
        return (String) getAlias.invoke(device);
    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
        return null;
    }
}
```
Riot 3.7のkey

Riot 3.7では、ループするタグに`key`属性を加えることができるようになっています。

# Riotでのループ

改めて説明するまでもないかもしれませんが、Riotでは`each={item in items}`のようにすることで、配列などを展開してそれぞれごとに要素を生成することができます。

## `key`なしでの場合

`key`のない場合、配列を変更した後に`update`するとなると、DOM要素は適宜使いまわされることになります。通常の場合はそれでかまわないのですが、Riotで管理していない属性、例えば以下のようなものがある状況だと、それがきちんと対応しなくなります。

* フォーカスの状態（一覧表に行を上下させるためのボタンを付けると、行の中身は移動したのにフォーカスだけもとのままとか、見栄えの悪い動作になることがあります）
* `<input type='file'>`の中身（`onchange`ですぐ`FormData`に起こして管理する、というような場合を除けば、送信すべきデータをそのまま引き回すためにはDOM要素ごと移動させるぐらいしか手段がありません）

また、値が移動した場合の照合は`Array.prototype.indexOf`で行っている加減で、巨大なリストになれば線形探索のコストが無視できなくなってきます。

# `key`を入れた場合

これらの問題は、`key`を指定することで解決できます。キーは`indexOf`のリニアサーチよりずっと早く照合できますし[^1]、`key`付きのDOMは、きちんと配列要素と対応して移動してくれます。`key`の指定方法には2通りあって、

* `key='property'`…ループオブジェクトの`.property`の値をそのまま`key`として使う。
* `key={...}`…JavaScriptの式でキーを生成する

というようになっています。

## 注意点

その性質上、`key`が重複したり途中で書き換わったりしてしまうと、走査が正常に行われなくなります。データベースに入っているものならPRIMARY KEYをそのまま使えばいいのでしょうけど、そうでない場合には注意が必要です。ループで回す要素を追加する場合、追加時点で`key`となる値は確実にセットする必要があります。

# 外部リンク

* [Riot Guideの対応部分（英語）](http://riotjs.com/guide/#key)

[^1]: 「This will improve massively the loop performance in case your collections are immutable.」が何故早くなるのか、この解釈とは違うかもしれません。
github で見つけた顔関係のドキュメント

github 上に顔関係のドキュメントを見つけた。

バージョン管理し共有し、複数の人で更新すべきものは、ソースコードに限らない。
目まぐるしく、新しい実装がでてくるので、自力で調べ切るには限界がある。

- 2015-10-09-dl-applications.md
https://github.com/handong1587/handong1587.github.io/blob/master/_posts/deep_learning/2015-10-09-dl-applications.md


- Deep Learning for Face Recognition (May 2016)
https://gist.github.com/jdsgomes/68a2da4a59908ba4738b1fabe2c1c3cc

- Awesome Deep Vision
https://github.com/kjw0612/awesome-deep-vision


## github 上で顔関係を探す場合
github 上で以下のタグを選択して、関連するリポジトリを表示させる。
- https://github.com/topics/face-detection
- https://github.com/topics/face-recognition
- https://github.com/topics/face-alignment
- https://github.com/topics/age-estimation
- https://github.com/topics/face-tracking
- https://github.com/topics/facial-landmarks
- https://github.com/topics/face-attributes
- https://github.com/topics/liveness-detection
- https://github.com/topics/anti-spoofing
- https://github.com/topics/face-database
docker上でnginxを動かすまで

docker上でnginxを動かす方法を順に説明します。
動作環境はmacOS High Sierradです。

## __dockerの起動__
dockerのアイコンをクリック![スクリーンショット_2018_01_09_22_40.jpg](https://qiita-image-store.s3.amazonaws.com/0/222267/6f456230-0a59-78db-e491-d02c8079897c.jpeg)

メニューバーにdockerのアイコンが表示されたら起動完了
![Item-0_と_Item-0_と_Item-1_と_AppleBluetoothExtra_と_AirPortExtra_と_AppleTextInputExtra_と_AppleClockExtra.jpg](https://qiita-image-store.s3.amazonaws.com/0/222267/2b46209a-4310-1fc1-e996-73b103d4a27e.jpeg)

## nginxの起動
起動が確認できたら以下のコマンドを実行します。

```shell
$ docker run -d -p 80:80 --name {コンテナ名} nginx
```
このコマンドでnginxを起動させますが、dockerにnginxがない場合はdocker hubから自動でダウンロードしてくれます。
※[docker hub](https://hub.docker.com)とはdocker上で動作するイメージがまとめてあるwebサイトです。
ここからdocker内で動かしたいものをダウンロードしてくるという感じです。基本的には無料なので色々なOSやミドルウェアを試す事ができます。


ブラウザからも起動確認
http://localhost:80
![Welcome_to_nginx_.jpg](https://qiita-image-store.s3.amazonaws.com/0/222267/926b3eca-3be8-83e5-7cae-c804ff4d2d64.jpeg)

恐ろしく簡単にnginxが起動できました。
しかもローカルにインストールをしていないので削除も簡単なんです。
（私はローカルに開発系のアプリをあんまりインストールしたくないので可能な限り仮装環境で済ませたい)

最初でつまづくとやる気をなくすので、私のような経験の浅いエンジニアがモチベーションをキープできますね。

参考：[DockerをMacにインストールする (更新：2017/5/26)]
(https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81)
Vim / Vi を終了させる方法

設定ファイルを編集する際に普段使わないvimやviを開いて修正したけど、vim/viからターミナルに戻れない。
そんなときにvim/vi（以降vimとだけ表記）の終了の仕方

## まずはエスケープキー【Esc】を押す
これでVimをニュートラルなモードにしてコマンド入力できるようにする

## 終了コマンドを入力
画面左下に入力中のコマンドが表示されるはずだ

### 保存済みのファイルを開いているvimから抜ける場合
```
:q
```

### ファイルを保存しないでvimを抜ける場合
```
:q!
```

### ファイルを保存してからvimを抜ける場合
```
:wq
```

-----
余談

オレはemacsおじさんなのでViの終了のさせ方を忘れるんだな。
requirejs で jsx を babel-standalone で処理しつつ読み込む


## Q. こんなのいつ使うの

A.
パフォーマンス無視できる
ビルド環境用意するのが面倒

## 実装例

```html:index.html
<script src="//unpkg.com/requirejs/require.js" data-main="config.js"></script>
```

```javascript:main.jsx
import React from 'react'
import ReactDOM from 'react-dom'
import {Main} from 'jsx!main.class'

ReactDOM.render(
  <Main cont="hoge" />,
  document.querySelector('#out'))
```

```javascript:main.class.jsx
import React from 'react'
export const Main = props =>
  <div>{props.cont}</div>
```

```javascript:config.js
require.config({
  paths: {
    babel: "https://unpkg.com/@babel/standalone/babel.min",
    react: "https://unpkg.com/react/umd/react.production.min",
    "react-dom": "https://unpkg.com/react-dom/umd/react-dom.production.min"
  }
});
require(['jsx!main'])
```

```javascript:jsx.js
(() => {

const callMethod = name => obj =>
  obj[name]()
const transform = babel => code =>
  babel.transform(code, {presets: ['react', 'es2015']}).code
const format = code => `define((require, exports, module) => {
  ${code}
  ;return exports;})`

define(['babel'], babel => ({
  load: (name, req, onload, config) => {
    const path = req.toUrl(name) + '.jsx'
    fetch(path)
      .then(callMethod('text'))
      .then(transform(babel))
      .then(format)
      .then(onload.fromText.bind(onload))
      .catch(onload.error.bind(onload))
  }
}))

})()
```

## 参考文献
[RequireJS使い方メモ](https://qiita.com/opengl-8080/items/196213867b859daea719)
[GitHub - icecreamliker/requirejs-babel-plugin: A better RequireJS plugin for babel](https://github.com/icecreamliker/requirejs-babel-plugin)
[RequireJS + babel-standalone + JSX](https://qiita.com/kenichi_odo/items/6767aa077585e395134d)