OmniAICreator/Qiita-1.07M huggingface dataset:
【Swift】iOSで放置型育成ゲームを作るよ(10) ~戦闘画面を考える その1~

## 今日のゴール
- 戦闘の流れを考える

## やったこと
### 戦闘をデザインする
いやはや仕事が忙しかったり戦闘画面に凝りだしたらキリがなくて1ヶ月ほど放置してしまいました
今日からまた頑張ります
ちなみにこの記事ではコードは書きません

- 育成画面作るのにちょっと飽きてきたので戦闘画面に手をつけるよ
- まずどんな戦闘システムにしたいか大雑把に考えるよ
- 個人的に好きな放置ゲームに「僕の魔界を救って！(通称：ぼくまか)」というのがあるよ
    - [AppStoreに飛びます](https://itunes.apple.com/jp/app/%E5%83%95%E3%81%AE%E9%AD%94%E7%95%8C%E3%82%92%E6%95%91%E3%81%A3%E3%81%A6/id445773628?mt=8)
    - このゲームの特徴はいくつかあるんだけど、僕の好きな特徴として
        - 攻略する場所と時間、ユニット、アイテムを選択するだけでよい
            - ポチポチするとか連打するのとかは面倒臭くて自分には合わない
        - 時間とともにログが進んでいくのを見るのが気持ちいい
        - 他対他のバトルで、60体くらい一気になぎ倒すのを見るのがテキストなのに爽快
- 好きなものと好きなものを合成するというコンセプトで戦闘画面は「僕まか＋艦これ」にしようと思うよ

#### つまりどういうことだってばよ？
戦闘についてはざっっっっっっくりこんなイメージで進めようと決めたよ

- 戦闘のログをTableViewで表示
- 時間経過でログが増えていく
- セルの内容は僕まかリスペクトさせてもらう
- セルタップでログから戦闘アニメーションを生成・再生
    - ここを艦これっぽくする

#### 定義的なものを考える
| 項目    |    定義  |
|:-----------------:|:-------------------:|
| 戦闘参加ユニット            |             他対他  |
| 戦闘終了の条件           |           どちらかのユニットが0体になる  |
| 戦闘勝利の条件              | 味方ユニットが1体以上 && 敵ユニットが0体になる  |
| 戦闘敗北の条件                |味方ユニットが0体になる && 敵ユニットが1体以上|
| 戦闘のシークエンス              |後述|
| ダメージ計算式          | 後述 |
とりあえずこんなところでいいかな

#### 戦闘シークエンスを考える
- 多分メジャーではないと思うんだけど、戦闘の流れをシークエンスと呼ぶことにするよ
- デジコレではこんな感じで戦闘が進むようにしたよ
    - フラグ管理もっといい感じにできる気がするなあ🤔
![Untitled (7).png](https://qiita-image-store.s3.amazonaws.com/0/115590/babe3997-d15a-85f6-0fa6-52fe41682ee7.png)

- 「戦闘ログの生成」の処理では、TableViewに乗っけられるように下記ログを生成することにするよ
    - 「誰が(味方ユニットか敵ユニットか)」
    - 「誰に(味方ユニットか敵ユニットか)」
    - 「どんな攻撃をして」
    - 「どの程度ダメージを受けたのか」
    - 「全戦闘参加ユニットのステータス」


#### ダメージ計算式について
- 諸々検索して調べたけど正直どこから手をつけていいのかわからないのでとりあえず一番簡単な「攻撃側の攻撃力 - 防御側の防御力 = ダメージ」を採用するよ
    - ちょっと調べるとアルテリオス計算式という名前らしい(多分非公式)
    - [アルテリオス計算式とは](http://dic.nicovideo.jp/a/%E3%82%A2%E3%83%AB%E3%83%86%E3%83%AA%E3%82%AA%E3%82%B9%E8%A8%88%E7%AE%97%E5%BC%8F)

#### 必要になる実装・改修を考える
必要になるだろうクラスをあらかじめ考えておくよ
多分不足してたり、やっぱりこうしたいみたいなものが出てきそうだけどそこはストレッチに柔軟にやっていくよ

- Enemyクラス
    - キャラクタークラスから生成する味方ユニットと敵ユニットを区別するため
- 戦闘ログクラス
    - 上記した、誰が誰に何を、のあたりの処理をまとめて保持しておくクラス
    - 1ユニットが行動するたびに生成されるイメージ
- 戦闘ログジェネレータークラス
    - 戦闘参加する味方ユニットと敵ユニットを引数で渡せば、勝利 or 敗北までの複数の戦闘ログを返してくるクラスのイメージ
- BattleTableViewControllerクラス
    - 戦闘ログジェネレーターで返ってきた戦闘ログを基にTableを表示するViewController
- BattleAnimationViewControllerクラス
    - 戦闘ログからアニメーションを生成して再生するViewController
    - BattleTableViewControllerのセルタップで遷移する
- BattleUnitViewクラス
    - BattleAnimationViewControllerにaddSubViewされる感じ
    - ユニットの画像とHPなどを表示するクラス
    - ユニットが死ぬと非表示になる or ダウン時の画像になる(素材次第や・・・)

なんか一気にクラス増えるな・・・　まあとりあえず手を入れていきましょう

### 結果
- 戦闘に関する骨組みができた(といいなという希望)

### 次回
次回は実際にコード書いていこうと思います〜
【Swift】iOSで放置型育成ゲームを作るよ(9) ~戦闘画面を考える その2~

### 最後に
ご指摘大歓迎です:pray:
publicなメンバ変数はやめよう

## メンバ変数はprivateにしよう

「メンバ変数は private にする」

これは一般的なルールです。
メンバ変数を隠蔽する、つまりクラスの外から見えないようにします。
メンバ変数は大切なものです。
大切なものは他人に勝手に触られないように隠すのが常識です。

でも、外からメンバ変数にアクセスしたい場合もありますよね？
そのために getter や setter と呼ばれる public な関数を用意します。
コードにすると、こんな感じです。

```cpp
class Sample {
public:
    int getValue() {
        return _value;
    }
    void setValue( int value ) {
        _value = value;
    }
private:
    int _value;
}
```

getter/setter のことを「アクセサ」と呼びます。
「汗くさ」じゃなくて「アクセサ(accessor)」です。
「アクセスするもの」という意味です。
普通に考えると "アクセス + er" になると思いますが、英語の謎ルールで er ではなく or になります。

こうやってアクセサを使うことで、private にして隠蔽したメンバ変数にアクセスすることができるようになります。

「いや、ちょって待て。」
「それじゃあ、メンバ変数を public にしたのと変わらないじゃん。」
そう思う方もいるでしょう。

隠蔽性に関して言えば、先ほどのクラスは、このクラスと大差ありません。

```cpp
class Sample {
public:
    int value;
}
```

どちらもメンバ変数の値を取得できます。

```cpp
int x = sample.getValue();
int x = sample.value;
```

どちらもメンバ変数に値を設定できます。

```cpp
sample.setValue( 10 );
sample.value = 10;
```

それでも、public なメンバ変数にするより、アクセサを使うべきです。


## アクセサのメリット１：ReadOnlyにできる

メンバ変数をクラスの外に公開する理由は、値の設定だけではありません。
値を参照したいという理由で公開したい場合もあります。
その場合、public変数方式だと、取得にしか使わないのに、メンバ変数は外から変更可能な状態になってしまいます。
当然、必要ないならメンバ変数は外から変更可能にすべきではありません。

一方、アクセサ方式だと、setter を宣言せずに getter だけ宣言すれば、メンバ変数の値は取得しかできません。
こちらの方法だと外からメンバ変数を変更することはできないので安全です。

逆に setter だけ宣言すれば、WriteOnly な状態も作れます。


## アクセサのメリット２：メンテナンス性

「たまに _value が変な値になることがある」という不具合が発生した場合、public変数だと、値を設定している箇所を全て調べなければなりませんが、アクセサだと setter にブレークポイントを貼るだけで犯人が特定できます。
同様に、getter/setter にブレークポイントを貼れば、変数を使うタイミングを検出したり、変数にアクセスしようとしている輩を簡単に判別したりすることができます。


## アクセサのメリット３：カスタマイズ性

アクセサ方式だと、値の取得や設定の処理をカスタマイズできるようになります。

例えば、取得時、状況によって返す値を変えることが可能です。

```cpp
//  無効な場合は 0 を返す
int getValue() {
    if ( isEnabled() ) {
        return _value;
    }
    else {
        return 0;
    }
}
```

値を設定する際の範囲チェックもできます。

```cpp
//  マイナスなら 0 を設定する
void setValue( int value ) {
    if ( value < 0 ) {
        _value = 0;
    }
    else {
        _value = value;
    }
}
```

また、「値を設定したときに、ついでにテキストも更新しておいて」と仕様が追加されたらどうなるでしょう？
public変数方式だと、value に値を設定している箇所を検索して、その全ての場所で対応しなければなりません。
しかし、アクセサ方式だと、以下のように setter を修正するだけで済みます。

```cpp
void setValue( int value ) {
    _value = value;
    _text = ...(略)...
}
```


## public変数のメリット

アクセサで変数にアクセスするようにすると、オーバーヘッドが気になるところです。
アクセサ経由で変数にアクセスするよりも、変数にダイレクトにアクセスする方が早いのは想像に難しくありません。
ただ、よっぽどパフォーマンスにシビアな環境ではない限り、気にするほどの差は無いと思います。
それに、getter/setter をインライン化すればオーバーヘッドは阻止できると思いますし、インライン化しなくても最適化をかければオーバーヘッドが無くなるかもしれません。
実際に確認したわけではないので断言はできませんが。
(そこまでパフォーマンスにシビアな環境にいたことがないので、調べたことがありません。)

public変数の最大のメリットは、実装の容易さでしょう。
private な変数と getter/setter の３つを用意するより、public な変数１つだけを用意する方が簡単です。
とにかく急いで機能だけ実装したい場合は有効かもしれません。
もちろん、後でリファクタリングしてアクセサ方式に変えるという前提で。
また、テスト用に一時的に実装して、使い終わったら削除するつもりのクラスはpublic変数でも良いでしょう。

逆に言うと、public変数はそれぐらいしかメリットが無いような気がします。
ですので、積極的にアクセサを使いましょう！
Slack Realtime Message APIをRx.Observableにする

以下のコードの大部分は　https://github.com/slackapi/node-slack-sdk から。

```js

var  Rx = require('rx');

var RtmClient = require('@slack/client').RtmClient;

var CLIENT_EVENTS = require('@slack/client').CLIENT_EVENTS;

var botToken = process.env.SLACK_BOT_TOKEN;

var rtm = new RtmClient(botToken);

var channel;

rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, (rtmStartData) => {
  for (const c of rtmStartData.channels) {
    if (c.is_member && c.name ==='general') { channel = c.id }
  }
  console.log(`Logged in as ${rtmStartData.self.name} of team ${rtmStartData.team.name}, but not yet connected to a channel`);
});

var source = Rx.Observable.create((observer) => {
  rtm.on(CLIENT_EVENTS.RTM.RAW_MESSAGE, x =>observer.onNext(x))
});

source.filter(msg => msg.match(/Banana/).subscribe(() => {
  rtm.sendMessage("Banana!", channel)
});

rtm.start();
```

実際必要なのはこの部分

```js
var source = Rx.Observable.create((observer) => {
  rtm.on(CLIENT_EVENTS.RTM.RAW_MESSAGE, x =>observer.onNext(x))
});

var source = Rx.Observable.create((observer) => {
  rtm.on(CLIENT_EVENTS.RTM.RAW_MESSAGE, x =>observer.onNext(x))
});
```
AWS サービスがどこにあるのかまとめ


　AWS 上のセキュリティや NW 構成を考えるにあたって、どのサービスがどこにあるのか、AZ サービスなのか、リージョンサービスなのか を考える機会が多く、自分の頭の整理のため簡単にまとめます。

# まとめた図
　サービスの「場所」を表現する為の図です、全エッセンスを入れるとゴチャゴチャするので、一部省略しています。
![Image](https://qiita-image-store.s3.amazonaws.com/0/130874/1a6cf2b2-163b-1e3f-b80c-f8ac5aaf7517.png)


# 説明
　代表的なもの以外（というか個人的に普段使わないもの）は入れてなかったりします。サービスと呼んでいいのかわからないものも混ぜ込みました。

- AZ サービス
    - Subnet
        - サブネット単位で必要となる NAT Gateway / NACL も AZ サービス
    - EC2
        - AZ単位で設定する EBS / Placement Group も AZ サービス
    - RDS
    - ELB [^1]
    - ElasticCache
    - Redshift
- リージョンサービス
    - VPC
        - VPC毎に必要となる Security Group / VPC Endpoints / VPC Peering / EIP も リージョンサービス
    - Auto Scaling
    - S3 [^2]
        - バックエンドで S3 を利用している EBS Snapshot / AMI も リージョンサービス
    - DynamoDB
    - SQS
    - CloudSearch
    - Lambda [^3]
    - API Gateway [^3]
    - Code 兄弟
- グローバルサービス
    - IAM
    - Route53
    - CloudFront
    - WAF
    - Key Pair [^4]

　誤りあれば、ご指摘ください。

[^1]: リージョンサービスにも見えますが、実態は Multi-AZ で AutoScaling なインスタンスです、図示する場合は Subnet の間に書くのがよいです
[^2]: S3 はサービスとしてはグローバルで、データはリージョンに配置されます 
[^3]: 指定した VPC / Subnet 内に起動することもできるが、Endpoint（ARN）はリージョン
[^4]: EC2キーペアはリージョン毎、RSA キーペアはグローバル
Pythonのctypesで、構造体のメンバへのポインタを取得する

Pythonのctypesでこういうことをしたかった

```c
typedef struct{
    int x;
    int y;
} point;
point p = {100, 200};
someFunc(&p.y); //yへのポインタを渡す

```
ただ普通に書いたところで

```python
from ctypes import *

class Point(Structure):
    _fields_ = [("x", c_int), ("y", c_int)]

p = Point(100, 200)
somedll.someFunc(byref(p.y))
```
`TypeError: byref() argument must be a ctypes instance, not 'int'`

と怒られてしまう
`p.y`で得られる値はctypesインスタンスではなく、ただの(Pythonの)int数値なので、byrefしたところで参照をとることはできない

こうする

```python
y_offset = Point.y.offset
y_addr = addressof(p) + y_offset
somedll.someFunc(y_addr)
```
取得したのはポインタというかアドレスそのものだがまあ同じようなもんだろう

どうも
`(Structureのサブクラスの)クラスオブジェクト.メンバ名.offset`
でそのメンバの、構造体先頭からのオフセットを取得することができるようだ
構造体先頭のアドレスを取得し、オフセットを足してやれば晴れてメンバのアドレスを取得できるというわけだ

ちなみに
`クラスオブジェクト.メンバ名.size`
でそのメンバのサイズを取得することができる

多用するなら以下のように関数化しておくとよいのではないか

```python
def get_address_of_member(obj, member_name):
    return addressof(obj) + obj.__class__.__dict__[member_name].offset

p = Point(100, 200)
somedll.someFunc(get_address_of_member(p, "y"))
```
なんかスマートではない気がするがまあいいか
もっといい方法があれば、是非ご教示していただければ幸いです
Google App Maker ー 環境の違いを理解する

[Google App Maker（App Maker）](https://developers.google.com/appmaker/)には環境という概念があってこれが結構ややこしい。
忘れそうなのでメモがてら記事にしておく。

そもそも App Maker ってなに？という人は、以下の記事を参照してください。
[Google App Maker とは？ 短期間で Web アプリケーション構築を可能にした理由](https://www.topgate.co.jp/what-is-google-app-maker)


## 環境の全体像
![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/34e64312-1290-a154-65bc-e86194df3033.png)

※ App Maker は [G Suite](https://gsuite.google.co.jp/intl/ja/features/) 内のサービスなのだが、GCP で動いているのでこういう図にしている。


## 環境はいくつでも作れる
さきほどの画像では、 PREVIEW（開発環境）・検証環境・本番環境 の3つしか書いていないが、いくつでも作れる。（11個までは確認）[^1]
[^1]: 無料で使える割には太っ腹な仕様


## 環境は PUBLISH（PREVIEW） した時点のソースをもとに配備される
仮にソースを書き換えても、どの環境にも自動で反映されたりはしない。
※ PREVIEW（開発環境）も例外ではなく、勝手に反映されない。


## 環境ごとに別のプロジェクトIDが割り当てられる
それぞれの環境を作ると、Google Cloud Console では別のプロジェクトIDが割り当てられる。
そのため環境ごとに以下のようになる。

- サーバーのログ（Stackdriver Logging）が独立
- アプリケーションの認可が独立

![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/d323444d-18e0-cae3-68ef-8a89f73b68de.png)


## Drive Table は環境ごとに用意される
Drive Table は環境ごとに用意される。
そのため本番データと検証データが混ざることはない。
逆を言えばデータの管理方法をしっかり考えて設計しておかないととあとで苦労する。

※全体図でアイコンはスプレッドシートを使ってしまったが、Drive Table の意味。（Drive Table にアイコンがないため）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/eec5d8a0-0c34-0dee-740d-9e86ad345e7f.png)

また、図には書いていないが、Drive Table ではなく Cloud SQL 使用時も環境ごとにインスタンスを指定できる。


## Roll は環境ごとに用意される
App Maker では Roll 機能が用意されており、管理者しか触れない画面やモデルを作ることができる。
この場合、管理者ロールを作ってユーザー（メールアドレス）を追加していくのだが、それも環境ごとに設定する。
※ PREVIEW（開発環境）には Roll の概念はなく全アクセスが可能となっている。そのため、Roll が正しく設定されているかは、検証環境や本番環境でそれぞれ実際に動かして確認する必要がある。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/6820a0b4-0676-2485-7e06-de8946485b05.png)


## リソースは共通で Google Cloud Storage に格納される
リソース（画像）は環境ごとに用意されない。
本番環境で使ってたけど、要らなくなったからといって開発中に消したりすると本番環境から参照できなくなる。
消す場合は、本番環境にリソースを使わないコードを PUBLISH してからおこなうこと。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/4dedcd9b-4687-88b7-60f4-432faa9651d6.png)


## トリガー
App Maker でも [GAS](https://developers.google.com/apps-script/) のトリガーが利用できる。
注意点として、トリガーは環境内の特定の関数を呼び出す **参照** を持っている。

たとえば `本番環境のdoSomething()` をトリガーに設定したとする。
エディタ上で`doSomething()` 内のコードを書き換えて 本番環境に PUBLISH すると、 **トリガーの処理が変わる**。
あくまで **参照** ということに注意する。
node-jt400を試してみた（execute）

#execute
コーディング例にはありませんが、executeというメソッドもあります。
推測するに、戻り値の無いSQLが発行できそうです。

という事で、QCMDEXCが実行できるか試してみました。
OVRDBFが実行できれば、メンバーが利用できますね。

まず、物理ファイル：MEMBERにメンバー(ADDMEMBER)を追加します。
（ちょっとネーミングがややこしくなってしまいました。）

```
ADDPFM FILE(MYLIB/MEMBER) MBR(ADDMEMBER) TEXT('メンバー追加')
```
以下のデータをDFUで追加しました。
![nodejt13.png](https://qiita-image-store.s3.amazonaws.com/0/146069/ae8ba4e4-155e-ccde-b0e0-a3f2b67d343a.png)

```SQLexecute.js
app.get("/execute", function (req, res, next) {
  let execstmt = "CALL QCMDEXC('OVRDBF FILE(MEMBER) TOFILE(MYLIB/MEMBER) MBR(ADDMEMBER) OVRSCOPE(*JOB)',70)";
  let sqlstmt = "select * from member";
  pool.execute(execstmt).then(
    function (result) {
      pool.query(sqlstmt).then(
        function (result){
          res.json(result);
        }
      )
    });
});
```
実行してみました。
![nodejt14.png](https://qiita-image-store.s3.amazonaws.com/0/146069/539281c3-3ca7-9f19-577a-39251c498639.png)

OVRDBFが上手く行っていないようです。
WRKACTJOBで確認するとQZDASOINITが二つ存在していて、OVRDBFとSQLが別のジョブになっていました。

[前回](http://qiita.com/yamurata/items/f15c7add045f663f504a)試したトランザクションは同じpoolを使うようなので、そちらで書き直してみました。

```SQLexecute.js
app.get("/execute2", function (req, res, next) {
    pool.transaction(function (tran) {
        return tran.execute("CALL QCMDEXC('OVRDBF FILE(MEMBER) TOFILE(MYLIB/MEMBER) MBR(ADDMEMBER) OVRSCOPE(*JOB)',70)" 
        ).then(function () {
            return tran.query("select * from member").then(
              function (result)
            {
              res.send(result);          
            } 
        )});
    });
});
```
![nodejt15.png](https://qiita-image-store.s3.amazonaws.com/0/146069/27df24cc-2fe5-13f6-765e-430747dc35d9.png)

今度は上手く行きました。
Vue.jsで画像が横からスライドで切り替わるサンプル

サンプルはここ
https://keng0o.github.io/vue-slide-emoji/

アニメーションの方法はCSSトランジションを利用。

トランジション利用については公式に詳しくのっています。
https://jp.vuejs.org/v2/guide/transitions.html#トランジションクラス

注意点として、トランジションコンポーネントにラップされた要素が挿入あるいは削除されるときにトランジション適用されるかの検知を行うので、DOMの構造を変えずに中のデータだけ変更しようとするとトランジション適用されません。

具体的にコードでいうと、

```html
<p :key="products[product%5]">
    {{products[product%5]}
</p>
```

を

```html
<p>
    {{products[product%5]}}
</p>
```

としてしまうと表示するデータだけの変更になるので、DOMの構造は変わらないのでトランジション適用されるか検知されずCSSのアニメーションはおこりません。

なので、keyに一意な値を入れデータが変更されるたびDOMが挿入されるようにします。DOMの挿入・削除によりCSSトランジションのアニメーションが適用されます。

```html:index.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://vuejs.org/js/vue.js"></script>  
<style type="text/css">
.slide-enter-active, .slide-leave-active {
  transition: transform .5s
}
.slide-enter {
  transform: translateX(300px)
}
.slide-leave-active {
  transform: translateX(-300px);
}

p {
  position: absolute;
  margin: 0;
  font-size: 3em;
}
</style>
</head>

<body>
  <div id="app">
  <button @click="product++">次</button>
  <transition name="slide">
    <p :key="products[product%5]">{{products[product%5]}}</p>
  </transition>
</div>
  <script>
new Vue({
	el: '#app',
  data: {
  	product: 0,
  	products: ['😀','😂','😎','😼','👷']
  }
})
</script>
</body>
</html>
```
メモ: Screens VNC の設定 (ssh対応vncビュアー iOSアプリ)

* [Screens](https://itunes.apple.com/jp/app/screens-vnc-%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%81%AB%E9%81%A0%E9%9A%94%E6%93%8D%E4%BD%9C/id655890150?mt=8) iTunesストア

設定が分かりづらかったためメモ

## 設定

|項目|設定する値|
|:--|:--|
| 一般設定 -> アドレス | ssh接続先からみたVNCサーバーが動いているアドレス(192.168.2.2) or ドメイン(接続元制限をしている場合用。) |
| 一般設定 -> ポート | 5900 |
| オペレーティングシステム | Linux |
| 認証方法 | vncパスワード |
| セキュリティ保護された接続 | on |
| 詳細 -> アドレス | ssh接続先のグローバルIPアドレス or ドメイン |
| 詳細 -> ポート | 22 |
| 詳細 -> ユーザ名 | sshユーザ名 |
| 詳細 -> パスワード | ssh鍵指定 |
api.aiのwebhookを受けるサーバでパラメータを受け取る

api.aiではfulfillmentの設定で、webhookで呼び出すエンドポイントを指定できる。
Intent内の設定でユーザの入力に対応するパラメータを定義して、webhook時にリクエストボディに含めることができる。

api.aiからのリクエストを受けるサーバではどのようにしてパラメータを取得するかメモ。今回はデモアプリ用にherokuでnode.js/expressフレームワークのサーバを立てて検証した。

## パラメータの抽出
`req.body.result.parameters`でパラメータオブジェクトを取得できる。
レスポンスはパラメータオブジェクトを文字列にして返すだけの例。

```
router.all('/', function(req, res, next) {
  console.log('[REQUEST]', req.body.result.parameters);
  res.set('Content-Type', 'application/json');
  res.json({
    displayText: JSON.stringify(req.body.result.parameters),
    speech: JSON.stringify(req.body.result.parameters),
  });
});
```

## ひとくちメモ
- herokuのログを見る方法 `heroku logs -t`
- レスポンスボディの`speech`に設定した値がwebデモなどで確認できるテキストになる
文字列型のバグをできるだけ埋め込みたくない

「静的型付き言語を使おうが、文字列型は変わらずバグの温床である」というような話を見かけたので、文字列の自由奔放さに抗って型に嵌め殺すために今できることについて考えてみた。

## 例えばこういうミス

```ts
/** @param url {string} URL文字列を指定してください。 */
function printURL(url: string): void {
    console.log(url);
}

printURL('焼肉食べたい');  // コンパイラ「OK!」
```

静的型付けの恩恵をまったく生かせていないコード。
人類は愚かなので、コンパイラがOKだと言えばそれを信じるし、typoだってする。
あまりにもイケてない。どうすればいいのか。

## 取りうる値が決まっているとき

独自定義したいくつかのイベントに名前をつけて、文字列で判別する。というのはよくあるパターンだと思う。こういったケースには割と簡単にstaticなやり方を持ち込むことができる。

### 定数を定義して使う

```ts
const EVENT_START: string = 'start';
const EVENT_PAUSE: string = 'pause';

function emitGameEvent(eventName: string): void {}

emitEvent(EVENT_START);
```

脳みそが停止していると一番最初に書くコードだけれど、ごちゃごちゃしやすいのであんまりやりたくない。
しかも型は`string`のままなので、結局関係のない値を突っ込めてしまう。
これは型安全性のためにやることではない。気休めにしかならない。

### String Literal Type を使う

https://www.typescriptlang.org/docs/handbook/advanced-types.html#string-literal-types

```ts
type GameEvent = 'start' | 'pause' | 'end';

function emitGameEvent(event: GameEvent): void {}

emitGameEvent('start');  // OK!
emitGameEvent('stop');  // コンパイルエラー
```

TypeScriptらしい素晴らしい機能。
簡単に取りうる値を列挙できる上に、妙な値を指定としたときはきちんとコンパイルエラーを吐いてくれる。
非常にスマートでよい。こういうのが欲しかったんだ。

他所で使わない場合は、引数の型として直接指定することもできる。

```ts
function emitGameEvent(event: 'start' | 'pause' | 'end'): void {}
```



### String Enums を使う

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html#string-enums

```ts
enum GameEvent {
    START = 'start',
    PAUSE = 'pause',
    END = 'end'
}

function emitGameEvent(event: GameEvent): void {}

emitGameEvent(GameEvent.START);
```

TypeScript 2.4から導入された **String Enums** 。
上記のString Literalと大体同じようなものなのだけれども、こっちのほうがリファクタリングはしやすいと思う。

## 取りうる値に幅があるとき

URLやらファイルパスやら、決め打ちにはできないけれど、一定の法則を持つ値を扱う場合の話。
コンパイル時に拾うのは難しいし、だいたい問題になるのはこういったケースだと思う。

### 正規表現でチェックする

```ts
function printURL(url: string): void {
    assert(urlPattern.test(url), `urlとして不適切な書式 "${url}"`);
    console.log(url);
}
```

型自体は`string`のままなのでコンパイル時には拾えていない。バグは発生する。
ただ実行時に早い段階でエラー原因を捕捉できるので、最低限このくらいはやっておきたいという話。

### ラッパークラスを活用する

```ts
import { URL } from 'url';

function printURL(url: URL): void {
    console.log(url);
}

const target: URL = new URL('https://example.org/foo#bar');
printURL(target);
```

文字列型のままだからいけないのだ。
URLやらファイルパスなんかには、大抵ラッパークラスが用意されているのだから、
できるだけ関数の引数などではラッパークラスの型で指定しておき、極力生の文字列のまま取り廻さないようにすればいい。
そうすればエラー原因となりうる箇所の範囲は最小化できるはずだ。（無くなるとは言っていない）

独自のパターンをもつ文字列に対して、ラッパーを定義して使うのも有効だと思う。

```ts
class UserID {

    readonry value: string;

    private static pattern: RegExp = /^[A-Z]\\d{4}$/;

    public constructor(value: string) {
        assert(UserID.pattern.test(id), `不正な形式のUserID "${id}"`);
        this.value = value;
    }

}
```

ただ若干面倒くさいし、冗長になってしまうかもしれない。
濫造するのもよくない気はする。

### Decoratorでチェック

https://www.typescriptlang.org/docs/handbook/decorators.html

（サンプルコードを書こうと思ったけど挫折）

Javaのフレームワークなんかを使っていると、Annotationで値チェックなんてことをよくやる。JSでもDecoratorで値の正当性をチェックすることもやることがあるかなぁ、とだけ考えた。
実装するのはかなり面倒だし、これもやっていることは実行時のアサーションに過ぎないのでそもそも静的型付的なアプローチでもない。
でもDecoratorってなんかかっこいいよね。

## まとめ

プレーンなJavaScriptよりは当然できることは多いのだけれども、
コンパイラがなんでもかんでもに目を配ってくれるわけではない。
まあコンパイラの庇護をできるだけ広い範囲で受けられるようなコードを書こう、という感じ。
それが無理なところは、せめて実行時チェックするしかないよね。

typeを正規表現で定義できるようになったりしないですかね？（脳みそからっぽ）
JavaでPreparedStatementを使用する

DB接続の必要なバッチやアプリケーションでは、大抵の場合下記クラスを用いて接続の処理を実装します。
 - java.sql.Connectionクラス
 - java.sql.Statementクラス
 - java.sql.ResultSetクラス

しかし最近では、Statementクラスを用いずにjava.sql.PreparedStatementクラスを使用することがポピュラーのようです。
その理由を記しておきます。



## 理由
1. SQLインジェクション対策になる
2. 名前の通り、SQLがDBにキャッシュされるため、繰り返し同じSQL文を発行する場合に処理速度が速くなる。

## 使い方
Statementクラスと比較した使い方です。

### Statementクラスの場合
1. Statementクラスのオブジェクトを取得する。
Connectionクラスのオブジェクト.createStatement()で取得できます。
2. Statementクラスのオブジェクトを用いて、SQL文を実行する。
Statementクラスのオブジェクト.execute()で実行できます。

```
Connection con = DriverManager(hoge,hoge,hoge);
String sql = "select name from hogeData where id = '1'";
Statement st = con.createStatement(sql);
st.execute();
```

### PreparedStatementクラスの場合
0. 実行したいSQL文の値を?に置き換えておきます。その際、シングルクオートで囲む必要はありません。
1. PreparedStaetmentクラスのオブジェクトを取得する。
Connectionクラスのオブジェクト.preparedStatement()で取得できます。引数でSQL文も渡しておきます。
2. PreparedStatementクラスのオブジェクト.setHoge()で、?に値を挿入します。その際、整数型の場合はsetInt()、文字列型の値が入る場合はsetString()して下さい。
引数には、?の位置を指定します。SQL文の左側の?から1番目の?なら、第一引数に1、第二引数には挿入したい値を渡してあげてください。
3. PreparedStatementクラスのオブジェクト.executeQuery()または.executeUpdate()で実行できます。
返却されるResultSetの有無で使用するメソッドが変わります。


```
Connection con = DriverManager(hoge,hoge,hoge);
String sql = "select name from hogeData where id = ?";
Statement st = con.preparedStatement(sql);
st.setInt(1, 1);
ResultSet rs = st.executeQuery();
```

---

使用したほうが良い理由について深掘りしたい方は下記を読んで下さい。
（後日追記します）
Command Prompt > forによるファイルの列挙 | 別の拡張子の表示 | GAMESSのバッチ処理

```txt:動作環境
Windows 8.1 Pro (64bit)
```

量子化学計算のGAMESS関連
http://www.msg.ameslab.gov/gamess/index.html

Windows版のGAMESSを使って処理を実行する場合、batファイルを用意して処理をすることになるだろうか。

以下を試してみる。

- forを使ってinputs/にあるinpファイルを表示する
- 拡張子を.outにしたものを表示する

```group_run_170828.bat
for %%d in ( inputs\*.inp ) do ( 
    echo %%d
    echo inputs\%%~nd.out
)
```

```txt:結果(一部)
inputs\exam44.inp
inputs\exam44.out
```

### 参考

http://fpcu.on.coocan.jp/dosvcmd/bbs/log/cat3/cat10/3-0506.html
> %~n1 - %1 をファイル名だけに展開します。

## GAMESSのバッチ処理

```txt:動作環境
Windows 8.1 Pro (64bit)
GAMESS version:gamess-64-2016-pgi-linux-mkl.msiによるインストール
   - PGI v15.4
   - -fastsse -Mipa=fast,safe
   - Intel MKL
```

- inputs以下の*.inpファイルをすべて処理する
- outputs以下に.outという拡張子で結果を保存する
- 実行ファイルは`gamess.2016-pgi-linux-mkl.exe`とする
- CPUは1つだけ使用

```group_run_170828.bat
for %%d in ( inputs\*.inp ) do ( 
REM    echo %%d
REM    echo inputs\%%~nd.out
    rungms.bat %%d 2016-pgi-linux-mkl 1 0 outputs\%%~nd.out
)
```

以前に処理したことがある場合は、restartフォルダ内の「README.txt以外」の作業ファイルが残っている。これらのファイルがあるとGAMESSの処理が進まないため、すべて消してから`group_run_170828.bat`を実行すること。
bool型とBoolean型の違いについて

初めまして。プログラミング初心者です。
C#の勉強をしている中でif文を学んでいたところ、bool型(true/false)で処理を分けれることを知りました。そこで、簡単な処理分岐をしてみようとVisualStudioで宣言したところ、boolの他に候補でBooleanというものがあることを知りました。ところが、ネットで調べても大体同じ扱いをしているように思いました。何故二つ用意されているのでしょうか？違いやそれぞれのメリット、デメリットなどを教えていただけませんか？よろしくお願いいたします。
kafka python

`kafka-python` という良く整備されているライブラリがある。これを利用したプログラムを作る。そうすると自動的に、ユニットテストで kafka が欲しくなる。

どうやるか？というと、Java では色々な技が編み出されているらしい。
http://qiita.com/kmizumar/items/60c60284501bda111065

だがしかし python ライブラリではどうするか？……というと、`kafka-python` 自身では subprocess で kafka を起動させていた。
https://github.com/dpkp/kafka-python/blob/master/test/fixtures.py#L23

kafka のバイナリ配布物には簡単設定の起動ファイルがあるけれど、`kafka-python` では自前の設定ファイルを使って起動させている。bind するポートなどをパラメータ設定できるようにするためで、それ以上の何かは無さそう。

とっても簡単なライブラリであれば、バイナリ配布物の設定ファイルでテストすればいいかな。
Cheapest Cloud Server

For the Developers, Startups and Business, its beneficial to look for the cheapest option for the cloud server.

One of the company providing Cheapest Cloud Server is F(x) Data Cloud.
It is the Asia's first company which is based on OpenStack to provides the Public Cloud Services at the cheapest price. 

The Services and plans are starting at just $1.99/Month with 99.95% Uptime.
It takes seconds to deploy your server. 
Also, users are provided with the option of custom SSD Storage.
For deploying server, you have multiple option for OS (Ubuntu, OpenSUSE, Fedora, Debian, CentOS and Windows) and DBMS (MySQL, MariaDB, Percona Server, MongoDB, PostgreSQL, CouchDB, Couchbase, Cassandra, Percona XtraDB Cluster) with Backup and Replication feature.
Heavy traffic is no more an issue with the Scale Up and Scale Out feature. 

The Cloud Service offered are: 
1) Infrastructure as a Service 
2) Database as a Service 
3) Block Storage as a Service 
4) Object Storage as a Service 
5) Network as a Service 
6) Backup as a Service 

For more details, Visit: https://fxdata.cloud
Auditsで計測した際に指摘されるポイント

Chrome 60 より、 Dev tools Audits が Lighthouse になったそうです。
https://developers.google.com/web/updates/2017/05/devtools-release-notes#lighthouse

# Performance で指摘されるポイント

## サイトに初回ペイントの遅延を引き起こすリソースを使用しない


# Best Practices で指摘されるポイント

## サイトの独自リソースに HTTP/2 を使用する
HTTP/2 を使用すると、ページのリソースの読み込み速度が向上し、データ通信量が削減されます。

## Passive Event Listener を使用してサイトでのスクロール パフォーマンスを向上させる

```js:js
document.addEventListener('touchstart', onTouchStart, {passive: true});
```

## サイトで document.write() を使用しない
2G、3G、低速 Wi-Fi など、低速のネットワークに接続している場合は、document.write() で動的に挿入された外部スクリプトによって、メインページのコンテンツ表示が数十秒単位で遅れる場合があります。

## サイトで rel="noopener" を使用して外部アンカーを開く
target="_blank" を使用して任意のページから別のページにリンクしている場合、リンク元のページとリンク先のページは同じプロセスで動作します。 そのため、リンク先のページで負荷の高い JavaScript が実行されていると、リンク元のページのパフォーマンスが低下するおそれがあります。

また、target="_blank" にはセキュリティ上の脆弱性もあります。リンク先のページでは window.opener を使用して親ウィンドウのオブジェクトにアクセスしたり、window.opener.location = newURL によって親ページの URL を変更したりできます。

レポートを確認して、Lighthouse で特定された各リンクに rel="noopener" を追加します。 一般的に、外部リンクを新しいウィンドウまたはタブで開く場合は、必ず rel="noopener" を追加してください。

```html:html
<a href="https://examplepetstore.com" target="_blank" rel="noopener">...</a>
```

## マニフェストに定義したアプリの省略名が切れずにホーム画面上に表示される
ユーザーがホーム画面にウェブアプリを追加すると、アプリ アイコンの下に short_name プロパティがラベルとして表示されます。 short_name が 12 文字を超えると、ホーム画面上で途中までしか表示されません。

Chrome の場合は、short_name が定義されておらず、name プロパティの値が十分に短ければ、name プロパティの値が代用されます。

ウェブアプリ マニフェストの short_name プロパティを 12 文字以下にします。

```js:js
{
  ...
  "short_name": "Air Horner",
  ...
}
```
【MarkLogic Server】XQueryでノードの要素名と値、属性を動的に設定する方法

はじめに
===

XQueryでXMLのノードを生成する時、外部ファイルなどから取得した内容を要素名や値、属性として設定したい場合があります。
XQueryでノードの要素名と値、属性を動的に設定する方法を紹介します。

概要
===

MarkLogicのXQueryでノードの要素名と値、属性を動的に設定する方法を記載します。

| 対象MarkLogicバージョン |
|---|
|8.0-6|

内容
===

ノードの記述は計算コンストラクタの「element」を利用します。
計算コンストラクタの「element」は以下のように記述することで要素ノードが生成されます。

```
element <要素名> {"値"}
```

例：root要素内に"123"の値を持つtest要素を設定します。

```
element root {
  element test {
    "123"
  }
}
```

上記XQueryを実行した結果は以下となります。

```
<root>
　<test>123</test>
</root>
```

動的に要素名や値を設定したい場合、
以下のようにlet句で設定したい要素名と値を変数に保持し、保持した内容を「element」に設定します。
変数の値を変更することで、動的に要素名と値を変更することが可能になります。

```
let $tagNameRoot := "root"
let $tagNameTest := "test"
let $value := "123"

(: 要素ノードを返却(xs:QName()での型変換は省略可能) :)
return element {xs:QName($tagNameRoot)} {
                  element {xs:QName($tagNameTest)} {
                    $tagNameTest
                  }
                }
```

上記XQueryを実行した結果は以下となります。

```
<root>
　<test>123</test>
</root>
```

利用例
===

利用例を記載します。

* 実装内容

CSVファイル（InputFile.csv）を読み込み、各行の要素名と値で要素ノードを生成します。
また、各要素ノードには属性を定義します。
生成した要素ノードをroot要素内に設定し、その結果をXMLファイル（OutputFile.xml）に出力します。

* 入力ファイル

入力ファイルの内容は以下になります。Tag1～Tag3を要素名、Value1～Value3を値とします。

```text:InputFile.csv
Tag1,Value1
Tag2,Value2
Tag3,Value3
```

* XQuery

XQueryは以下のように記述します。
属性の生成は計算コンストラクタの「attribute」を利用します。

```text
(: CSVファイルの読み込み :)
let $csvFile := fn:doc("/InputFile.csv")

let $node :=
  (: 読み込んだCSVファイルを1行ずつ処理 :)
  for $line in fn:tokenize($csvFile,"\n")
    (: カンマ区切りで配列に変換 :)
    let $array := fn:tokenize($line,",")
    (: 要素名を保持 :)
    let $tagName := $array[1]
    (: 値を保持 :)
    let $value := $array[2]
    (: 属性名を保持 :)
    let $attributeName := "id"
    (: 属性値を保持 :)
    let $attributeValue := fn:concat("id_",$array[2])
    (: ノードを返却 :)
    return element {xs:QName($tagName)} {
                      (: 属性ノードを生成 :)
                      attribute {xs:QName($attributeName)} {
                                    $attributeValue
                                },
                      $value
                    }

(: root要素内に処理結果を設定 :)
let $tagNameRoot := "root"
let $ret := element {xs:QName($tagNameRoot)} {$node}

(: XMLファイルを出力し終了 :)
return xdmp:document-insert("/OutputFile.xml",$ret)
```

* 出力ファイル

XQuery実行後、以下のファイルが出力されます。

```xml:OutputFile.xml
<?xml version="1.0" encoding="UTF-8" ?>
<root>
 <Tag1 id="id_Value1">Value1</Tag1>
 <Tag2 id="id_Value2">Value2</Tag2>
 <Tag3 id="id_Value3">Value3</Tag3>
</root>
```


おわりに
===

計算コンストラクタは要素ノードを生成する「element」や属性ノードを生成する「attribute」の他に、コメントノードを生成する「comment」やテキストノードを生成する「text」などがあります。
コメントノードやテキストノードなども動的に値を設定できるためとても便利です。

```math
\def\textsmall#1{%
  {\rm\scriptsize #1}
}
```

------------------------------------------------------------------------

**免責事項**

​​​​​$\textsmall{当ユーザ会は本文書及びその内容に関して、いかなる保証もするものではありません。}$
​​​​​$\textsmall{万一、本文書の内容に誤りがあった場合でも当ユーザ会は一切責任を負いかねます。}$
​​​​​$\textsmall{また、本文書に記載されている事項は予告なしに変更または削除されることがありますので、予めご了承ください。}$
Pythonでバイナリサーチ(二分探索)

Qiita初投稿です。

今回は、バイナリサーチをループと再帰の2パターンで実装してみました。


##ループでバイナリサーチ

```py:binary_search_loop.py
from typing import List


def binary_search_loop(data: List[int], target: int) -> int:
    left, right = 0, len(data)

    while left <= right:
        mid = (left + right) // 2
        if data[mid] == target:
            return mid
        elif data[mid] < target:
            left = mid + 1
        else:
            right = mid - 1

    return None


if __name__ == "__main__":
    data: List[int] = [int(x) for x in input("ソート済配列(スペース区切り)を入力: ").split()] # 内包表記を使った
    target = int(input("targetを入力: "))

    result = binary_search_loop(data, target)
    if result is not None:
        print(f"found: {result}番目にありました")
    else:
        print("not found")

```


##再帰でバイナリサーチ

```py:binary_search_recursion.py
from typing import List


def binary_search_recursion(data: List[int], target: int) -> int:
    def recursion(left=0, right=len(data) - 1):
        if left > right:
            return None

        mid = (left + right) // 2
        if data[mid] == target:
            return mid
        elif data[mid] < target:
            return recursion(mid + 1, right)
        else:
            return recursion(left, mid - 1)

    return recursion()


if __name__ == "__main__":
    data: List[int] = list(map(int, input("ソート済配列(スペース区切り)を入力: ").split())) # mapを使った
    target = int(input("targetを入力: "))

    result = binary_search_recursion(data, target)
    if result is not None:
        print(f"found: {result}番目にありました")
    else:
        print("not found")

```  


##気付いたことなど

- input()で得られるデータはstr型なのでint型に変換する。
    - str型のままだと比較のところで数字じゃなく文字コードで比較されてしまう。
ElectronでOpalとCRubyを使ってプロセス間通信する

```html:communication_process_demo.html
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>if (window.module) module = window.module;</script>
<script src="http://cdn.opalrb.org/opal/current/opal.js"></script>
<script src="http://cdn.opalrb.org/opal/current/opal-parser.js"></script>
<script src="http://cdn.opalrb.org/opal/0.10.1/external/opal-jquery-0.4.2.js"></script>
<script type="text/javascript">Opal.load('opal-parser')</script>

<script type="text/javascript">
function electron_spawn(cmd,arg) {
    let p = require('child_process').spawn(cmd,arg)
    p.stdout.on_data=(action,listener)=>{
        p.stdout.on('data',(data)=>{
            let d = JSON.parse(data.toString())
            if (d.action == action) listener(d)
        })
    }
    p.on('exit',(code,signal)=>{
        console.log(`child process exited:${code} signal:${signal}`)
    })
    p.on('disconnect',()=>{
        console.log('child process disconnect.')
        window.alert('child process disconnect.')
    })
    p.on('error',(err)=>{
        console.error('child process error:',err)
        window.alert('child process error:'+err.toString())
    })
    p.stderr.on('data',(data)=>{
        console.error('stderr:',data.toString())
        window.alert('stderr:'+data.toString())
    })
    window.addEventListener('beforeunload',(event)=>{
        p.kill()
    })
    return p
}
</script>

<title>communication process demo</title>

<body>
<h1>Addition</h1>
<form id="frm" method="post" onsubmit="return false;">
    <input type="number" step="0.1" name="x" placeholder="x" required> +
    <input type="number" step="0.1" name="y" placeholder="y" required> =
    <input type="number" step="0.1" id="z" placeholder="z">
    <input type="submit" id="btn">
</form>
</body>

<!-- プロセス間通信イベントリスナー(子プロセス) -->
<script id="cruby" type="text/plain">
STDOUT.sync = true
require 'json'
loop do
  Thread.start JSON.parse(gets.chomp) do |input|
    case input['action']
    when 'addition'
      output = {
        :action => :addition,
        :z => input['x'] + input['y']
      }
      puts output.to_json
    else
      STDERR.puts 'input:', input
    end
  end
end
</script>

<!-- CRuby起動 -->
<script type="text/ruby">
scpt = Element.find('#cruby').text
$Process = $$.electron_spawn 'ruby', ['-e',scpt]
</script>

<!-- プロセス間通信イベントリスナー(レンダラープロセス) -->
<script type="text/ruby">
$Process.stdout.on_data :addition do |data|
  Element.find('#z').value = data.JS[:z]
  Element.find('#btn').prop :disabled, false
end
</script>

<!-- UIイベントリスナー -->
<script type="text/ruby">
Element.find('#frm').on :submit do |evt|
  Element.find('#btn').prop :disabled, true
  data = `new FormData(#{evt.target.get(0)})`
  json = {
    :action => :addition,
    :x => data.JS.get(:x).to_f,
    :y => data.JS.get(:y).to_f
  }
  $Process.stdin.write <<EOS
    #{json.to_json}
  EOS
end
</script>
```
テスト環境用 Zabbix Server 3.4

##初めに
以前に [テスト環境用 お手軽zabbix server](http://qiita.com/Toshihiro_SKK/items/2b5e31bd625fb2edaa1f) を書いた訳ですが
8月後半にZabbix 3.4が正式リリースしたので性懲りもなく、Hyper-V用Zabbix3.4イメージを作ってみました。

##概要
Hyper-Vイメージで構築した、CentOS7上のZabbix Server 3.4です。
こちらに7zで圧縮して置いています（容量は522MBになりました）。
＜こちらはZabbix4.0が出たので配布を中止します。＞

圧縮ファイルを解凍して（今回も64GBのディスク容量が必要となりますので、HDD等は注意して下さい。）
Hyper-Vマネージャーで、解凍して出てきたフォルダーをインポートをして
下さい。
後は起動するだけです。
無事起動しましたらブラウザ上で http://192.168.1.126/zabbix と入力すればLogin画面が出て来ます。

##Zabbixサーバーで登録しているID&Pass等の設定
Zabbix3.0の時と全く同じです。

・Zabbix
　Username: admin
　Password: zabbix

・CentOS
　rootID: root
　rootPass: root
　userID: user
　userPass: user

・mysql
　userID: zabbix
　userPass: zabbix

・CentOS上のネットワーク
　IP address   192.168.1.126
　Sub-net mask 255.255.255.0
　Gateway      192.168.1.1
　DNS 8.8.8.8

今回も必要応じて書き換えて下さい。

##注意点
Zabbix_server.conf　　my.cnf　の書き換え
Zabbixのグラフの文字化け対策
こちらを行ってますが今回はほぼスッピンです。

3.4.1のリリースも近いそうですしZabbix3.4自体がポイントリリースの為
判って使われる方が多いと思いますので殆ど手を加えませんでした。


##おわりに
Twitterで俺が何時も構築する手順が知りたいとか言われるんですが
実際5ポイント程度の手順しかしてないんですよね。
構築の手順を知りたいと言われるので来月あたりに書いてみようと思います。
stoneを使い別のport番号でも待ち受ける

標準ポートを別のポートで待ち受けたいことはよくある。

例: 

* sshだと 22 -> 2222
* httpだと 80 -> 8080
* vncだと 5900 -> 8888 など。

iptables を使うとできると思うが、手軽にユーザー権限で行いたい。

```sh:インストール(ubuntu17.04にて確認)
apt install -y stone
```

```sh:5900を8888で待ち受ける場合
stone localhost:5900 8888
```

```sh:22を2222で待ち受ける場合
stone localhost:22 2222
```
document.getElementsByClassName で要素の幅を取得

document.getElementsByClassName で要素の幅を取得するとき、

```js:script.js
const Box = document.getElementsByClassName("box");
const W   = Box.clientWidth;
```

とすると undefined となり値が取れないので、以下の方法で値を取得

# idで取得する場合

```js:script.js
const Box = document.getElementById("box");
const W   = Box.clientWidth;
```

# classで取得する場合

```js:script.js
const Box = document.getElementsByClassName("box");
const W   = Box[0].clientWidth;
```

# HTMLCollection
HTMLCollection は要素群(document 内の順序)の一般的な集合(配列)を表現したインターフェイスで，リストから選択するためのメソッドとプロパティを提供します．
※配列ではないので注意

# おわりに
jQurey大好きな僕としては、一つコードを書くたびに「jQueryなら簡単なのに」と度々脳裏をよぎりますが、
そんな事を言っている時代でもない[^1] みたいなので、ひとつずづ頑張って覚えていこうと思います。
他にも良い方法があれば、是非コメントをください。

# 参考
[HTMLCollection - Web API インターフェイス | MDN](https://developer.mozilla.org/ja/docs/Web/API/HTMLCollection)
[^1]: [You Don't Need jQuery](https://github.com/oneuijs/You-Dont-Need-jQuery)
tint2 - タスクバー表示

## tint2

* [Tint2 - ArchWiki](https://wiki.archlinuxjp.org/index.php/Tint2)

vncserver でopenboxを使っていたが、タスクバー欲しいなと思って`tint2`入れてみたら使いやすかった。

```sh:
apt install -y \
  tint2 \
  xfce4-terminal openbox tightvncserver
```

```sh:.vnc/xstartup 
#!/bin/sh

xrdb $HOME/.Xresources
xsetroot -solid grey20
#x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
#x-window-manager &
# Fix to make GNOME work
export XKL_XMODMAP_DISABLE=1
#/etc/X11/Xsession

openbox&
tint2&
#
firefox&
xfce4-terminal&
```

```sh:
vncserver -geometry 1152x864 :0
```


## 左端に表示するランチャー

* .config/tint2/tint2rc にてfirefoxなどを設置できる。

```diff:
+ launcher_item_app = /usr/share/applications/xfce4-terminal.desktop
+ launcher_item_app = /usr/share/applications/xfce4-screenshooter.desktop
  launcher_item_app = /usr/share/applications/firefox.desktop
```
Androidのタブの実装方法

タブの実装方法は複数あり、各々がどういう位置づけかよくわからなかったのでまとめました。
コードは載せていなので、各自調べていただければと思います。
※第三者が提供しているライブラリは除きます。

#ActionBar
この方法API21の時に[非推奨](https://developer.android.com/reference/android/app/ActionBar.html#NAVIGATION_MODE_TABS)とされていますので、これから開発する方は使わないようにしましょう。
ただ、スワイプ＋タブの実装方法の[ベストプラクティス](https://developer.android.com/training/implementing-navigation/lateral.html
)として、ActionBarを使った方法が紹介されているんですよね。。。

#TabLayout
Android 5.0の時に[マテリアルデザイン](https://material.io/guidelines/components/tabs.html#)が発表されましたが、その際にマテリアルデザインに則った開発ができるようGoogleから[デザインサポートライブラリ](https://android-developers.googleblog.com/2015/05/android-design-support-library.html
)というものが提供されました。デザインサポートライブラリはAndroid 2.1以上をカバーできます。
TabLayoutはデザインサポートライブラリに含まれているものであり、マテリアルデザインに則った開発をするならばTabLayoutを使うべきです。

#ActivityTab
現在は[非推奨](https://developer.android.com/reference/android/app/TabActivity.html)となっているので、ActivityTabを使うならば後継のFragmentTabHostを使いましょう。

#FragmentTabHost
タブをフラグメントとして扱います。よって、例えばタブ上にアイコンを表示させたいときは、アイコンを表示するViewを作成し、それをFragmentTab上にセットします。
前述のTabLayoutと比較して、FargmentTabHostはタブというよりはフラグメントを扱っている感じです。(その分FragmentTabHostは柔軟なタブ表示ができます。)
どのようなタブデザインにするのかによってはFragmentTabHostを選択するのもありだと思いますが、マテリアルデザインに則ったデザインを行う場合は、マテリアルデザイン用に作られたTabLayoutを使った方がよいのではないかと考えられます。

#PagerTabStrip
ViewPagerとセットで使う必要があります。
一番簡単に「タブ(文字表示のみ)＋スワイプ」を持った画面の開発ができます。
ただ、同時に表示できるタブの個数が３つまでだったり、タブ上にアイコンを表示させる場合に一工夫が必要だったり、少し凝ったことをするとコーディング量が増えます。
フォントに斜めグラデーションを入れる


Demo : https://codepen.io/mo4_9/pen/MvPwJX

![スクリーンショット 2017-08-28 16.55.12.png](https://qiita-image-store.s3.amazonaws.com/0/136286/9c6fd805-e3df-5458-d3a6-4cd07036e027.png "スクリーンショット 2017-08-28 16.55.12.png")


```css
.text{
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-image: linear-gradient(45deg,#fd107f,#ff8519);
}
```

※IEでは使えない
[CSS text-stroke and text-fill](http://caniuse.com/#feat=text-stroke)

> 参考
[[CSS]「background-clip」を使って、テキストの下に画像を表示するスタイルシート](http://coliss.com/articles/build-websites/operation/css/css-tutorial-image-under-text.html)
FreeBSDでNAT64(Tayga編)

[ZRouterにIPv6のプロファイル](http://qiita.com/yamori813/items/1ce37cb67c145ce2b576)をいれてビルドできるようにしたので、せっかくなので実践的に使えるように設定してみました。

ISPはV4だけのところなので、自宅内の一部でIPv6をはることにしました。

V6からV4への変換はNAT64というらしく、いろいろなソリューションがあるようです。Linux向けに開発された物ですがFreeBSDでも使える[Tayga](http://www.litech.org/tayga/)を試してみました。

とりあえずportsにあったのでZRouterのportsにコピーしてビルドしたらすんなりビルドは通り、ターゲットイメージにコピーするためMakefileに2行だけ追加しました。

こんな構成で試してみました。

![NAT64.png](https://qiita-image-store.s3.amazonaws.com/0/104066/ed9a8589-9c9d-5921-ff2d-4bf67e7525b5.png)

iBookの内蔵EthernetにIPv6アドレスの2001:db8:12::1とルーターの2001:db8:12::2を設定しておきます。

AR7240では以下を設定します。

```
ifconfig arge0 inet 10.10.10.70 netmask 255.255.255.0
ifconfig arge1 inet6 2001:db8:12::2 prefixlen 64
```

taygaの設定ファイルはこんな感じにしてみました。

```
tun-device nat64
ipv4-addr 10.10.10.70
ipv6-addr 2001:db8:12::2
prefix 2001:db8:12:ffff::/96
dynamic-pool 10.10.10.128/30
data-dir /var/db/tayga
```

taygaはステートレスなNATでプールしているIPから1対1で払い出してそれぞれのIPで外部に接続を行います。上記の設定では10.10.10.128から10.10.10.131までを使います。

上記の設定でtaygaを起動するとnat64というインターフェースが表れます。起動した後に以下を実行します。

```
# sysctl net.inet.ip.forwarding=1
# sysctl net.inet6.ip6.forwarding=1
# sysctl net.link.ether.inet.proxyall=1
# ifconfig nat64 up
# route -n add -inet6 2001:db8:12:ffff::/96 -interface nat64
# route add 10.10.10.128/30 -interface nat64
```
natのarpを返すためにnet.link.ether.inet.proxyallの設定が必要でした。

iBookからIPv4側にIPアドレスでpingを送るとこんな感じです。

```
hiroki:~ hiroki$ ping6 -c 1 2001:db8:12:ffff::10.10.10.3
PING6(56=40+8+8 bytes) 2001:db8:12::1 --> 2001:db8:12:ffff::a0a:a03
16 bytes from 2001:db8:12:ffff::a0a:a03, icmp_seq=0 hlim=61 time=2.616 ms

--- 2001:db8:12:ffff::10.10.10.3 ping6 statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 2.616/2.616/2.616 ms
```

sshやtelnetもv6ネットワークからv4ネットワークにできました。

実はどうにか動くようになったのですが、pingが届くが返答しない状態で、なんでかなと思ってtcpdumpでぶいぶい言わせたらわかりました。taygaはBigendianなマシンで動かすとchecksumが壊れるようです。ググったらOpenWRT方面にパッチがあって同じようにあてました。

checksumのエラーがあってもsyslogにもsysctlにも出てこないようなのですが、どっかに情報出るようにした方が良いかもしれません。

パッチを当ててもtcpdumpでbad cksumと出ていて直ってないかと思ったら、FreeBSDのpingのレスポンスのICMPパケットはチェックサムを0で送る仕様でした。

名前でアクセスするにはDNS64というものが必要になるようです。
ファイル名だけでPHPの文法チェックをまとめて実行する手抜きシェルスクリプト


とりあえずチェックしたいファイルを引数にぶち込んでいけばチェックしてくれるようにした
正直誰得な気もするけど(

```verifyPHPSyntax.sh
#!/bin/sh

for x in "$@"
do
    find . -name "$x.php" -exec php -l {} \;
done
```

配下のPHPファイルを片っ端から文法チェックかけるとか前方一致で引っかかったPHPファイルを片っ端から文法チェックかけるとかでも良いと思ったけどとりあえず1〜2ファイルとかで良かったからこんなんで落ち着いてる
ES2017のasync/awaitを使って「同期的sleep処理」をワンライナーで書く

async関数の中であれば、この1行でOK！

```js
await new Promise(resolve => setTimeout(resolve, 5000));
```

JavaScriptで同期的sleep()関数を作る例は巷に色々と転がってますが、
ワンライナーでサクッと書けるのが嬉しいと思うのです。いい時代になった :joy:

実用例はこんな感じね。
ChromeのDevTools Consoleにコピペすれば動きますよ〜。

```js
(async () => {
  alert('ザ・ワールド！');
  await new Promise(resolve => setTimeout(resolve, 5000));
  alert('5秒経過！時は動き出す・・・');
})();
```

~~※注意
2017年8月現在、ES2017のasync/awaitを使えるブラウザは限られてます。
特にスマホ系は厳しい。
本番環境で使う時は、BabelでES5にコンパイルするのをお勧めします。~~

2018-09-14追記：
この一年で、ブラウザのasync/await対応かなり進みましたね！[IE以外はもうパーフェクト](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function#Browser_compatibility)！嬉しい。
しかも、Chromeでは「トップレベルawait」が実現しとるではないですか！これ本当に便利。今後ほかのブラウザも対応していくのかな？

トップレベルawait対応してるブラウザではasync関数で括らなくても良いので、冒頭に書いた`await new Promise(resolve => setTimeout(resolve, 5000))`これ1行でOKですねっ！

参考：
[ES7's async/await syntax.](https://gist.github.com/danharper/74a5102363fbd85f6b67)
[async function - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function)
[コマンドラインのトップレベル await がすごく便利](http://var.blog.jp/archives/73460179.html)
通番管理テーブルを使用して通番の取得をする

よくある社員データ管理アプリケーションで
 - 部署
 - 社員
それぞれのデータ登録時に取得する最新の通番を、通番管理テーブルから取得するようにした。

◇前提
 - autoCommitはfalse
 - トランザクション分離レベルはREAD_COMMITTED

◆通番管理テーブル使用前
select max(hogeId)で最大の通番を取得し、+1の通番を登録時に使用。

◆通番管理テーブル使用後
取得と同時に通番管理テーブルの通番を更新しトランザクション開始、本当に更新したいテーブルにデータをinsert後commit。
これで、トランザクション中に別ユーザが通番管理テーブルを更新しようとしても待ちの状態になり、不整合は発生しない。
TweenMaxを使ったSVGラインアニメーション

祝Qiita初投稿！

簡単なSVGアニメーションならわざわざSVGのライブラリ入れなくても実装できるぞってことで復習がてらに書いていきます。
今回はよく使うラインアニメーションに絞りました。

## ラインアニメーションって何？
文字通り線に沿って実行されるアニメーションで、よくイラレやフォトショで文字をアウトライン化しておいて！なんて言われると思いますが、アウトライン化することで文字の周りにパスが生成されます。
この「パス」がラインアニメーションに置ける「ライン」となります。
よくあるアニメーションでは、文字の外側にラインが引かれて最後に色が付くみたいなアニメーションもラインアニメーションです。

## ラインアニメーションで押さえておきたいCSSプロパティ
- stroke - 線の色を変更できる
- stroke-width - 線の太さを変更できる
- stroke-opacity - 線の半透明度を変更できる
- stroke-dasharray - 線を点線などに設定できる（stroke-dasharray: 表示長さ,間隔長さ）
- stroke-dashoffset - dash地点（点線の開始位置）からいくつ移動するかを設定できる

ラインアニメーションでは特にstroke-dasharrayとstroke-dashoffsetが重要になってきます。

## 実際にラインアニメーションを見てみる
[デモ](https://codepen.io/nokonokojr/pen/OjByqr)
stroke-dashoffsetの初期値は0になっており、
0から数字が増えただけstroke-dasharrayで設定した地点からラインが移動します。
といっても主にstroke-dasharrayは破線や点線を実装するために使用するのですが、
svgの長さいっぱいに表示長さと間隔長さを設定してあげてstroke-dashoffsetでSVGの長さいっぱい移動させてあげることで上のcodepenのアニメーション1のように線が描かれるようにアニメーションができます。
設定の仕方によってはアニメーション2のように出したり戻したりもできます。


## よくあるラインアニメーションを作ってみる
[よくあるデモ](https://codepen.io/nokonokojr/pen/MvPKGm)
冒頭でも紹介した文字のラインアニメーションです。
このようにSVG用のライブラリ使わなくてもTweenMaxで事足ります。

## まとめ
もっと工夫すればある程度複雑なアニメーションも可能でしょうが、あまりにも実装に時間がかかったり、SVGアニメーションの量が多いならライブラリを使った方が良いと思います。
Qiitaの月間の画像アップロード容量を増やすために投稿しましたが、書いてみると意外と楽しかったです。
参考にしたサイト様
 - https://triple-underscore.github.io/SVG11/painting.html#SpecifyingPaint
node-jt400を試してみた（Transactions）

#Transactions
テストを実施する前に物理ファイルにジャーナル処理を開始します。

```
STRJRNPF FILE(MYLIB/MEMBER MYLIB/MEMBER2) JRN(MYLIB/JRN) IMAGES(*BOTH)
```

```SQLtransactions.js
//コミットされる例
app.get("/tranCommit", function (req, res, next) {
    pool.transaction(function (tran) {
        var Id = 110;
        return tran.update("insert into member (ID,LNAME,FNAME,PROF,TOKUTEN) VALUES(?,?,?,?,?)", 
        [Id, "徳川","家綱",'４代目', 4]).then(function () {
            return tran.update("insert into member2 (ID,LNAME,FNAME,PROF,TENSU) VALUES(?,?,?,?,?)", 
            [Id, "徳川","家綱",'４代目', 4]); 
        });
    });
    res.send('end');
});

//ロールバックされる例。member2.TENSUに文字をセット
app.get("/tranRollback", function (req, res, next) {
    pool.transaction(function (tran) {
        var Id = 111;
        return tran.update("insert into member (ID,LNAME,FNAME,PROF,TOKUTEN) VALUES(?,?,?,?,?)", 
        [Id, "徳川","綱吉",'５代目', 5]).then(function () {
            return tran.update("insert into member2 (ID,LNAME,FNAME,PROF,TENSU) VALUES(?,?,?,?,?)", 
            [Id, "徳川","綱吉",'５代目', 'a']); 
        });
    });
    res.send('end');
});
```

/tranCommitを実行すると、それぞれの物理ファイルに正しくレコードが追加されます。
/tranRollbackを実行すると、member2 のインサート文でエラーが発生し、memberにレコードは追加されませんでした。
Avastをインストールしている際のSSL証明書の発行元表示問題

先日SSLの証明書更新作業を行なっていた際にブラウザで表示されるSSLの発行元がおかしいことに気づきました。

#証明書に記載されている認証機関名がavastになっている

通常、ブラウザから証明書の詳細を閲覧すると、発行元は各認証局が表示されるはずなのですが、
今回これがなぜか**[avast]**と表示されていました。

![SSL証明書認証機関表示.png](https://qiita-image-store.s3.amazonaws.com/0/174392/c4bcf621-7d78-4163-9823-f45e41ca2bab.png)

有効期限は更新されていて動作も問題なさそうなのに。。これが正常な状態なのかどうか確認できず、、

#avastのWEBスキャンを設定を変更する

実はこの状態、avast側でSSLにおけるチェックが行われているため起きる現象のようです。
きちんと指定された証明書のインストールを確認したいので、avastでの設定を変更をします。

まずavastを開いて、左下の歯車マークをクリック。

![avast04.png](https://qiita-image-store.s3.amazonaws.com/0/174392/5dcca1b9-fb8b-30ae-c7d7-9d81b8e36a01.png)

シールド　＞　ウェブシールド　＞　設定を選択。

![avast02.png](https://qiita-image-store.s3.amazonaws.com/0/174392/b944a44b-54ca-d127-0cec-88f676cf0621.png)

セキュリティ保護された接続をスキャンするの部分のチェックを外します。このチェックを外すと下段にあるブラウザからの〜。の部分のチェックも自動的に外れます。

![avast03.png](https://qiita-image-store.s3.amazonaws.com/0/174392/1585496f-9eda-68cc-fcb7-f2a4ff1e3103.png)

#再度証明書の確認をします

無事発行元がSymantecに更新されていることが確認できました。

![SSL表示.png](https://qiita-image-store.s3.amazonaws.com/0/174392/480849b9-b13e-63e8-386e-af1c2fd932be.png)
Fathomで遊んでみる

なぜかFathom Neural Compute Stick[^4]を手に入れたので，チュートリアルを動かしてみました．

## Fathomとは

- USB型の計算機をPCなどに差すだけで動作[^3]
- 推論を高速にやってくれるという代物らしい[^1]．(学習は無理)
- TensorFlowで書くと動作する．
- GPUより低消費電力

## 環境

- MacBook Air
- OS: macOS Sierra

## 実行手順(Docker版)

多分チュートリアル通りやっても動かないので，少し修正が必要となります．

Fathomのチュートリアル[^2]にseq2seqを試すコードがありますが，ルート権限が必要な場所にデータが置く必要があるコードになっているため，チュートリアルの手順で記載されているfathomユーザーではなくrootユーザーでログインして作業する必要があります．

```bash
docker pull rdadolf/fathom
docker run -it --user root rdadolf/fathom
```

### Seq2Seqのサンプル実行

ダウンロードするデータのファイル名が変わっているので，`fathom/seq2seq/data_utils.py`を下記に修正します．

```python
- train_path = os.path.join(directory, "giga-fren.release2")
+ train_path = os.path.join(directory, "giga-fren.release2.fixed")
```

下記コマンドでSeq2Seqのサンプルを実行します．
最初チュートリアルのSeq2Seqを動かすために必要なWMT'15のデータダウンロードに一時間ほどかかるので待ちます．(プログレスバーとかは出ないですが動いています．）

```bash
cd fathom/
mkdir -p /data/WMT15
python fathom/seq2seq/seq2seq.py 
```

## まとめ

- 用途としてはドローンとかラズパイ，監視カメラなどの画像認識処理を早めるために利用．
- 空き容量が50GBぐらいあるので，USBメモリとしても使える．
- 分からないことはフォーラム[^5]で聞けば良いっぽいです．

## References

[^1]: Adolf, [Fathom: Reference Workloads for Modern Deep Learning Methods](https://arxiv.org/abs/1608.06581), 2016.
[^2]: rdadolf, [Fathom - Installing Prerequisites](https://fathom.readthedocs.io/en/latest/quickstart/)(Fathomのチュートリアル)
[^3]: Armasu, [Deep Learning On A Stick: Movidius' 'Fathom' Neural Compute Stick (Updated)](http://www.tomshardware.com/news/movidius-fathom-neural-compute-stick,31694.html), 2016.
[^4]: Movidius, [Framework for DNN Prototyping](https://uploads.movidius.com/1463004959-Fathom-Combined-2-pager-web.pdf), 2016.
[^5]: [NCFS Forum](https://ncsforum.movidius.com/discussions)
LuaをVC2015でコンパイルする

単なるメモです。
めっちゃ簡単。

#手順
0. Luaのソースファイルをダウンロードする
1. VC2015を立ち上げる
2. ファイル→新規作成→新しいプロジェクト
3. Win32コンソールアプリケーションを選択して次へ
4. 「空のプロジェクト」にチェックを入れ、「SDLチェック」のチェックを外して完了
5. ソリューションエクスプローラーのソースファイルに、srcフォルダの.cファイルを全部突っ込む
6. ソリューションエクスプローラーのヘッダーファイルに、srcフォルダの.hファイルを全部突っ込む
7. luac.cをプロジェクトから除外する(lua.cとluac.cでmainが重複するため。luacはバイトコードコンパイラ)
8. ビルドする
9. 実行する

#メモ
Windowsかどうかなどは、luaconf.hが自動判別しているようです。
5.2, 5.1との互換性設定などもここでできます。

init.cのloadedlibsを削ることで、読み込むライブラリを減らすことができます。

#その他
※ただしここで出来上がるのは単体で走るLua環境です。
DLLやstaticなlibを作りたい場合はこっち
http://qiita.com/gpsnmeajp/items/5ae55d8f79d129f7c62b