OmniAICreator/Qiita-1.07M huggingface dataset:
Julia v1.0.0でfinalizerの引数順序が変更された

Juliaのmutable structのディストラクタとしてfinalizerを使用しますが、v1.0.0からfinalizerの引数順序が変更されました。

# v1.0.0での書き方
finalizerの第一引数がfunction、第二引数がfinalize対象のオブジェクトに変更されました。
ちょうど変更前と逆の順序になります。
以下の例ではdo syntaxを使って引数の順序を変えています。

```julia

mutable struct Synth
    synth_ptr::Ptr{Cvoid}
    setting_ptr::Ptr{Cvoid}
    function Synth()
        synth = new(C_NULL, C_NULL)
        finalizer(synth) do synth
          # ディストラクタの処理
        end
        synth
    end
end
```

# v1.0.0以前での書き方

```julia
mutable struct Synth
    synth_ptr::Ptr{Cvoid}
    setting_ptr::Ptr{Cvoid}
    function Synth()
        synth = new(C_NULL, C_NULL)
        finalizer(synth,
            function(synth::Synth)
              # ディストラクタの処理
            end)
        synth
    end
end
```

# 投入コミット
https://github.com/JuliaLang/julia/commit/52d81b037a25799ac7a93415c70edb1c991bb421

# どうでもいい話
v1.0.0の話をする時、v0.7.0じゃないの？と無限に揚げ足を取れるわけですが、どっちで言うのがいいんですかね…。
rails 11章　sendgridメールが作成されない時の解決方法

【sendgridメールが作成されない時の解決方法】
約一日はまったのでメモとして残しておく。

【原因】
SENDGRID_USERNAMEが設定されていなかった

【経緯】
11章の最後、herokuへデプロイし、本番環境から新規ユーザ登録するも、

We're sorry, but something went wrong.

の画面が表示される。

そのページを再読み込みすると、ユーザは登録されているが、sendgridの有効化メールが作成されていない状態であることが判明。


【行ったこと】
コンソールにてheroku logsでログ確認

