OmniAICreator/Qiita-1.07M huggingface dataset:
グローバル環境で定義されたオブジェクトを関数内で変更する

あるオブジェクトをRのコンソール画面で定義したとする。
例えば、

```{R}
hoge <- 1
```
というものがあったとする。
やりたいことは、このオブジェクトの値を関数の中から変更したい。

難しいのは、関数内で定義されたオブジェクトは、同じ名前だったとしても、グローバル環境で定義されたものとはスコープが違うので、関数内で変更を加えても、グローバル環境には変更が及ばない。

```{R}
library("pryr")
hoge <- 1
where("hoge") # <environment: R_GlobalEnv>にある
changeValue <- function(hoge){
    print(where("hoge")) # <environment: 0x7fd747dd4a40>にある
}
changeValue(hoge)
```

ただ、これだけなら、単純に永続代入（<<-）すれば、簡単に変更できる。

```{R}
hoge <- 1
changeValue <- function(){
    hoge <<- 2 # 変更
}
changeValue()
hoge # 2
```

しかし、ここではさらに、この変更関数を、後々以下のようにあるクラスに対するメソッドとして定義していきたい。

```{R}
setGeneric("changeValue", function(obj){standardGeneric("changeValue")})
setMethod("changeValue", "hoge-class", function(hoge){
    # hogeに対する何らかの変更処理
})
```

なので、changeValueの引数は、hoge-classからインスタンス化されたオブジェクトであってほしい。
このしばりのせいで、地味にはまったので、色々試行錯誤したものをメモ。

# 引数を文字列にしてみた

```{R}
hoge <- 1
changeValue <- function(hoge2){
	hoge <- eval(parse(text=hoge2))
	hoge <- 2 # 変更
	hoge <<- hoge
}
changeValue("hoge")
hoge # 2
```

changeValueの引数を文字列として、eval & parse & textで評価して、変更を加え、永続代入。
これだと、引数が文字列なので、やりたいこととずれる。

# グローバル環境に一回検索をかけて、上書き

```{R}
hoge <- 1
changeValue <- function(hoge2){
	userobjects <- ls(env=.GlobalEnv)
	target <- which(sapply(userobjects, function(x){
				identical(eval(parse(text=x)), hoge2)
			  }))
	hoge2 <- 2 # 変更
	assign(names(target), hoge2, envir=.GlobalEnv)
}
changeValue(hoge)
hoge # 2
```

これは一番やりたいことと近かったのだが、identicalで同じオブジェクトをグローバル環境にあるか探索することに頼っているので、同じものが複数定義されていた時に、どっちが変更されるかわからない。
実際、hogeと同じ内容のオブジェクトが2つ以上あると、最初の1個のほうを使いましたという警告が出てしまう。


# deparse & substitute

```{R}
hoge <- 1
changeValue <- function(hoge2){
	target <- deparse(substitute(hoge2))
	hoge2 <- 2 # 変更
	assign(target, hoge2, envir=.GlobalEnv)
}
changeValue(hoge)
hoge # 2
```

