OmniAICreator/Qiita-1.07M huggingface dataset:
Distributed Prioritized Experience Replayを読んだので解説してみる

# はじめに

この記事は [DeepLearning論文紹介 Advent Calendar 2017](https://adventar.org/calendars/2112)の16日目の記事です．

[Distributed Prioritized Experience Replay](https://openreview.net/pdf?id=H1Dy---0Z)を読んだので解説してみようと思います．
(Under review as a conference paper at ICLR 2018 ...査読中みたいです．)

# 論文について

この論文は**強化学習**について書かれたものです．
内容についてですが，**APE-X**という新しい学習モデルを利用し，Prioritized Experience Replayを効率的に分散化する事でstate-of-the-artとなる結果を出した，というものです．
分散型強化学習の他の手法として，**A3C**や**UNREAL**といった手法があります．
また，強化学習の基礎的な手法として**Q学習**や**DQN**，**DDQN**などの手法が挙げられますが，今回の解説ではこれらについては割愛します．
従来手法の解説については，以下の記事がとても参考になりました．

* [これから強化学習を勉強する人のための「強化学習アルゴリズム・マップ」と、実装例まとめ](https://qiita.com/sugulu/items/3c7d6cbe600d455e853b)

# 解説

Prioritized Experience Replayとは，Networkの学習の際に，TD誤差が大きい経験を優先して利用する手法の事です．
簡単に言うと，効率よく学習出来る経験を優先的に利用しましょう，という事です．
詳しく知らない方は，以下の記事が分かりやすいと思います．

* [【強化学習中級者向け】実装例から学ぶ優先順位付き経験再生 prioritized experience replay DQN 【CartPoleで棒立て：1ファイルで完結】](https://qiita.com/sugulu/items/10ac7ce53de40d4c8891)

**APE-X**では，この手法を効率的に分散しています．
![1.JPG](https://qiita-image-store.s3.amazonaws.com/0/203894/8d19de54-8d72-5541-4c16-dd626062e197.jpeg)
↑は，論文に乗せられていた**APE-X**の概要図になります．

**APE-X**では，学習モデルをLearnerとActor，Replay Memoryの３つに分離して考えます．以下でそれぞれ説明します．

* Actor
    * Agentの役割は，学習環境で経験を集めて，それをReplayMemoryに貯めることです．Actorはマルチスレッド上で並列に動き，それぞれに学習環境や行動を決定するためのNetworkを持ちます．また，Actorが持つNetworkは学習されることはなく，一定間隔毎にLearnerのNetworkからパラメータをコピーすることで最新の状態に更新されます．
* Learner
    * Learnerの役割は，ReplayMemoryに貯められた経験を利用してNetworkを学習することです．LearnerはGPU上で1つだけ動いています．
* ReplayMemory
    * ReplayMemoryは，Agentから受け取った経験を貯め，それをLearnerに渡すことです．構造上，メモリサイズは結構必要になります．

従来の**A3C**などの分散型強化学習モデルでは，各Agentがパラメータを共有したNetworkを持ち，それぞれのAgentがNetworkを好き勝手に更新していきます．(多分．)

一方**APE-X**では，学習を行うのはLearnerのみとなっています．
経験を集めるタスクと学習を行うタスクを上手く分離して処理を行うことで，従来よりも高速な学習を可能にしているようです．

他にも，従来手法同様，Advantageやmulti-step bootstrap targetsなどの手法を利用し，学習効率を高めています．

# 結果

![2.JPG](https://qiita-image-store.s3.amazonaws.com/0/203894/ca1d1143-6a70-33fe-0fb0-cdb9d0e231c1.jpeg)

論文に掲載されていた結果の一部です．
学習効率，成果ともに半端ない進歩ですね．
Rainbowがはるか下にいますね．ｼｭｺﾞｲ．

# 感想
実装も**UNREAL**みたいな従来手法より楽そうだし，これからの主流になっていきそう．
Anonymous authors...一体誰なんだ...

（追記）
DeepMindだった．
Node-REDの技術情報

Node-REDを仕事で使用しており、いくつかわかったことがあリますので技術情報を共有します。

# １．HTTPの通信エラーを検知する方法

msg.statusCodeの内容で判定して、通信エラーを検知することができます。
具体的には、msg.statusCodeの内容が200かotherwiseというように判定する。
msg.statusCodeには、数値だけではなく文字列が入ることがあるためです。
例えば、HTTPリクエスト先URLのサーバが起動していない場合は、msg.statusCodeに”EHOSTUNREACH”という文字列が入ってきます。

（例）msg.statusCode：200
![スクリーンショット 2017-12-16 20.12.32.png](https://qiita-image-store.s3.amazonaws.com/0/223295/57b97ea9-6e68-651b-1ec3-6fc5c19388b7.png)

（例）msg.statusCode：”EHOSTUNREACH”（HTTPリクエスト先URLのサーバが起動していない場合）
![スクリーンショット 2017-12-16 20.18.38.png](https://qiita-image-store.s3.amazonaws.com/0/223295/7a4dd0ae-330a-10eb-4ce4-15384bdbd1ce.png)

通信エラーを検知して画面に何かアラートを表示する際には、活用できると思います。

# ２．メモリの負荷を減らす工夫

デバッグノードを繋ぐことでフローが二股になるようなところでは、メモリの負荷を減らすために、デバッグノードの線を削除した方が良いです。
フローが二股になるとmsgデータがコピーされるため、メモリの負荷に繋がるようです。

私の場合は、デバッグノードを使用せずに、ファンクションノードでnode.status関数を使用して、ファンクションノードの下にデバッグノードで表示していた内容を表示するように工夫しています。

（例）ファンクションノード
![スクリーンショット 2017-12-16 21.07.18.png](https://qiita-image-store.s3.amazonaws.com/0/223295/fba783ab-eee1-cff5-70e2-f6d4f7cfa8d0.png)

node.status関数の使用方法は、[ドキュメント](https://nodered.org/docs/creating-nodes/status)を参照ください。

# ３．WebSocketの接続エラーを検知する方法

ステータスノードを使用すると、WebSocketの接続状態を検知することができます。
具体的には、connected 又は disconnectedという状態が取得できます。

（例）ステータスノード：connected
![スクリーンショット 2017-12-16 21.54.03.png](https://qiita-image-store.s3.amazonaws.com/0/223295/ffa50eac-a360-738c-157e-9364c100ed28.png)

（例）ステータスノード：disconnected
![スクリーンショット 2017-12-16 21.56.10.png](https://qiita-image-store.s3.amazonaws.com/0/223295/c4be7ecc-a9f5-3d6f-73b8-34d386f1716a.png)

WebSocketの接続状態を検知して、画面に何かアラートを表示する際に活用できると思います。
pythonで多次元配列を作成する関数を自作した

# 初めに
pythonの多次元配列を作るには内包表記を入れ子にしなければなりません。
それでは面倒なので多次元配列を作る関数を自作しました。

# ソースコード

```python3

def make_array(n,init_elem=0,td=1):
       dimension=len(n)
       if td>=dimension:
           return [init_elem for i in range(n[td-1])]
       else:
           return [make_array(n,init_elem,td+1) for i in range(n[td-1])]
```


# 使い方

## 1次元配列を定義する

```python3
print(make_array([10],0))
#[0,0,0,0,0,0,0,0,0,0]
```
## 初期化する数値を変える

```python3
print(make_array([10],1))
#[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
```


## 5\*4の2次元配列

```python3
print(make_array([5,4],0))
#[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
```

## 5次元配列(2\*2\*2\*2\*2)

```python3
print(make_array([2]*5,0))
#[[[[[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[0, 0], [0, 0]], [[0, 0], [0, 0]]]], [[[[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[0, 0], [0, 0]], [[0, 0], [0, 0]]]]]
```
R.layout.activity_mainってなに？


```java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

```
ソースコードを追ってみると、Rクラスのlayout(staticなメンバークラス)のactivity_mainという変数を参照している。
Rクラスではjavaで使用する変数と様々なファイル(Androidで描画などに使用するxmlファイル)の紐付けをしている模様。
Rクラスはパッケージ直下のディレクトリに配置されている(MainActivity.javaなどと一緒の階層)。Android StudioではProjectウィンドウでPackageを選択すると探しやすい。
Amazon Linux 2 で Headless Chrome を動かしてみた

# 概要

Amazon Linux で Google Chrome を動かそうとすると、パッケージの依存関係の問題でインストールがなかなかうまくいきません。

Amazon Linux 2 の LTS 版が出たので、早速再挑戦してみました。

試した環境はこんな感じ。

```
$ cat /etc/system-release

Amazon Linux 2
```


# Google Chrome をインストール

Linux 版が RPM で配布されているのでこれを使用します。

```
$ sudo yum -y install https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
```

パッケージの依存関係のエラーは出ず、インストールは完了。


# Headless モードで動かしてみる

スクリーンショットを撮ってみます。

```
$ google-chrome --headless --disable-gpu --window-size=1024,768 --hide-scrollbars --screenshot='yahoo.png' https://www.yahoo.co.jp

[0716/141244.079664:ERROR:gpu_process_transport_factory.cc(1017)] Lost UI shared context.
Fontconfig warning: "/etc/fonts/fonts.conf", line 146: blank doesn't take any effect anymore. please remove it from your fonts.conf
[0716/141245.205569:INFO:headless_shell.cc(590)] Written to file yahoo.png.
```

エラーは出ましたがスクリーンショットを保存した画像ファイルが生成されました。

結果

![yahoo.png](https://qiita-image-store.s3.amazonaws.com/0/18609/5e85f58c-b6de-60e3-6c47-3b3416f57a3a.png)

残念。
スクリーンショットは撮れましたが、日本語が出ません。


日本語フォントをインストールしてからもう一度。

```
$ sudo yum -y install ipa-gothic-fonts

$ google-chrome --headless --disable-gpu --window-size=1024,768 --hide-scrollbars --screenshot='yahoo.png' https://www.yahoo.co.jp

[0716/142052.156208:ERROR:gpu_process_transport_factory.cc(1017)] Lost UI shared context.
Fontconfig warning: "/etc/fonts/fonts.conf", line 146: blank doesn't take any effect anymore. please remove it from your fonts.conf
[0716/142053.271844:INFO:headless_shell.cc(590)] Written to file yahoo.png.
```

同じエラーが出ていますが、スクリーンショットを保存した画像ファイルが生成されました。

結果

![yahoo.png](https://qiita-image-store.s3.amazonaws.com/0/18609/6c6cec12-2da3-554f-c86c-7e20cde389f3.png)

成功🎉


# 発生したエラーについて

```
Fontconfig warning: "/etc/fonts/fonts.conf", line 146: blank doesn't take any effect anymore. please remove it from your fonts.conf
```

このエラーは `Fontconfig` の設定ファイル（ `/etc/fonts/fonts.conf` ）の変更で対応。

`blank` タグの定義が不要になったので、`<blank>` と `</blank>` を消してしまうか、

```
<!-- <blank> -->
※この間はそのまま
<!-- </blank> -->
```
のようにコメントアウトで対応。

```
[????/??????.??????:ERROR:gpu_process_transport_factory.cc(1017)] Lost UI shared context.
```

このエラーは Chrome を Headless モードで実行した時に発生するらしい。対応方法については現時点では不明。Chrome のアップデートで解消されることを期待。

# まとめ

Headless Chrome を使えば、Webサイトのサムネイルを作ったり、 Selenium でごにょごにょしたりといろいろできます。

Amazon Linux 2 のLTS版が出たので、これからいろいろなAWSサービスでも使えるようになるかもしれませんね。

Lambda や Fargate のようなサーバレスなサービスでも使えるようになると面白そう。
BUFFALO RAMDISK ユーティリティーをWindows10で動作させる

BUFFALO RAMDISK ユーティリティーをWindows10にインストールし、動作させることに成功しました。(※いくつか注意点あり)
インストールしたのはASUS TransBook T304UA(T304UA-7200) Windows 10 Homeです。
![2017-12-16 (2).jpg](https://qiita-image-store.s3.amazonaws.com/0/178471/d54a67f1-3556-2099-ed82-6046cf488b4a.jpeg)


#なぜBUFFALO RAMDISK ユーティリティーなのか？
他にもRAMDISKソフトはあるのですがベンチマークが出なかったり、設定が面倒だったりと一長一短で、シンプルなこのソフトを使っていました。Windows7やWindows8.1は対応しているので問題なく動作していたのですがWindows10になってからはインストールするとブルースクリーンエラーを起こし、永遠と再起動するので諦めていました。

#BUFFALO RAMDISK ユーティリティーとはなんぞや？
下記で解説していますのでこの記事では説明を省略します。

ラムディスクでWindowsの限界を突破する | メモリーMAX増設で本当の力が目を覚ます | BUFFALO バッファロー
http://buffalo.jp/products/catalog/memory/speedup/ramdisk.html

筆者はRAMDISK上にFirefoxをインストールして使っています（とても快適です

#ダウンロードは以下から可能です。
BUFFALO RAMDISK ユーティリティー
http://buffalo.jp/download/driver/memory/ramdisk.html

#Window10にインストールするには
全ての環境で検証している訳ではないため実行は自己責任でお願いします。
Windowsの互換モードでWindows7としてインストールします。
ダウンロードしたbuffalo_ramdisk_utility-xxxx.exeを右クリック

プロパティを開きます
![2017-12-16.jpg](https://qiita-image-store.s3.amazonaws.com/0/178471/e11f6383-3461-774f-ef8e-cad8f3f93849.jpeg)


互換性タブをクリックして互換モードでこのプログラムを実行するにチェックを入れて、プルダウンからWindows7を選びます。
![2017-12-16 (1).jpg](https://qiita-image-store.s3.amazonaws.com/0/178471/06a2d5d5-da40-e2bc-60f6-69754420f58a.jpeg)


適用→OKを押してexeファイルをクリックしてインストールを行います。

後はインストーラーの指示に従って再起動します。

#注意点
- Windows10の大型アップデートが来るたびにRAMDISKの設定が消され、内容も消えます。
- 大型アップデートの後もタスクトレイに起動していますが再設定できませんので再インストールする必要があります。(再インストールする場合、Cドライブに展開されたインストーラーでも可能のようです。)

BUFFALOさんWindows10対応してくれるかなぁ・・・

PS:
Windows10 1803からはこの方法は使えませんでした。
MMD4MecanimでUnity上でMMDモデルがfbxに変換できない

###MMDモデルをUnity上で使う
には具体的に
http://tsubakit1.hateblo.jp/entry/2014/09/27/235941
や
https://qiita.com/hiroyuki_hon/items/931c79164b0ffe19517f
などを参考にしてください。

そこで
http://stereoarts.jp/
上記のサイトからMMD4Mecanimってのを使うと思うんですが、
手順通りに進んでいくと、prosessボタンおして3dモデルがつくられる！
ってとこで詰まります。
`processed pmx2fbx`
ってコンソール上にでるんですけど謎のコードがたくさん書いてあるファイルが出力され特にfbxのモデルは出力されません。

MMD4Mecanim/Editorの中にunity4,unity5というフォルダがあって
どうやら**現時点(2017/12/16現在)ではUnity2017は対応してないっぽい**です。


Unityのバージョンを下げると動くっぽいのでもし詰まっている人いたら試してください。
ほかの楽譜ソフトから LilyPond ソースに変換する (MusicXML)

[LilyPond Advent Calendar 2017](https://qiita.com/advent-calendar/2017/lilypond) 12月17日の記事です。

こんばんは、 norisio (aka. [skb_apos](https://twitter.com/skb_apos)) です。

# TL; DR
GUI ソフト → MusicXML → (`musicxml2ly`) → LilyPond ソース
`musicxml2ly` は python2 スクリプト

# MusicXML とは
> MusicXMLは、XML形式の楽譜表記のためのオープンなファイルフォーマットである。
> (中略)
> **Finale**や**Sibelius**、Rosegarden、Notionなどの楽譜作成ソフトウェアによって作成することが可能である。

[(Wikipediaより引用)](https://ja.wikipedia.org/wiki/MusicXML?oldformat=true)

つまりは、「楽譜」の「共通フォーマット」ということですね。 LilyPond のパッケージには、この MusicXML を LilyPond ソースに変換するスクリプトが付属しています。

これを使うことによって、

* 最初は他の GUI ソフトで MIDI キーボード を使ってゴリゴリ打ち込み
* 変換して LilyPond で浄書
 
というフローをとることができそうです。

# 実際にやってみる
GUI ソフトで音符を打ち込み、 LilyPond ソースに変換して組版をかけてみます。

### Musescore で打ち込み
できました。

<img width="803" alt="ss 2017-12-16 21.43.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/102831/cc9dc47d-0d45-bf77-411b-fc0f79680dde.png">

強弱記号（デフォルト位置からずらす）、フェルマータを入れてみました。

これを、 `gakufu.xml` として MusicXML 形式でエクスポートしておきます。

### `musicxml2ly` で処理

コマンドラインから `musicxml2ly` に MusicXML を食わせます。

```
$ /path/to/musicxml2ly gakufu.xml
```

Mac で LilyPond パッケージ版の場合、スクリプトは `/Applications/LilyPond.app/Contents/Resources/bin/musicxml2ly` にあります。
Windows でインストーラを使ってインストールした場合、 `C:\Program Files (x86)\LilyPond\usr\bin\musicxml2ly.py` にあります。

**注意:** `python` コマンドで起動する Python インタプリタが **Python 3 系であると動作しません**。 Python 2 系が起動するように変更してください。

### LilyPond で組版

できました。
<img width="943" alt="ss 2017-12-16 21.59.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/102831/b64975e1-1881-23bc-9261-ada667c2858b.png">

歌詞が少し消えていますが、変換自体は概ね正しいものです。

# `musicxml2ly` の出力の特徴
Musescore からの変換しか試せていませんが、概ね次のような特徴をもったソースを吐き出します。

* 歌詞・パートはそれぞれの変数に代入される
    * 一部複数ボイスがあると `s1` が量産される Voice ができる
* Staff にひとつあればよい記述 (`\bar` など) が全てのパートに存在こともある
* 連桁はすべて陽に記述される (`autoBeaming = ##f`)
* 改行・改ページはすべて `\break`, `\pageBreak` で陽に記述される
* 小節チェック `|` の箇所で改行され、小節番号がコメントされる

# おわりに

LilyPond は打ち込み用のソフトウェアではないので、こういった分業もけっこう「あり」だと思います。
開発環境の構築をモブプログラミングを用いてやってみた話

- これは[DMM\.com \#2 Advent Calendar 2017 \- Qiita](https://qiita.com/advent-calendar/2017/dmm2) 16日目の記事です。
- 昨日は @h_shinonome さんの [カンファレンス、勉強会にいこう！](http://shinonome.hateblo.jp/entry/2017/12/15/192514) でした
- カレンダーのURLはこちら
    - [DMM\.com \#1 Advent Calendar 2017 \- Qiita](https://qiita.com/advent-calendar/2017/dmm)
    - [DMM\.com \#2 Advent Calendar 2017 \- Qiita](https://qiita.com/advent-calendar/2017/dmm2)

## tl;dr
- 先に言うと、構築は完了できませんでした
    - ヤマもオチもないです
- 構築に用いる技術の話はしません

## まえがき
- 開発環境をプライベートクラウド上に構築しようとした時の話です
- 構築する際以下の要素が課題になりそうだった
    - ansible周りの技術ノウハウ
    - Docker周りの業務ノウハウ
    - 環境構築に必要なネットワーク周りのノウハウ
- メンバーは4人
- [モブプログラミングを実際にやってみた \- Qiita](https://qiita.com/TAKAKING22/items/31e027dfb6ea8b1a8d69) とか見つつ、以下の理由からモブプログラミングを採用した
    - チーム内に各課題の詳細をわかっている人がいなかった
    - 一人でやるより知恵を出し合った方がスムーズに進みそう
    - 作業で得た知見の共有コストを減らしたい

## 実際やってみた

### 共通ルール
- 定時前に1日1時間毎日やる
- モブプログラミングより案件優先
- 参加者が少ない場合はスキップ
- 会議室等でなく、ドライバーの自席付近に集まっておこなう
- モブプログラミング中のチャットは毎回slackの新規スレッドを立ててそこで会話する
    - 環境構築のスレッドと混ぜると後から見た際ノイズになるため
    - 毎回立て直すことで「この問題モブプログラミング3回目で参考にしたURLに解決方法書いてあったな」といったものを見つけやすくする
        - 実際これは多々あった

### 序盤ルール＆反省点
- 1つのデスクトップPCをドライバ交代ごとにローテーションして使用する
    - 不慣れなキーボードやターミナルでのストレスによる効率の悪さが目に見えてわかった
- 15分でドライバーをローテーションする
    - 作業が慣れてくる前に交代してしまうので進捗ゼロになることもあった
- モブプロ中のわからなかったことはその場ではなく終わってから質問する
    - 理解していないまま作業を続行しても共有にならなかったりする
    - 質問事項を忘れてしまう

### 中盤以降のルール
- 自分のPCを使用する
    - tmuxでセッション共有する
        - ドライバーのローテーションがスムーズになる
        - コマンドを斜め読みしつつWebブラウザで解決方法探すとかがやりやすくなった
- 30分でドライバーをローテーションする
    - 60分だとドライバーが疲弊してしまう
    - 30分がちょうどよかった
- モブプロ中にわからないことがあればその場で質問する
- モブプロ開始前、終了後にブリーフィングをする
    - 開始前
        - 昨日どこで終わったのか
        - 今日まずどこから手をつけるのか
    - 終了後
        - 今日なにをしたのか
        - モブプロに対するKPTを実施
        - 明日のモブプロ開始前までに解決しておいた方がいい課題がないか

## 突然のまとめ＆感想

- ある程度まで構築ができていたが、案件優先でメンバーの集まりが悪くなりモブプログラミングでの構築は断念することに。。。
- チャット(slackのスレッド)の利用方法, tmuxでの画面共有, ブリーフィングはとても効果があった
- 自分自身としては環境周りの知見を得ることができた
- 知見の共有しつつ作業するのにモブプロはとても向いてると思うのでチャンスを見つけて再挑戦したい
- ISUCON参加とかこんな感じなのかなと思った

## おわりに

- 明日は @naka_kyon さんになります。おたのしみに
- \\( ⁰⊖⁰)/ ***Let's ﾓﾌﾞﾓﾌﾞ!!***
安全性解析手法STAMP/STPAセミナー＠大阪に行ってきました

# [安全性解析手法STAMP/STPAセミナー＠大阪](https://sec.ipa.go.jp/seminar/20171216.html) に
行ってきました。
すいません、遅れて入っていって。

## 主な配布物
以下に公開されている資料を書籍でいただきました。ありがとうございます。
https://www.ipa.go.jp/sec/reports/20160428.html
https://www.ipa.go.jp/sec/reports/20170324.html

あと、講演内容の資料も。

# 以下、その時の記録メモ。

## STAMP/STPAって何？
いただいた資料『はじめてのSTAMP/STPA』の「はじめに」に、

* STAMP : Systems-Theoretic Accident Model and Processes
* STPA : System-Theoretic Process Analysis

とあります。
あれ？前者はシステムが複数、後者はシステムが単数。
まあ、誤記かなぁ？まあいいや。

先にすすんで、2ページ目「1.1.アクシデントモデル STAMP」にも説明がありました。

*「STAMP(Systems-Theoretic Accident Model and Process):システム理論に基づくアクシデントモデル」*
とあります。
あれ？英語の"and Process"はどこいった？

システム理論とは、[一般システム理論](https://ja.wikipedia.org/wiki/%E4%B8%80%E8%88%AC%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E7%90%86%E8%AB%96) のことなんでしょうか？
ともかく、ここで重要そうなのは、
**「制御する側(コントローラー)のプロセスモデルが、制御される側(被コントロールプロセス)の状態を正しく反映できていない」⇒「制御する側(コントローラー)が不適切なコントロールアクションを起こしてしまう」** ということのようですね。
確かにそうかも。

で、3ページ目「1.2.安全解析手法 STPA」の説明を読んでみます。
*Leveson教授が提唱したSTPA(STAMP based Process Analysis)* ???
あれ？さっきと違う。「STAMPに基づいたプロセス解析」ってなっていますね。
どちらが正しいんでしょうか？どちらにせよ、プロセス解析をする方法のようですね。

```
Step 0:(準備1)アクシデント、ハザード、安全制約の識別
Step 0:(準備2)コントロールストラクチャーの構築
Step 1:非安全なコントロールアクション(UCA)の抽出
Step 2:ハザード要因(HCF)の特定
```
これってプロセス解析の手順とはあんまり思えないなぁ。
ちょい疑問がわいてきました。

## STAMP/STPAの個人的な理解と見解(現時点)

いまのところ、STPAは、STAMP based Process Analysisの方がしっくりきています。(後日ちゃんと調べてみたい。)
まあ、どちらにせよ、プロセスを分析する手法なんですよね。たぶん。

そして、STAMPとSTPAの関係性は、
STAMPで問題定義されている **「制御する側(コントローラー)のプロセスモデルが、制御される側(被コントロールプロセス)の状態を正しく反映できていない」⇒「制御する側(コントローラー)が不適切なコントロールアクションを起こしてしまう」** を、STPAで分析することで要求分析の時点でシステムに対する要求として安全性を担保しようということなんじゃないかなぁ？

でも、ここでのプロセスってなんなんだろう？
もしかすると、プロセス＝シナリオって、捉えてみると少ししっくりきた。
プロセス分析(ここではSTPA)した結果は、HCF⇒UCAの起こるシナリオがたくさん記述できる。
STAMPに記述のある被コントロールプロセス(Controlled Process)も、
それを模したプロセスモデル(Process Model)もシナリオの塊と捉えるといいのかな？
或る意味、ふるまいと捉えてもいいのかもしれない。

たくさんの人が受講していたので、みなさんどのように捉えてみられていたのだろうか？
RDBでのインデックス戦略

#RDBにおけるインデックスとは
インデックスを制する者はDBを制すぐらい重要な存在らしいです。
実生活で例えるなら、書籍などの巻末にある索引と同じような働きです。
それをDB上で行ってくれるのでテーブルに大量のデータが格納されていても検索を高速化できるのです。

#不適切なインデックスではデメリットも
便利なインデックスですが、インデックスもデータなので無駄が存在すると逆に処理が遅くなることもあるみたいです。

次のような箇所にはインデックスを作成するのは控えたほうが良さそうです。

・そもそも検索が行われないカラム
・格納されるデータが少数であるテーブル
・頻繁に更新が行われるテーブル

#RDBにおけるインデックスの種類と特徴
いくつか種類があり、要件によって使い分ける必要があります。

■B＋ツリーインデックス
これが一番ポピュラーなインデックスで、テーブルのデータとは別にデータ（インデックスの値）が格納されたリーフノードと、リーフノードへの経路を示すノンリーフノードが形成されます。

ノンリーフノードにはリーフノードが保有している最小値が格納されます。
階層が増えても1つの経路を検索すればいいので効率的です。

![スクリーンショット 2017-12-16 20.46.50.png](https://qiita-image-store.s3.amazonaws.com/0/210891/d2f4942e-2b60-a3c5-ee00-4bfa937a2402.png)

■ハッシュインデックス
範囲検索（100〜200までの値を検索したい等）は出来ないが等価比較（123という値を検索したい等）による検索は非常に早いのが特徴です。

■全文検索インデックス
行に含まれる単語や文字列で構成されたインデックス、英字には強いが日本語に弱いです。

■Rツリーインデックス
最小外接矩形という図形を用いた概念で構成されます。

■関数インデックス
関数を適用したクエリでインデックスを使いたい場合に有効です。

■ビットマップインデックス
カラムをビットで判定していてインデックスのスキャンは高速になるが、更新処理だと時間がかかるようです。

#最適なインデックス設計をするには
1.検索が行われない、データ少、更新多のケースでのインデックス作成は控える
2.インデックスが利用可能であるSQL構文を把握して、その構文に合ったインデックス作成を選定する
3.全体的なバランスを頭に入れてインデックスの組み合わせを考える
4.やり過ぎない

#参考文献
技術評論社 「理論から学ぶデータベース実践入門」
【AutoScalingGroup】スケールのスケジュール実行方法メモ



# スケジュールされた時間にスケールする

- [スケジュールに基づくスケーリング](http://docs.aws.amazon.com/ja_jp/autoscaling/latest/userguide/schedule_time.html#create-sch-actions-aws-cli)

```
$ aws autoscaling put-scheduled-update-group-action \
  --scheduled-action-name scheduled-scale-out \
  --auto-scaling-group-name sample-auto-scale \
  --start-time "2017-12-10T14:00:00Z" \
  --desired-capacity 2
```

# CloudWatchのメトリクスを元にスケールする


- [簡易スケーリングとステップスケーリングポリシー](http://docs.aws.amazon.com/ja_jp/autoscaling/latest/userguide/as-scaling-simple-step.html)

今回はCPU使用率をメトリクスに以下のルールでスケールするように設定します。

| CPU使用率 | アクション |
|:--|:--|
| 70 <= CPUUtilization < 80 | 現在のインスタンス数から10%増やす|
| 80 <= CPUUtilization < 90 | 現在のインスタンス数から20%増やす|
| 90 <= CPUUtilization (90%以上) | 現在のインスタンス数から30%増やす|

## ScalingPolicyを作成する

```
$ aws autoscaling put-scaling-policy \
  --auto-scaling-group-name sample-auto-scale \
  --policy-name sample-auto-scale-step-policy \
  --policy-type StepScaling \
  --adjustment-type PercentChangeInCapacity \
  --metric-aggregation-type Average \
  --step-adjustments MetricIntervalLowerBound=10.0,MetricIntervalUpperBound=20.0,ScalingAdjustment=10 \
                     MetricIntervalLowerBound=20.0,MetricIntervalUpperBound=30.0,ScalingAdjustment=20 \
                     MetricIntervalLowerBound=30.0,ScalingAdjustment=30 \
  --min-adjustment-magnitude 1

```

`--step-adjustments`のパラメータですが、

> API または CLI を使用している場合は、違反しきい値と相対的に上限と下限を指定します。

なので、`CloudWatch Alarm`の閾値を60%にする想定で、差分を指定しています。
例えば、CPU使用率70%以上80未満の指定は `MetricIntervalLowerBound=10.0,MetricIntervalUpperBound=20.0`のように行っています。

## CloudWatch Alarmを設定する

```
$ aws cloudwatch put-metric-alarm \
  --alarm-name sample-auto-scale-out-alarm \
  --metric-name CPUUtilization --namespace AWS/EC2 \
  --statistic Average \
  --threshold 60 --comparison-operator GreaterThanOrEqualToThreshold \
  --period 180 --evaluation-periods 1 \
  --dimensions "Name=AutoScalingGroupName,Value=sample-auto-scale" \
  --alarm-actions arn:aws:autoscaling:us-west-2:999999999999:scalingPolicy:xxxxxxxx-yyyy-zzzz-aaaa-999999999999:autoScalingGroupName/sample-auto-scale:policyName/sample-auto-scale-step-policy
```

対象のAutoScalingGroupを　`--dimensions`で指定します。
またこのアラームで作成したScalingPolicyを呼び出して欲しいので `--alarm-actions`で先ほど作成したScalingPolicyのARNを指定します。
またScalingPolicy作成時に閾値を60に想定して差分指定していたので`--threshold`を60に指定します。
Redmine本体のクラスメソッドを変えるプラグインを作る

あまり推奨されるようなことではないけれど、Redmineの機能や表示を変えたい時に、本体を変更しなければ実現できないことがある。

これらの方法については、クラスメソッドではないメソッドを ``alias_method_chain`` を使って変更する方法が良く紹介されている。

ところが、まれにクラスメソッドや特異メソッドと呼ばれる、selfの付いたメソッドを変更したくなる時があり、意外とその方法がすぐには見つけられなかったので、今回書いておこうと思った。

ただ、この方法がRubyやRails的に最適なのかが分かっていないのが泣きどころ。バッドノウハウになることも覚悟している。

## 具体的にやりたいこと
Redmineのガントチャートにおいて、バージョンごとのチケットは開始日によってソートされる。今回やりたいのは、このソート順を開始日ではなくチケット名にすること。

というのも、要望を出してきたプロジェクトでは、チケットにプレフィックスを付けて工程を表していて、開始日でソートされると工程順が崩れるのでイヤだと。

このソート順は、Redmineを見ていくと、 ``redmine/lib/redmine/helpers/gantt.rb`` の ``sort_issue_logic`` メソッドが担っていることが分かった。
このメソッドは、 ``self.sort_issue_logic`` と定義されていて、プラグインからの書き換え方法が分からなかったのが発端。

## 実現方法
プラグインの **lib** 以下に置いたファイルが読み込まれるように、プラグインの **init.rb** で読み込みを追加。

```init.rb
Dir[File.expand_path('../lib/sort_subject_patch', __FILE__) << '/*.rb'].each do |file|
  require_dependency file
end
```

で、書き換えている場所。名前汚染を避けるため、moduleで囲ってる。
また、 ``define_singleton_method`` を使って、クラスメソッドを書き換えている。

```lib/sort_subject_patch/gantt_patch.rb
module GanttSortSubject
  module GanttPatch
    # includedを使うためにActiveSupportのConcernをextend
    extend ActiveSupport::Concern

    # 書き換えている場所
    included do
      # プラグインの設定によって、オリジナルも呼べるように退避
      original = Redmine::Helpers::Gantt.method(:sort_issue_logic)

      # define_singleton_methodを使うと、クラスメソッドを置き換えられる
      define_singleton_method :sort_issue_logic do |issue|
        # プラグイン設定がONの場合は、名前でソートに変更
        if '1' == Setting.plugin_redmine_plugin_gantt_sort_subject['sort_subject_enabled'].to_s
          issue_subjects = []
          current_issue = issue
          begin
            issue_subjects.unshift(current_issue.subject)
            current_issue = current_issue.parent
          end while (current_issue)
          issue_subjects
        # プラグイン設定がOFFの場合は、退避しておいたオリジナルを呼ぶ
        else
          original.call(issue)
        end
      end
    end

  end
end

# オリジナルのGanttクラスに差し込み
ActionDispatch::Reloader.to_prepare do
  unless Redmine::Helpers::Gantt.included_modules.include? GanttSortSubject::GanttPatch
    Redmine::Helpers::Gantt.send(:include, GanttSortSubject::GanttPatch)
  end
end

```

## まとめ
今回、本体のしかもクラスメソッドを書き換えてみて、プラグインで実現できる柔軟性に感心するとともに、こんなに気軽に書き換えられる怖さも感じた。

プラグインで外に出していて、かつ設定でオリジナルも呼び出せるようにしたとはいえ、バージョンアップによる変更や他のプラグインとの衝突時に不具合解析を追うのが難しそう。

どうしても実現したい時に、最小スコープでやるようにして、乱用しないように気をつける必要がある。

## 参考
[今回作ったプラグイン - Gantt Sort Subject plugin](https://github.com/Qhornet/redmine_plugin_gantt_sort_subject)
jsPerfで速度測定

コードの速度を測定するとなると、意外と準備とか評価が面倒ですが、JavaScriptの場合は[jsPerf](https://jsperf.com/)というサイトがあります。

# 使い方
まずは、GitHubアカウントが必要なので、連携ログインします。すると、入力フォームが出てきます。

* Your details…作者の情報。なくても動きます。
* Title…テストのタイトル（必須）
* Slug…テストに振るURL（必須、既存のと重複不可）
* Preparation code HTML…テスト用に準備しておくHTML。DOM操作のテストをする場合の準備や、あるいは`<script>`でJavaScriptライブラリを読み込んでおくなどに使えます。
* Define `setup` for all tests…時間測定に入らない、事前準備の部分。必要な関数・変数を用意するなどに使いましょう。
* Define `teardown` for all tests…時間測定に入らない、後片付けの部分。生成したDOM要素を処分するなど、必要な時があるかもしれません。
* テストケース…比較対象を書いていきます。

これを入れれば、あとは「Run」を押すだけで、繰り返し測定、標準偏差の算出など、自動的に進んでいきます。同じURLにアクセスすれば、ブラウザを変えての測定もいとも簡単にできてしまいます。

# 注意点

「暗号の安全性確保のために処理速度がかかる必要がある、あるいは複数の処理対象で有意な時間差を作ってはいけない」というような例を除けば、「速くなることがデメリットになる」場面はほぼ存在しません。

ただし、速くしてどれだけのメリットがあるのかは、状況によって違ってきます。たとえば、ブラウザ上で行うイベント処理などは、速い方がいい…のは間違いないのですが、ブラウザが1フレームを描画し直す1/60秒に間に合うのであれば、それ以上高速化してもユーザーへのメリットはほぼありません。

ということで、自分の考える使い方は以下のようなところです。

* 悪魔に魂を売ってでも、速さが必要な場合…思考ルーチンや仮想DOMのメインループなど、速さがプロダクトの価値そのものに直結する場合は、徹底的に考えて書く必要があります。
* 関数などでラップできるような場合…関数化できる操作であれば、適切なテストを行いつつ、関数外には影響を及ぼさずに内部だけの最適化が可能です。
* 地雷を避ける場合…JavaScriptでは、ときおり「書き方によって数十倍以上遅くなってしまう」ようなことがあります（[実際に遭遇した例](https://qiita.com/jkr_2255/items/d53200e6001b4d28e8f7)）。高速にチューニングする必要がないような場面でも、さすがに数十倍遅いものは選ばないほうがいいでしょう。

逆に、`click`ハンドラ内のコードを書くときに、「スコープの遠い変数が遅い」とか「`i++`と`++i`は速度的にどっちがいいのか」なんてのを気にするのは、やりすぎです。
MergeRecyclerAdapter使って、複雑なデータ構造のRecyclerViewを簡単に実装しよう


さてMergeRecyclerAdapterを知っていますか？
これはRecyclerViewで使うRecyclerView.Adapterを拡張したものです。
https://github.com/cattaka/AdapterToolbox/blob/master/adapter-toolbox/src/main/java/net/cattaka/android/adaptertoolbox/thirdparty/MergeRecyclerAdapter.java

確か1年位前に見つけ、今でもバリバリ使っています。
実際にどのように使うのかお伝えしたいと思います。

#導入

MergeRecyclerAdapterはGitHabで公開されております。
ライセンスもapache2.0なので問題いなく使えますね。
僕の場合は直接ファイルを直接取り込んで使っています。

```java
        RecyclerView recyclerView = ((RecyclerView) findViewById(R.id.list));
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        MergeRecyclerAdapter<BaseAdapter> mergeRecyclerAdapter = new MergeRecyclerAdapter<>(this);

        mergeRecyclerAdapter.addAdapter(new HeaderAdapter("aHeader"));
        AAdapter aAdapter = new AAdapter(aList, "aTag");
        mergeRecyclerAdapter.addAdapter(aAdapter);
        mergeRecyclerAdapter.addAdapter(new FooterAdapter("aFooter"));

        mergeRecyclerAdapter.addAdapter(new HeaderAdapter("bHeader"));
        BAdapter bAdapter = new BAdapter(bList, "bTag");
        mergeRecyclerAdapter.addAdapter(bAdapter);
        mergeRecyclerAdapter.addAdapter(new FooterAdapter("bFooter"));

        mergeRecyclerAdapter.addAdapter(new HeaderAdapter("cHeader"));
        AAdapter cAdapter = new AAdapter(cList, "cTag");
        mergeRecyclerAdapter.addAdapter(cAdapter);
        mergeRecyclerAdapter.addAdapter(new FooterAdapter("cFooter"));
        recyclerView.setAdapter(mergeRecyclerAdapter);

```

簡単に書くとこのような感じです。
A要素B要素C要素があり、それぞれの塊ごとにheader,footerを持つリストを作っています。
A要素とC要素は同じデータ構造をしています。

HeaderAdapter、FooterAdapter、A要素を表示するAAdapter、B要素を表示するBAdapterを作成しておきます。
C要素に関してはA要素と同じデータ構造なのでAAdapterを使いまわします。
これらのadapterはBaseAdapterというTagを保持できるRecyclerView.Adapterを継承しています。

まず各adapterを生成してMergeRecyclerAdapterに追加していきます。
そしてMergeRecyclerAdapterをrecyclerViewにセットしてあげます。

これで表示までは完了です。
とても簡単ですね。

リストにクリックに関してはDataBinding+ViewModelを用いて行のレイアウトに直接onClickListenerを設定し、EventBusにてActivityやFragmentに通知を行いハンドリングを行っています。

#メリット
使った上で気がついたメリットを何点かあげます。

Adapterが大きくならない
　1つのadapter内で別のデータを扱わないので、データの型の確認をしてlayoutやviewModel指定しなくてよい
汎用性が増す
　データの型ごとにadapterを作るので、1画面1adapterにならず、adapterの使い回しが容易
複数の配列を組み合わせる時のpositionを考慮しなくて良い
　adapterごとにpositionが0から取れるのでIndexOutOfBoundsExceptionが起きにくい
全件分のデータ取得を待つ必要がない
　adapterごとにデータがあればいいので、複数APIでデータを取得するとしても取得したところから表示ができる
　その場合は先にadapterを生成してMergeRecyclerAdapterに渡し、データ取得後にnotifyDataSetChanged()などで変更を通知すれば良い

#デメリット
クラスの数がとても増える
　これがデメリットになるかは毎度問題になりますが、しいて挙げるならこれくらいになるでしょうか。

#まとめ
サンプルでは各adapterがtagを持っていますが実際には使う機会は少ないです。
例えばpagingをする必要があり、なおかつpagingしたブロックごとに何かをしないといけない場合とか。
adapterの持つデータに関して何か行う場合に、同じ型のadapterが複数ある可能性があるのでその時の対応策です。

これを使って思ったのがiOSのtableViewのセクションと同じような動作をさせられること
分割してデータを入れられたり簡単にheder,footerが入れられたり、メリットが沢山あるものです。

ご覧の通りAdvent Calendar 2017の記事になるのですが、本当はGoogle Homeのことを書きたかったのですが、思ったとおりに動かすことができず、断念。
急遽この内容に変更しました。
近いうちにつまずいたところも含めGoogle Homeの記事を書きたいなと思っています。
SICP読書録 #4 1.2.1 線形再帰と反復

[hiroshi-manabe様の日本語訳](https://github.com/hiroshi-manabe/sicp-pdf)を使わせてもらいます。
練習問題等は[Gauche](http://practical-scheme.net/gauche/index-j.html)で実行。

[前回はこちら](https://qiita.com/shuetsu@github/items/0ecf93e71abc06d40f4e)

# 1.2.1 手続きとそれが生成するプロセス

階乗を求める以下のコード。
これは、$n! = n(n-1)!$ だということを利用している。

```1_2_1_0.scm
(define (factorial_1 n)
  (if (= n 1)
    1
    (* n (factorial_1 (- n 1)))))
```

`(factorial_1 5)`がどう展開されるか？

```1_2_1_1.scm
(factorial_1 5)
(* 5 (factorial_1 4))
(* 5 (* 4 (factorial_1 3)))
(* 5 (* 4 (* 3 (factorial_1 2))))
(* 5 (* 4 (* 3 (* 2 (factorial_1 1)))))
(* 5 (* 4 (* 3 (* 2 (* 1))))))
...
```

これを**再帰プロセス**という。
ネストが深くなるたび右へ伸びる。つまり記憶すべき情報量が増えていく。

では、次の例はどうか？
掛け算を`1*1`から始め、1ずつ数を増やす。指定された`n`に到達したら終了。

```1_2_1_2.scm
(define (factorial_2 n)
  (define (iter product counter)
    (if (> counter n)
      product
      (iter (* counter product)
            (+ counter 1))))
  (iter 1 1))
```

レキシカルスコーピングにより`n=5`は`iter`手続きから見える。
展開すると以下のように。

```1_2_1_3.scm
(factorial_2 5)
(iter 1 1)
(iter 1 2)
(iter 2 3)
(iter 6 4)
(iter 24 5)
(iter 120 6)
120
```

右へ伸びていかない。つまり記憶すべき情報量が再帰のたびに増えない。
これを**反復プロセス**という。

どちらも**再帰手続き**（手続きが、その手続き自信を参照してる）なんだけど、
`factorial_1`は再帰プロセスとなり、`factorial_2`は反復プロセスとなって、それぞれ異なる。

一般的な言語では、再帰手続き 即 再帰プロセス になっちゃう。
スタックを積まなきゃいけないしね。だからforやwhileのようなループ構造があるのだ。

しかしSchemeでは再帰手続きの結果をなんらかの演算に使わないのなら、
それを反復プロセスとして実行する。これを**末尾再帰**という。

## 練習問題 1.9

`+`を以下のように再定義しちゃった。
ちなみに`inc`はインクリメント。`dec`はデクリメント。


```ex1_9_0.scm
(define (+ a b)
  (if (= a 0) b (inc (+ (dec a) b))))
```

`(+ 4 5)`を展開すると。

```ex1_9_1.scm
(+ 4 5)
(inc (+ 3 5)))
(inc (inc (+ 2 5)))
(inc (inc (inc (+ 1 5))))
(inc (inc (inc (inc (+ 0 5)))))
(inc (inc (inc (inc 5))))
(inc (inc (inc 6)))
(inc (inc 7))
(inc 8)
9
```

右に伸びていくので再帰プロセスになってる。

これならどうか。

```ex1_9_2.scm
(define (+ a b)
  (if (= a 0) b (+ (dec a) (inc b))))
```

同様に`(+ 4 5)`を展開する。

```ex1_9_3.scm
(+ 4 5)
(+ 3 6)
(+ 2 7)
(+ 1 8)
(+ 0 9)
0
```

めでたく反復プロセスになった。

## 練習問題1.10

これを*アッカーマン関数*というらしい。

```ex1_10_0.scm
(define (A x y)
  (cond ((= y 0) 0)
        ((= x 0) (* 2 y))
        ((= y 1) 2)
        (else (A (- x 1) (A x (- y 1))))))
```

実行結果は以下のとおり。

```ex1_10_1.scm
gosh> (A 1 10)
1024
gosh> (A 2 4)
65536
gosh> (A 3 3)
65536
```

以下の手続きについて数学的定義を与えよ。

```ex1_10_2.scm
(define (f n) (A 0 n))
(define (g n) (A 1 n))
(define (h n) (A 2 n))
```

なんだか知らないけど、それぞれ`n=4`として展開してみる。

```ex1_10_3.scm
(f 4)
(A 0 4)
(* 2 4)
8
```

`(f n)`の結果は$2n$。

```ex1_10_4.scm
(g 4)
(A 1 4)
(A 0 (A 1 3))
(A 0 (A 0 (A 1 2)))
(A 0 (A 0 (A 0 (A 1 1))))
(A 0 (A 0 (A 0 2)))
(A 0 (A 0 (* 2 2)))
(A 0 (A 0 4))
(A 0 (* 2 4))
(A 0 8)
(* 2 8)
16
```

`(g n)`の結果は$2^n$。

```ex1_10_5.scm
(h 4)
(A 2 4)
(A 1 (A 2 3))
(A 1 (A 1 (A 2 2)))
(A 1 (A 1 (A 1 (A 2 1))))
(A 1 (A 1 (A 1 2)))
(A 1 (A 1 4)) ; (A 1 2) = 2^2
(A 1 16)      ; (A 1 4) = 2^4
65536         ; (A 1 16) = 2^16
```

`(h n)`の結果は$2^{2^n}$か？と思ったけど違う。。。

例えば`(h 4)`は$2^{2^{2^2}}=65536$。`(h 3)`は$2^{2^2}=16$。2乗を$n-1$回繰り返した数になる。
数学的定義としてはどう書けばいいんだろう？
Storyshotsが最高すぎる件

こんにちは、@takanoripです。

今回は最近導入した`Storyshots`というやつを紹介していきたいと思います。

## [Storyshots](https://github.com/storybooks/storybook/tree/master/addons/storyshots)
`Storyshots`は`Storybook`のアドオンで、Storybookに登録されているコンポーネントのスナップショットテストをしてくれます。できることはjestのスナップショットテストとほぼ同じです。

Storyshotsを使うと、コンポーネントごとにテストファイルを用意しなくて良いので手軽にスナップショットテストを導入することができます。

すでにStorybookを導入していれば、下記ファイルを追加するだけでOKです。

```js:Storyshots.test.js
import initStoryshots from '@storybook/addon-storyshots';

initStoryshots();
```

簡単でしょ？

また、Storyshotsを使うと、スナップショットテストができること以上に良い効果をProjectにもたらすことができます。その効果について説明していきます。

## [Storybook](https://storybook.js.org/)
Storybookは皆さんご存知だと思うので説明を省略します。
詳しく知りたい方は下記の記事を読むと良いと思います。

[UI開発の流れが変わる！React Storybookでデザイナーも開発者も幸せになれる](https://www.webprofessional.jp/react-storybook-develop-beautiful-user-interfaces-with-ease/)
[Introduction](https://storybook.js.org/basics/introduction/)

ReactでSPAを開発してい人はけっこう使ったことあるんじゃないかなと思います。

コンポーネントをサクッと一覧にしてくれてとっても便利なStorybookなんですが、1つ欠点があります。

それは**「めんどくささ」**です。

## `Storybook`にコンポーネント追加するのめんどくさい問題
どんなものもこの壁にぶち当たりますよね。

**「`Storybook`たしかに便利だけど、めんどくさいし後回しでいっかー」**

って感じにとてもなりやすいです。
特にStorybookはプロダクトには影響がないので、運用されなくなって枯れて死んでしまう…なんてこともあったりなかったりすると思います。

枯れたスタイルガイドほど役に立たないものはありません。

そこで`Storyshots`の登場です。

## `Storybook + Storyshots` = 「スタイルを確認できるUnit Test」
StorybookにStoryshotsを入れることで、「ただのスタイルガイド」ではなく、**「スタイルを確認できるUnit Test」**と考えることができるようになりいます。

プロダクトの品質を担保する上でテストは欠かせないもので、「めんどくさいからやらない」とはなりません。
このテストのフローにStorybookを乗せることによって、**スタイルガイドの更新もできスナップショットテストもできる**、素晴らしい流れが生まれるのです。

これでスタイルガイドがアップデートされず枯れてしまうことを防ぐことができ、簡単な設定でテストをすることができるようにもなります。

## まとめ
`Storyshots`を使ってより良いStorybookライフを送りましょう。
【Google Apps Script】その12　メール送信機能を作る

この記事は[Google Apps Scriptを実例交えて基礎からざっくり学ぶ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/gas_beginner)　12日目の記事です。

本アドベントカレンダーは@rt_pの個人プロジェクトですが、筆者は[Ateam Brides Inc. Advent Calendar 2017](https://qiita.com/advent-calendar/2017/a-t-brides)にも参加しています。そちらでも出張版記事を書いているので、覗いていただけると嬉しいです。

# はじめに

今回は簡易的なメルマガ配信システムを作ります。
メルマガで最も気をつけるべきことは、*宛先は一通一通TOを設定する、もしくはBCCを設定する*ことでしょうか。

TOや宛先に複数の送信先を設定すると他の受信者が見えてしまいます。稀に企業がメルマガの設定を失敗して情報漏洩のニュースになっていますね…気をつけましょう。


![mail.png](https://qiita-image-store.s3.amazonaws.com/0/199678/b2afc814-ede0-90ab-9f35-3f66bd1d21fe.png)

# メール配信リストを作る

まずはスプレッドシートを開き、下記のようなリストを作りましょう。
A列にメールアドレス、B列に相手の名前を入れます。

![sheet.png](https://qiita-image-store.s3.amazonaws.com/0/199678/8c11371b-723d-ca5c-e0cb-501d31982316.png)

**実在する可能性のあるメールアドレスは絶対に入力しないように！**そのメールアドレスに持ち主が存在する場合迷惑が掛かってしまいます。
`@example.com`はサンプルとして使っていいフリードメインなので安心です。

受信の確認をする為、自身のメールアドレスを入れるといいでしょう。


スクリプトエディタを開き、以下コードに置き換えて実行します。
スクリプトエディタの開き方や*承認が必要です*メッセージが出た際の対処法が分からない場合は
[アドベントカレンダー1日目のHello, world!記事](https://qiita.com/rf_p/items/0535ec495df8f9d2b894)をご参照ください。

```javascript:send_mail.gs
function myFunction() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var values = sheet.getDataRange().getValues();
  for (var i in values) {
    sendMail(values[i][0], values[i][1]);
  }
}

// メールを送る
function sendMail(mailto, name) {
  var subject = name + 'さんこんにちは';
  var body = name + "さん、お元気ですか？\r\n私は元気です。";
  GmailApp.sendEmail(mailto, subject, body); // メール送信
}
```

> sendEmail(recipient, subject, body) 

https://developers.google.com/apps-script/reference/gmail/gmail-app#sendEmail(String,String,String)

なんとこのコードを実行するだけで、入力した3名にメールが配信できます。

![mail.png](https://qiita-image-store.s3.amazonaws.com/0/199678/b2afc814-ede0-90ab-9f35-3f66bd1d21fe.png)

メールの送信を覚えたらできることが一気に広がります。
今まで紹介してきた定期実行の仕組みやAPIと組み合わせて、あらゆる指標の定期レポートが作れますね。

# おわりに

今回は短いですが以上です。

ちなみに`GmailApp`はメールの送信だけでなく、受信ボックスの中身を取り出して処理もできます。
今回のアドベントカレンダーでは特に触れませんが、興味があれば調べてみてください。

# 明日

[【Google Apps Script】その13　スプレッドシート上のグラフを画像として保存やメール送信する](https://qiita.com/rf_p/items/0480d85325811017b715)
となります。
スプレッドシートで作成したグラフを画像としてGoogleドライブに保存したり、メールで配信する方法を紹介します。

前の記事
[【Google Apps Script】その11　Webサイトのスクリーンショットを定期的にGoogle Driveに保存する](https://qiita.com/rf_p/items/1d9b3e7ac3c63d6dd117)
次の記事
[【Google Apps Script】その13　スプレッドシート上のグラフを画像として保存やメール送信する](https://qiita.com/rf_p/items/0480d85325811017b715)
vmware mksに接続できません ソケットの接続試行が多すぎます

VMware Workstation 14 Player
インストール、アンインストールを繰り返していたら

「mksに接続できません ソケットの接続試行が多すぎます」

環境：Windows7

コントロールパネル->システムとセキュリティ->管理ツール->サービス

VMware Authorization Service を開始させたら解決しました。
フロンターレをマイクロサービス化する

この記事は[FUJITSU Advent Calendar 2017](https://qiita.com/advent-calendar/2017/fujitsu)の17日目です。


本稿では、フロンターレの選手情報を、富士通のMicroProfile実装である[Launcher](https://github.com/fujitsu/launcher)を使用し、REST APIで提供するプログラムを作成する方法を紹介します。


#その前に、MicroProfileとは
MicroProfileは、企業向けマイクロサービスをJavaで実現するための仕様検討などを行うコミュニティです。  (http://microprofile.io)
本稿では、MicroProfile 1.1で策定されている、以下の４つのAPIを使います。

- JAX-RS
- CDI
- JSON-P
- Config

#プログラム作成にあたり事前に用意するもの

- Launcher(https://github.com/fujitsu/launcher/releases/download/1.0/launcher-1.0.jar)
- JDK 8

Launcherの中に上記４つのAPIがすべて含まれているので、それ以外のライブラリやJava EE用の開発環境等は不要です。


#処理の流れ

 1. Config APIを使い、フロンターレのページのURLや、必要に応じてPROXY情報を取得します。
 2. [フロンターレのページ](http://www.frontale.co.jp/)からHTMLを取得します。取得したHTMLをゴリゴリ解析、選手情報一覧を作成します。(ここはMicroProfileと関係なし)
 3. RESTのエンドポイントをJAX-RS/CDIで作成します。
 4. リクエストが来たら、JSONで返却します。

#ソースの作成

- [Player.java](https://github.com/kazumura/microprofile-frontale/raw/master/src/Player.java)
- [Frontale.java](https://github.com/kazumura/microprofile-frontale/raw/master/src/Frontale.java)
- [FrontaleApplication.java](https://github.com/kazumura/microprofile-frontale/raw/master/src/FrontaleApplication.java)
- [FrontaleService.java](https://github.com/kazumura/microprofile-frontale/raw/master/src/FrontaleService.java)
- [microprofile-config.properties](https://github.com/kazumura/microprofile-frontale/raw/master/src/microprofile-config.properties)

Frontale.javaのConfig APIのところだけ、解説。

```Frontale.java
     71     Config config = ConfigProvider.getConfig();
```

ConfigProviderからConfigオブジェクトを取得します。実際のプロパティ値は、このConfigオブジェクトを通して獲得します。

```Frontale.java
     77       url = config.getValue("frontale.url", String.class);
```

getValueメソッドの第一引数にプロパティ名、第二引数に型を渡します。プロパティ値が見つからなければ、NoSuchElementExceptionがスローされるます。

プロパティの指定はいろいろな方法がありますが、このプログラムでは、デフォルトのプロパティファイルを使用し、以下のように記述します。

```microprofile-config.properties
  frontale.url = http://www.frontale.co.jp/profile/2017/number.html
```

#コンパイル

~~~
% javac -classpath launcher-1.0.jar -d classes *.java
~~~

#jarの作成

クラスファイルおよびプロパティファイルは、以下のように、jarにまとめておきます。

~~~
% jar tf frontale.jar
META-INF/
META-INF/MANIFEST.MF
WEB-INF/
WEB-INF/classes/
WEB-INF/classes/META-INF/
WEB-INF/classes/kzr/
WEB-INF/classes/kzr/frontale/
WEB-INF/classes/META-INF/microprofile-config.properties
WEB-INF/classes/kzr/frontale/Frontale$1.class
WEB-INF/classes/kzr/frontale/Frontale$Parser.class
WEB-INF/classes/kzr/frontale/Frontale$Parser2.class
WEB-INF/classes/kzr/frontale/Frontale.class
WEB-INF/classes/kzr/frontale/FrontaleApplication.class
WEB-INF/classes/kzr/frontale/FrontaleService.class
WEB-INF/classes/kzr/frontale/Player.class
~~~

#アプリの起動

以下のコマンドを実行するだけ。JDK以外、事前のインストールは不要。

~~~
% java -Djava.io.tmpdir=. -jar launcher-1.0.jar --deploy frontale.jar​
~~~

#実行結果

- 選手の番号一覧 (http\://localhost:8080/list)
![](https://github.com/kazumura/microprofile-frontale/raw/master/pic/list.png)



- 狩野健太の情報 (http\://localhost:8080/25)
![](https://github.com/kazumura/microprofile-frontale/raw/master/pic/kanoken.png)



#おわりに

「マイクロサービス化」というのは言い過ぎでしたが、ここで紹介したように、MicroProfileを使うことで、簡単に軽量コンテナで動作するアプリケーションを作成することができるようになります。
ソーシャルメディアをPythonでスクレイピングしたときの参考リンク

## Twitter
- アクセストークン取得からTweepyを使ってみるところまで
[Tweepyを使って、PythonでTwitterのAPIを超簡単に操作する]
(http://www.statsbeginner.net/entry/2015/10/21/131717)

- Tweepyでできること
[API Reference]
(http://tweepy.readthedocs.io/en/v3.5.0/api.html)

- Streaming APIについて
[PythonでTwitter Streaming APIを叩いた話]
(https://qiita.com/nasa9084/items/40f223b5b44f13ef2925)

## Facebook

- アクセストークン取得まで
[FacebookのグラフAPIを使って簡単に自分の友達情報を取得する方法まとめ [python]]
(http://www.iruca21.com/entry/2017/09/17/210000)

- Facebook SDK for PythonでGraph APIを使う
[API Reference]
(http://facebook-sdk.readthedocs.io/en/latest/api.html)

- APIを簡単に試す
[グラフAPIエクスプローラ]
(https://developers.facebook.com/tools/explorer)

- Graph APIでできること
[Graph API Reference]
(https://developers.facebook.com/docs/graph-api/reference)

## YouTube

- APIキー取得とYoutubeAPIでできること
[YouTube Data API (v3)]
(https://developers.google.com/youtube/v3/getting-started?hl=ja)

- Youtubeの情報を取得する
[YouTube Data in Python]
(https://medium.com/greyatom/youtube-data-in-python-6147160c5833)
コンソールゲーム制作 第1章 描画(1)

# はじめに
(再び)コンソールで動くゲームの制作をする機会を得たので0から自分なりに効率の良い制作の仕方を紹介して行きます。

# コンソールゲームとは
ここでいうコンソールゲームはWindowsのコンソール上で動くゲームの事を指します。
![01.gif](https://qiita-image-store.s3.amazonaws.com/0/174660/19b2b96d-b319-1ecb-6a6f-ca35c6e882ac.gif)
*誰もが知っているこの黒い画面です。*

こんな者でゲームが動くわけがないと思うかもしれませんが、以外とこれでゲームを作ってる人がいて、Youtubeで「windows console game」と調べてみると色々出て来ます。

最初に書いたように"再び"制作するのですが、過去にこんなゲームを作っています。
C言語覚えたての頃なので温かい目で見守ってやって下さい（；
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">コンソールゲーム（黒歴史 <a href="https://t.co/DM5NsFvT5I">pic.twitter.com/DM5NsFvT5I</a></p>&mdash; Selector (@selector828) <a href="https://twitter.com/selector828/status/870923781618884608?ref_src=twsrc%5Etfw">2017年6月3日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

*埋め込みツイートが見れない場合はこちらの[リンク](https://twitter.com/selector828/status/870923781618884608)から

# 開発環境
- Visual Studio 2015 VC++
- Surface Pro 4
- Windows10
- Intel i5
- メモリ 4GB

PC性能でゴリ押しーなんて事はしたく無いので標準的(?)なスペックで制作をしています。

# 描画(出力)
コンソールでゲームを作るに当たって、間違いなく一番工夫をしなきゃ行けないのは**描画**です。
元々ゲーム向けでは無いので、用意されている物だけを使ってゲームを作らなきゃ行けません。

コンソール用に用意されている関数はMSDN([英語](https://docs.microsoft.com/en-us/windows/console/console-functions) : [日本語](https://msdn.microsoft.com/ja-jp/library/cc429123.aspx))で確認できます。
*英語ページの方が関数が数個多いので英語版も目を通しておくと良いかもしれません。*

今回は描画の処理を作っていくので出力に使えそうな関数に注目します。
出力関数といえば標準出力のprintf関数を思い浮かびますが、ゲーム制作には向いていません。(後々解説します）

# 出力関数
- FillConsoleOutputAttribute：指定位置から指定したセル分の色（文字・背景）を再設定する。
- FillConsoleOutputCharacter：指定位置から指定したせる分の文字を再設定する。
- WriteConsole：指定した位置から指定した文字列を書きこむ。
- **WriteConsoleOutput**：指定した長方形ブロックに含まれる文字セルに、文字と色(文字、背景)。
- WriteConsoleOutputAttribute：指定した長方形ブロックに含まれる文字セルに、色（文字・背景）の再設定します。
- WriteConsoleOutputCharacter：指定した長方形ブロックに含まれる文字セルに、文字の再設定します。

補助

- SetConsoleTextAttribute：カーソルの色（文字、背景）を設定します。
- SetConsoleCursorPosition：カーソル位置を設定します。

## 次回

[次回](https://qiita.com/selector828/items/a1d8793fea19ba5490bd)はそれぞれの出力関数の使い所と理由を説明します。

長い文は書き慣れていなくて、体力が尽きたので続きは後日投稿します。

また来て下さい。
2011/04/05 チェックボックスとラベルの間で改行させないCSS例

昔書いた社内ブログ記事です。

---


![20110405.gif](https://qiita-image-store.s3.amazonaws.com/0/214263/dd28e532-3c65-ad9d-3187-8892a29acd2a.gif)


＜一番上＞

外側のボックスの幅が決まっているとき、
英数字の連続文字が枠をつきやぶってしまうことがありますよね。

https://jsfiddle.net/k7zt47sg/

＜真ん中＞

下のCSSを追加してみたんですが、ブラウザによって改行したりしなかったり。

```css:CSS
word-wrap: break-word;
word-break: break-all;
```

https://jsfiddle.net/0nLdnb2q/ 

IE8　&rarr;　○
FF3　&rarr;　&times;
Chrome　&rarr;　○
Opera　&rarr;　&times;
Safari　&rarr;　○

＜一番下＞

最後は苦肉の策でした。

```html:HTML
<div style="
 width:120px;
 border:1px solid #333;
 word-wrap: break-word;
 word-break:break-all;">
  <input type="checkbox" id="cb" name="cb" value="1" style="
   position:absolute;" />
  <label for="cb" style="
   padding:0 0 0 1.5em;">this_is_a_label_for_the_checkbox</label>
</div>
```

https://jsfiddle.net/3dsxk4sg/

`label` を `display: block;` にして `text-indent` を設定してもいけますね。

他にも案あったら教えてください（人&acute;&omega;&acute;）♪
スクショ撮影〜Twitterワンストップ投稿を実現する方法

# これは何？
スクリーンショットを撮影してTwitterに投稿するツールを作りました。つくりかただけ公開します。

# どういうツールなの？
- macOSのみ対応。app形式です
- 起動するとスクショの説明入力を求められます
- 説明を入力して「撮影する」ボタンを押すと、範囲指定でスクショを撮影します
- 撮影したものをそのままツイッターに投稿します
- さっき入力した説明も添えられて投稿されます
- エラー処理とか投稿可否の確認とか一切なしです。あぶねぇ

# どういうライブラリ、環境で作成したの？

- macOS High Sierra v10.13.1
- Automator
- ruby 2.3.0
- [Twitter CLI](https://github.com/sferik/t) v3.1.0(不具合あり。ローカルで修正)

## 注意
Twitter CLIのインストール方法はgithubのREADMEを見に行ってください。gemなので基本`gem install`で入手可能です。でも現時点でインストールされるv3.1.0は不具合があるのでご注意を。[uninitialized constant Twitter::REST](https://github.com/sferik/twitter/issues/878)とかいうエラーが出て`t authorize`にしくじります。修正方法はリンク先へ。

# どうやって作ったの？
#### **1. Automatorを起動して新規に「アプリケーション」を作成**
#### **2. 次の画像通りのやつを作ります**
![ツールつくりかた.png](https://qiita-image-store.s3.amazonaws.com/0/95847/90118a19-49c2-5c76-d421-314289d30251.png)
AutoMatorの使い方は[こちらの記事](http://blog.personal-factory.com/2016/11/19/how-to-capture-screen-and-resize-images-by-automator/)が役立ちました。以下、スクリプトだけ載せておきます。

```
TWEET_CMD=/usr/local/bin/t 
DST_PATH=/Users/$USER/Pictures/
DST_PATH=$DST_PATH`date "+%Y_%m%d_%H%M"`.jpg
screencapture -i -t jpg $DST_PATH

if [ -e $DST_PATH ]; then
    # スクリーンショットがちゃんと保存されてたらツイート。ESCキーでキャンセル
    $TWEET_CMD  update $1 -f $DST_PATH
fi
```

#### **3. app形式で書き出す**
#### **4. 作成したappを起動**

# 改善したほうがいいところ
- エラー処理とか投稿確認とか
- スクショ撮ってから説明書いて投稿、という流れにしたいよねー
- ほんとは「Automatorだから非プログラマでもできる！」と言いたかったが...

# その他ハマったポイント

- [Twitterで携帯電話番号の登録に失敗する](https://qiita.com/tk1024/items/644ead20793a6e869b83)
KiCADでRS272Xのガーバデータを要望されたときの設定

#はじめに
　基板設計のフリーのCADであるKiCADでRS272Xのガーバデータを要望されたのですが、調べてみたけどどこにも記載がなくて、試行錯誤しました。備忘録として記載します。
　KiCADのバージョンは4.0.7です。

#RS272Xを出力する設定
次のような設定でガーバデータを出力したら、製造会社で受け付けてもらえました。
フォーマットを4.5にして、Protelの拡張子を使用をOFF、拡張属性を含むをOFFにしています。
![Image1.png](https://qiita-image-store.s3.amazonaws.com/0/82334/23e619f7-fa0a-975c-639e-5c910bcfb8b7.png)
※同じ設定で274Xで要望されたところにも対応できました。

#普段の設定
いつもはP板ドットコムで頼んでいるのですが、この時は以下の設定で出力しています。
フォーマットを4.6にして、Protelの拡張子を使用をON、拡張属性を含むをONにしています。
![Image2.png](https://qiita-image-store.s3.amazonaws.com/0/82334/20977f5b-58b7-03a0-a071-32e37f097d0e.png)


#Elecrowの設定
最近Elecrowでよく頼んでいます。（何しろ安いので）この時の出力は下記の設定にします。
![Image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82334/261186ad-b2b6-4d26-a627-37a94ead6545.png)

出力した後、以下のバッチファイルで拡張子を変更してファイルを送っています。

```bat:sample.cmd
set %n=Sample

del %n%.GTL
del %n%.GBL
del %n%.GTS
del %n%.GBS
del %n%.GTO
del %n%.GBO
del %n%.TXT
del %n%-NPTH.TXT
del %n%.GML

ren %n%-F.Cu.gbr %n%.GTL
ren %n%-B.Cu.gbr %n%.GBL
ren %n%-F.Mask.gbr %n%.GTS
ren %n%-B.Mask.gbr %n%.GBS
ren %n%-F.SilkS.gbr %n%.GTO
ren %n%-B.SilkS.gbr %n%.GBO
ren %n%.drl %n%.TXT
ren %n%-NPTH.drl %n%-NPTH.TXT
ren %n%-Edge.Cuts.gbr %n%.GML

```

※Elecrowは安いのでいいのですが、基板表面に傷やレジスト剥がれがよくあります。そういうものと割り切って使わないと残念な気分になります。
また、ビアを0.6mmビア穴0.3mmで注文していた時は何回か数%の確率でビアが導通していないものがありました。ビアを0.8mmビア穴0.4mmにしてからはそのようなことは（今のところ）発生していません。


#Gerberデータの説明
上記の普段の設定で出力されるデータの意味です。
基板は両面基板で、部品面のみシルク印刷とします。
Sample-Edge.Cuts.gm1　　 基板外形
Sample-F.Cu.gtl　　　　　部品面（F面）パターン
Sample-F.Mask.gts　　　　部品面（F面）レジスト
Sample-F.SilkS.gto　　　 部品面（F面）シルク
Sample-B.Cu.gbl　　　　　半田面（B面）パターン
Sample-B.Mask.gbs　　　　半田面（B面）レジスト
Sample-drl_map.gbr　　　　穴位置と種類を記したドリルマップファイル（P板.COMでは、これを使用）
Sample-NPTH-drl_map.gbr　 穴位置と種類を記したドリルマップファイル（P板.COMでは、これを使用）
Sample-NPTH.drl　　　　　 ノンスルーホール用ドリルデータ
Sample.drl　　　　　　　　スルーホール用ドリルデータ
Sample-drl.rpt　　　　　　ドリルデータレポート（使わない）
自宅でPrometheusを使ってみる

自宅にRaspberry Pi 3があるのですが、Prometheusを入れてみた所面白かったので記事にします。

### スクリーンショット
![スクリーンショット 2017-12-16 19.54.44.png](https://qiita-image-store.s3.amazonaws.com/0/87092/60fcaa65-ead3-3a25-f92d-57d413b37733.png)

### インストール
[Prometheus を Raspberry Pi で動かしてみた](https://qiita.com/ozakit/items/618cc254d9bf1092510f)
を参考にしました、バージョン等は違いますが概ね動きました。

### 温度を測る
Prometheusでは手軽にマシンのメトリクスを測ることができますが、自宅のRaspberry Piではあまりおもしろくありません。
何らかのセンサーを繋いで、グラフにしてみましょう。
今回使用しているのはボッシュ社製のBME280という温湿度気圧センサーです。
これ一つで温度、湿度、気圧を計測することができます。秋月電子で購入しました。
http://akizukidenshi.com/catalog/g/gK-09421
ブレッドボード経由で接続しています。
![2017-12-16_20-03-48_589.jpeg](https://qiita-image-store.s3.amazonaws.com/0/87092/15fd4500-054f-b77d-5e73-800e222e0209.jpeg)
センサー情報を取得するのは
https://github.com/SWITCHSCIENCE/BME280/blob/master/Python27/bme280_sample.py
のスクリプトを使用しています。
Prometheusにデータを渡すには、node_exporterでテキストファイルを読み込ませるのが簡単でした。
[Prometheus に Raspberry Pi の温度データを突っ込んでみた](https://qiita.com/ozakit/items/187667ff41aebd90f42a)を参考にしました。
cronでセンサー情報収集スクリプトを回し、指定パスに結果を書き込むことで、node_exporterがPrometheus側にデータを渡してくれます。

### スピードテスト
ネット回線のスピードテストの結果をグラフにしてみると
* どの時間帯にどの程度落ち込むか
* 速度の落ち込み具合は改善しているか、悪化しているか
などを分かりやすく視覚化できます。
スピードテストに使っているのは[speedtest-cli](https://github.com/sivel/speedtest-cli)です。
計測結果をPrometheusに渡すのは、先程と同じくnode_exporterを使用します。
speedtest-cliには計測結果の出力をcsvやjsonといった加工しやすい形式を選択することができ便利です。
ここではcsv形式を使って簡単なスクリプトを書いています。

```bash

#!/bin/bash
BINDIR=/var/spool/prometheus/bin
OUTDIR=/var/spool/prometheus/collector

$BINDIR/speedtest-cli --csv | awk -F, '{print "node_speedtest_ping " $6; print "node_speedtest_download " $7; print "node_speedtest_upload " $8}' > $OUTDIR/node_speedtest.prom.$$
mv $OUTDIR/node_speedtest.prom.$$ $OUTDIR/node_speedtest.prom
```

スピードテストの計測間隔は負荷も考えられるので長めに設定しておきます。
今後は計測用のセンサーを足したり、Prometheusのアラート機能で発報させてみたいと思います。
2011/03/28 ありがとうさぎでレースを作ってみた

昔書いた社内ブログ記事です。

---

どうも（ｐ・ω・ｑ）


ちょっと前になりますが、
テキトーな絵からレース画像を作る方法を知りました。

レースの描き方メモ（SAI） on Twitpic
<a href="http://twitpic.com/3vf0qs" target="_blank">http://twitpic.com/3vf0qs</a>


これが結構すごくて、すてきなレースができたので貼っつけてみます！

![20110327_5.gif](https://qiita-image-store.s3.amazonaws.com/0/214263/728094d2-640e-61b4-0dd7-60b0d5f19d01.gif)



なんの画像を回転して作ったかというと・・


（ｐ・ё・ｑ）＜ﾎﾟﾎﾟﾎﾟﾎﾟ-ﾝ!!


![20110327_5_.gif](https://qiita-image-store.s3.amazonaws.com/0/214263/ae8a8ce1-d71c-796d-55c0-014caca763db.gif)

画像 <a href="http://volcanosuzuki.blog90.fc2.com/blog-entry-128.html">http://volcanosuzuki.blog90.fc2.com/blog-entry-128.html</a>


いやーこの作業結構楽しいなー。
Workplace Botを作ろう〜Workplace Graph APIでHello World

この記事は [MicroAd Advent Calendar 2017](https://qiita.com/advent-calendar/2017/microad) の25日目の記事です。今日で2017年のAdvend Calendarは終了ですね。参加者の皆様、お疲れ様でした。

# はじめに

業務改善のためにWorkplaceで特定のグループに対して定期実行ができたらいいな〜などと考えていました。ところがわたくし、Botを作ったことがありません。と、いうことで、プログラマらしくまずはHello Worldを投稿してみることにしました。

## この記事のゴール
WorkplaceのグループにHello Worldを投稿する。

## 対象者
WorkplaceでBotを作りたいんだけど、一度も作ったことがないという人。

## 環境の前提
特にありません。プログラミング経験も必要ありません。[^1] なお、Graph APIというWeb APIを利用するため管理者にアクセストークンを発行してもらう必要はあります。

[^1]: Hello Worldの投稿に関しては、です。定期的な自動実行や、投稿するコンテンツを自動生成する場合はこの限りではありません。

# 操作の流れ

- 投稿用グループの準備
- APIトークンの取得
- Restlet ClientからのAPI実行

## 投稿用グループの用意

適当に投稿用のグループを作りましょう。今回は「Advend Calendar 2017 Bot」などと非常にわかりやすい名前を付けています。

![グループの作成](https://i.gyazo.com/2e9076918080144b83198693601fcf71.png)

ちなみにグループ種別はなんでもいいです。プライバシー設定を「秘密のグループ」にしても動作します。

## アクセストークンの取得
アクセストークンを取得するためにはシステム管理者の権限を所有している必要があります。あなたがシステム管理者の権限を所有していない場合には、システム管理者の権限所有者にこの操作を代行してもらいましょう。

### アプリの作成

ダッシュボード > 統合 > カスタム統合 とメニューを辿っていき、[カスタムアプリの作成]ボタンを押下します。名前は適当にどうぞ。

![カスタムアプリの設定画面](https://i.gyazo.com/88c490639b274b6aa9bbe3e04f64c667.png "実名が表示されているけれまあご愛敬で。")

## [アクセス許可]および[グループを選択]

カスタムアプリ作成後の設定画面からは[アクセス許可]、[グループを選択]、[Webhooksを設定]そして[詳細オプション]というオプション項目を設定することができます。が、今回はただ投稿するだけのアプリなので[Webhooksを設定]および[詳細オプション]は設定不要です。[アクセス許可]および[グループを選択]のみ設定しましょう。

### [アクセス許可]
今回は特定のグループに投稿するだけなので[グループのコンテンツを管理]を設定しています。

![アクセス許可](https://i.gyazo.com/c015e4d7587577995ff3ab09f54f3d02.png)

### [グループを選択]

セキュリティリスクを考慮して、グループを設定しておきます。当然、先ほど作成した投稿用グループを設定します。

![グループを選択](https://i.gyazo.com/f4a7079afc8259599bb2e74399c6aa51.png)

これで準備完了です。

## Restlet ClientからのAPI実行

最後にアクセストークンを利用してPOST実行します。URIはこんな感じです。

```
https://graph.facebook.com/{グループID}/feed?message={メッセージ}&access_token={アクセストークン}
```

今回はコードを記述する手間を省くためにRestlet Clientを利用します。Reslet Clientの紹介は以下の記事をご覧ください。
https://qiita.com/84zume/items/fac99705c39d2f18ada7

それでは早速実行してみましょう！

![Hello Worldの実行結果.png](https://qiita-image-store.s3.amazonaws.com/0/4347/857a3cad-b67c-93bd-27ab-0218f03f74ae.png)

お！200が返ってきましたね。そのままWorkplaceを確認してみましょう！

おおお、無事に表示されましたね。
![Hello World](https://i.gyazo.com/9cdcce139dbed46d30beccaa4246e2de.png)

アクセストークンがあれば簡単に実行できますね。この調子で社内の目標達成度なんかを定期的にポストできたら便利ですね。

# 最後に

この記事をきっかけにGraph APIを実行してみていただけたら幸いです。

# 参考記事

- https://developers.facebook.com/docs/workplace/integrations/custom-integrations/bots
- https://qiita.com/84zume/items/fac99705c39d2f18ada7