出ていたエラーは
FATAL--Completed 500 Internal Server Error
FATAL--Net::SMTPAuthenticationError (535 Authentication failed: Bad username / password
FATAL--app/models/user.rb:49:in `send_activation_email'

各ファイルを見直すも、コードの書き間違い等は見当たらず。。
もう一度１１．４からやり直し、
$ heroku config:get SENDGRID_USERNAMEを実行したところ、

SENDGRID_USERNAMEの値が設定されておらず、ブランクになっていることが発覚。
（設定していたはずだが、エラーではまっている途中herokuのdbをリセットしたのでその時に消えたのでしょうか。。）

SENDGRID_PASSWORDは設定出来ている。

そのため、SENDGRID_USERNAMEを再設定します。

値を確認するコマンド
heroku config:get SENDGRID_USERNAME
heroku config:get SENDGRID_PASSWORD

値を設定するコマンド
heroku config:set SENDGRID_USERNAME=設定したい値〇〇〇
heroku config:set SENDGRID_PASSWORD=設定したい値〇〇〇

設定したいUSER_NAMEをsendgridのアカウントページで確認する。

その後コンソールにて
$ heroku config:set SENDGRID_USERNAME=設定したいUSER_NAME〇〇〇
を実行。以下の実行結果が表示される。
Setting SENDGRID_USERNAME and restarting ⬢ morning-forest-74192... done, v19
SENDGRID_USERNAME: app108355452@heroku.com

パスワードは設定されている
$ heroku config:get SENDGRID_PASSWORD
e0e5lqgk8035

その後、

git add -A
git commit -m
git push
git push heroku

を行う。

再度herokuからアプリ立ち上げ。
１０分メールを使って、再度本番環境から新規登録。
https://10minutemail.net/

すると新規登録が出来た。

トップページへリダイレクトされ、アカウントを有効化しろとのメッセージが表示される。

１０分メールのメールBOXをチェックすると、有効化メールが来ていた。

本文のactiveをクリックしたら、ページへ飛んで有効化出来ました。


【反省と学び】
何か変更したら、git addとgit commitを行う。加えた変更が適用されないため。
エラーになって色々修正していると、正しく設定出来ていたことに誤った変更を加えてしまっている可能性もあるので、落ち着いて見直していく。
Forkしたプロセスの制御 - disable fork

本記事は以下の3部構成の一部です。

1. [fork joinとその仲間たち](https://qiita.com/triggerfish/items/055464c8b46825f0af49)
2. [Forkしたプロセスの制御 - disable fork](https://qiita.com/triggerfish/items/13f6d2e7a8b86aede37e)
3. [Forkしたプロセスの制御 - processクラス](https://qiita.com/triggerfish/items/4894f6be377a10d24292)

---

# disable forkとは
disable forkはforkしたプロセスを停止する命令です。

disableと似ていますが、disableは引数を取るのに対してdisable forkでは引数がありません。命令が実行されたスコープ内での全てのforkされたプロセスが停止します。複数のプロセスを一気にまとめて停止するのに便利ですが、スコープに注意を払わないと意図したものより多くのプロセスを停止させてしまう可能性があるので注意してください。

下のサンプルプログラムでは複数のforkしたプロセスで、シミュレーション開始から3ns後にメッセージを表示させています。並行して2nsの時点でdisable forkでスコープ内にあるプロセスを停止させています。

ログの通り、メッセージが表示されているのはdisable forkより上の階層にある"d1"のみとなります。

```verilog
 module top;
  initial begin
    fork: d1
      delayPrint("d1", 3ns);
      begin
        fork: d2_a
          delayPrint("d2_a", 3ns);
        join_none

        fork: d2_b
          delayPrint("d2_b", 3ns);
          fork: d3
            delayPrint("d3", 3ns);
          join
        join_none

        #2ns;
        disable fork;
      end
    join
  end

  task automatic delayPrint(input string s,
                            input time dly = 0ns);
    #dly;
    $display(s);
  endtask
endmodule
```

```plaintext
run -all;
# KERNEL: d1
# KERNEL: Simulation has finished. There are no more test vectors to simulate.
```
# 参考文献
 "9.6.3 Disable fork statement". [1800-2017 - IEEE Standard for SystemVerilog--Unified Hardware Design, Specification, and Verification Language](https://doi.org/10.1109/IEEESTD.2018.8299595). p.229
ReactNativeで前のページに戻したくない場合

ログイン後のページなどで前のページに戻らさせたくないのに、iOSだったら画面の左をスワイプしたら前のページに戻り、Androidだったらハードウェアキーの戻るボタンで画面が前のページに戻ってしまいます。~~ネイティブだったら画面遷移するタイミングで今の画面をfinish()などして戻らなくさせる裏技を行えるのですが、ReactNativeには自身を終了させるメソッドはありません。~~react-native-router-fluxを使用時の場合
そこで、前のページに戻らさせない方法を調べたのでここに記します。

##ちなみに
react-native-router-fluxを使って画面遷移を行なっています。

##ログインのある画面遷移でやってみる
```jsx:App.js
<Router>
  <Scene key="Root" >
    <Scene key="Top" component={Top} hideNavBar={true} initial/>
    <Scene key="Login" component={Login} hideNavBar={true} />
    <Scene key="Main" component={Main} hideNavBar={true} panHandlers={null}/>
    <Scene key="MenuA" component={MenuA} hideNavBar={true} />
    <Scene key="MenuB" component={MenuB} hideNavBar={true} />
    <Scene key="MenuC" component={MenuC} hideNavBar={true} />
  </Scene>
</Router>
```
このような画面構成のアプリがあるとします。Scene"Login"でログイン成功したらScene"Main"にActionsで画面遷移します。そして、何もしなければ先述した通りScene"Main"からScene"Login"に戻ることができてしまいます。

なので、戻らせないSceneに以下のオプションを設定します。

```jsx:
panHandlers={null}
```
これだけで解決します。

僕はこのオプションを探すのになかなか苦労しました。見つけてからこのプログラムだけで検索してみると、意外と日本語の記事がありました。いつになったら苦労せずに探せることやら。。。
楽々ローカルDocker環境構築

## 前提条件

* Window/Macos
* Vagrant
* virtual box
    * [vagrant-vbguest](https://github.com/dotless-de/vagrant-vbguest)
    * [vagrant-proxyconf](https://github.com/tmatilai/vagrant-proxyconf)
    * [vagrant-teraterm](https://github.com/tiibun/vagrant-teraterm)
* Tera Term

## なぜ必要

DockerがWindows/Macosをサポートしませんのため、WindowsのユーザがDockerを利用する場合、

1. [Docker for Windows](https://docs.docker.com/docker-for-windows/)
2. LinuxのVM上で構築

が一般だと思います。

１の場合、ローカルにDocker for Windowsソフトをインストールしないといけないと加えて、Linuxでの操作と若干違うともあります。

## 環境構築

> 前提条件がクリスされること

下記のリポジトリをローカルにクローンして、centos7-docker-ceフォルダーに移動する。

    https://github.com/gekal/vagrant-local-env-dev.git

```powershell
# 開始コマンド
vagrant up
```

## その他
社内で利用する場合、プロキシを通すのは一般です。下記の環境変数を設定すれば、ネット周りを意識せず使えます。

```conf
http_proxy="http://username:passwd@proxyserver:8080"
```
redux-sagaを使いながら外部リソースのfetchにだけスタンドアローンでApolloを使ってGraphQLの恩恵を受けている


APIサーバをRESTで書くとルーティングを増やしたりqueryにパラメータ追加したりという諸々の作業が面倒くさいので最近はGraphQLで書いているが、個人的にフロントエンドはJSXとredux-sagaで秩序を保ちたい派なので、クライアントサイドはデータのfetchにだけGraphQL(Apollo)を使ってますという話。

### さんぷる(github)

https://github.com/lidqqq/react-redux-saga-apollo-link-standalone

ほとんど[redux-sagaテンプレート](https://github.com/zeit/next.js/tree/canary/examples/with-redux-saga)のままなのでclockとcounter処理をそのまま置いてあるかつ[counterコンポーネント](https://github.com/lidqqq/react-redux-saga-apollo-standalone/blob/master/src/app/components/counter.js)に追加してるあたりがアレなんですが、サンプルということで悪しからず。

クライアントサイドのクエリは[ここ](https://github.com/lidqqq/react-redux-saga-apollo-standalone/blob/master/src/app/lib/gql/operation.js)に書いていて、サーバサイドは[ここ](https://github.com/lidqqq/react-redux-saga-apollo-standalone/blob/master/src/server/typeDefs.js)で型定義して、[ここ](https://github.com/lidqqq/react-redux-saga-apollo-standalone/blob/master/src/server/resolvers.js)で処理をハンドリングしてる。

GraphQLはエンドポイント(？)をメソッド感覚でぽこぽこ追加できるところがいい。一方でドキュメントが少ないので取り組みづらさみたいなものはある。

[react-apollo](https://github.com/apollographql/react-apollo)とredux-sagaって綺麗に共存できるんですかね、できたら最高なんですけど、redux-sagaは手放せないのでapolloだけというのは個人的にはキツそう。

:moyai: キャッシュ...
インターネット ショートカット アイコンがエラーで開けなくなったのを直す|Firefox の削除

(参考)インターネット ショートカット アイコンがエラーで開けなくなったのを直す 2018/02/13[公開]
https://www.ikt-s.com/url-shortcut-dont-open/


(現象と結果)どんぴしゃ。
デスクトップに出したサイトURLのアイコン（インターネット ショートカット）
あまりそーゆー使い方はしません。

お気に入りの登録は、できていました。
14個のうち10個の項目がこのプログラムを既定のプログラムとして設定しています。
↓
対応
↓
このプログラムで開くことのできる項目すべてが、これを既定のプログラムとして設定しています。

(原因)
「Windows7でChromeブラウザーをアンインストールしたら出るようになったエラーです。」


(おまけ)Firefox の削除 | Firefox ヘルプ - Mozilla Support
https://support.mozilla.org/ja/kb/uninstall-firefox-from-your-computer
yum を実行する際のマイナーリリースを指定する方法

yum を実行する場合、基本的には以下のように最新のバージョンが適用される。

```shell-session
$ yum list systemd
読み込んだプラグイン:product-id, search-disabled-repos, subscription-manager
インストール済みパッケージ
systemd.x86_64                                                               219-30.el7                                                                   @anaconda/7.3
利用可能なパッケージ
systemd.x86_64                                                               219-57.el7_5.3                                                               rhel-7-server-rpms
```
この場合、`--releasever=x.x` を付与することで、マイナーリリース (RHEL7.3 とか RHEL7.4 とかのこと) を指定することが可能。

```shell-session
$ yum list systemd --releasever=7.4
読み込んだプラグイン:product-id, search-disabled-repos, subscription-manager
rhel-7-server-rpms                                                                                                                                   | 3.5 kB  00:00:00
(1/3): rhel-7-server-rpms/7.4/x86_64/group                                                                                                           | 710 kB  00:00:02
(2/3): rhel-7-server-rpms/7.4/x86_64/updateinfo                                                                                                      | 2.4 MB  00:00:04
(3/3): rhel-7-server-rpms/7.4/x86_64/primary_db                                                                                                      |  48 MB  00:01:13
インストール済みパッケージ
systemd.x86_64                                                              219-30.el7                                                                    @anaconda/7.3
利用可能なパッケージ
systemd.x86_64                                                              219-42.el7_4.10                                                               rhel-7-server-rpms
```
以下のように `/etc/yum/vars/releasever` ファイルを使用することも可能。

```shell-session
$ echo 7.4 > /etc/yum/vars/releasever
$ yum list systemd
読み込んだプラグイン:product-id, search-disabled-repos, subscription-manager
インストール済みパッケージ
systemd.x86_64                                                              219-30.el7                                                                    @anaconda/7.3
利用可能なパッケージ
systemd.x86_64                                                              219-42.el7_4.10                                                               rhel-7-server-rpms
```
next の引数指定で saga の call の戻り値を差し替えてテストを進める

redux-saga で、`yield call` の戻り値の処理をしたあと、次の yield 式を呼び出すときのテストコードについて検討しました。単純化したコードはこうです。API呼び出しのアクションを実行したあと、_SUCCESS アクションを実行するパターンです。

```js
export function* targetSaga() {
  const response = yield call(callApi)
  const foo = response.foo
  yield put(barActionCreator(foo))
}
```

ここで `yield put` のテストを開始するにはどうすればよいでしょうか。

[引数つきでnext() を呼ぶとジェネレーター関数の実行が再開され、処理が停止していた yield 式を next() の引数で置き換えます](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/function*)。挙動を確認しましょう。

```
% node
> function* generator() {
...   const one = yield '1'
...   console.log('one', one)
...   const two = yield '2'
...   console.log('two', two)
...   const three = yield '3'
...   console.log('three', 'three')
... }
undefined
>
> gen = generator()
{}
>
> gen.next('aaa')
{ value: '1', done: false }
> gen.next('bbb')
one bbb
{ value: '2', done: false }
```

`gen.next('aaa')` では、「処理が停止していた yield 式」がまだないので、'aaa' はどこにも反映されません。
`gen.next('bbb')` では、「処理が停止していた yield 式」は `const one = yield '1'` です。この yield 式である `yield '1'` が 'bbb' に置き換わります。つまり、`const one = 'bbb'` となります。その結果次の `console.log('one', one)` が `one bbb` を出力しています。


この機能は次のようにテストコードで利用できます。


```js
import { put, call } from 'redux-saga/effects'
import { cloneableGenerator } from 'redux-saga/utils'

const barAction = barActionCreator()
const generator = cloneableGenerator(targetSaga)(barAction)
const clone = generator.clone() // ここまでは準備

expect(clone.next().value).toEqual(call(callApi, { editingId }))
const foo = {
  // something
}
expect(clone.next(foo).value).toEqual(put(barActionCreator(...
```

「処理が停止していた」 `yield call` の戻り値を next の引数で差し替えたうえで、次の yield 式である、`yield put(barActionCreator...` が実行されます。

## リファレンス

- https://github.com/redux-saga/redux-saga/blob/master/examples/shopping-cart/test/sagas.js
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/function*
json ファイルで diff したい

# 結論
[benjamine/jsondiffpatch](https://github.com/benjamine/jsondiffpatch) が良い感じ。

# インストール例
```bash
$ npm install -g jsondiffpatch
/usr/local/bin/jsondiffpatch -> /usr/local/lib/node_modules/jsondiffpatch/bin/jsondiffpatch
+ jsondiffpatch@0.3.11
```

# 使用例
Lambda 関数の設定を取得してバージョン差分を確認する

```bash
$ aws lambda get-function-configuration --function-name sampleFunction --qualifier 1 > lambda-function-1-config.json
$ aws lambda get-function-configuration --function-name sampleFunction --qualifier 3 > lambda-function-3-config.json
$ jsondiffpatch lambda-function-1-config.json lambda-function-3-config.json 
{
  CodeSha256: "0EjYPyo5GvxKVGZpHcoAGGWxV5EgvOj9+fVhazy3Clg=" => "6MX2C98sWJBLs0qIWY7z+vVJw8l9bLHw99s9G3F471s="
  CodeSize: 300 => 302
  Description: "test" => "fuga"
  FunctionArn: 
    55,9 entDump:13
  
  LastModified: "2018-09-27T08:54:08.055+0000" => "2018-09-27T12:49:39.694+0000"
  MemorySize: 128 => 1088
  RevisionId: "bc777ab7-4b83-4041-977d-50894fd25c19" => "d02f5bc6-83ef-451f-ae27-4bf57ab109f4"
  Timeout: 3 => 15
  Version: "1" => "3"
  VpcConfig: {
    "SubnetIds": [],
    "VpcId": "",
    "SecurityGroupIds": []
  }
}
```

MemorySize とか Timeout が増えてることがサクッと判別できて便利。
[Demo ページ](https://benjamine.github.io/jsondiffpatch/demo/index.html)を使えばブラウザに json コピペして見ることも可能。

# リンク
- [jsondiffpatch - npm](https://www.npmjs.com/package/jsondiffpatch)
- [benjamine/jsondiffpatch: Diff & patch JavaScript objects](https://github.com/benjamine/jsondiffpatch)
- [JsonDiffPatch](https://benjamine.github.io/jsondiffpatch/demo/index.html)
とっても便利なPythonの辞書型について覚え書き

# はじめに
Pythonの辞書型はとっても便利なのですが、時折使い方をど忘れするので自分の備忘録のための書き残します。

##  辞書型？
keyとvalueが組み合わせになったデータの型です。
keyを使ってvalueを呼び出せるので、情報のヒモ付けと言う点でとっても便利。

```python:辞書型の基本的な形
dic = {key1 : value1, key2 : value2}
```

# 使い方
## 新規の辞書作成
```python:そのまま書き込む場合
dic = {"A" : 1, "B" : 2}
print(dic)
# 出力
# {"A" : 1, "B" : 2}
```
```python:空の辞書に書き込んでいく場合
dic = {}
dic["key"] = "value"
print(dic)
# 出力
# {"key" : "value"}
```
```python:valueにはリストも取れます
dic = {}
dic["key"] = ["value1", "value2"]
print(dic)
# 出力
# {"key" : ["value1", "value2"]}
```

## 要素を取り出す
```python:既存の辞書のkeyに対応するvalueを取り出す
dic = {"A": "cat", "B": "dog"}
print(dic["B"])
# 出力
# "dog"
```
```python:既存の辞書のkeyのリストを取り出す
dic = {"A": "cat", "B": "dog"}
print(dic.keys())
# 出力
# ["A", "B"]
```
```python:既存の辞書のvalueのリストを取り出す
dic = {"A": "cat", "B": "dog"}
print(dic.values())
# 出力
# ["cat", "dog"]
```

## 要素を変更する
```python:既存の辞書のvalueを変更
dic = {"A" : "cat"}
dic["A"] = "dog"
print(dic)
# 出力
# {"A": "dog"}
# keyに対してvalueの書き換えはできますが、その逆はできないので注意
```
```python:既存の辞書の要素を削除する
dic = {"A": "cat", "B": "dog"}
dic.pop("A")
print(dic)
# 出力
# {"B": "dog"}
```

## 辞書に存在しないkeyを入れる
```python:存在しないkeyを参照しようとすると
dic = {"A": "cat", "B": "dog"}
print(dic["C"])
# エラーが出る
# KeyError: 'C'
```
```python:setdefault()を使うと
dic = {"A": "cat", "B": "dog"}
print(dic.setdefault("C", "hoge"))
# 出力
# "hoge"
# 第一引数に参照したいkeyを入れる
# keyがなかった場合、第二引数の値を返す

# setdefault()で追加された要素は、元の辞書に反映される
print(dic)
# 出力
# {'A': 'cat', 'C': 'hoge', 'B': 'dog'}
```
```python:リストと組み合わせたりもできる
lst = ["A", "B", "C", "D", "E"]
dic = {}
n = 1
for i in lst:
    # nが奇数が偶数かでkeyを振り分ける
    # setdefault()の第二引数は空リスト=[]にしておく
    if n % 2 == 1:
        dic.setdefault(1, []).append(i)
    else:
        dic.setdefault(2, []).append(i)
    n = n + 1
print(dic)
# 出力
# {1: ['A', 'C', 'E'], 2: ['B', 'D']}
```
Wlinuxでbuild-essentialをインストールしたい

# 追伸(2018-09-28)

2018-09-28の アプデ (Version 1.1.17) で、WLinux インストール時に build-essential がプリインストールされるようになりました。
なのでこの記事は読む必要ありません。

# 動機

最初からgccとか入っていないので環境を入れるべくbuild-essentialを入れようと思いました。
しかし普通にやっても入らなくて困ってたら公式回答を頂いたので載せておきます。

# 試した環境

- Windows10 Home (Build 1803)
- WLinux 1.1.16



# 失敗するパターン

普通にコマンドを打つ

```shell-sessionon
$ sudo apt update
$ sudo apt install build-essential
```

するとエラーが出る

```
Reading package lists... Done
Building dependency tree
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:
The following packages have unmet dependencies:
build-essential : Depends: libc6-dev but it is not going to be installed or libc-dev
Depends: g++ (>= 4:6.3) but it is not going to be installed
E: Unable to correct problems, you have held broken packages. 
```

# とりあえず入れる方法

```
$ sudo apt update
$ sudo apt -t testing install build-essential -y
```

# 補足

偉大なる公式アカウントより教えていただきました。

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="en" dir="ltr">$ sudo apt -t testing install build-essential -y<br><br>Fix coming in 1.1.17.</p>&mdash; WLinux (@WLinuxApp) <a href="https://twitter.com/WLinuxApp/status/1045286600362663936?ref_src=twsrc%5Etfw">September 27, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

9/28 予定のアプデで WLinux 1.1.17 でこのapt関連の修正を行うようです。
(ROADMAPには書かれていませんが…)
https://github.com/WhitewaterFoundry/WLinux/blob/master/ROADMAP.md#release-1117---master-branch
Texture（旧AsyncDisplayKit）の仕組みを理解する

[Texture](https://github.com/TextureGroup/Texture)は60fpsを実現するiOS用の高速非同期UIフレームワークです。Pinterestが開発しており、Pinterestアプリでも使用されています。以前はAsyncDisplayKitという名前でFacebookが開発していました。

「Async」という以前の名称からも分かるように、Textureは「非同期」であるというのが大きな特徴です。iOSのUIKitはすべてメインスレッドで操作する必要があり、それがパフォーマンスのボトルネックになる場合があります。例えばTableViewのCellを表示する場合、UIKitではひとつのスレッドがCellを上から順番に描画しています。Textureでは複数のスレッドが複数のCellを同時に描画するため、パフォーマンスが格段に上がります。

# Textureの仕組み

Textureは内部的にUIKitのコンポーネントを利用しています。例えばボタンである`ASButtonNode`は内部的に`UIView`を使っています。またテーブルビューである`ASTableNode`は内部で`UITableView`を利用しています。それではTextureはどのように非同期でUIを作り上げているのでしょうか。

その答えは`CALayer`です。具体的に言うと、`CALayer.contents`にオフスクリーン画像（`UIGraphicsBeginImageContextWithOptions`で作成する`UIImage`）を入れることで非同期を実現しています。iOSではテキストの幅や高さを取得したり、テキストや画像を描画したりするコードはメインスレッド以外でも動作します。Textureはこれを利用して、例えばテーブルビューのセルを描画する際に、セルと同じサイズのオフスクリーン画像を作り、そこにセルのコンテンツを描き込む処理を別スレッドで行なっています。そして出来上がった画像を`CALayer.contents`にセットするところだけをメインスレッドで実行することにより、メインスレッドの負荷を最小限に抑え、60fpsを実現しています。

# UIが表示されるまでの流れ

`ASTableNode`を例にして、Textureがどのように動いているのかを見てみます。`ASTableNode`を作成してサブノード（Textureのビュー階層）に追加すると、内部的に`UITableView`が作成され、画面に追加されます。そして`UITableView`のDataSourceである`tableView(_:cellForRowAt:)`が呼ばれたタイミングで、`UITableViewCell`が作成されます。

`ASTableNode`はPreloadingに対応しており、`UITableViewCell`が作成される以前からデータが準備されます。この時、`ASTableNode`のDataSourceである`tableNode(_:nodeBlockForRowAt:)`が呼ばれます。`ASTableDataSource`ではセルを返すのではなく、セルを描画する`ASCellNode`クラスを返します。

`ASCellNode`は内部的に`UIView`を保持しており、非同期でUIを表示します。例えば`ASTextCellNode`はTextKitを利用して`UIImage`にテキストを描画し、それを`CALayer.contents`にセットします。このビューが`UITableViewCell`に追加されて`UITableView`にコンテンツが表示されます。

Textureの他のUIコンポーネントも内部でUIKitのビューを持ち、`UIImage`に描画して`CALayer.contents`に入れるような仕組みでUIを表示しています。

# Textureのデメリット

このようにいいことずくめに見えるTextureですが、デメリットもあります。それはメモリとバッテリーを多く消費するということです。UIKitと比べて、画像を作成して描画する分だけメモリとバッテリーを消費します。そして`ASTableNode`やコレクションビューの`ASCollectionNode`の場合は、セルが画面に表示されるタイミングで毎回画像の作成と描画が発生するため、その影響は小さくないと考えます。

またTextureの導入には大きなコードの変更が必要となります。UIKitのViewはTextureの`Node`に、そしてViewControllerは`ASViewController`に置き換える必要があります。またTextureではAuto Layoutも使えないため、レイアウトコードも書き直す必要があります。

Textureの導入はアプリ毎に様々な側面から判断すべきです。
IoT Python USB Relay その1

### 1000円ぐらいで買えるUSB RelayをPythonでプログラムする。
#### リレーとは、電気的にOn Offできる装置です。Pythonからコマンドを送ると100V AC電源をOn または、Offできます。
### つまり音声入力と組み合せば「電気をつけろ」といえば電気をつけます。
![cap1.JPG](https://qiita-image-store.s3.amazonaws.com/0/274715/fb50c2bf-829d-975f-4f37-cd5f24de0d27.jpeg)
#### 品名　1 x LCUS-1 5V USB Relay Module CH340 USB Intelligent Control Switch Relay Module for Smart Home (12488) = $6.28
+ トラッキング付きの送料込みで1000円でおつりくるぐらいかなぁ。
+ ![tracking.PNG](https://qiita-image-store.s3.amazonaws.com/0/274715/65ee03e3-9ed1-f5ab-f03f-443b76413c44.png)

https://www.amazon.com/LCUS-1-Module-Intelligent-Control-Switch/dp/B077ZMJZBS

+ 別にこれでなくても「CH340」チップの名前だからキーワードに検索してください。

### USBに差し込むと
![cap1000.PNG](https://qiita-image-store.s3.amazonaws.com/0/274715/f4a17749-aed5-047b-4d91-1b1728eadb8f.png)

### Windows 10　の場合、 自動的ドライバーがインストールされCOM4に接続されていることがわかる
### 準備 

```
>pip install serial
```
### コマンドモードで実験

```
>python
Python 3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 10:22:32) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import serial
>>> on =bytearray(b"\xA0\x01\x01\xA2")
>>> off=bytearray(b"\xA0\x01\x00\xA1")
>>> ser = serial.Serial('COM4', 9600,timeout=0)
>>> ser.write(on)
4
>>> ser.write(off)
4
>>> ser.close()
>>>
```

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">relay <a href="https://t.co/a5KgeDfMXH">pic.twitter.com/a5KgeDfMXH</a></p>&mdash; 平田　裕 (@hiratayutaka) <a href="https://twitter.com/hiratayutaka/status/1045178923892404224?ref_src=twsrc%5Etfw">2018年9月27日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# つづく
Redis導入したら、やらかしてしまった話

## はじめに
最近インフラ周りを触り始めたエンジニアです。
日々予想外の出来事に悩みながら、一つ一つ勉強しています。
今回はElastiCacheを導入しようとしたときに、うっかりやってしまったミスを紹介します。

## ElastiCacheの設定
ドキュメントやブログを参考にして以下のような構成で用意しました。
- キャッシュエンジン：Redis
- 1シャード3ノードの構成

※シャードとノードについては[こちら] (https://nyamadori.hatenablog.com/entry/2017/09/12/103523)がわかりやすかったです。

よし(๑•̀ㅂ•́)و✧
そしてサーバの方でエンドポイントを設定します。
AWSのコンソールからクラスターを選択してエンドポイントを把握！そのままエンドポイントを設定しました...

## 何が起きたのか
1シャード3ノードの場合、以下のようになります。
Primary Node ✕ 1 = 読み書き可能
Replica Node ✕ 2 = 読み込みのみ可能
エンドポイントの設定でクラスターのエンドポイントを設定したために、キャッシュを書き込む際に**Replica Nodeにも**書き込みを行ってしまってました...そりゃエラーになるわけだぜベイベー...orz

## どうすべきだったのか
現状はReplica Nodeを削除してPrimary Nodeのみで運用してます。
これ正直ベストはわかってないのですが、
書き込み時はPrimary Nodeのエンドポイントを指定
読み込み時はReplica Nodeのエンドポイントを指定
するのがよいのかなーと検討してます。
どなたかベスト・プラクティスを知ってる方いたらご教授いただきたいです...!

## 最後に
やっぱインフラは触ってみないとわからないこと多いですね。
挫けず日々精進したいと思います。
【JavaScript】0011は3じゃない！？2進数、8進数、16進数を表現する数値リテラルについて(知らない人向け)


JavaScriptで２進数を入力できるか調べるためにchromeのコンソールを立ち上げて`0011`と入力したときに、自分が予想してた値は`3`でしたが出力された値は`9`でした。

ここで`9`が出力されることを普通に知っていた方は本記事は対象外となっております。。

```javascript
> 0011
< 9 //予想では3
```
他にも`0010`や`0100`を入力してみてどうやらJavaScriptでは数字の頭に0をつけると入力した数値を8進数として解析し、10進数として出力される仕様があるのだろうという予想ができました。

```javascript
> 0010
< 8 
```
```javascript
> 0100
< 64
```

ではなぜ頭に0をつけると８進数として解析されるのか？
結局２進数としては解析できないのだろうか？
という疑問を抱き[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Grammar_and_types#Numeric_literals)に飛んで調べて見ました。
以下調べた概要をまとめます。

# 数値リテラル（Numeric Literal）
## 概要
- JavaScriptの整数は10進数、2進数、8進数、16進数で表現することができます。
- 2進数は`0b`,`0B`から始まり 後に続く`0`と`1`で構成されます。
- 8進数は`0o`,`0O`または`0`から始まり、後に続く`0`から`7`の数値で構成されます。　
- 16進数は`0x`,`0X`から始まり、後に続く数字 (`0`から`9`) と `a` から `f` および `A` から `F` のアルファベットで構成されます。 

## 10進数(Decimal)
- 先頭が0 (ゼロ) ではない一連の数字で構成されます。
- 先頭のゼロに続く数字が8以上の時、10進数として解析されます。  
※この先頭が０の時の挙動に関しては[こちら](https://bugzilla.mozilla.org/show_bug.cgi?id=957513)に詳細が載っているっぽいです。

```javascript
> 12345678 
< 12345678 //通常の10進数

> 0888    
< 888 //10進数として解析され888として出力されます

> 0777   
< 511 //８進数として解析され10進数の511が出力されます。
```


## 2進数(Binary：`0b`,`0B`から始まる)
- 先頭ゼロに続いて、小文字または大文字のラテン文字`B` (`0b` または `0B`)を使用します。
- この仕様はECMAScript2015から新しくサポートされている仕様です。
- `0b`後の数字が`0`または`1`でない場合`SyntaxError`がスローされます。

```javascript
> 0b00010101 //bが小文字
< 21

> 0B00011011 //bが大文字
< 27

> 0b00000002 //0bのあとに0,1以外の数値
< Uncaught SyntaxError: Invalid or unexpected token //例外をスロー
```

## 8進数(Octal:`0o`,`0O`から始まる)
- 先頭ゼロに続いて、小文字または大文字のラテン文字'O' (`0o` または `0O`)を使用します。
- 先頭ゼロに続く数値が0から7の場合も8進数として解析されます。
- この仕様はECMAScript2015から新しくサポートされている仕様です。
- `0o`後の数字が範囲外(`01234567`) の場合`SyntaxError`がスローされます。

```javascript
> 0o644 //oが小文字
< 420

> 0O755 //oが大文字
< 493

> 0o1238 //0oの後に01234567以外の数値
< Uncaught SyntaxError: Invalid or unexpected token //例外をスロー
```

## 16進数(Hexadecimal:`0x`,`0X`から始まる)
- 先頭ゼロに続いて、小文字または大文字のラテン文字`X` (`0x` または `0X`)を使用します。
- `0x`の後の数字が範囲外(`0123456789ABCDEF(abcdef)`)の場合`SyntaxError`がスローされます。

```javascript
> 0xFFFFFFFFFFFFFFFFF
< 295147905179352830000 //xが小文字

> 0X123456789ABCDEF
< 81985529216486900 //xが大文字

> 0XA
< 10

> 0xG1234
< Uncaught SyntaxError: Invalid or unexpected token //例外をスロー
```

# 参考

- [MDN:文法とデータ型->数値リテラル](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Grammar_and_types#Numeric_literals#Numeric_literals)
- [MDN:字句文法->Numeric リテラル](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Lexical_grammar#Numeric_literals)

# 最後に
JavaScriptではまだまだ知っている仕様よりも知らない仕様の方が多いと思いますが、こういう勘違いがきっかけでも正しい仕様を少しずつ覚えていければと。
yaml でテストが書ける Tavernというテストツールがすごい

## Tavern
[Tavern](https://taverntesting.github.io/)はRESTfulなAPIのテストコードを `yaml` で書けるテストツールです。これを使えば毎回似たようなテストコードを書く必要が無くなりますし、気軽にテストコードの修正が可能になります。既に沢山のAPIを持っていてテストコード書くのツライって言う人はぜひ使ってみてください。

## できること例
下記のようなテストを全て `yaml` で書けます

- hoge.com/api/ に POST でリクエストしステータスコードやBodyのチェック
    - もちろんエラーパターンも書けます
- login API などにアクセスし token 取得、以降はその tokenを用いてリクエストを投げる
- JWT認証にも対応

## インストール

```
$ pip install tavern[pytest]
```

## test コードをyamlで定義

命名規則は `test_*.tavern.yaml` です。

```test_minimal.tavern.yaml
test_name: Get some fake data from the JSON placeholder API

stages:
  - name: Make sure we have the right ID
    request:
      url: https://jsonplaceholder.typicode.com/posts/1
      method: GET

    response:
      status_code: 200
      body:
        id: 1
```

このyamlをカスタマイズすれば色んなパターンのテストを作成できます :smiley: 

## 実行と結果

`py.test test_minimal.tavern.yaml  -v` で実行

```
platform darwin -- Python 2.7.14, pytest-3.8.0, py-1.6.0, pluggy-0.7.1 -- /Users/kyohei/.pyenv/versions/2.7.14/envs/hogehoge/bin/python2.7
cachedir: .pytest_cache
rootdir: /User/tmp/hello_world, inifile:
plugins: tavern-0.18.1
collected 1 item

test_minimal.tavern.yaml::Get some fake data from the JSON placeholder API PASSED                                                                                   [100%]
```

うまくテストすることが出来ました！なかなか良い。

pytestベースで実行しましたが Tavern のcliでもテストできます。

`tavern-ci --stdout test_minimal.tavern.yaml`

## ログイン認証有りのAPIの叩く
1. ログイン -> token取得
2. tokenを利用しuser情報を取得

```test.yaml
test_name: login testing

stages:
  - name: login
    request:
      url: https://hogehoge.com/login
      json:
        id: hogehoge
        password: password
      method: POST
      headers:
        content-type: application/json
    response:
      headers:
        content-type: application/json
      status_code: 200
      body:
        status: 200
        expireStr: !anything
        userId: !anything
        token: !anything
        expire: !anything
        message: success
      save:
        body:
          test_user_id: userId
          test_login_token: token

  - name: Get a user info
    request:
      url: https://hogehoge.com/user/{test_user_id}
      method: GET
      headers:
        content-type: application/json
        Authorization: "Bearer {test_login_token}"
    response:
      status_code: 200
      headers:
        content-type: application/json
      body:
        result:
          userId: "{test_user_id}"
```

## 備考
- 依存ライブラリなどは最新にしておくこと
    -  `sudo pip3 install --upgrade requests`
-  どんな値が来るか分からないレスに対しては `!anything` を使う
-  tokenなどの保存は `save: test_token:token` で可能、保存した値は `{test_token}` で取得する
-  External functionsと呼ばれるテスト用の関数を呼び出せる
    -  これを使えばJWT認証を試せる
    -  関数一覧はここhttps://github.com/taverntesting/tavern/blob/68fae4d97b231476dfaef3f71e353e20899ef24e/tavern/testutils/helpers.py
ESP8266を使ったラズパイの電源制御（概要編）

# 背景

電源のないところでラズパイを制御させたい
しかし、ラズパイの消費電力は半端なく大きく、
１週間モバイルバッテリーを使って駆動させることは無理
しかし、畑の真ん中で稼働させたい、
カメラや3Gの制御はArduinoよりもラズパイのほうが楽！
色々考えた結果がこちらである。


# 何ができるのか

畑の真ん中の電源がないところで、定期的に畑の様子を撮影し、
3G回線でインターネットへ送信できるようになった。
畑の様子を見たいけど、近くじゃないから頻繁には行けない、
そんな用途にピッタリでした。
撮影以外にも、距離計をつければ水位の監視が可能かも。
これで、台風とかで畑が心配になっても、安心して様子を確認できますね。

# 外観

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89176/53fffe47-0c4a-df5e-0bda-888fb0af6851.png)


# どれくらい持つのか

１時間に１度の撮影を繰り返し、
10000mAhのモバイルバッテリーで1週間もちました。
これで、畑に行くのは1週間に１度で済むようになります。


# 仕組み

ラズパイをずっと起動させてしまうと、
すぐにバッテリーの残容量がなくなってしまうので、
必要なときだけ起動させることにします。

ラズパイで撮影＆送信が完了したら、シャットダウンさせます。
しかし、ラズパイはシャットダウンした後も、結構電池を消費するので、
電源を断つ必要があります。
また、ラズパイは１度シャットダウンさせてしまうと、
自分で起動することができません。

そこで、電源制御するマイコンが必要になります。

今回はESP8266を使用しました。
ESP8266には技適が通っているWi-Fiが搭載されていますが使用しません。
代わりに、Deep-Sleepという機能を使用します。
Deep-Sleepを使用すると電流は20nAまで抑えられ、節電効果が抜群です。
また、一定時間が経つと、自分で起動することもできます。

ESP8266で電源制御をするために、OUTPUT先にはスイッチ回路を設けました。
そのスイッチ回路で、ラズパイに供給する電源をON/OFFします。

ラズパイがシャットダウンした後に電源供給をOFFにするためには、
ラズパイからESP8266向けに信号線を設けました。

以上の流れを整理すると以下です。

1. ESP8266がDeep-Sleepから目覚める
1. ESP8266経由でスイッチ回路をONにする
1. スイッチ回路経由でラズパイへの電源供給が開始する
1. ラズパイが起動する
1. ラズパイのカメラで撮影する
1. ラズパイの3Gモデムでインターネットへ画像を送信する
1. ラズパイからESP8266に信号を伝える
1. ESP8266が検知するとラズパイがシャットダウンする相当時間を待つ
1. ラズパイがシャットダウンする
1. ESP8266経由でスイッチ回路をOFFにする
1. スイッチ回路経由でラズパイへの電源供給が停止する
1. ESP8266がDeep-Sleepになる
1. ESP8266が暫く待つ
1. (最初に戻る)


# 回路図
![image.png](https://qiita-image-store.s3.amazonaws.com/0/89176/5aa8d40a-a467-30ae-8051-45b3a6e012d1.png)


# 部品

- Raspberry Pi 3 Model B
- ESP8266 (ESP-WROOM-02)
- リレー＆ダイオード
- プルアップ/プルダウン用の抵抗
- 3.3V ３端子レギュレーター
- 10000mAh モバイルバッテリー


# 詳細編
構成の詳細は２回目に掲載します。


# 参考

【ESP8266】長時間deepsleepするとモバイルバッテリーがOFFになっちゃう件をどうにかする
https://qiita.com/rukihena/items/59a355926cb116e6d572
Node　生粋のメモ

JSON.parse()　　　　JSONをJavascriptの値やオブジェクトに変換する。 
JSON.stringify()　　　 javascriptの値をJSONに変換する。（オブジェクトで渡す必要がある）

fs.writeFile()　　ファイルに書き出す事ができる（非同期的に）
fs.writeFileSync()　ファイルに書き出す事ができる（同期的に）

fs.readFile()     ファイルを読み込む事ができる（非同期的に）
fs.readFileSync()　　ファイルを読み込む事ができる（同期的に）


デバッグする時のやつ
node inspect ファイル名にするとデバッグを開始できる。
debug>　こんな感じで待ってくるから
cを打つと実行して進むコード内にdebuggerと打ち込んでおくと
そこで止まってくれる。
list(n)を打ち込むと打ち込んだ数字分だけ上下に表示してくれる。
runをするとプログラムが走る。restartでまた最初から走る。
oを押すと関数の終わりで止まる他にも色々ある。

replというコマンドもあった REPL(Read-eval-print loopの略)らしい。
これは対話型なんちゃらこうちゃらでこちらが打ち込むと向こうも答えを返してくる。
なんか。PCと話せてイイね。

それと --inspect-brk　を使うとスクリプトの１行目からデバッグが始まるのでとても便利ですよ。
nodemon --inspect-brk ファイル名　処理　みたいな感じで使う。

chrome://inspect　このURLに飛べばchromeのデバッグツールを使用する事ができてとても便利。
chrome://version chromeのversionを見れるよ。

yargsの.commandについて。
これマジですごい。

書くのめんどくさいから引用

const titleOptions ={
    describe:'Title of note',
    demand: true,
    alias: 't'
};

const argv = yargs
.command('add','Add a new note',{
    title:titleOptions,
    body:{
        describe:'Body of note',
        demand: true,
        alias: 'b'
    }
})
.command('list','List all notes')
.command('read','Read a note',{
    title:titleOptions
})
.command('remove','Remove a note',{
    title:titleOptions
})
.help()
.argv;

これでコマンドを打ち込むときに必要な値とか注意事項とかを表示させる事ができる。めちゃくちゃすごい。
なぜか日本語対応でコンソールに日本語が出てきて感動した。

今日はこれで終わり
Oculus 常にカメラに中央に表示されるタイトル画面の作成

Unity初心者のメモ

私がOculus Goで動くコンテンツを作成していて、「常にカメラに中央に表示されるタイトル画面を作成したい」と思ったときに実践した方法です。

# 環境
unity: Unity 2018.1.9f1
使用するasset: [Oculus Integration](https://assetstore.unity.com/packages/tools/integration/oculus-integration-82022)

# 方法
OculusGoのヘッドセットに追従するタイトル画面を作る方法を説明します。

## 1. シーンにOculusGo用のカメラを用意する
Oculus Goを使用する場合、デフォルトで存在するmain cameraでは目線が追従しません。そこで、Oculus用のカメラを用意します。
asset storeより、[Oculus Integration](https://assetstore.unity.com/packages/tools/integration/oculus-integration-82022)をダウンロードしてインポートします。(もちろん無料です！)

## 2. OVRCameraRigを用意する
Oculus Integrationをインポートすると、Assetsフォルダ内に、Oculusというフォルダが生成されます。その中にある、VR > Prefabs内に、OVRCameraRigが存在するので、ドラッグ＆ドロップでヒエラルキーに持っていきます。
![qiita_oculus_go_1.PNG](https://qiita-image-store.s3.amazonaws.com/0/203706/f7a83672-f4eb-96bc-5978-4270b228e3fe.png)
![qiita_oculus_go_2.PNG](https://qiita-image-store.s3.amazonaws.com/0/203706/3c46485b-64c7-550b-0ec1-20708580f777.png)
あとはデフォルトで存在したMainCameraを無効化します。
これで実行すると、ヘッドセットにカメラが追従してくれます。

## 3. Canvasを用意する
次にタイトル画面となるCanvasを用意します。Canvasは文字通り「画用紙」のようなもので、こちらに文字や画像を配置してタイトル画面を作成していきます。
ヒエラルキービュー上で右クリックし、UI > Canvas を選択します。
![qiita_oculus_go_3.PNG](https://qiita-image-store.s3.amazonaws.com/0/203706/94ead9c6-4744-db53-3273-0211a2901d25.png)

その後作成したCanvasをOVRCameraRig内の直下に配置します。
![qiita_oculus_go_4.PNG](https://qiita-image-store.s3.amazonaws.com/0/203706/148f9053-24e1-d432-6a4c-0b2511408b56.png)

## 4. Canvasの設定を変更する
CanvasをOVRCameraRigの配下に置いただけではカメラに追従しません。Canvasの設定を変更してあげる必要があります。
先ほど作成したCanvasのInspectorを確認し、Canvasコンポーネント内のRender Cameraフォームの値を変更します。フォームの右にある○を選択すると候補が表示されたウィンドウが表示されます。その中にある CenterEyeAnchor(Camera)を選択します。
![qiita_oculus_go_5.PNG](https://qiita-image-store.s3.amazonaws.com/0/203706/3ad503db-6a0f-41ac-7671-345796ac085e.png)

## 5. Canvas配下にTextやImageを配置する
ここまでできたら、表示したい文字や画像をCanvas内に配置するだけです。ヒエラルキービューで右クリックして、UI > Textにあるように、表示したいオブジェクトを選択し、Canvas直下に配置します。あとはそれぞれサイズ、色、位置等を調整すれば出来上がりです！

# 完成
私が作ったタイトル画面です。UnityEditor上の画像なので追従している感が全く分からないですが、ヘッドセットを被ると、ここに表示されているタイトル画面が常に画面中央に表示されます。
![qiita_oculus_go_6.PNG](https://qiita-image-store.s3.amazonaws.com/0/203706/544a3bd2-e590-8706-9b9f-3b8eec4de494.png)
JavaScript で関数型プログラミングをするの？

脳みそダンプ

# #01. 不変性
JavaScriptでは ある程度不変性を意識して書ける。具体的には Array や String の `slice`, `concat`, `map`, `filter`、 `...`(スプレッドシンタクス)、`Object.assign`、あと`JSON.stringify` & `JSON.parse`（筋悪？）。ただ、どうしても冗長な書き方になるうえ、うっかりするとすぐにシャロ―コピーになってしまう。**JavaScript で不変性を志向した書き方をするのは難しい**といわざるを得ない。

解決策の方向性は二つある。生のArray, Objectのまま頑張る **Ramda.js 方式**と、類似の新たなデータ構造で頑張る **Immutable.js 方式**。Ramda 方式では、ライブラリとして、Array, Object に対する**ディープコピー**機能を提供するだけでなく、**レンズ**機能を提供する。Ramda 方式のメリットは、特別なクラスやデータ構造を導入しないでよいという点だろう。一方、Immutable.js 方式は、新たなデータ構造に変換するという手間がある反面、**効率の良いオブジェクトの生成（structural sharing）**が可能だったり、各種メソッドが不変オブジェクトを返すので扱いやすい。

総論でいえば、Immutable.js 方式の方がよい（反論はうけつける）。Ramdaは不変性を保つための手段の選択肢を増やしただけで、前述の危険性を減らすことには貢献しないため。（一人で書くなら Ramda でもよいが、、、あの柔軟性と機能性は魅力）。何より Immutable は特別な使い勝手ではないので、数日も使えば手にすぐ馴染む。

# #02. 遅延と無限
JavaScript には、ジェネレータやイテレータプロトコル、オブザーバブルや、関数スコープを持ったクロージャがある。これらを使うことで、**必要に迫られるまで処理をしない**ことは可能だ。しかし、ただ可能というだけで、それが使いやすいかというのは別問題であり、実際なかなか厳しい。

解決策はいくつかあって、Immutable の `Seq`、Lodash の `chain`、RxJSの `Observable`、 Ramda の `transduce` などがあげられる。多くの場合これらで間に合うことが多いが、少し要件が複雑になった場合に対応しきれるかといわれると、よどみなくYesと答える自信はない


# #03. 再帰
言うまでもないが、JavaScript では末尾再帰の最適化が（現時点では）できない（としたほうが安全）ので、再帰を多用できない。最悪、トランポリンなどで何とかするしかない。

# #04. ADT
`Maybe`, `Either`, `IO`, `State` などのモナドの実装がすぐに手に入る(Monet.js, Folktale, crocks,  ...)うえ、それらの相互運用性を定めた仕様（Fantasy-Land)がある。これにより、自作のモナドも簡単につくれるし、Ramda が提供する `lift`, `sequence` 関数と相互運用することが可能になる。関数型プログラミングの醍醐味は、JavaScript でも十分感じられる。一般の JSer に読めない黒魔術となること請け合いであるが・・・

# #05. 関数合成・ポイントフリー
JavaScript では関数は第一級オブジェクトなので、高階関数・コンビネータは可能。lodash, Ramda, crocks のいづれかのライブラリを入れておけばすぐに使え、関数合成によるソフトウェアの組み立てができる。JavaScript のアローによる匿名関数の簡略な記法も一役買っている。

# さいごに
JavaScript で関数型にプログラミングをする際のあれこれをダンプした。**意見・感想・議論は非常にウェルカムです**
Molecule で ansible の config を設定する


----

ansible の role を作っている際に、`ansible.cfg` を置かずにデフォルトのままだと、become(sudo) をしてくれなかったり、失敗した時に playbook.retry を作成してくれます。
しかし、毎回実行時引数で設定するのは面倒なので、以下のように`ansible.cfg` で設定するのはよくやると思います。

```ini:ansible.cfg
[defaults]
retry_files_enabled = False

[privilege_escalation]
become              = True
```
これを、Molecule[^1] で実行する ansible でも適用したいときにどうすればいいでしょうか。

# 前提条件
- molecule の driver を vagrant にしている
    - おそらく vagrant 以外は発生しない


# だめだった例
`molecule.yml` で provisioner の env として ANSIBLE_CONFIG を与える方法

```yaml:
provisioner:
  name: ansible
  env:
    ANSIBLE_CONFIG: PATH/TO/ansible.cfg
```
一見良さそうですが、provisioner を vagrant にした時(network 設定を変えるテストをしたいときとか)に失敗しました。

molecule はテスト用の vagrant も  ansible 経由で立ち上げますが、その際にも上記の `ansible.cfg` が適用されてしまい、実行環境で sudo をしようとして、molecule の実行ユーザに sudo の権限がないと provision が失敗します。

# 正解

```yaml:
provisioner:
  name: ansible
  options:
    become: True
  config_options:
    defaults:
      retry_files_enabled: False
```

`provisioner` に `option` や `config_options` で指定してあげると、vagrant で上げる時は適用されずに、provision 時にのみ効くようになります。

ちなみに、`config_options` で全部設定できるのでは?と思いましたが、キーとしては `defaults` か `privilege_escalation` だけのようです。[^2]




[^1]: Molecule についてはこちら: https://qiita.com/ysknkd/items/c738bb01f355dc378e94

[^2]: https://github.com/metacloud/molecule/blob/6fabd378ed5cd8d9ec1803df2a777afd95e41037/molecule/model/schema_v2.py#L273-L296
Apple Music APIで作成したプレイリストはシェア用のURLが取得できない

Apple Musicの仕様に関してメモ。
Apple Music API経由でプレイリストのIDを取得すると```p.xxxxxxx```といった形式で出るのだが、シェア用のIDはこれと異なり```pl.xxxxxxx```と表示される(しかもxxxxxの部分はバラバラ)
そのため、共有用のリンクをAPI経由で取得するのは無理みたいです。

#参考
https://stackoverflow.com/questions/49803564/how-to-get-an-id-for-an-apple-music-playlist
7 Step of Web Development Process

Before the beautiful web pages shine on the internet, before the eyes of the owner gets watery with ecstasy, before the web app attracts huge traffic, before it becomes a badass revenue generating machine and before it creates an apogee of user experience, the web application goes through various stages that people are generally unaware about.

#1. Understanding Client’s Needs 
#2. Deep Research and Analysis 
#3. Planning 
#4. Design 
#5. Development 
#6. Testing and Deployment 
#7. Post Deployment and Maintenance

Read Full Artcile Here About [Web Development Process] (https://www.techuz.com/blog/web-development-process-a-guide-to-complete-web-development-life-cycle/)
JavaScript のデフォルトエクスポートのオブジェクトと名前付きエクスポートの違い

# 概要

Vue.js の vuex のテストを書こうとしていたときにハマった

- `export default {foo, bar}` と `export {foo, bar}` は違う
- `import {foo, bar} from 'module'` は名前付きエクスポートの分割代入

これを認識してなかったので，テストコードで import するときに困った


## export default {foo, bar}

- `{foo, bar}` というオブジェクトをデフォルトエクスポートしてる
- `import {foo, bar} from 'module'` とはできない
  - 同じようなことをするときは下のように書く

  ```.js
  import module from 'module'
  const {foo, bar} = module
  ```

## export {foo, bar}

- `foo, bar` という2つの変数を名前付きエクスポートしてる
- なので，`import {foo, bar} from 'module'` とできる
- オブジェクトにまとめるときは `import * as module from 'module'`

##参考
- [ES6の import / export](https://qiita.com/kiyodori/items/01d07d5c0659e539ecb9#default-exports)
    - `default` は `import {default} from 'module'` で受け取れる
アプリ起動時にIn-App Messagingのポップアップ位置がずれる時の対処法

Firebaseに最近追加されたIn-App Messagingをドキュメント見ながらアプリに導入していざモーダルビューを表示させたら、何故か表示位置がずれた。

<img width="375" alt="Screen Shot 2018-09-27 at 19.44.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/103047/4f4f47b4-784a-5728-173a-4ce2ae941695.png">


## 発生原因
Firebaseがポップアップを表示する時に、表示位置をAppDelegateクラスのwindowパラメータから前面のウィンドウサイズを取得して、そこから表示位置を決めているようです。

```objective_c:FIDRenderingWindowHelper.m

+ (UIWindow *)UIWindowForModalView {
  static UIWindow *UIWindowForModal;
  ....
  dispatch_once(&onceToken, ^{
    UIWindow *appWindow = [[[UIApplication sharedApplication] delegate] window];
    UIWindowForModal = [[UIWindow alloc] initWithFrame:[appWindow frame]];
    ....
  });
  return UIWindowForModal;
}
```

なので、最初に表示する画面をStoryboardのis Initial ViewControllerで設定せずUIWindowのrootViewControllerに直接セットしているようなアプリでは、UIViewControllerがセットされない限りウィンドウサイズがゼロなので、正しい位置に表示されなくなるみたいです。

## 対処法
空のUIViewControllerを設定したUIWindowをAppDelegateのwindowパラメータにセットしてから`FirebaseApp.config()`することで解決

```swift:AppDelegate.swift
 let window = UIWindow(frame: UIScreen.main.bounds)
 window.makeKeyAndVisible()
 let blankVC = UIViewController()
 window.rootViewController = blankVC
 self.window = window
 ......

 FirebaseApp.config()
```

## 結果

<img width="375" alt="Screen Shot 2018-09-27 at 19.51.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/103047/b85e1118-755b-a779-fe5a-33a71e3c89b0.png">
Gtags(GNU GLOBAL) で C++ のクラス名のタグが生成されない問題の対応

Gtags で C++ のクラス名が正しく取得できない問題が出て、その解決ができたので書き残しておこうと思います。

プロジェクトルートに `gtags.conf` を配置すると `gtags` は自動的にその設定を読み込みます。ぼくはスキップしたいディレクトリ `build/` があったのでそれを追加しました。
設定は `homebrew` でインストールした `/usr/local/opt/global/share/gtags/gtags.conf` からコピーして不要そうな部分を削除しています。

```sh
$ cat gtags.conf
default:\
	:tc=gtags:
#---------------------------------------------------------------------
# Configuration for gtags(1)
# See gtags(1).
#---------------------------------------------------------------------
common:\
	:skip=GPATH,GTAGS,GRTAGS,GSYMS,,HTML/,HTML.pub/,html/,tags,TAGS,ID,y.tab.c,y.tab.h,cscope.out,cscope.po.out,cscope.in.out,SCCS/,RCS/,CVS/,CVSROOT/,{arch}/,autom4te.cache/,build/:
gtags:\
	:tc=common:\
	:langmap=c\:.c.h,yacc\:.y,asm\:.s.S,java\:.java,cpp\:.c++.cc.cpp.cxx.hxx.hpp.C.H,php\:.php.php3.phtml:
gtags
```

この設定のとき、C++ のプロジェクトで `gtags` を実行しても `global Klass` の結果が取得できなかったのが今回の問題です (Klass は例)。

# 原因

僕の C++ プロジェクトではソースコードの拡張子が `.cpp` と `.h` なのですが、この `gtags.conf` の設定では C++ の拡張子に `.h` がなく、C の方に `.h` がありました。要するにヘッダファイルだけ C++ ではなく C としてパースされてしまい、C には class が存在しないのでタグが生成されなかったのでした。

# 解決方法

```sh
:langmap=c\:.c.h,yacc\:.y,asm\:.s.S,java\:.java,cpp\:.c++.cc.cpp.cxx.hxx.hpp.C.H,php\:.php.php3.phtml:
gtags
```

この部分を

```sh
:langmap=c\:.c,yacc\:.y,asm\:.s.S,java\:.java,cpp\:.c++.cc.cpp.cxx.hxx.hpp.C.H.h,php\:.php.php3.phtml:
gtags
```

と変更しました。あと、C/C++ しか必要がないのでもっとシンプルに

```sh
:langmap=c\:.c,asm\:.s.S,cpp\:.c++.cc.cpp.cxx.hxx.hpp.C.H.h:
```

としておきました。.h は必ず C++ としてパースされてしまいますが、互換性があるはずなので問題ないはずです。まだこの状態でバリバリコードを書いてないのでミスがあるかもしれませんがとりあえず動いてます。

今日の今まで ctags を使い続けてましたが、gtags 良いですね。乗り換えてよかった！
DialogFlowAPI v2 APIの使い方2 バックアップファイルを作成

<span class="ymarker">DialogFlowのバックアップの手動実行はそこまで手間ではないですが、日々バックアップを取りたい時などは自動化したいですよね。
そんなときに使えるDialogFlow v2のAPIをご紹介いたします。

<h2>API実行方法</h2>
DialogFlowのagent RestoreのAPIを使用します。
<a href="https://dialogflow.com/docs/reference/api-v2/rest/v2/projects.agent/export">https://dialogflow.com/docs/reference/api-v2/rest/v2/projects.agent/export</a>

※APIキーの取得は前の記事 <a href="https://qiita.com/tayack/items/6f0d76c980200be10c85">DialogFlow v2 APIの使い方１　API実行に必要なアクセストークンをコマンドプロンプトで取得する方法</a>をご覧ください

ちょっとわかりにくいと思うのでhttpのPOSTしてバックアップのメタデータを取得した部分をご紹介いたします。
![request-768x233.png](https://qiita-image-store.s3.amazonaws.com/0/294965/993fd717-8bee-f5ff-7e22-d081a2ce7ca8.png)

![response-768x283.png](https://qiita-image-store.s3.amazonaws.com/0/294965/21772d8e-05b5-29df-2e90-397f07d37ec6.png)




※ARCというクロームのプラグインを用いてHTTP通信を実行しています。
<a href="https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo?hl=ja">https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo?hl=ja</a>

<h2>metaデータをZipに変換する方法</h2>
responseのagentcontentをbase64で変換し、その文字列をZipにすることでバックアップが行われます。
自作バリデータ のエラーメッセージを多言語化する

組み込みのバリデーションのエラーメッセージを多言語化する方法はよく見るけど自作のバリデータ の場合の方法って意外と見かけない気がしたので。

## 前提

- Userモデルがあり、`name`、`email`、`password`カラムを持っている
- `password`は半角英数字両方を含む必要がある

## バリデーションメソッドの実装

まずは普通に日本語のエラーメッセージを返すバリデーションメソッドを実装する

```app/models/user.rb
class User < ApplicationRecord

# 省略

  validate :check_password_format

  def check_password_format
    unless password =~ /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i
      errors.add(:password, 'は半角英数字両方を含んでいるもののみ有効です')
      return
    end
  end

end
```

## エラーメッセージの多言語化

### 翻訳ファイルの用意

日本語と英語の翻訳ファイルを用意する

```config/locals/models/user/ja.yml
ja:
  activerecord:
    models:
      user: ユーザー
    attributes:
      user:
        name: 氏名
        email: メールアドレス
        password: パスワード
    errors:
      messages:
        invalid_password: は半角英数字両方を含んでいるもののみ有効です
```

```config/locals/models/user/en.yml
en:
  activerecord:
    models:
      user: User
    attributes:
      user:
        name: Name
        email: Email Address
        password: Password
    errors:
      messages:
        invalid_password: must contain both alphameric and numeric characters
```

### エラーメッセージの呼び出し

```app/models/user.rb
class User < ApplicationRecord

# 省略

  validate :check_password_format

  def check_password_format
    unless password =~ /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i
      errors.add(:password, :invalid_password)
      return
    end
  end

end
```

`t( user.errors.messages.invalid_password )` と書かなくても、`errors.add`で `t( user.errors.messages )` までは呼ばれているということなんだと思う。
最初見たときパッとわからなかったが気づいたときにアハ体験だった。
シェルスクリプトのエラー出力を整形したい

むかしむかしあるところに、たいそうシンプルなログ出力を行うシェルがあったそうな。

```command.sh
#!/bin/sh
command 1>>log.log 2>>error.log
```

ところがシェルスクリプトで時刻だのなんだの、細かいエラーログを出力する必要がでてきたので、もう少し頑張って頂きたい。
しかしエラー出力の加工ってどうやるんだろうか。
やれやれ。僕は検索した。

-----
[**シェルの入出力制御あれこれ**](https://qiita.com/tag1216/items/7ce35b7c27d371165e56)
[**[bash]時刻付きでログファイルに出力する**](https://qiita.com/mashumashu/items/eb0b9a0f78784d1b9686)

-----
###awkを使ってみる

なるほど`awk`というコマンドに渡せばいいのだな。
方法は他にもあるようだけど、とりあえずこれでやってみよう。
こうやってこうじゃ。
（`$0`変数にエラーメッセージが渡ってくる）

```command.sh
#!/bin/sh
command 1>>log.log 2> >(awk '{printf("[ERROR!!!]\n%s\n%s\n",strftime("%Y/%m/%d %H:%M:%S"),$0)}' >>error.log) 
```

と、長々と書いて実行！！！

```console
syntax error unexpected token near `>'
```
はいエラー！！！
でもこれは欲しいエラー（コマンド実行エラー）ではなくシェルの文法エラーである……。

-----
###原因
お分かりだろうか……

```command.sh
#!/bin/sh
command 1>>log.log 2> >(awk '{printf("[ERROR!!!]\n%s\n%s\n",strftime("%Y/%m/%d %H:%M:%S"),$0)}' >>error.log) 
```

```sh
#!/bin/sh ←こいつを
```

```sh
#!/bin/bash ←こうじゃ
```

完成

```command.sh
#!/bin/bash
command 1>>log.log 2> >(awk '{printf("[ERROR!!!]\n%s\n%s\n",strftime("%Y/%m/%d %H:%M:%S"),$0)}' >>error.log) 
```

すさまじく時間を浪費してしまった。
今回使った記法はbashの拡張記法であるところ、shを宣言してしまいインタプリタが解釈出来なかったようです。

-----

###テスト

```command.sh
#!/bin/bash
peropero 1>>log.log 2> >(awk '{printf("[ERROR!!!]\n%s\n%s\n",strftime("%Y/%m/%d %H:%M:%S"),$0)}' >>error.log) 
```

###出力結果


```error.log
[ERROR!!!]
2018/09/27 10:33:59
No manual entry for peropero

```

これでよし。
mac に Ubuntu Linux デスクトップ環境を構築する (xhyve編)

普段は Mac で仕事をしているものの、Linux Desktop を使わないといけない案件があって、VirtualBox でもと思ってやり始めたものの、High Sierra の「拡張機能がブロックされました」のエラーで先にするめない。

そういや xhyve もあったなとググってたら結構使えるっぽいのでやってみたら、意外といいかんじ。

## xhyve のインストール

Homebrew なら一行でOK。

```shell-session
$ brew install xhyve
```


## Ubuntu をインストール

ほぼ https://gist.github.com/mowings/f7e348262d61eebf7b83754d3e028f6c の通り。
18.04 は kernel panic でインストーラが起動しなかったので、16.04 を入れた。

```shell-session
$ curl -O http://archive.ubuntu.com/ubuntu/dists/xenial/main/installer-amd64/current/images/netboot/mini.iso
$ dd if=/dev/zero bs=2k count=1 of=tmp.iso
$ dd if=mini.iso bs=2k skip=1 >> tmp.iso
$ hdiutil attach tmp.iso
$ cp /Volumes/CDROM/linux .
$ cp /Volumes/CDROM/initrd.gz .
$ umount /Volumes/CDROM
$ rm tmp.iso  # kernel をコピーしたら用済み

$ dd if=/dev/zero of=hdd.img bs=1g count=40  # 40GB のディスクイメージ
$ sh ./install.sh  # 下記参照
```


```sh:install.sh
#!/bin/sh

KERNEL="linux"
INITRD="initrd.gz"
CMDLINE="earlyprintk=serial console=ttyS0"

# Guest Config
MEM="-m 1G"
IMG_CD="-s 1,ahci-cd,mini.iso"
IMG_HDD="-s 2,virtio-blk,hdd.img"
NET="-s 3:0,virtio-net,en0"
PCI_DEV="-s 0:0,hostbridge -s 31,lpc"
LPC_DEV="-l com1,stdio"
ACPI="-A"

# and now run
sudo xhyve $ACPI $MEM $PCI_DEV $LPC_DEV $NET $IMG_CD $IMG_H -f kexec,$KERNEL,$INITRD,"$CMDLINE"
```

Ubuntu のインストーラが起動するので、ふつーにインストールする。ただし kernel ファイルをコピるため、インストーラを終了する前に `Go Back` を選択して `Execute a shell` を実行する。

```shell-session
# cd /target
# sbin/ifconfig
# tar c boot | nc -l -p 1234
```

このまま mac で別の端末を開き、以下を実行する

```shell-session
$ nc <Ubuntu の IP アドレス> 1234 | tar x
```

これでインストールは完了。

## Ubuntu を起動

以下のスクリプトを実行する。

```run.sh
#!/bin/sh
KERNEL="$(ls boot/vmlinuz-* | sort -u | tail -1)"
INITRD="$(ls boot/initrd.img-* | sort -u | tail -1)"
CMDLINE="earlyprintk=serial console=ttyS0 acpi=off root=/dev/vda1 ro"

# Guest Config
UUID="c643a961-c20b-11e8-9979-3200139e2000"  # python -c 'import uuid; print(uuid.uuid1())'  等で生成する。IPアドレスを固定できる。
CPU="-c 2"
MEM="-m 4G"
IMG_HDD="-s 2,virtio-blk,hdd.img"
NET="-s 3:0,virtio-net,en0"
PCI_DEV="-s 0:0,hostbridge -s 31,lpc"
LPC_DEV="-l com1,stdio"
ACPI="-A"

# and now run
sudo xhyve　$UUID $ACPI $CPU $MEM $PCI_DEV $LPC_DEV $NET $IMG_CD $IMG_HDD -f kexec,$KERNEL,$INITRD,"$CMDLINE"
```

つらつらとログが流れた後、ログインプロンプトが表示される。めでたい。

```
Ubuntu 16.04.5 LTS rabbit ttyS0                
                                               
rabbit login:                                  
```

せっかくなので、18.04 にアップグレードしておく。

```shell-session
$ do-release-upgrade
```

## xrdp のインストール

```shell-session
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install xrdp xfce4 xfce4-goodies
$ sudo apt-get install chromium-browser  # お好みで。
```

## リモートデスクトップ接続

xrdp は特に設定がいらないようで、ubuntuのIPアドレスを指定して、マイクロソフトのリモートデスクトップクライアントから接続できる。

VNC よりも描画が速いし、いい感じ。
Hiawatha web server を試してみる

## 背景

[archlinuxのサーバページ](https://wiki.archlinux.jp/index.php/サーバー) を見ていると、 [hiawatha](https://www.hiawatha-webserver.org) なるものがあることに気づいてちょっと試して見た。
ついでに qiitaに記事がないので書いてみる。

## 情報

ライセンス: GPL2
最新バージョン: 10.8.3 (2018-09-27 現在)
初回リリース: 2002年

hiawatha はモホーク族インディアンの男性戦士の模様

## インストール

centos7 で試して見た。
案の定標準のリポジトリには入っていないので、外部のを有効にする。
公式サイトにリポジトリが書いてあるのでそれを利用。

```bash
sudo yum install -y epel-release
sudo yum install -y http://anku.ecualinux.com/7/x86_64/anku-release-8-1.noarch.rpm
sudo yum install -y hiawatha
```

## とりあえず実行してみる

設定ファイル（ `/etc/hiawatha/hiawatha.conf` ）を読んだところ、そのまま実行できると思うので、実行

```bash
sudo systemctl start hiawatha
```

これでこのサーバにアクセスしてみると以下のようなベージが出現する。

![hiawatha page.png](https://qiita-image-store.s3.amazonaws.com/0/241538/261fc039-976e-de75-aef2-329b8770e0a7.png)

とりあえず動いた。

## 設定を見ていく

簡単に設定ファイルを見て見た限り、web アプリを実行するには fastcgi のようである。

## 今後

実際に色々といじって見たいけど一旦今回はここまでにしておきます。
今後は、phpの実行など見ていこうと思います。