そもそも、hogeという名前を、関数の中で取得することが難しいから、上のように色々やっていたのだが、
deparse & substituteを使えば、この名前が取得できるらしい(https://stackoverflow.com/questions/10520772/in-r-how-to-get-an-objects-name-after-it-is-sent-to-a-function )。

結局、これを知らなかったからはまっただけだった。
Julia言語ではmutableな関数として!つけるだけのことなのだが...
slot-value がメソッドじゃない件

```cl
(defclass x ()
  ((integer-value :initarg :integer-value :initform 0)))

(let ((x (make-instance 'x :integer-value "1")))
  (values (slot-value x 'integer-value)
          (progn
            (setf (slot-value x 'integer-value) "2")
            (slot-value x 'integer-value))))
;;⇒ 1
;;   2
```

こんなふうに文字列をわたしても整数変換して欲しい、みたいなことありますよね。

でも次のようにしても `(setf slot-value)` はメソッドではないのでエラーなります。

```cl
(ignore-errors (defmethod (setf slot-value) ((value string) (x x) (slot (eql 'integer-value)))
                 (setf (slot-value x slot) (parse-integer value))))
;;⇒ NIL
;;   #<SB-INT:SIMPLE-PROGRAM-ERROR "~@<~/sb-ext:print-symbol-with-prefix/ ~
;;                              already names an ordinary function or a ~
;;                              macro.~@:>" {100B5BC9A3}>
```

しかたなので `(setf sb-mop:slot-value-using-class)` を経由しました。

```cl
(defvar *slot-value-next-method*)

(defmethod (setf %slot-value) (value object slot-name)
  (funcall *slot-value-next-method* value))

(defmethod (setf sb-mop:slot-value-using-class) :around (value class (object x) slotd)
  (let ((*slot-value-next-method* (lambda (value) (call-next-method value class object slotd))))
    (setf (%slot-value object (sb-mop:slot-definition-name slotd)) value)))

(sb-mop:finalize-inheritance (find-class 'x))

(defmethod (setf %slot-value) ((value string) (x x) (slot (eql 'integer-value)))
  (setf (%slot-value x slot) (parse-integer value)))

(let ((x (make-instance 'x :integer-value "1")))
  (values (slot-value x 'integer-value)
          (progn
            (setf (slot-value x 'integer-value) "2")
            (slot-value x 'integer-value))))
;;⇒ 1
2
```
Docker for Macでdocker-composeの入力補完をできるようにする（zsh）

いろんなDocker-compose入力補完のサイト見たけど、bashしか載ってないとか、windows版しかないとか
macでzshもあるんだけど、なぜかできないとか

そういうのが多かったので、まとめてみました。



# zsh-completionsをインストール

こいつは、zshのタブ補完を色々できるやつ

```zsh

brew install zsh-completions
```

# .zshrcに追記する

```.zshrc

# zsh_completions
fpath=(/usr/local/share/zsh-completions $fpath)
```

このfpathは、zsh-completionsをインストールしたときに、同じようなものが出てくるので、それを.zshrcに追記してください。


# 権限を与える

同じように、zsh-completionsをインストールしたときに、chmodから始まるコマンドを実行してくださいというのが出てくると思うので、それを実行してください。

多分、`/usr/local/share`に権限を与えろっていう指示だったと思う・・・。

これをしないと、zshを立ち上げるたびにエラーが出ます。

僕の場合はうまくかなかったので、

```zsh

chmod 755 /usr/local/share 
```

にしました。


# そしてもう一つ

これを実行せよという指令が出ていました。

```zsh

rm -f ~/.zcompdump; compinit
```


まあ、zsh-completionsをインストールしたときに出た指示を全部やってくださいということですね！


# あとはコマンドをタブで補完できるように

```zsh

curl -L https://raw.githubusercontent.com/docker/compose/1.21.2/contrib/completion/zsh/_docker-compose > zsh-completionsまでのパス/_docker-compose 
```

ちなみに、僕の場合はこう

```zsh
curl -L https://raw.githubusercontent.com/docker/compose/1.21.2/contrib/completion/zsh/_docker-compose > /usr/local/share/zsh-completions/_docker-compose 
```

# 最後に

```zsh
autoload -Uz compinit && compinit -i
exec $SHELL -l
```


これでできるようになってます。


見ながらやってたら、できないな〜〜って最初は思ってたんですが、途中で自分の勘違いに気づいたので、他のサイトでもできるかもしれないです笑
darknet yolo v3をpython3(.5.2)で試す 

# やりたいこと
[darknet yolo](https://pjreddie.com/darknet/yolo/)にpython IFがありますが、
公開されている`python/darknet.py`はデフォルトではpython2でしか動作しなかったので、
python3(.5.2)で動作するようにする

# 実行環境
- Ubuntu 16.04.4
- python 3.5.2

# python3(.5.2)で実行した場合のエラー

ひとまず、必要最低限の下記3点を変更し実行

1. `libdarknet.so`のパス
2. config, weightファイルのパス
3. print関数(`print r` -> `print(r)`)


が、あえなくエラー...

```
Traceback (most recent call last):
  File "python/darknet_org.py", line 151, in <module>
    net = load_net("cfg/yolov3.cfg", "yolov3.weights", 0)
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type
```


# 修正のための調査
どうやら`load_network`のタイプが違うと言われているので調査

```py
...
 85 load_net = lib.load_network
 86 load_net.argtypes = [c_char_p, c_char_p, c_int]
 87 load_net.restype = c_void_p
...
151     net = load_net("cfg/yolov3.cfg", "yolov3.weights", 0)
...
```

`c_char_p`に対してstr型の`"cfg/yolov3.cfg"`や`"yolov3.weights"`をインプットしているところが怪しい
で、python3のリファレンス[16.16. ctypes — Pythonのための外部関数ライブラリ¶(原文)](https://docs.python.jp/3/library/ctypes.html)で確認してみると...
16.16.1.4. 基本データ型に`c_char_p`はバイト列 or Noneと記載されている
ということは、`"cfg/yolov3.cfg"` -> `b"cfg/yolov3.cfg"`というようにバイト文字で引数指定すればよいのでは！？

# 修正 & 実験
`c_char_p`で指定されている部分の引数をすべてb"..."にして、実行してみる

```py
...
151     net = load_net(b"cfg/yolov3.cfg", b"yolov3.weights", 0)
152     meta = load_meta(b"cfg/coco.data")
153     r = detect(net, meta, b"data/dog.jpg")
...
```

```sh
$ cd ~/work/darknet
$ python3 python/darknet.py
```

```
...
Loading weights from yolov3.weights...Done!
[(b'bicycle', 0.9941979646682739, (363.7811279296875, 278.96038818359375, 397.52166748046875, 331.17120361328125)), (b'dog', 0.9904678463935852, (221.56198120117188, 380.4324645996094, 186.3259735107422, 312.14471435546875)), (b'truck', 0.9110047221183777, (581.7490234375, 127.70638275146484, 215.17813110351562, 86.2370376586914))]
```

おお、動いた！めでたし、めでたし
結果もbytes型で返ってくるんや。

# 参考
- [YOLO: Real-Time Object Detection](https://pjreddie.com/darknet/yolo/)
- [16.16. ctypes — Pythonのための外部関数ライブラリ¶(原文)](https://docs.python.jp/3/library/ctypes.html)
M5StackのLCDディスプレイの色をRGBで指定する。

##目的
M5StackのLCDディスプレイでは、16Bit Colorで色を指定するようになっている。
直感的にわかりやすい、RGBの24Bit color(8Bit color x 3channel)で、色を指定する。


##従来

M5Stackで、LCDディスプレイに赤を表示するサンプルコードは
例えば以下のようになる。

```
#include <M5Stack.h>

void setup() {
   M5.begin();
   M5.Lcd.fillScreen(TFT_RED);
   //M5.Lcd.fillScreen(0xF800);
}

void loop(void) {
  delay(100);
}
```

色を指定する場合は、LCDのディスプレイであらかじめ定義されている変数を使うか、
16Bit Colorを直接入力する必要がある。

https://github.com/m5stack/M5Stack/blob/master/src/utility/In_eSPI.h

```
                                     /*   R,   G,   B */ 
 #define TFT_BLACK       0x0000      /*   0,   0,   0 */ 
 #define TFT_BLUE        0x001F      /*   0,   0, 255 */ 
 #define TFT_GREEN       0x07E0      /*   0, 255,   0 */ 
 #define TFT_RED         0xF800      /* 255,   0,   0 */ 
 #define TFT_WHITE       0xFFFF      /* 255, 255, 255 */ 
```

##実装1

16Bit Colorと24Bit Colorとは、以下の式の関係がある。

```
uint16_t color = ((red>>3)<<11) | ((green>>2)<<5) | (blue>>3);
```

 この式を組み入れた関数を用意すれば

直感的にわかりやすい、24Bit color(8Bit color x 3channel)で、色を指定できる。~~


```
#include <M5Stack.h>

uint16_t getColor(uint8_t red, uint8_t green, uint8_t blue){
  return ((red>>3)<<11) | ((green>>2)<<5) | (blue>>3);
}

void setup() {
   M5.begin();
   M5.Lcd.fillScreen(getColor(255,0,0));
   //M5.Lcd.fillScreen(0xF800);
   //M5.Lcd.fillScreen(TFT_RED);
}

void loop(void) {
  delay(100);
}
```

####参考
C++ defined 16bit (high) color
https://stackoverflow.com/questions/13720937/c-defined-16bit-high-color

## 実装2
M5.Lcd.color565()関数を使う

構文:
>color565(uint8_t red, uint8_t green, uint8_t blue);
　関数で使用する色コード(rgb565)に変更します。
引数:
　　　　red	赤	int8_t
　　　　green	緑	int8_t
　　　　blue	青	int8_t

使用例:

```
#include <M5Stack.h>
    uint16_t colorvalue=0;
    colorvalue= M5.Lcd.color565(255,0,0);
```
https://docs.m5stack.com/#/en/api/lcd?id=color565
Androidアプリでボタンの背景を動的に変える


## やりたいこと

こんな感じで、背景色を指定した角丸ボタンについて、プログラムから動的に色を変えたい。

![スクリーンショット 2018-06-17 9.49.00.png](https://qiita-image-store.s3.amazonaws.com/0/62874/3e9a983f-1faa-5c0d-a814-2851149df8fe.png)

## レイアウトファイルでのイメージ

xmlで固定の色でやる場合はこんなイメージ

ボタン背景用のDrawable。
ボタンが押された時と通常時で、別の色を指定したselectorを用意した。

```xml:res/drawable/button_back.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <corners android:radius="@dimen/button_radius" />
            <solid android:color="@android:color/holo_red_dark" />
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <corners android:radius="@dimen/button_radius" />
            <solid android:color="@android:color/holo_red_light" />
        </shape>
    </item>
</selector>
```

ボタンのレイアウト。上記ファイル(button_back.xml)をbackgroundとして指定している。


```xml:res/layout/sample_button.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/button_back"
    android:layout_width="150dp"
    android:layout_height="50dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:text="サンプル"
    android:textAllCaps="false"
    android:textColor="@color/button_text_color"
    android:textSize="@dimen/answer_button_font_size"
    android:textStyle="bold" />
```

## コード上でやる場合

レイアウトファイルの
`<selector>`は`StateListDrawable`
`<shape>`は`GradientDrawable`
にそれぞれ置き換えられるらしい。

```kotlin:dynamic_background_button.kt
val button = View.inflate(context, R.layout.sample_button, null)
val radius = context.resources.getDimensionPixelSize(R.dimen.button_radius).toFloat()
val res = StateListDrawable()

val pressedColor = context.resources.getColor(android.R.color.holo_red_dark)
val pressedDrawable = GradientDrawable()
pressedDrawable.cornerRadius = radius
pressedDrawable.setColor(pressedColor)
res.addState(intArrayOf(android.R.attr.state_pressed), pressedDrawable)

val color = context.resources.getColor(android.R.color.holo_red_light)
val drawable = GradientDrawable()
drawable.cornerRadius = radius
drawable.setColor(color)
res.addState(intArrayOf(), drawable)

button.setBackgroundDrawable(res)
```

ちなみに角丸が不要で、背景色だけ変わればいいという場合は`ColorDrawable`を使うと簡単そう。

```kotlin:dynamic_color_button.kt
val button = View.inflate(context, R.layout.sample_button, null)
val res = StateListDrawable()

val pressedColor = context.resources.getColor(android.R.color.holo_red_dark)
res.addState(intArrayOf(android.R.attr.state_pressed), ColorDrawable(pressedColor))

val color = context.resources.getColor(android.R.color.holo_red_light)
res.addState(intArrayOf(), ColorDrawable(color))

button.setBackgroundDrawable(res)
```

## 参考

Android create selector programmatically - Stack Overflow
https://stackoverflow.com/a/33986111

Shape drawableをxmlではなくJavaコードで動的に生成する - Qiita
https://qiita.com/guchio/items/bebc13db0d2c0ae03363
Parcelでbackground-image: url(...)しようとしてエラーが出る時は

# tl;dr

* 404エラーが出た場合はurl内をクォーテーションで囲う
* Cannot found moduleエラーが出た場合はCSSをJSで読み込むようにする

# 404エラー

ParcelでSassを書いている時、背景画像を読み込もうとしたら404エラーが出ました

```css
body {
    background-image: url(../assets/images/background.png);
}
```

```
> GET http://localhost:4300/assets/images/background.png 404 (Not Found)
```

ParcelではCSS内での画像などの参照は`'`（クォーテーション）で囲んだものをアセットとして`/dist`内にコピーし、そうでないものは外部ファイルとしてそのまま通すようです

そのため、`/dist`にコピーさせたいファイルの場合は

```css
background-image: url('../assets/images/background.png');
```

というようにクォーテーションで囲み、CDNなどで配信されているものを指定する時は

```css
background-image: url(/assets/images/background.png);
```

とクォーテーションなしで書くのが良さそうです

そもそも、クォーテーションありの場合は依存関係を解決しようとするため、絶対パスなどで同一ドメインから配信されるファイルを参照しようとすると

```
> Cannot resolve dependency './../../../../../../../assets/images/background.png' at '/assets/images/background.png'
```

とエラーになってしまいます

（http://などで始まる場合は有無に関係なく依存関係の解決はされません）

## Cannot find moduleエラー

さて、きちんとクォーテーションで囲い、パスもあっているはずなのですが、以下のようなエラーが出ました

```css
background-image: url('../assets/images/background.png');
```

```
> main.9f57420d.js:39 Uncaught (in promise) Error: Cannot find module 'background.2bfd8f6a.png,18'
```

このエラーが出る場合は、HTMLからCSSを呼び出しているのが原因です

```html
<!-- index.html -->
<style rel="stylesheet" href="./styles/main.sass" />
```

依存関係を解決させたい場合はJS内にCSSをimportしなければいけません

```js
// main.js
import '../styles/main.sass';
```

以上で依存関係は正しく解決されるようになります

# 終わりに

普段通りに書いていたら難儀してしまうCSSでの依存関係の解決についてでした

## 参考

* https://github.com/parcel-bundler/parcel/issues/879
AnsibleでRHEL7系にCloudWatch Logs Agentをいれた話

# 背景
数十台の`RHEL 7.2`のサーバーにCloudWatch Logs Agen(以下、CWLAgent)を導入することタスクが発生した。省力化というより構成管理の観点からAnsibleでCWLAgentを導入することになった。

#環境

Ansibleサーバー
OS: `RHEL7.5`
Ansible: `2.5`

ServerA(実行対象)
OS: `RHEL7.5`

個人的で触れる環境が`RHEL7.5`しかなかった、、、

# 目的
いい感じにAnsibleで対象のサーバーにCWLAgentを導入すること


# playbook/task
サーバーごとにplaybookを作っています。
命名法はhost名.yml

```ruby:ServerA.yml
- hosts: ServerA
  remote_user: ansible
  become: yes
  become_user: root
  vars_files:
    - /etc/ansible/variable/test/host_vars/ServerA_vars
    - /etc/ansible/variable/test/group_vars/GroupA_vars

  roles:
#    - common
     - cloud_watch_logs_agent
```

この記事のメインは下のroleです。(正しくないroleです。正しいのは章：'改善したrole'を参照)


```ruby:roles/cloud_watch_logs_agent/tasks/main.yml
- name: copy Install Script
  copy:
    src: tmp/awslogs-agent-setup.py
    dest: /tmp
    owner: root
    group: root
    mode: 0755

- name: copy awslogs.conf
  copy:
    src: tmp/awslogs.conf
    dest: /tmp/awslogs.conf
    owner: root
    group: root
    backup: yes
    mode: 755

- name: install AWS CloudWatch Logs Agent
  shell: python /tmp/awslogs-agent-setup.py -n -r ap-northeast-1 -c /tmp/awslogs.conf

- name: enabled awslogs
  service:
    name: awslogs
    enabled: yes

```
*文字に変な色ついてる。　なんでだろ？

このplaybook(role)を実行しても、CWLAgentは導入されるけど、自動起動が有効化(enabled)にならない。
ansibleでやりたいことに自動起動も含まれているので、どうにかしたい。
いろいろ試した
# serviceモジュール　がおかしいのかな？　(原因不明)
ansibleにはserviceモジュール、systemdモジュールがあることがわかった。
serviceモジュールをsystemdモジュールに置き換えた。それ以外はオプションも含めて変更なし。

###だめだ。自動起動設定入ってない

もっといろいろ原因を探した。原因がpythonスクリプトで導入するという意味のわからんことをやっているかもしれないとか思ってた。
深夜2時くらいまでAnsible実行前の状態のサーバーを再構築してPlaybook流すのループとか5回くらいやった

# 改善したtask
これでいけた。(原因はわかってないんだが)　できたときは　`初めて自分で自分をほめたいと思います`って思った

```ruby:roles/cloud_watch_logs_agent/tasks/main.yml
- name: copy Install Script
  copy:
    src: tmp/awslogs-agent-setup.py
    dest: /tmp
    owner: root
    group: root
    mode: 0755

- name: copy awslogs.conf
  copy:
    src: tmp/awslogs.conf
    dest: /tmp/awslogs.conf
    owner: root
    group: root
    backup: yes
    mode: 755

- name: install AWS CloudWatch Logs Agent
  shell: python /tmp/awslogs-agent-setup.py -n -r ap-northeast-1 -c /tmp/awslogs.conf

- name: enabled awslogs
  service:
    name: awslogs.service
    enabled: yes

```

serviceモジュールの対象のサービスを指定する部分を`awslogs.service`に変更したらいけた

# あとがき
なにが原因なんだ。

それよりも、ymlファイルの`/tmp/`の色が緑になっている方が気になる。
PCがMacなんだが、そんなのが関係しているのかな？
和英辞典：〇〇性


* 開発系や分析系に携わっていると『〇〇性』という言葉によく遭遇するので、まとめていく。
* 随時更新予定。

|日本語|英語|
|:--|:--|
|可用性| availability |
|持続可能性|sustainability|
|可読性|readability|
|同一性|identity|
|再現性|reproducibility|
|柔軟性|flexibility|
|冗長性|redundancy|
|脆弱性|vulnerability|
|耐障害性|fault tolerance|
iframe について

Monacaでアプリ開発を行う場合、`iframe` を利用してコンテンツを表示させる機会があると思います。

Monacaで利用されているCordovaは、アプリ起動時に iframe を使った処理を行なっています。

そのため、アプリ起動時にコンテンツ側でも iframe を使って外部サイトを表示させている場合、Cordova 側の iframe 処理と競合して、スプラッシュ画像が表示されたままの状態になることがあります。

この状態を回避するためには、iframe タグで外部サイトを表示させるのではなく、JavaScript から iframe オブジェクトを作成して、表示位置に追加する等の対策が必要になります。

```html:例1
<script>
  window.addEventListener('load', function() {
    var iframe = document.createElement("iframe");
    iframe.src = "https://ja.monaca.io";
    iframe.style.width = "100%";
    iframe.style.height = "100%";

    var element = document.querySelector("body");
    element.appendChild(iframe);
  }, false);
</script>

<body>
  <!-- iframe src="https://ja.monaca.io" / -->
</body>
```

# Onsen UI の場合

Onsen UIを利用している場合は、下記のように `ons-page` の `.page__content` に追加する必要があります。

```html:例2
<script>
  document.addEventListener('init', function(event) {
    var page = event.target;
    if (page.matches('#page1')) {
      var iframe = document.createElement("iframe");
      iframe.src = "https://ja.monaca.io";
      iframe.style.width = "100%";
      iframe.style.height = "100%";

      var element = document.querySelector("#page1 > .page__content");
      element.appendChild(iframe);
    }
  });
</script>

<body>
  <ons-page id="page1">
    <!-- iframe src="https://ja.monaca.io" / -->
  </ons-page>
</body>
```

# おわりに

iframe を利用している場合で、アプリ起動時にスプラッシュ画像が表示されたままの状態になる場合は、一度、iframe タグからではなく、JavaScript から iframe を追加してみてください。
AtCoder Beginner Contest 100 解説備忘録

#前書き
AtCoder Beginner Contest 100 を解いてみた．解けなかった問題の備忘録．

#D問題
[[問題はこちら]](https://abc100.contest.atcoder.jp/tasks/abc100_d)

・N個のケーキのうち，M個のケーキを取る．
・そのうち，(綺麗さの合計の絶対値) + (おいしさの合計の絶対値) + (人気度の合計の絶対値) が最大になるように選ぶ．すなわち，

$\max \\{ |x_1+x_2+\cdots +x_M| +  |y_1+y_2+\cdots +y_M| +  |z_1+z_2+\cdots +z_M| \\}$

を求めたい．

・$_NC_M$通りをループしてしまうのは明らかにタイムアウト．

・ここで絶対値の意味を考える．


$
|X|= 
\begin{cases}
X ~~~~(X\geqq 0)\\\
-X ~ ~(X<0)
\end{cases}
$

となることから，絶対値をとるときは **「(絶対値の中身) × (+1)」か 「(絶対値の中身) × (-1)」の二通り**を考えれば良い．

・今回の場合，$|X|,|Y|,|Z|$ の3つの絶対値の和を考えるのだから，$2^3$通りを考えれば良い．

```main.cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <cmath>
#include <set>
#include <sstream>
#include <bitset>
#include <stack>
#include <cstdlib>
#include <utility> //pair

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

typedef long long ll;

using namespace std;

ll a[8][3] = {{1,1,1},{1,1,-1},{1,-1,1},{1,-1,-1},{-1,1,1},{-1,1,-1},{-1,-1,1},{-1,-1,-1}};


int main() {
    
    ll n,m;
    cin >> n >>m;
    
    vector<ll> x(n),y(n),z(n);
    
    FOR(i, 0, n){
        cin >> x[i] >> y[i] >> z[i];
    }
    
    ll ans = -(1ll<<60);
    FOR(i, 0, 8){
        vector<ll> tmp(n);
        FOR(j, 0, n){
            tmp[j] = x[j] * a[i][0] + y[j] * a[i][1] + z[j] * a[i][2] ;
        }
        sort(tmp.begin(),tmp.end(),greater<ll>());
        ll sum=0;
        FOR(j, 0, m){
            sum += tmp[j];
        }
        ans = max(sum,ans);
    }
    
    cout << ans << endl;
    
    
    return 0;
}

```
#あとがき
精進します．
Macで右Commandキーで入力言語をタイ語に切り替える

毎回`Command+Space`で言語を選択するのがめんどくさかったので`Hammerspoon`を使って右`⌘キー`でタイ語入力になるように設定しました。

```init.lua
ctrlPressed = false
keyPressed = false
layoutWatcher = hs.eventtap.new({hs.eventtap.event.types.flagsChanged, hs.eventtap.event.types.keyUp}, function(e)
    local flags = e:getFlags()
    local keyCode = e:getKeyCode()
    if flags.cmd and keyCode == 0x36 and not (flags.alt or flags.shift or flags.ctrl or flags.fn) then
        ctrlPressed = true
        keyPressed = false
    elseif ctrlPressed and not (flags.cmd or flags.alt or flags.shift or flags.ctrl or flags.fn) and not keyPressed then
        ctrlPressed = false
        if keyCode == 0x36 then
            hs.keycodes.setLayout("Thai")
        end
    else
        keyPressed = true
    end
end)

layoutWatcher:start()
```

### 参考
https://github.com/Hammerspoon/hammerspoon/issues/1039
[Windows 10] 拡張子なしファイルを Sublime Text 3 で開くよう関連付けする

## 方法

管理者権限でcmd.exe を開いて、以下のコマンドを実行する。

```
C:\WINDOWS\system32>assoc .=no_ext
.=no_ext

C:\WINDOWS\system32>ftype no_ext="C:\Program Files\Sublime Text 3\sublime_text.exe" "%1"
no_ext="C:\Program Files\Sublime Text 3\sublime_text.exe" "%1"
```

## 参考

* https://superuser.com/questions/13653/how-to-set-the-default-program-for-opening-files-without-an-extension-in-windows
フロントエンドエンジニアへの復帰の道 ー情報収集ー

制作現場から一年くらい離れて、tech系のブログ等を読み漁り、今の自分のスキルではこの先生き残れないということを実感した。
主に以下のサイトで情報収集した。

・collis(https://coliss.com/)
ー初心者向け。css、デザインのヒントが載っている。

・css tricks(https://css-tricks.com/
ーcssのあらゆる使い方が載っていて、サイトも綺麗だし見てて楽しい。

・ICS media(https://ics.media/)
ーweBだけではなくて、いろんなTech系の記事が載っていて面白い。

・MDN(https://developer.mozilla.org/ja/docs/Learn/JavaScript)
ーなんと言っても公式だし、軽い復習がてら、解説からのクイズがてきて便利。これが一通り終わったらオライリーガッツリ読みたい。

・Code grid(https://www.codegrid.net/)
ー毎週末新しいフロントエンドのトピックがメルマガで届く。正直レベルが高くてよくわからないところが多いけど、月額800円はかなりお得。
一回やめてたけどまた始める予定。

・infoQ(https://www.infoq.com/jp)
ー海外のプログラマー(多分)の人たちの記事とかをまとめてるサイト。フロントエンドの話題はそんなにないけど時々チェックしてます。

・その他：オライリーのJavaScriptの本欲しいんだけと、多すぎて何選べばいいのかわからない。全くの初心者と中級者の間ぐらいのがいいのですかね。

他にも色々あるけど、今日のところはここまで。
web browserのカスタマイズをする

##WEBブラウザーをカスタマイズ
ウェブブラウザは現在たくさんあります。その中でもっともカスタマイズ性の高いものを探して、そこからスクリーンショットを自動的にとって処理してくれるようなものをカスタマイズすれば、しんたーねっととしてなる。
このセキュリティーに関しては、ブラウザを作ったところに任せればいいのではないか？
フロントエンドエンジニアへの復帰の道 ー序章ー

昨年の六月にコーディング職から離れ、一年ほどウェブ制作会社で単純作業をやっていた人(私)のフロントエンド勉強記録。

経歴：
・四年ほど前に派遣事務職を退職し、ハローワークの紹介で三ヶ月ウェブの職業訓練校に通って一通り簡単なサイトが作れるようになった。

・インターン制度があったので、一ヶ月間医療系のウェブ制作会社で働いた。

・就職活動を始める。実務経験ほとんどがないので難航したが、ECサイトのコンサル会社でコーダ―兼デザイナーのアルバイトとして、一年ほど働いた。ECサイトの構築や、バナーづくり、LPのコーディングなどを担当した。申し訳ないくらい優しい会社だったけどスキルアップは難しいと思った。

・デザインできないな、と思い退職し大手の制作会社でフロントエンドエンジニア(正社員)として勤務。文字修正や地味な作業ばかり、しかも深夜一時くらいまで残業が続き、心身を壊して休職した。面談時の人事の人の圧迫間が怖く、怯えながら過ごした。

・半年くらい傷病手当てと失業手当で生き延びた。無職になった。

・就職活動を始め、昨年三月にコーディング専門の制作会社にアルバイトで採用された。wordpressで中小企業のコーポレートサイトを作るのが主な仕事だったので、簡単なwordpress構築は余裕でできるようになった。

・三ヶ月ほどでまた心身の調子が悪くなり退職。
会社の人はよい人ばかりで迷惑をかけて申し訳なかった。

・２ヶ月休みを取り、就職活動をはじめる。朝が苦手なので、始業が遅いweb系の会社に派遣として勤務。web系には珍しく固い会社で、エンジニアとは全く関係ない単純作業を担当する。
ものすごく楽だけど、将来が不安だし、コードが書きたくてウズウズしてきたので、九月末で契約終了することを決意。

・一年ぶりにガッツリとフロントエンドの情報を毎日漁り、必要なスキルと自分の実力が全然足りてないことを大体把握する。

・javascriptがちゃんと書けるようになって、react、rubyでサイトが作れるようになる事が目標。

・11月に転職できるように、今からポートフォリオ用の作品を作りたいが、PCの故障でてが動かせず、iunputばかりしている。早くゴリゴリコート書きたいのに、悲しい。とりあえずgenius barに行く。

今までの経歴と、今の状況はこんな感じです。
Laravel5.5こと始め 〜5. ユーザリストのペジネーション表示〜

# 内容
以下の順番にまとめます。
[1. MacへのXAMPP+Laravelインストール](https://qiita.com/sonrisa/items/f08112fe0ec4f51e4bdf)
[2. ユーザログイン機能の追加](https://qiita.com/sonrisa/items/207fd53eced13fc88acf)
[3. MVCとルーティングの説明]
(https://qiita.com/sonrisa/items/809adf872e6fb3657f81)
[4. ユーザリストの表示]
(https://qiita.com/sonrisa/items/929486929ed8d851a24e)
[5. ユーザリストのペジネーション表示]
(https://qiita.com/sonrisa/items/86efb8caebe207ab8fa8) ←いまここ
[6. ユーザ管理APIの追加](https://qiita.com/sonrisa/items/bc4894e6803632089ceb)
[7. Vue.jsとAPIベースのユーザ管理アプリの追加準備](https://qiita.com/sonrisa/items/595f080c6ecf1ed61b93)
[8. Vue.jsとAPIベースのユーザ管理アプリの追加](https://qiita.com/sonrisa/items/48a9a8e73e757c81619a)
[9. Vue.jsとAPIベースのユーザ管理アプリへのペジネーション追加]
(https://qiita.com/sonrisa/items/d58c56b638924d8c6810)
[10. APIへのJWTAuth認証の追加]
(https://qiita.com/sonrisa/items/97c1f3e8491f76dc2ce2)
[11. Vue.jsとAPIベースのユーザ管理アプリへの認証の追加](https://qiita.com/sonrisa/items/1976cbd049cadfec1285)

# 5. ユーザリストのペジネーション表示
たくさんのユーザが登録されるとリスト表示する場合に表がページからはみ出してしまいます。そのような場合、１ページに表示するユーザ数に上限を設けて、次へと前へといったボタンと一緒にページ送りの機能があると便利です。この機能をペジネーションと呼びます。

ペジネーションの実装はそこそこ複雑で開発者泣かせなのですが、Laravelにはペジネーションを簡単に実装できる機能があらかじめ備わっています。

まずは、「app/Http/Controllers/HomeController.php」のindex関数を編集します。

```app/Http/Controllers/HomeController.php
...
class HomeController extends Controller
{
...
    public function index()
    {
        $users = User::paginate(1); // ←修正
        return view('home', ['users' => $users]);
    }
```

paginate関数の引数の数字（ここでは1）は、１ページに表示するユーザ数に上限を表します。通常はブラウザの下限に達する程度のもう少し大きめの数字になると思いますが、ここではペジネーションのテストを容易にするために、1行表示したら次へボタンが表示されるように設定しています。

次に「resources/views/home.blade.php」を編集し、テーブルの後に「{{ $users->links() }}」を追記します。

```resources/views/home.blade.php
...
<table class="table table-striped table-bordered">
  <tr>
    <th>ID</th>
    <th>NAME</th>
  </tr>
  <tr>
  @foreach($users as $user)
    <td>{{ $user->id }}</td>
    <td>{{ $user->name }}</td>
  @endforeach
  </tr>
</table>
{{ $users->links() }} <!--追加-->
...
```

それでは「php artisan serve」を実行して、http://localhost:8000 にアクセスしてみましょう。ログインページからログインを行うと下図のようにペジネーションが表示されます。

<img width="575" alt="スクリーンショット 2018-06-17 12.39.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/263562/c852a31c-9c7a-1f98-a9fe-e36f33a3d00a.png">

表には「paginate(1)」と設定したとおり１ページに１行のみ表示されます。また、表下のペジネーションで２ページを選択すると下図のとおりページが遷移します。

<img width="570" alt="スクリーンショット 2018-06-17 12.40.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/263562/b4a4f141-2806-8ea2-7330-026f18dc107b.png">

ペジネーションのデザインはbootstrapを利用していますがCSSでカスタマイズが可能です。

以上、「5. ユーザリストのペジネーション表示」が完了です。旧来型のHTML/CSSベースのWebアプリケーションが簡単に作れることがわかったと思います。

次からは、Vue.jsというJavaScriptベースのシングルページアプリケーション構築ライブラリとREST APIの組み合わせのWebアプリケーションを開発します。まずは「[6. ユーザ管理APIの追加](https://qiita.com/sonrisa/items/bc4894e6803632089ceb)」を行います。
『将棋AIで学ぶディープラーニング』のUSIエンジンを「将棋所」に登録するためにはエラー出力抑制

『将棋AIで学ぶディープラーニング』でUSIエンジンを「将棋所」に登録するためには、1.ディレクトリ変える http://www2.ezbbs.net/cgi/bbs?id=shogidokoro&dd=09&p=1 … まではわかったがその後大苦戦。
結局、Pythonが出力するWarningが原因とわかり、 バッチに 2>NUL 付加でエラー出力を抑止してやっと登録できた。4時間かかった（笑）

```
@echo off
python -m pydlshogi.usi.usi_policy_player 2>NUL
```
perlで複数行をまとめて置換

##やりたいこと
例えば次のようなテキストがあったとする。

```test.txt
	a('aiueo')
	k('kakikukeko')
	s('sasisuseso')
	t('tatituteto')
```

このうち、

```
	k('kakikukeko')
	s('sasisuseso')
```

を

```
	h('hogehoge')
	f('fugafuga')
	b('bar')
```

に置換したいとする。
つまり、置換後の形は次の通り。

```
	a('aiueo')
	h('hogehoge')
	f('fugafuga')
	b('bar')
	t('tatituteto')
```

##回答例
次のようなperl のプログラムを書いて、

```test.pl:

#!/bin/perl

my $before = <<'EOS';
        k('kakikukeko')
        s('sasisuseso')
EOS

my $after = <<'EOS';
        h('hogehoge')
        f('fugafuga')
        b('bar')
EOS

s/\Q${before}\E/${after}/
```

次のように実行

```bash
$ perl -0p test.pl test.txt
        a('aiueo')
        h('hogehoge')
        f('fugafuga')
        b('bar')
        t('tatituteto')
```

##解説
* -p : 入力ファイルの各行に対してperlのプログラムを実行する。
* -0 : -p で行のセパレータがヌル文字(\0)になる。つまり、ファイル全体を一度に読み込むことになる。
* "\Q"と"\E": 正規表現のメタ文字である括弧()をエスケープしている

筆者はperlに詳しいわけではないので、他にもっと良い方法を知ってる方がいたら教えていただけると幸いです。

##参考ページ
* https://qiita.com/takc923/items/e608568a9734e2d84f7f
* https://qiita.com/xtetsuji/items/9939143a7619956997e1
* https://qiita.com/akata/items/75b45635e9a0e34c407c
* http://d.hatena.ne.jp/perlcodesample/20080619/1214053531
XMLマスターベーシックを受けてみた

最近 XML マスター：ベーシック V2 試験を受けてきました。
なぜこれを受けようとしたかというと、XML を使ったテクニックや技術や研究を時たま見るな～と思い、勉強するついでに資格もとってみようと思ったからです。
特にいえばデータ記述言語としてデータ操作によく使われてるから体系的に知っときたいというのが主な理由。応用技術の代表例としては SVG とか XHTML とか。
XML は2000年前半期に最盛期を経て様々な分野で利用されていますが、今じゃ世間ではもう過去の技術になってしまった風潮なのか、XML に関する本があまり出ていないようです（少なくとも日本では）。
そういう自分もいまさら XML とか勉強するもんなのかと思っておりましたが(←おい)
自分の備忘録として載せておこうと思います。
# **使った本**
・[やさしいXML 第3版](https://www.amazon.co.jp/%E3%82%84%E3%81%95%E3%81%97%E3%81%84XML-%E7%AC%AC3%E7%89%88-%E9%AB%98%E6%A9%8B-%E9%BA%BB%E5%A5%88/dp/479735366X "やさしいXML 第3版")
・[徹底攻略XMLマスター ベーシック問題集 V2試験対応 (ITプロ/ITエンジニアのための徹底攻略)](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5XML%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC-%E3%83%99%E3%83%BC%E3%82%B7%E3%83%83%E3%82%AF%E5%95%8F%E9%A1%8C%E9%9B%86-V2%E8%A9%A6%E9%A8%93%E5%AF%BE%E5%BF%9C-IT%E3%83%97%E3%83%AD-IT%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5/dp/4844321420 "徹底攻略XMLマスター ベーシック問題集 V2試験対応 (ITプロ/ITエンジニアのための徹底攻略)")
やさしいXMLを一読してから徹底攻略に取り組みました。どうでもいいことだけどこの徹底攻略問題集を俗に黒本[^1]というらしい。
やさしいXMLの著者の本は他にも読んだことはありますがこれも実に読みやすい。一気に読めました。ただ試験のことを考えると DOM や SAX までは読む必要はないです[^2]。
やさしいXMLを読んだら黒本をやるだけ。これ、誤植がかつて多かったようですが、第4刷以降からだいぶ訂正されたようです。今は第6刷が最新で買うならこれがいいと思います。
勉強期間は二週間ぐらい（かな？）、集中的にやりました。

# **試験感想**
結果としては合格しました。で、色々言いたいことはあるんですが[^3]、まァここで書かないことはググって他のかたの感想に任せるとして・・・時間が本当にギリギリでした。どうも強い人にとっては簡単みたいですが、私は終了時間３秒前に終わりました。
試験時間は60分で全部で50問あるんですが、25問解き終わった時点で残り27分とかだったからね。こりゃオワタと思いますよ、マジで。
時間泥棒の原因は DTD と XML Schema。その資料のコードが読みにくいというか……。普通に読んでると時間が溶けるので、正しいと思ったらさっさと選択して次進むべきだった。XSL のある問題のが簡単。
黒本でそんな感じになるだろうとは想像してましたが、ここまで危機一髪だとは。受かったからいいものの落ちる可能性も十分にありました。

# **まとめと今後**
試験は時間との戦いだったという一言に尽きますが、反省としては演習が少なかったことも考えられます。思えば黒本の模擬試験も時間をはかってなかった。
さて、ベーシックを取得したわけですが、ベーシックを持ってる事で受けられる上位資格のXMLマスタープロフェッショナルは実務経験がある人にとっても時間制限が厳しいらしいので、どんだけヤバいんだろうと戦々恐々としています。受けるならアプリケーション開発のほうですが……実務経験がある人にとっても難しいなら自分にはまだ先の話になりそう。
でも DOM や SAX を使いこなせたら嬉しいことが増える気がするので、プロフェッショナルを受験するかはともかくその分野の勉強は進めたい。
# **終わりに**
最後に宣伝。ベンダ資格[^4]にはしばしば有意性が3年とか5年とかありますが、XML マスターは有意性の期限がないのでおすすめ。
**何か勉強して資格とりたいなって人は XML マスター：ベーシックとろう！
~~マイナーだからネタにもなるし！！~~**

でも舐めてると落ちると思うのでしっかり勉強しようね。おしまい。

[^1]: Oracleなどベンダ系資格の問題集。
[^2]: プロフェッショナルだと範囲。
[^3]: 具体的な問題内容は規定により言えないよ！
[^4]: 実はそもそもXMLマスターはベンダ資格とは違うんですけどね！ベンダっぽいけど。
【Keras】メモ：Kerasのモデルを別スレッドで使用する

使用したいときに忘れているためメモ。

マルチスレッドでKerasのモデルを利用したい時には、
ロードしたモデルに対して、以下のAPIを呼んで事前コンパイルしておく。
(メイン関数でロードしたモデルを別スレッドに渡して、別スレッド内で推論する場合等)

```python
model._make_predict_function()
```

以上。
Javaの一部の処理をJavaScriptに委譲する

「Javaの一部の処理を外部から注入できないか？」ということで調べた結果の個人的メモです。

# 方法
調べてみたらJava上の**JavaScript スクリプティングエンジン（Nashorn）**というものがあったのでそれを使用してみました。
Nashornは、Java SE8の[javax.script](https://docs.oracle.com/javase/jp/8/docs/api/javax/script/package-summary.html)パッケージから呼び出すことができます。
※Java SE6,7では、Mozillaが実装したJavaScript スクリプティングエンジン（Rhino）が使われています。

# サンプルコード
`List`のフィルタ処理をJavaScriptに委譲するサンプルコードです。

```java:Main.java
public class Main {

    public static void main(String[] args) throws Exception {
	    List<Person> list = Arrays.asList(new Person("a", 1), new Person("b", 2), new Person("c", 3));
        // JavaScriptのフィルタ処理を委譲する
		List<Person> resultList = list.stream().filter(e -> eval(e)).collect(Collectors.toList());
		// フィルタ前のリストを表示
		System.out.println("フィルタ前: " + list);
		// フィルタ後のリストを表示
		System.out.println("フィルタ後: " + resultList);
    }

	/**
	 * JavaScriptの実行結果を評価する
	 * @param person
	 * @return true/false
	 */
	public static boolean eval(Person person) {
    	boolean result = false;
		try {
			ScriptEngineManager manager = new ScriptEngineManager();
			// JavaScriptエンジンを作成する
			ScriptEngine engine = manager.getEngineByName("javascript");
			// Java側のオブジェクトをJavaScriptの変数に設定する
			engine.put("person", person);
			// ファイルからJavaScriptファイルを読み込む
			Reader script = new InputStreamReader(Main.class.getResourceAsStream("sample.js"));
			// JavaScriptを実行する
			result = Boolean.valueOf(true).equals(engine.eval(script));
		} catch(ScriptException ex) {
			ex.printStackTrace();
		}
		return result;

	}
}
```
リスト内の要素となるJavaオブジェクト。
JavaScriptからフィールド変数にアクセスできるように`public`なgetterを定義しています。

```java:Person.java
public class Person {
    private String name;
    private Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public Integer getAge() {
        return age;
    }
    public String toString() {
        return "{ name: " + this.name + ", age: " + this.age + "}";
    }
}
```

以下のsample.jsで、Java側の`filter`メソッドの処理を行っています。
Javaから渡された`person`オブジェクトのフィールドにアクセスすることもできました。

```JavaScript:sample.js
// personはJava側から渡されたリストの要素
// nameフィールドにアクセスし、判定式に利用している
person.name === 'a' || person.name === 'b';
```

# 処理結果

上記のサンプルコードの処理結果は以下となります。
sample.jsの評価結果により、`List`の内容がフィルタされたことが分かります。

```
フィルタ前: [{ name: a, age: 1}, { name: b, age: 2}, { name: c, age: 3}]
フィルタ後: [{ name: a, age: 1}, { name: b, age: 2}]
```

# 感想

今回のケースのような使い方をすれば、
例えば画面上からユーザがフィルタリング条件をその都度変更できるリストを作れて便利だなと思いました。

# 備考
以下、参考リンクです。
[Java の上の JavaScript エンジン Nashorn の基本](http://etc9.hatenablog.com/entry/2017/02/05/014701)
[OpenJDK wiki >> Nashorn](https://wiki.openjdk.java.net/display/Nashorn/Main)

※追記：Nashornは非推奨になので使わない方が良さそうです。
[JavaでJavaScriptを実行する「Nashorn」が非推奨に、ECMAScriptの速い進化に追いつけないと。代替案はGraalVM](https://www.publickey1.jp/blog/18/javajavascriptnashornecmascriptgraalvm.html)
Amazon Dash Buttonでサプリの服用管理をする

私は1日に1回サプリを服用しているのですが、最近飲んだかどうかの記憶があやふやな時があるのでプログラムで管理しようと思いました。またAmazon Dash Buttonネタですが、便利だからね、しょうがないね。


# 環境

- Ubuntu 18.04 LTS
- Python 3.6.4
- pip 10.0.1
- Node.js 8.11.2
- npm 6.1.0
- Dasher 1.4.1


# 前準備

[Dasher](https://github.com/maddox/dasher)をインストールしておいてください。
また、Amazon Dash Buttonのセットアップは[過去に書いた記事](https://qiita.com/lightning5x5/items/98e7c91939bcbfc8a131)を参考に行ってください。


# プログラムの概要
Amazon Dash Buttonを押すとcsv形式のログファイルを読み込み、末尾の日付と今日の日付を比較します。異なれば今日の日付を書き込み、同じであればM/Bからビープ音を鳴らして警告します。


# プログラムをセットアップ
## 1.プログラムを作業ディレクトリ内に配置する
[GitHub](https://github.com/lightning5x5/supplcounter_with_amazon_dash_button)にプログラムを用意したので、supplcounter.pyとsuppl_log.csvを`作業ディレクトリ直下`に、config.jsonを`dasher/config/`に配置してください。

```
supplcounter(作業ディレクトリ)
  ├─ supplcounter.py
  └─ suppl_log.csv

dasher
  ├─ app.js
  ├─ config
  |   ├─ config.example.json
  |   ├─ config.json
  |   └─ org.dasher.plist
  └─ 以下略
```

## 2.先程配置したプログラムに書き加える
supplcounter.pyに、`suppl_log.csvの絶対パス`を、config.jsonに`Amazon Dash ButtonのMACアドレス`と`supplcounter.pyの絶対パス`を書き加えてください。
この時にsupplcounter.pyに実行権限を付与するのを忘れないでください。


## 3.M/Bからビープ音が鳴るようにする
UbuntuだとM/Bからのビープ音がデフォルトで無効になっているので、設定ファイルを少し弄る必要があります。

まずは、

```bash
$ sudo apt install beep
```

で、beepをインストールしてください。

そして、

```bash
$ sudo vim /etc/modprobe.d/blacklist.conf
```

で、`blacklist pcspkr`という項目をコメントアウトしてください。

あとは、

```bash
$ sudo modprobe pcspkr
```

で、起動すると無事ビープ音が鳴るようになります。


# 実行してみる
`dasher/`内で

```bash
$ sudo npm run start
```

を実行し、Amazon Dash Buttonを押すと、

・実行前
![Screenshot from 2018-06-17 00-06-29.png](https://qiita-image-store.s3.amazonaws.com/0/154116/cc75784c-9e97-29d6-f399-a268c9bd68b0.png)

・実行後
![Screenshot from 2018-06-17 00-06-11.png](https://qiita-image-store.s3.amazonaws.com/0/154116/921489a9-7204-d7ac-a9da-c6f42c6f59a1.png)

無事実行できました！


# あとがき

今回は結構実用的なものが作れたかなと思います。ただ、常時ネットワークを監視するとなるとサーバーが必要になるので、Raspberry Piが欲しくなりますね...
今回は1日に1回という条件下だったので回数を記録するカラムは追加しませんでしたが、指定回数を超えると警告するようにしても面白そうですね。


# 参考

https://qiita.com/tortuepin/items/b4231c587d37bb707f2a
https://qiita.com/SquidSky/items/aa570c50e8f4c6d94130
Parcelでバンドルされたファイルの内訳を確認する

Webpackには`webpack-bundle-analyzer`というバンドルされたファイルの内訳や解析をみることができるプラグインがあります

> **webpack-bundle-analyzer**
> https://www.npmjs.com/package/webpack-bundle-analyzer

Parcelでもプラグインをインストールするだけでこの機能を利用することができます

それが`parcel-plugin-bundle-visualiser`です

> **parcel-plugin-bundle-visualiser**
> https://www.npmjs.com/package/parcel-plugin-bundle-visualiser

# 使い方

まずはプロジェクトにプラグインをインストールします

```
$ yarn add -D parcel-plugin-bundle-visualiser
```

あとはただビルドすれば、プロジェクトルートに`report.html`という名前で解析結果が生成されます

```
$ parcel build src/index.html
```

`report.html`をブラウザで表示すると以下のようにバンドルされたファイルの内訳が表示されます

![image.png](https://qiita-image-store.s3.amazonaws.com/0/127934/4bff7761-34e3-0ce2-eda1-d037e28dcdc1.png)

このレポートでは以下のようなことを確認することができます

* バンドルされたファイルやフォルダ、アセットファイル名
* プロジェクトルートに対する相対パス
* バンドルされたファイルのサイズ
* gzipした場合の推定サイズ
* バンドルに要した時間

バンドルファイルの内訳から無駄なファイルがないかなどを調べることができます

## おまけ：ビルド終了時にブラウザでレポートを開く

`parcel-plugin-bundle-visualiser`はレポートを生成するだけで表示は手動で行わなければなりません

そこで、ビルドの実行後にレポートを開くようなコマンドを書いておくのをお勧めします

Macユーザーの場合は

```
$ parcel build src/index.html; open report.html
```

Windowsユーザーの場合は

```
$ parcel build src/index.html & start report.html
```

これでビルドが終了したら自動的にレポートが開かれるようになります
Dockerでnode-configを使い環境変数をうまいこと扱う(目的はpuppeteer）

# 背景
Dockerコンテナ上のpuppeteerでE2Eテストを各環境ごとでやる場合、
環境変数をどうやってうまいことセットすれば良いのか、検証した


# 状況
puppeteerが目的のサイトにアクセスしてなんやかんやテストするスクリプトを書きたい
↓
開発環境とかステージング環境とか本番環境とかで違う変数を簡単に定義したいなあ
↓
node-configっていうのが便利なのか
↓
全部あわせてDockerに組み込んでみよう

# 縛り
`docker-compose build`
で、puppetterやnode-configがインストールされ
`docker-compose up`
でdockerが立ち上がり、テストする、という流れは崩さない。
なんか別にコマンド使ったり設定変えるたびに毎回コンテナをbuildしたりはしない。

# やり方

```Dockerfile
FROM node:9.10.0

RUN apt-get update \
 && apt-get install -y \
      gconf-service \
      libasound2 \
      libatk1.0-0 \
      libc6 \
      libcairo2 \
      libcups2 \
      libdbus-1-3 \
      libexpat1 \
      libfontconfig1 \
      libgcc1 \
      libgconf-2-4 \
      libgdk-pixbuf2.0-0 \
      libglib2.0-0 \
      libgtk-3-0 \
      libnspr4 \
      libpango-1.0-0 \
      libpangocairo-1.0-0 \
      libstdc++6 \
      libx11-6 \
      libx11-xcb1 \
      libxcb1 \
      libxcomposite1 \
      libxcursor1 \
      libxdamage1 \
      libxext6 \
      libxfixes3 \
      libxi6 \
      libxrandr2 \
      libxrender1 \
      libxss1 \
      libxtst6 \
      ca-certificates \
      fonts-liberation \
      fonts-ipafont \
      fonts-ipaexfont \
      libappindicator1 \
      libnss3 \
      lsb-release \
      xdg-utils \
      wget \
  && npm i config puppeteer

WORKDIR /app

CMD bash /app/start.sh
```

```docker-compose.yml
version: '3'
services:
  puppeteer:
    build: .
    container_name: "puppeteer"
    working_dir: "/opt/data-volume"
    volumes:
    - .:/opt/data-volume
    - ./script.js:/app/script.js
    - ./start.sh:/app/start.sh
    tty: true
    stdin_open: true

```

上記のようにdockerの準備をする
Dockerfileに色々書いていますが、大半がpuppeteerのためのもので（たぶん）
ミソは最後の`CMD bash /app/start.sh`
これで以下のシェルを実行している

```start.sh
#!/bin/bash
export NODE_ENV=development
node /app/script.js
```

node-configにどの環境のファイルを読むかを指定している
これで、起動するとbuild時に指定しておいた`CMD bash /app/start.sh`が実行され
以下のpuppeteer稼働用のscript.jsを実行する
そう、環境変数をセットするため、start.shを挟んだということです。

```script.js
var config = require('config');
console.log("NODE_ENV=%s", process.env.NODE_ENV);
console.log(JSON.stringify(config));

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    args: [
      '--no-sandbox',
      '--disable-setuid-sandbox'
    ]
  });
  const page = await browser.newPage();

  await page.goto(config.url, {waitUntil: 'networkidle0'}); //ここでconfigでセットしたものが入る

  await console.log('access top');
  await page.screenshot({ path: 'top.png'});

  browser.close();
})();
```

で、以下のようなjsonで書かれた環境ごとのファイルが読み込まれる

```config/development.json
{
  "message": "This is a default config",
  "user": "user",
  "password": "password",
  "url": "https://dev.example.com/"
}
```

これで、例えば本番の設定を呼びたいときなどは

start.shの
`export NODE_ENV=development`を　　
`export NODE_ENV=production`などに変えてやればいい
そうすれば`docker-compose up`時に以下のように別に用意しているproduction.jsonが呼ばれることになる

```config/production.json
{
  "message": "This is a production config",
  "user": "user",
  "password": "password",
  "url": "https://prd.example.com/"
}
```

# 雑感
何でもかんでも実行をシンプルにしておくと、「これどうやって使うんだっけ？」がなくなるんで便利。
コマンドの引数で制御してやればもっと楽になるやも。
puppeteerのシナリオ書くの面倒。（今回関係ないけど）
Elm＋Leafletでマーカーをぐりぐりいじるためのメモ書き

# はじめに

Elm＋Leafletをしようとした場合、下記のリポジトリのようにWeb-componentsとして操作する、という手があります。
https://github.com/cbenz/elm-leaflet-maps

このやり方だとElmコードだけで完結するという利点がありますが、例えば「マーカーを表示→それを消して別のマーカーを出す」などの操作をすると、期待した動きにならないことがあります。Leaflet の全機能を使うためには、portsを使ってJavaScriptでの操作が必要なようです。

私はwebpackをちゃんと理解しているわけではないので、これが最適かどうかはわからないですが、ひとまずworkaroundのメモとして書きます。

# 前提

Elmアプリのプロジェクトはcreate-elm-appで作成するものとします。通常なら「elm-app start」でコーディングし始めることも多いでしょうが、npmでLeafletをインストールするため、create-elm-appしたらすぐに「elm-app eject」しておきます。Leafletはnpmでインストールするのが一番手間が小さいかと思いますが、他の手段でもElmでの利用は可能です（bowerあるいは手動でのダウンロードなど）。

# Leafletのインストール

上述した「elm-app eject」が済んでいると、packages.jsonが既にあるはずなので、コマンドラインで下記を実行します。

```
$ npm install leaflet --save
```

npmでインストールされたleafletを読み込むために、index.jsに下記を追記します。こうすることで、index.jsにて「L.map()」等のメソッドが利用できるようになります。

```javascript:src/index.js
import '../node_modules/leaflet/dist/leaflet.css';
import '../node_modules/leaflet/dist/leaflet.js';
```

# Leafletの使い方

ここまで済めば、LeafletはJavaScriptとして操作することになるので、Elmとして注意する点はほとんどありません。

Mapの初期化はこんな感じになるでしょう（Leaflet関連の部分だけ記載）。修正：コメントで「Leafletの操作はDOMができてから実行するのが安全」という話をいただきましたので、反映させました。（参考：[[Elm] DOM更新後にJSコードを実行する](https://qiita.com/arowM/items/ff98bce79a7080cbb38a)）

```javascript:src/index.js
var mymap;

app.ports.initMap.subscribe(function(args) {
    requestAnimationFrame(function () {
        var lat = args[0];
        var lng = args[1];
        var mag = args[2];

        mymap = L.map("mymap").setView([lat, lng], mag);

        L.tileLayer(
	    'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
	    {
	        attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a>',
            maxZoom: 18
	    }
        ).addTo(mymap);
    });
});
```


```elm:src/Main.elm
port initMap : (Float, Float, Int) -> Cmd msg

init : ( Model, Cmd Msg )
init = ( {}, initMap (24.20578, 124.08943, 9) )

view : Html msg
view = div [id "mymap"] []
```

# 注意点
マップにマーカーを出す歳に、カスタムアイコンを画像ファイルで指定することもあるでしょう。その時に、elm-package.jsonでproxy機能を使っている場合、画像ファイルの読み込みがこのproxyに流れてしまいます。理由はよくわかっていません。これは、もちろんdev環境のみの話で、prod-buildの際は関係ありません。

私はたまたま逃げ道がありましたが、proxyの設定によってはちょっと面倒なことになるかもしれません。
他のプロセスがポートを占有してnginxを再起動できない

# 現象
nginxを起動しようとすると、Address already in useと言われ再起動できない。

~~~md
$ sudo /usr/sbin/nginx
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()
~~~

# 環境
~~~md
$ nginx -v
nginx version: nginx/1.12.2
~~~

# 原因
nginxが異常終了する等して古いhttpdプロセスが残っていることが原因。

# 対策
lsofコマンドで古いプロセスを表示し、killすればよい。

~~~md
$ sudo lsof -i | grep nginx
nginx    3254     root    6u  IPv4  20710      0t0  TCP *:http (LISTEN)
nginx    3254     root    7u  IPv6  20711      0t0  TCP *:http (LISTEN)
nginx    3255    nginx    6u  IPv4  20710      0t0  TCP *:http (LISTEN)
nginx    3255    nginx    7u  IPv6  20711      0t0  TCP *:http (LISTEN)
nginx    7013     root    6u  IPv4 227085      0t0  TCP *:vcom-tunnel (LISTEN)
nginx    7014    nginx    6u  IPv4 227085      0t0  TCP *:vcom-tunnel (LISTEN)
~~~
3254,3255,7013,7014のidをもつプロセスが残っていることが分かる。

~~~md
$ sudo kill -9 3254
$ sudo kill -9 3255
$ sudo kill -9 7013
$ sudo kill -9 7014
~~~

これで起動するようになる。
自分のサーバーから Node.js で obniz に Hello Obniz!

昨日まではObnizでリアルタイムチャートとかアナログ時計とか作ってきましたが、

　　ccchart-v1.12.090にObniz のリアルタイムチャート描画を暫定実装してみた 　　　　　　
　　https://qiita.com/toshirot/items/01afe0352aac9bbb6797

　　Obnizのディスプレイにアナログ時計を表示してみる。 
　　https://qiita.com/toshirot/items/43527d63d5a1b9bd8032

これらはWeb UI 経由でHTMLで書いていました。でも、

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">obniz は今のところ ccchart もアナログ時計も Web UI から動かしててそれは超簡単で便利なのだけど、<br><br>実際に使うときは Node.js でサーバーからデーモン化して使うなどのケースも多そうに思えるので、<br><br>今夜はその辺をやってみたい。</p>&mdash; 高橋登史朗 ( T blockchain T ) (@toshirot) <a href="https://twitter.com/toshirot/status/1007781497850380289?ref_src=twsrc%5Etfw">2018年6月16日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


ということで、今日は自分のサーバーからNode.jsでobnizへ命令を送って動かすのをやってみます。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Obnizを自分のサーバーからNode.jsで動かす手順はこのドキュメントに説明があります。<a href="https://t.co/jY1NtZ79ZY">https://t.co/jY1NtZ79ZY</a></p>&mdash; 高橋登史朗 ( T blockchain T ) (@toshirot) <a href="https://twitter.com/toshirot/status/1008003451555475458?ref_src=twsrc%5Etfw">2018年6月16日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

まず自分のサーバーで、プログラムを置きたい場所で npm で obniz モジュールをインストールします。

```npm

npm i obniz
```
すると、今回はv1.4.5が入りこんな依存モジュールリストが表示されてインストールが完了します。

```npm

obniz@1.4.5 node_modules/obniz
├── semver@5.5.0
├── eventemitter3@3.1.0
├── node-fetch@2.1.2
├── tv4@1.3.0
├── ws@5.2.0 (async-limiter@1.0.0)
├── node-dir@0.1.17 (minimatch@3.0.4)
└── js-yaml@3.12.0 (esprima@4.0.0, argparse@1.0.10)

```
ws@5.2.0使ってるのに親近感を覚えつつ、さっそくアプリを一つ作ります。
(※Nodeバージョンはobnizモジュール下のpackage.jsonに"_nodeVersion": "8.11.3"とあったので今回はv8.11.3でやってます)
とりま、ひな形はこんな感じ。

```Node.js
const Obniz = require("obniz");

const obniz = new Obniz("1234-5678");//1234-5678は自分のobnizIDに書き換える
obniz.onconnect = async function () {
   //ここにやりたいことを書く
}
```
やっぱり最初はあいさつから。下記を app-hello.js という名前で保存します。

```Node.js
const Obniz = require("obniz");

const obniz = new Obniz("1234-5678");//1234-5678は自分のobnizIDに書き換える
obniz.onconnect = async function () {
  obniz.display.clear();
  obniz.display.print("Hello Obniz!")
}
```
そして Node.js で実行

```
node app-hello.js
```
するとこうなる

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">というわけで自分のサーバーから Node.js で obniz に Hello Obniz! <a href="https://t.co/Eklc5TCZfj">pic.twitter.com/Eklc5TCZfj</a></p>&mdash; 高橋登史朗 ( T blockchain T ) (@toshirot) <a href="https://twitter.com/toshirot/status/1008017831005306882?ref_src=twsrc%5Etfw">2018年6月16日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

明日はアクセストークンを発行してセキュアにアクセスするというのをやってみます。
この規模でreduxは草だけど流石にstoreとactionは別で管理したいって時はredux-zeroがオススメ

:writing_hand: **[redux-zero](https://github.com/concretesolutions/redux-zero)**

```sh:version
node：8.11.3
yarn：1.7.0
```

```sh:setup
npx create-react-app my-app --scripts-version=react-scripts-ts
cd my-app
yarn add redux-zero axios
yarn add -D json-server
touch db.json src/store.ts src/actions.ts
```

```json:tslint.json
  "rules": {
    "no-console": false,
    "no-empty-interface": false,
    "no-shadowed-variable": false,
    "variable-name": false
  }
```

```json:db.json
{
  "comments": [
    { "id": 1, "body": "some comment", "postId": 1 }
  ]
}
```

```javascript:store.ts
import createStore from "redux-zero";

interface IState {
  count?: number;
  data?: any;
  loading?: boolean;
}

const initialState: IState = { count: 1, data: [], loading: false };

// tsエラーがでるので一旦any型へ格納
const _createStore: any = createStore;
const store = _createStore(initialState);

export default store;
```

```javascript:actions.ts
import client from "axios";

const actions = ({ setState }: any) => ({
  decrement: (state: any) => ({ count: state.count - 1 }),
  // 非同期もいける
  getComments: (state: any) => {
    setState({ loading: true });
    return client
      .get("http://localhost:3000/comments")
      .then(payload => ({ data: payload.data, loading: false }))
      .catch(error => ({ error, loading: false }));
  },
  increment: (state: any) => ({ count: state.count + 1 })
});

export default actions;
```

```tsx:App.tsx
import * as React from "react";
import { connect } from "redux-zero/react";
import actions from "./actions";

interface IProps {
  store?: any;
}

interface IState {}

const mapToProps = ({ count, data, loading }: any) => ({
  count,
  data,
  loading
});

class App extends React.Component<IProps, IState> {
  public constructor(readonly props: any) {
    super(props);
  }

  public render(): JSX.Element {
    return (
      <div>
        <h1>{this.props.count}</h1>
        <div>
          <button onClick={this.props.decrement}>decrement</button>
          <button onClick={this.props.increment}>increment</button>
          <button onClick={this.props.getComments}>getComments</button>
        </div>
        <ul>{this.props.data.map((v: any) => <li key={v.id}>{v.body}</li>)}</ul>
      </div>
    );
  }
}

export default connect(
  mapToProps,
  actions
)(App);
```

```tsx:index.tsx
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Provider } from "redux-zero/react";
import App from "./App";
import store from "./store";

const Root = () => (
  <Provider store={store}>
    <App />
  </Provider>
);

ReactDOM.render(<Root />, document.getElementById("root") as HTMLElement);
```

```sh:start
yarn run json-server --watch db.json
yarn start
```

:moyai: 「...このライブラリ略したらリゼロですやん」