OmniAICreator/Qiita-1.07M huggingface dataset:
今更ながらLINE BOTを作成してみた

### はじめに
初めまして。
PHPでサーバーサイドエンジニアをしております。
koisan1153と申します。

PHPを利用したLINEのBOTを作成してみたので、ツラツラと書いてみます。

### 必要なモノ
LINEの個人アカウント
サーバー(https通信が必要)

### 登録
LINE BOT はLINE＠の[Messaging API]を利用したものになりますので、
まずはLINE@への登録が必要です。

こちらを参考に準備しました。
[LINE BOTの作り方を世界一わかりやすく解説（１）【アカウント準備編】](https://qiita.com/yoshizaki_kkgk/items/bd4277d3943200beab26)

### httpsが必要
>Webhook URL ※SSLのみ対応

ということで、https〜で始まるサーバーを用意してください。
私はドメイン取得後に、[お名前.com VPS](https://www.onamae.com/server/vps/) ＋ [Let's Encrypt](https://letsencrypt.jp)で用意しました。

### PHPで書いてみる

まずはおうむ返しBOTを。
[メッセージタイプ](https://developers.line.me/ja/docs/messaging-api/message-types/)
ここの「テキスト」が来たら返すようにします。
また、イベントは「message」に限定します。
[メッセージイベント](https://developers.line.me/ja/docs/messaging-api/reference/#message-event)


```php:bot.php
// アクセストークン指定
$ACCESS_TOKEN = 'developerの[メッセージ送受信設定]の[アクセストークン]';

//ユーザーからのメッセージ取得
$json_string = file_get_contents('php://input');
$json_object = json_decode($json_string);

//取得データ
$replyToken = $json_object->{"events"}[0]->{"replyToken"};  //返信用トークン
$message_type = $json_object->{"events"}[0]->{"message"}->{"type"}; //メッセージタイプ

//メッセージタイプが「message」以外のときは200を返す
if($message_type != "message"){
  echo 200; exit;
}

//メッセージ内容
$message_text = $json_object->{"events"}[0]->{"message"}->{"text"};

//レスポンスフォーマット
$response_format_text = [
  "type" => 'text',
  "text" => $message_text
];

//ポストデータ
$post_data = [
  "replyToken" => $replyToken,
  "messages" => [$message_text]
];

//curl実行
$ch = curl_init("https://api.line.me/v2/bot/message/reply");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  'Content-Type: application/json; charser=UTF-8',
  'Authorization: Bearer ' . $ACCESS_TOKEN
));
$result = curl_exec($ch);
curl_close($ch);

echo 200;
```

こんな感じですかね。
コレでおうむ返しBOTが出来ました。

実際にはもっと色々なAPIと組み合わせたりして、
PUSH通知を使ってみたりなど出来るので、
面白いことが出来そうです。
デバッグに便利！ボタン1つでアプリを初期化する方法

アプリのデバッグなどをしている際に、一度アプリを初期化して、真っさらな状態から動作確認をしてみたい、というのが結構あるかと思います。

開発者であれば、adbのコマンドで

```
$ adb shell pm clear パッケージ名
```

とすればアプリの初期化をすぐに行なえます。

しかし、非開発者の人の場合だと
・アプリをアンインストールし、再度インストールする。
・端末の設定からアプリ一覧から該当するアプリの設定に行き、「データを消去」などでデータを消去する。
という、ちょっと面倒な手順を踏まなければなりません。


# アプリを初期化する処理を実装する
というわけで、アプリを初期化する処理を実装してみたいと思います。
といってもコード自体は結構簡単で、下記のような感じです。

```kotlin
Runtime.getRuntime().exec("pm clear パッケージ名")
```

`Runtime` に関しては、普段アプリ開発をしているなかでは、ほぼ使うことはないクラスかと思います。https://developer.android.com/reference/java/lang/Runtime.html

（正直詳しいところはわからないのですが） `Runtime.getRuntime()` でアプリ自身のランタイムを取得し、`exec` で任意のコマンドを実行することが出来る、みたいな感じのようです。

実際にアプリに組み込む場合は、デバッグ時だけに使えるデバッグメニューみたいなのを作って、そこに `アプリを初期化する` みたいなボタンを設置してあげるといいのではないかと思います。

```kotlin:DebugActivity.kt
...

clearButton.setOnClickListener {
    Runtime.getRuntime().exec("pm clear パッケージ名")
}

...
```

ちなみにこの処理を実行すると、アプリが強制的に終了するような挙動になります。

![clear_button.gif](https://qiita-image-store.s3.amazonaws.com/0/995/12d2862b-ed27-14d2-b4bc-cc3b4d129728.gif)

このボタンがあれば、デバッグ時に便利ではないでしょうか！

# 他のアプリの情報も消せるのか？
ここでふと、**「他のアプリでも初期化出来ちゃうのでは？」**という疑問が。
出来ないだろうなと思いつつも、もし出来たら相当良くないよな、ということで試してみました。

## 試してみる
↓おもむろにモンストのデータの初期化を試みる。

```kotlin
Runtime.getRuntime().exec("pm clear jp.co.mixi.monsterstrike")
```

これを実行してみると、**消すことは出来ませんでした。** :no_entry:

少し書き加えて、実行結果を確認してみると...

```kotlin

val result = Runtime.getRuntime().exec("pm clear jp.co.mixi.monsterstrike")
result.errorStream.bufferedReader().use {
    Log.d("DEBUG", it.readText())
}
```

```
Error: java.lang.SecurityException: PID 467 does not have permission android.permission.CLEAR_APP_USER_DATA to clear data of package jp.co.mixi.monsterstrike
```
権限が無い旨のエラーが出ておりました。
当然といえば当然の結果ですが、別アプリを削除することは出来ないようでした。

# 終わりに
`Runtime` を使ってのアプリの初期化方法を記載しました。
デバッグメニューなどに追加して、デバッグを簡単に行えるようにしていきたいですね :smile:
[Review] Tensorflow Multi-Thread Experiment

## Introduction
This is an experimental article with regard to multi-thread processing in Tensorflow.
Inside the code, there is nothing difficult stuff. It's just basic math addition operation and repeat it 40,000 times. Then compared the running time in two operations.

1. for loop
2. Tensorflow Multi-thread

Official docs:https://www.tensorflow.org/versions/r1.2/programmers_guide/threading_and_queues

## Code

```python
#!/usr/bin/python
import sys
from time import time
import tensorflow as tf

# Define an arbitrary tensor
x = tf.constant([[1, 2]])

num_threads = int(sys.argv[1])

counter = 0
N_EXAMPLES = 1000 * num_threads
with tf.Session() as sess:
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)

    print("Starting reading {} examples ... hold tight".format(N_EXAMPLES))
    timer = -time()
    while not coord.should_stop() and counter < N_EXAMPLES:
        sess.run(x)
        counter += 1
    
    timer += time()
    print("Took {} seconds for {} examples. {} seconds / example".format(timer, N_EXAMPLES, timer / N_EXAMPLES))
    coord.request_stop()
    coord.join(threads)


    counter = 0
    print("Starting reading {} examples ... hold tight".format(N_EXAMPLES))
    timer = -time()

    while counter < N_EXAMPLES:
        sess.run(x)
        counter += 1

    timer += time()
    print("Took {} seconds for {} examples. {} seconds / example".format(timer, N_EXAMPLES, timer / N_EXAMPLES))
    sess.close()
```

## Result
Sorry, since I did't print out the name of the function, it is not explicit which result is which. Above one is for tensorflow multi thread, and the other one is using loop operation.
As you can see, almost the same amount of time is consumed during the operation.

```bash
Starting reading 40000 examples ... hold tight
Took 3.0370140075683594 seconds for 40000 examples. 7.592535018920899e-05 seconds / example
Starting reading 40000 examples ... hold tight
Took 3.056126117706299 seconds for 40000 examples. 7.640315294265747e-05 seconds / example
```

## Conclusion
I need to check how efficiently use the tensorflow multi thread operation more!
GPSの研究　その８

#概要
GPSを理解したかった。
衛星の位置と、擬似距離から、受信機の位置を求めよ。

#問題のまとめ

衛星は、8個、見つかった。
単位は、メートルです。
受信機の位置を求めましょう。

| GPS衛星      |       X |    Y    |  Z |　擬似距離　|
|:-------------|:--------------:|:------------------:|:-----:|:--:|
|G02 |6262234.031370984 |-14613110.981922923 |21254935.229655903|22402645.008|
|G04 |19040661.998708855 |-8311756.524602333 |16532658.634675292|20565303.43|
|G07 |26078664.69836943 |5588070.077162541 |-239561.27794465935|22181773.156|
|G08 |24470813.305349953 |-95731.17177840695 |-10965308.78942738|24495107.648|
|G10 |10946425.106999923 |-13217422.981333993 |19960118.04486387|21478321.484|
|G13 |17400028.443231095 |1461399.2922087098 |19887536.270703305|20168944.047|
|G20 |14385911.569008492 |20514420.345839 |8765413.838559393|23186783.133|
|G23 |9336918.80677975 |12048291.269695656 |21723935.800126303| 21860039.258|

以上。
非公開関数のユニットテストについて 再び (C#)

# 非公開関数のユニットテストについて 再び (C#)

[前の記事](https://qiita.com/c-yan/items/f4acb3ab4c8090254a0e)で「PrivateObject クラス を使うとソースを書き換えずテストできますよ。」とコメントをもらったので.

静的メソッドは`PrivateType`、動的メソッドは`PrivateObject`でテストできるようです.
ただ、呼び出しがめんどくさいし、メソッド名が`nameof`できないので、リネーム機能の適用対象外になるのが辛い.
もちろんテストのためだけにアクセス修飾子を変えるのはどうよと言われるとそれはそれで悩ましいところがありますが、`internal`の方が気楽な感じがしました.


```csharp
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestTarget;

namespace TestTarget
{
    public class Target
    {
        private string value;

        public Target(string value)
        {
            this.value = value;
        }

        private string DynamicMethod()
        {
            return value;
        }

        private static string StaticMethod()
        {
            return "static";
        }
    }
}

namespace UnitTest
{
    [TestClass]
    public class Test
    {
        [TestMethod]
        public void StaticMethodTest()
        {
            Assert.AreEqual("static", new PrivateType(typeof(Target)).InvokeStatic("StaticMethod", null));
        }

        [TestMethod]
        public void DynamicMethodTest()
        {
            var value = "dynamic";
            Assert.AreEqual(value, new PrivateObject(typeof(Target), new object[] { value }).Invoke("DynamicMethod", null));
        }
    }
}
```
AWS Directory Serviceを使ってAmazon WorkSpacesを使用する際にハマったこと

※こちらの情報は2018/06/14時点の情報です

AWS Directory Service経由でADに参加させたAmazon WorkSpacesを使いたいと思って構築をやった際に、
ドハマリした内容をメモとして残しておきます。

結論から言いますと、 
**「ドキュメントには書いていないけれど、Workspaces用のディレクトリが作成できないAZがある！！」**
です。 

今回は、EC2上にADを構築して、そのADとAD Connectorを使用して作成したディレクトリを使用してWorkspacesを構築する
という要件だったのですが、これが一筋縄でいかずに結果的に3リージョンでの検証となりました...

構成は以下のような感じ。
---
- リージョン
  東京(ap-northeast-1)
  London(eu-west-2)
  Ireland(eu-west-1)

- VPC
  10.0.0.0/16  
  - subnet1  
    10.0.1.0/24  
  - subnet2  
    10.0.2.0/24  
  - subnet3  
    10.0.3.0/24  

- Security Group
  以下ポートを許可  
  - TCP/UDP 53 - DNS  
  - TCP/UDP 88 - Kerberos authentication  
  - UDP 123 - NTP  
  - TCP 135 - RPC  
  - UDP 137-138 - Netlogon  
  - TCP 139 - Netlogon  
  - TCP/UDP 389 - LDAP  
  - TCP/UDP 445 - SMB  
  - TCP 1024-65535 - Dynamic ports for RPC 
   
- ドメインコントローラ兼DNSサーバ
  - OS  
    Windows 2016 Base(日本語化済)
  - Active Directory  
    XXXX-test.jp
  - IP  
    10.0.3.134
  - connect用ユーザアカウント/パスワード  
    ad-test/XXXXXXXX

---

Directory ServiceでDirectory作成を行うところまでは全く問題なく進むのですが、Worksspaces側のディレクトリ登録を実施すると
以下のメッセージが表示されて登録されない状況に。

```
"Unsupported Subnet
The selected directory was created in a subnet that is not supported by the WorkSpaces service, and cannot be registered. Please try with a different directory or contact the AWS Support Team on the community forums and via AWS Premium Support."

"サポートされていないサブネット
選択したディレクトリは、WorkSpacesサービスでサポートされていないサブネット内で作成されたため、登録できません。別のディレクトリで試してみるか、コミュニティフォーラムやAWSプレミアムサポートでAWSサポートチームにお問い合わせください。"
```

エラーメッセージが抽象的すぎて、どこから切り分けていけばよいかと途方に暮れながら、VPCの作り直しやSubnetの作り直しなどを
行っていったのですが、そこであることに気づきました。

**「あれ？これってもしかしてSubnetがあるAZの組み合わせの問題なんじゃね？」**

ということでパターンを作ってディレクトリ作成→登録を行ってみると、やっと見えてきました...
やっぱり **「特定のAZが含まれていると作成ができない」** ということが。

というわけで、現段階での検証結果はこんな感じになります。
追って追記していきたいと思います。

```
※tokyo リージョン
  AD Connectorで"ap-northeast-1d"に作ったsubnet上には、workspaces用のディレクトリは作成できない
  
  ap-northeast-1a, ap-northeast-1c → OK
  ap-northeast-1a, ap-northeast-1d → NG
  ap-northeast-1c, ap-northeast-1d → NG

※London リージョン
  AD Connectorで"eu-west-2c"に作ったsubnet上には、workspaces用のディレクトリは作成できない

  eu-west-2a, eu-west-2b →OK
  eu-west-2a, eu-west-2c →NG
  eu-west-2b, eu-west-2c →NG

※Ilerand リージョン
  すべてのAZで問題なし！

  eu-west-1a, eu-west-1b → OK
  eu-west-1a, eu-west-1c → OK
  eu-west-1b, eu-west-1c → OK

```


こちらの記事が少しでも皆さんのお役に立ちますように。
Sassのコメントメモ


Sassは、jsで使う//１行コメントが使える。
普通に書いてたけど、これjsのコメントだった気がする（！）と思ったので調べ直したメモ。


##// １行コメント
Sassでは、//１行コメントが使える。
コンパイル後のCSSでは削除される。

```scss:scss
// コメント
```

##/* 通常のコメント */
CSSで使う通常のコメントも使える。
コンパイル後もコメントは削除されない。
コンパイル時のoutputStyleを「compressed」にした場合は、コメントは削除される。

```scss:scss
/* コメント */
```

「compressed」にした場合でもコメントを削除されないようにするには、
「/*」の直後に「!」を書く。

```scss:scss
/*! コメント */
```

##cssコメント

```css:css
/* コメント */
```

##htmlコメント

```html:html
<!-- コメント -->
```

##jsコメント

```js:js
// コメント
```
Ruby　配列まとめ

プログラミング言語はRubyから勉強し始め、今はPHPを勉強しています。

RubyとPHPで似ている点や同じようなコードが多々あるので理解しやすいのですが、
実際コードを書くとどうしてもごちゃ混ぜになってしまうので、
PHPの勉強を進めながら、こちらではRubyについて書いていくことにしました！

# 配列
配列とはいくつかのデータを種類別に箱の中に入れたようなイメージです。
まとめてデータを入れて置くことによって、複数の処理が１度にできると言う利点があります。

hanako,taro,mario
この3つの名前を使いましょう。

配列ではなく、変数に代入した場合
`name1 = "hanako"
name2 = "taro"
name3 = "mario"`
↓
`puts name1
puts name2
puts name3`
↓
｟プレビュー｠
hanako taro mario

名前を出力する作業を３回も行なっています。
このように1つ1つをputsして表示させるのは大変なので、１つの中にまとめて入れてしまい、
その箱をputsすることで、中身の要素をパパーっと表示させます。
例えば、namesと言う箱の中に、hanako,taro,marioといった名前を入れるとします。

`names = ["hanako","taro","mario"]`
namesにhanako,taro,marioの３つの名前を代入しました。
この場合のnamesは配列の変数名、hanako,taro,marioは要素。
要素は[]の中に、""で囲み、1つ1つの間は,で区切って書きます。
↓
`puts names`
↓
｟プレビュー｠
hanako taro mario

###インデックス番号
また、配列は順番関係なく入っている訳ではなく、
インデックス番号といって、入れた順に０から番号が割り振られています。

ここでの場合、
0:hanako
1:taro
2:mario
となっており、このインデックス番号を指定して、
その要素のみを取り出すことも出来ます。

`puts names[1]`
↓
｟プレビュー｠
taro

###変数展開
代入した変数の値は変数展開を使って文字列の中に入れることができます。

`puts "私の名前は#{names[3]}です"`
文字列の中の値を入れたい場所に**#{変数名[インデックス番号]}**を入れ込むだけ！
↓
｟プレビュー｠
私の名前はmarioです


##繰り返し処理
###each文
上記の変数展開した文字列を、インデックス番号別に出力させるには、
`puts "私の名前は#{names[インデックス番号]}です"`
番号の数だけこのコードを書かなくてはいけません…これまためんどくさい

そういった繰り返し同じ処理をしたい場合にはeach文を使います。

`配列　.each do |変数名|
  #実行したい処理
end`

ここでの場合は
配列にnames、変数名は要素の中身を表すものnameとし、
私の名前は○○です、と表示させるようにしたいとしましょう。

`names .each do |name|
  puts "私の名前は#{name}です"
end`
↓
私の名前はhanakoです
私の名前はtaroです
私の名前はmarioです


###ハッシュ
配列と同じように複数の値を扱えるものですが、
さらにそれぞれにキーと呼ばれる名前をつけることが出来ます。

１人のユーザーの情報が
名前がhanako、年齢が２８歳の時
user = {"name"=>"hanako","age"=>28}


と、ここまで書きましたがボツ記事。。

同じ処理でもRubyだとこう、PHPだとこう、って感じで書き直します。
レガシーなお問い合わせワークフローをTrelloを使って可視化する

##対象者
この記事の対象者は社内SE、情シス、サイトの運用を担当している人になりますが、考え方としては基幹システムの運用に携わる人等も参考にできると思います。

##最初に
企業のサイト・ポータルサイトには、必ずと言って良い程お問い合わせフォームがあります。
基本的な処理フローは以下の通りでしょう。![legacy.png](https://qiita-image-store.s3.amazonaws.com/0/105531/dbc7426f-5809-45b1-6042-f2bb49803bc9.png)

クラウドサービスを導入していたり、Wordpress に Flamingo or contact form DBなどのpluginを組み合わせている場合はお問い合わせデータをデータベース上に蓄積しているかもしれません。


私が管理しているサービスもサービス開始当初は上の図のような処理フローでしたが、着信したメールの内容を見て一次切り分けをして担当者にフェッチするような作業をしていましたが、サービスの拡大と共に以下のような課題がでてきました。
##課題
・処理状況とユーザへのフィードバックが不明
→時にはほったらかしになっている事も
・時間をとられる
→サービス開始当初は週2件程度で片手間で処理していたのが順調に問い合わせ件数が増えて現在は1日2件。今後も増える見込み。

##施策
・問い合わせはそのままAPIを通じてTrelloに登録。
→Trelloはslackと連携させてあるので、通知も確認できる。
　Trelloとslack連携方法は http://un-tech.jp/notify-from-trello/ を参照。
→「未処理」「処理中」「処理終了」「ペンディング」リストを作り、「未処理」に自動起票され、手を付けた案件は「処理中」に動かし、処理状況をカードのコメント欄に記載すると言う運用ルールを決め、処理が完了したカードは「処理終了」へ移動。管理者である私が目視で経緯の確認をした上でアーカイブ処理。

##プログラム
無し（笑）
実はcurlでtrello APIを叩くPHPを書いたところで「もしや…」と思いtrelloの設定を探してみたら、メール投稿でtrelloにカードを作成する機能がある事に気が付きました。
実際にプログラムをいじった部分は
・「問い合わせメール」の宛先をtrelloから取得したメールアドレスにconfigを変更
・メール本文の出力を整形
　→メールのタイトルがカードタイトルとなり、メール本文がカードの本文となります

trelloのメール投稿によるカードの作成方法は以下のエントリを参照。
http://kazsoga.com/trello-todo-mail-add/


##結果
・問い合わせ処理がどこまで進んでいるか？処理漏れが無いか？が「かんばん化」により直視でき、グループ内でも進捗状況を共有できるように。
・結果的に監督者の私は「処理終了」のカードのコメントを見て経緯をチェックし、問題が無ければアーカイブするだけの手間いらずに。スマホアプリを使えば帰りの電車でもできますね。

##wish
・処理件数が増える事が見込まれているので、問い合わせメニューにプルダウンを実装、その値を見て◯◯チームのボード、●●チームのボードへ振り分けられるようにフォーム側を改修
・Trelloカードの「期限」機能を利用して処理時間の統計などとってユーザエクスペリエンスの向上に役立てる
リダイレクトされるページをパースする（JsoupでLocationを使って画面遷移する）

### はじめに
私は、
〜2013年3月　文系大学学部卒
〜2018年4月　インフラ系のSIer　#　LinuxとかAzureとか
2018年5月〜 WEB系エンジニア　#　開発できるようになりたかった
という変遷をたどり、
絶賛業務でJava勉強中の身です。

開発のやり方が学べたら
フルスタックなスキルを身につけられるように頑張りたいと思ってます。

だいぶ初心者な記載が多いかもしれませんが、Outputを続けることで、
エンジニアスキルが積み上がっていけばなと。


### やりたかったこと
とあるWEBページのスクレイピング
検索画面にアクセスし（キーワードで検索した後、そのデータをスクレイピングし）たい。

こんな感じでアクセスしたいが、

```Java 
Connection.Response response = Jsoup.connect(Url)
        .headers(header)
        .cookies(cookies)
        .data(formData)
        .timeout(3000)
        .execute();
```

URLがこんなかんじ。

```
https://hoge.com/fuga.aspx?validation_no=123456789
```

もちろんそのままアクセスしてもエラーになるし、
validation_noを精製しようと頑張ってもよくわからん。

６時間ほど悩んだ後、ディベロッパーツールを眺めていたら、

```
https://hoge.com/fuga.aspx?validation_no=123456789
```
の前にアクセスしてるページ（※）に「Location」という文字があるじゃん！と気づく。
調べて見るとリダイレクト先を指定しているようだ。
あれ、つまりvalidation_no考えなくてもいいってこと！？


※仮に以下のURLとする

```
https://hoge.com/top.aspx
```
### やったこと
こんな感じで、一旦

```
https://hoge.com/top.aspx
```
を使い、下記でLocationを取得する。

``` 
Connection.Response res = Jsoup.connect(Url)
        .headers(header)
        .timeout(3000)
        .cookies(cookies)
        .method(Connection.Method.GET)
        .followRedirects(false)
        .execute();

System.out.println(response.header("Location"));
```

そうすると、validation_no付きのURLが取得できるので、
それを使って、やりたいことを実行する。


### 終わりに
見る人が見れば一発でわかりそうだけど、ハマってしまった。。。


参考：https://stackoverflow.com/questions/16243455/capture-header-location-with-jsoup-or-other-html-parser



###追記（2018/6/18）
受け取ったLocationで再度Jsoupを叩いていたんだけど、
そもそも、

``` 
        .followRedirects(true)
```
この存在だけでよかったっぽいです。
読んだ論文：Replacement AutoEncoder: A Privacy-Preserving Algorithm for Sensory Data Analysis


## どんなもの？
多次元のデータを匿名化することに着目している。主に時系列のデータを窓枠を定めて匿名化したい。
まず、データが匿名したいものから順にblack, gray, whiteの3種類に分けられることに触れ、blackは匿名化され、grayとして表現されるべきだとしている。ただし、時系列のデータの場合、窓を定めてしまうとblack、gray、whiteが混ざって存在するため、その場合は一番割合の多いラベルを採用している。

その際、単にgrayなデータでblackを置換するのではなく、置換したデータを教師としてAutoEncoderに学習させれば良い置換ができる学習器が出来上がるとしている。実際、MNISTのデータに対して偶数をblack、奇数をwhite、0をgrayなデータして与えたとき偶数の画像を与えると0の画像を返すReplacement AE (RAE)が生成できた。

![MNISTの結果](https://qiita-image-store.s3.amazonaws.com/0/254837/302ef09d-684c-2a4b-c238-ce8faf4d166f.png)

## 先行研究と比べてどこがすごい？
置換によって匿名化している点？

正直よくわからない

## 技術や手法のキモはどこ？
AutoEncoderで匿名化している点。denoising autoencoder[^dae]にヒントを得たとしている。
## どうやって有効だと検証した？
第三者の識別機であるHARを用いて、RAEで置換したデータを食わせ、blackがgrayとしかほとんど識別されないことを確かめた。
![検証用の識別器を含めたRAEの構成](https://qiita-image-store.s3.amazonaws.com/0/254837/0191deda-8828-a4b8-9f29-00af86969138.png)
![結果](https://qiita-image-store.s3.amazonaws.com/0/254837/661a9a64-4d3f-0e27-a6c3-4df519ca2822.png)




## 議論はある？
検証の一つとして、偽のgrayを識別する識別器をGANによってつくったところ、ほぼ100％識別できてしまうことが分かった。置換しても解析者に偽であることが明らかになるとWhiteなデータがあったことは露見してしまう。しかし、作者はこのGANの作成に生のデータが必要なため問題にならないとしているが、GANをほかの経路で得た同様な内容のデータで学習すればよいから問題だと思う。

## 次に読むべき論文は？
[denoising ae][1]は読んでもいいかもしれない。

## 感想
AEで匿名化するという発想は自分にもあったので読んだ。が、自分はAEで得た隠れ層の値にこそ意味があると思っているのだが、筆者はそこではなくAEの出力に着目している。これでは結局、教師に与えた関数の模写であり、なら教師として与えた関数である、blackをgrayにする関数を最初から匿名化に使えばよいのにと思う。現状ではただ単に時系列のデータのラベル付けをするN.N.を作成したに過ぎない結果だ。
また、第一に匿名化するときにblackなデータかどうかが分かっているというのも前提に疑問がある。そこまでわかっているなら消せばよいと思うのは駄目なんだろうか？少しでもデータを残したいんだとしても、「じゃそれblackじゃなくない？」と意味が分からない。

[^dae]: P. Vincent, H. Larochelle, Y. Bengio, and P.-A. Manzagol, “Extracting and composing robust features with denoising autoencoders,” in Proceedings of the 25th ICDM. ACM, 2008, pp. 1096–1103

[1]:  http://www.cs.toronto.edu/~larocheh/publications/icml-2008-denoising-autoencoders.pdf
【JavaScript】【Canvas】【Fabric.js】canvas上で波線などの装飾のある線を引く

# 前提
fabric.js Version 2.3.2

# 目的
HTML5のcanvas上に、任意の長さの波線などの装飾のある線を描画していく方法の検討。

# 戦法

canvasを扱うライブラリは[Fabric.js](http://fabricjs.com/docs/)を使います。
このライブラリには[線を描画する機能](http://fabricjs.com/docs/fabric.Line.html)は備わっていますが、
波線などは描画できないようです。
今回は波線の画像を連続させて波線を描画する作戦でいきました。

# やってみた

![mokumoku.png](https://qiita-image-store.s3.amazonaws.com/0/196806/231c34df-b958-e650-18b3-d88fcc2315bf.png)![mokumoku.png](https://qiita-image-store.s3.amazonaws.com/0/196806/231c34df-b958-e650-18b3-d88fcc2315bf.png)![mokumoku.png](https://qiita-image-store.s3.amazonaws.com/0/196806/231c34df-b958-e650-18b3-d88fcc2315bf.png)![mokumoku.png](https://qiita-image-store.s3.amazonaws.com/0/196806/231c34df-b958-e650-18b3-d88fcc2315bf.png)![mokumoku.png](https://qiita-image-store.s3.amazonaws.com/0/196806/231c34df-b958-e650-18b3-d88fcc2315bf.png)

こんかいはこういうモクモク線？でやってみました。

<p data-height="265" data-theme-id="0" data-slug-hash="dKzXGx" data-default-tab="js,result" data-user="momosetkn" data-embed-version="2" data-pen-title="もくもく線描画" class="codepen">See the Pen <a href="https://codepen.io/momosetkn/pen/dKzXGx/">もくもく線描画</a> by momosetkn (<a href="https://codepen.io/momosetkn">@momosetkn</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 解説

[fabric.Image](http://fabricjs.com/docs/fabric.Image.html)を[left属性](http://fabricjs.com/docs/fabric.Image.html#left)(要は左からの横方向の位置)を用意した画像の幅分足していきながら、並べていきます。
並べる画像のうち右端の画像は画像を部分的にしか使わないため[width属性](http://fabricjs.com/docs/fabric.Image.html#width)で部分的に削るようにします。
そして、最後に[fabric.Group#initialize](http://fabricjs.com/docs/fabric.Group.html#initialize)でグループ化します。
※グループ化しないと並べた画像のそれぞれが選択するさいにバラバラに選択されてしまいます

# 最後に

コードもっと綺麗にできた気がするけど…まあいっか。
バーチャルキャスト用のconfig.jsonの作成方法

# バーチャルキャスト用のconfig.jsonの作成方法

[バーチャルキャスト](https://virtualcast.jp/)でニコニ立体のモデルを使いたいけどconfig.jsonってどうやって作ればいいの？？　って方向けの文章です

## そのまえに
[らーめん](https://twitter.com/priramen)さんがconfig.jsonの中身を作成ツールを作ってくれました
ありがとうございます。

URLはこちらです
http://ramensoy.webcrow.jp/vc_json_creator/

これでシンタックスエラーも怖くない！

## config.jsonの作成

### １．拡張子を表示させる
config.jsonを作成する前に、Windowsは初期状態で[拡張子](https://flets-w.com/user/point-otoku/knowledge/pc-operate/pc-operate22.html)が表示されない状態になってますので、まず拡張子を表示させます

エクスプローラーの【表示】→【オプション】を選択します

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79067/5223b01f-623f-6335-d812-ee983bfa0690.png)

フォルダーオプションから【表示】タグを選択し
「登録されている拡張子は表示しない」のチェックを外します

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79067/313444a9-9a06-be5e-8fba-10964bf74112.png)

そうすると、今まで【VirtualCast】という名前だった実行ファイルが【VirtualCast.exe】という名前に変わり【.】（ピリオド）の後ろの拡張子が表示されます

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79067/829c67f3-1be0-cbab-0f4b-0bdb9348bc55.png)
※表示されました

### ２．config.jsonという名のファイルの作成

手段、方法は色々あるのですがとりあえずテキストファイルを作ってリネームして作成します

VirtualCast.exeがあるフォルダーを右クリックで
【新規作成(X)】→【テキストドキュメント】を選択して、【新しいテキスト ドキュメント.txt】を作成します 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79067/3bfdb07b-9118-8faa-de7b-fbe557a97f13.png)

作成した【新しいテキスト ドキュメント.txt】を右クリックで【名前の変更(M)】を選択し【新しいテキスト ドキュメント.txt】というファイル名を【config.json】に変更します

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79067/cc552dd0-19d0-e1a0-fa4f-a45c4b136563.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79067/23e11a69-92be-615b-0eb8-1bd8698dbd02.png)

### ３．config.jsonの編集

メモ帳を開いて、作成した【config.json】ファイルをメモ帳で開きます

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79067/3e54dd63-7b79-f325-9589-0cd9ba1e9a02.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79067/0a9ca9af-10c8-81a9-9cd6-43a23030e313.png)

開いたメモ帳にコンフィグを入れます

今回はこちらのモデルを使うことにします
https://3d.nicovideo.jp/works/td32947

このモデルのモデル番号は【32947】なのでコンフィグファイルは下の通りとなります

```json:config.json
{
  "niconico": {
    "character_models": [
        32947
    ]
  }
}
```

こんな感じでコピペします
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79067/47cb0466-d311-f756-2d15-7941cbf9177f.png)

コピペが終わったら【ファイル】→【上書き保存】で作成してコンフィグをセーブします

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79067/456c4de2-b5e4-7272-7057-bc35d39523a7.png)

### ４．バーチャルキャストを実行して確認

作成したコンフィグ正しければ、スタジオに入った後以下のような許諾同意画面が出て、同意すると設定したモデルが使えます

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79067/138a7cdc-3e20-e470-b54e-6b3951345a57.png)

### ５．注意事項

モデルを複数同時に使いたい場合はモデル番号をカンマ（,）区切りで書いていきます
※最後の数字の後ろにはカンマがいらないので注意が必要です

（例）

```json:config.json
{
  "niconico": {
    "character_models": [
        32947,35961,35206
    ]
  }
}
```
### ６.最後に

config.jsonの設定に関しては以下のURLを確認してください

モデルデータの設定方法
https://www.infiniteloop.co.jp/blog/2018/04/virtualcast-matsui/

パノラマ画像の設定方法
https://www.infiniteloop.co.jp/blog/2018/05/virtualcast-panorama/

ホワイトボード・カンペ・ダイレクトビューの設定方法
https://www.infiniteloop.co.jp/blog/2018/06/virtualcast-122-release/

[らーめん](https://twitter.com/priramen)さんのconfig.jsonの中身を作成ツール
http://ramensoy.webcrow.jp/vc_json_creator/
PowerShell で JSON 変換をするときに発生するアレコレ

# PowerShell で JSON 変換をするときに発生するアレコレ

## Q1. ConvertTo-Json で変換すると、深いところが変換されない

```powershell
PS> @{a=@{b=@{c=@{d=1}}}} | ConvertTo-Json
{
    "a":  {
              "b":  {
                        "c":  "System.Collections.Hashtable"
                    }
          }
}
```

## A1. -Depth を指定する.

```powershell
PS> @{a=@{b=@{c=@{d=1}}}} | ConvertTo-Json -Depth 100
{
    "a":  {
              "b":  {
                        "c":  {
                                  "d":  1
                              }
                    }
          }
}
```

## Q2. ConvertTo-Json で変換すると、Enum が数値になる

```powershell
PS> (Get-Date).DayOfWeek | ConvertTo-Json
4
```

## A2. Newtonsoft.Json に頼る

```powershell
PS> Import-Module .\Newtonsoft.Json.dll
PS> $settings = New-Object Newtonsoft.Json.JsonSerializerSettings -Property @{ TypeNameHandling = "None"; MaxDepth = 1024; Formatting = "Indented"; NullValueHandling = "Ignore"}
PS> $settings.Converters.Add((New-Object Newtonsoft.Json.Converters.StringEnumConverter))
PS> [Newtonsoft.Json.JsonConvert]::SerializeObject((Get-Date).DayOfWeek, $settings)
"Thursday"
```

## Q3. PSCustomObject を Newtonsoft.Json で変換すると大変なことになる

```powershell
PS> [Newtonsoft.Json.JsonConvert]::SerializeObject((Get-Date | Select-Object Year, Month, Day), $settings)
{
  "CliXml": "<Objs Version=\"1.1.0.1\" xmlns=\"http://schemas.microsoft.com/powershell/2004/04\">\r\n  <Obj RefId=\"0\">\r\n    <TN RefId=\"0\">\r\n      <T>Selected.System.DateTime</T>\r\n      <T>System.Management.Automation.PSCustomObject</T>\r\n      <T>System.Object</T>\r\n    </TN>\r\n    <ToString>@{Year=2018; Month=6; Day=14}</ToString>\r\n    <Obj RefId=\"1\">\r\n      <TNRef RefId=\"0\" />\r\n      <MS>\r\n        <I32 N=\"Year\">2018</I32>\r\n        <I32 N=\"Month\">6</I32>\r\n        <I32 N=\"Day\">14</I32>\r\n      </MS>\r\n    </Obj>\r\n    <MS>\r\n      <I32 N=\"Year\">2018</I32>\r\n      <I32 N=\"Month\">6</I32>\r\n      <I32 N=\"Day\">14</I32>\r\n    </MS>\r\n  </Obj>\r\n</Objs>"
}
```

## A3. PSCustomObject を避けるか、ConvertTo-Json を使う

```powershell
PS> $d = Get-Date
PS> [Newtonsoft.Json.JsonConvert]::SerializeObject(@{Year = $d.Year; Month = $d.Month; Day = $d.Day}, $settings)
{
  "Day": 14,
  "Year": 2018,
  "Month": 6
}
```

または

```powershell
PS> Get-Date | Select-Object Year, Month, Day | ConvertTo-Json
{
    "Year":  2018,
    "Month":  6,
    "Day":  14
}
```

## Q4. ConvertFrom-Json で変換すると、PSCustomObject になる

```powershell
PS> ('{"a": 1, "b": 2 }' | ConvertFrom-Json).GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    PSCustomObject                           System.Object
```

## A4. System.Web.Script.Serialization.JavaScriptSerializer を使う

```powershell
PS> (New-Object System.Web.Script.Serialization.JavaScriptSerializer).Deserialize('{"a": 1, "b": 2 }', [System.Collections.Hashtable]).GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Hashtable                                System.Object
```
wxPythonを使ってみる (5) 

こんにちは．これからwxPythonを使ってみる(5)について始めたいと思います．
対象や動作環境などのはじめに必要な情報は[wxPythonを使ってみる(1)](https://qiita.com/Kenta-Han/items/5ac4f38d518e3262905f) と同じになります．
また，今回の内容は前の4回の続きとなります．是非読んで見てください．

## 特徴
前回では，Sizerを使ったレイアウトのBoxSizerのflag引数について学びました．今回もSizerを使ったレイアウトの続きを学んで行きたいと思います．
今回はuserData引数について学びましょう．

userDataはアイテムの追加と同時に，開発者が任意のデータを埋め込むことができます．オブジェクトであれば引く数として渡すことができるのでとても便利です．


```python3:window_display11.py
import wx

class CustomData:
	def __init__(self):
		self.y = '2018'
		self.m = '06'
		self.d = '01'
		
class CustomFrame(wx.Frame):
		def __init__(self,title):
			wx.Frame.__init__(self,None,-1,title,size=(400,400))
			
			panel = wx.Panel(self)
			
			layout = wx.BoxSizer(wx.VERTICAL)
			layout.Add(wx.Button(panel,wx.ID_ANY,'B01'),userData='TestUserData')
			layout.Add(wx.Button(panel,wx.ID_ANY,'B02'),userData=100)
			layout.Add(wx.Button(panel,wx.ID_ANY,'B03'),userData=CustomData())
			
			print(layout.GetItem(0).GetUserData())
			print(layout.GetItem(1).GetUserData())
			print(layout.GetItem(2).GetUserData().y)
			print(layout.GetItem(2).GetUserData().m)
			print(layout.GetItem(2).GetUserData().d)
			
			panel.SetSizer(layout)
			
			self.Show()
			
app = wx.App(False)
CustomFrame('BoxSizer')
app.MainLoop()
		
```

上のwindow_display11.pyを実行すると以下の2つの図となります．

<img width="397" alt="スクリーンショット 2018-05-29 12.12.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/179248/fa963707-afd9-6430-fa25-cd061ff95725.png">

<img width="157" alt="スクリーンショット 2018-05-29 12.12.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/179248/235f27f3-f41f-4e6d-f92f-1514c2c56847.png">

3つのwx.Buttonを持つwx.Frameが表示されます，コンソール上へ次のように出力されます．
以上のように，任意のデータが任意のタイミンングで取り出すことができます．データベースから取得したデータをそのまま格納したりなど，便利な使い方を模索してみてください．

今回のwxPythonを使ってみる(5)は以上で終わります．
読んでいただいてありがとうございます．
次回からSizerを使ったレイアウトのStaticBoxSizerについて学媚態と思います．StaticBoxSizerは，その名の示す通りBoxSizerからの派生しているSizerです．予告はここまで，ではまた今度で会いましょ！



### 「wxpythonを使ってみる」目次
* [wxPythonを使ってみる(1)](https://qiita.com/Kenta-Han/items/5ac4f38d518e3262905f)
* [wxPythonを使ってみる(2)](https://qiita.com/Kenta-Han/items/dfd9764aedd64f9f92be)
* [wxPythonを使ってみる(3)](https://qiita.com/Kenta-Han/items/a7a58ad3cf5ae1f67625)
* [wxPythonを使ってみる(4)](https://qiita.com/Kenta-Han/items/89d11908d49c34976071)
CodeIgniterで配列を設定ファイルから呼び出す

固定された内容の配列を、コントローラーやモデルのどこでも呼び出せる様に、config配下に設定する。たとえば、住所入力時の都道府県のリストなど。

## CIのversion

``CI_VERSION = '3.1.8';``

## config配下に都道府県の配列のファイルを置く。

application/config/prefectures.php

```php

$config['prefectures'] = array(
    '1'=>'東京',
    '2'=>'神奈川'
);
```
### autoloadを設定

application/config/autoload.php

```php

$autoload['config'] = array('prefectures');
```
### 配列の呼び出し

どこのコントローラー、モデルからでも、以下で都道県の配列を取得できる。

```php
$this->config->item('prefectures');
```
railsでプロジェクト内でroot_pathを使う

## railsでプロジェクトのroot_pathを使いたい時
- railsコンソールでプロジェクト内の指定のファイルを引数に実行したかったので、調べた

```rb
# これで取得出来る
Rails.root
# プロジェクト内のファイルのpathと結合する
Rails.root.join("app/model/target_model.rb")
```
VBAで計算機を回す（物理）

VBAで自動的に計算機を回しまくる、というコードです。

```vba

'おまじない=======================================
'Win32apiというwindows操作する関数を呼び出してます。
'関数ごとに呼び出すので、行が多いです。やりたいことを「●● vba win32api」でぐぐると出てくるのでコピペです。
Public Declare Function Findwindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpwindowname As String) As Long
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWndParent As Long, ByVal hwndChildAfter As Long, ByVal lpszClass As String, ByVal lpszWindow As String) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long
Private Declare Function SetWindowPos Lib "user32.dll" (ByVal hWnd As Long, ByVal hWndInsetAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal uFlags As Long) As Long
Public Const WM_SETTEXT = &HC
Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type
'おまじない終わり=======================================
 
Sub VBAでパソコン操作のサンプル電卓回し()
 
    '電卓を回す回数をインプット
    回す回数 = InputBox("何回まわしますか？（最大20くらいにして下さい）", , 5)
    
    '電卓を起動する
    Shell "C:\Windows\system32\calc.exe", vbMinimizedFocus
    Sleep 1000
    
    '電卓のwindowハンドルを取得
    hWnd = Findwindow(vbNullString, "電卓")
    
    '電卓の計算欄に回す回数を記述=======================================
    hWnd2 = FindWindowEx(hWnd, 0, "CalcFrame", vbNullString)
    hwnd3 = FindWindowEx(hWnd2, 0, "Static", vbNullString)
    hWnd4 = FindWindowEx(hWnd2, hwnd3, vbNullString, vbNullString)
    hwnd5 = FindWindowEx(hWnd4, 0, vbNullString, vbNullString)
    hwnd5 = FindWindowEx(hWnd4, hwnd5, vbNullString, vbNullString)
    hwnd5 = FindWindowEx(hWnd4, hwnd5, vbNullString, vbNullString)
 
    Call SendMessage(hwnd5, WM_SETTEXT, 0, 回す回数 & "回まわします　")
    Sleep 2000
    
    '電卓を回す=======================================
    Dim myRect As RECT
    Const SWP_NOSIZE As Integer = &H1 '現在のサイズを維持（cx、cyは無視）
    Pi = WorksheetFunction.Pi() '回す用の円周率
    
    '中心を取得
    Call GetWindowRect(hWnd, myRect)
    'サインとコサイン使って回す。setwindowposでwindowの位置を指定できます。
    For i = 1 To 回す回数
        半径 = 300 * i / 回す回数
        For t = 1 To 360 Step 1
            Call SetWindowPos(hWnd, 0, myRect.Left + 半径 * Cos(t * Pi / 180), myRect.Top + 半径 * Sin(t * Pi / 180), -1, -1, SWP_NOSIZE)
        Next
        DoEvents
    Next
End Sub
Ubuntu 上で動く PHP-FPM でエラーログを出力する

サーバ移転前の環境では PHP 実行時のエラーログが標準（エラー）出力や error_log ファイルに書き出されていたが、新環境ではデフォルトで書き出されなくなっていた。

Web で調べてみると「`catch_workers_output`を`yes`に設定する」という記述がいくつかのサイトで見受けられたのだが、この設定でやっていることは「ワーカープロセスのログをメインのログにリダイレクトする設定」であり、ワーカープロセスが書き出したエラーのみ見たい場合には不適切だ。

ここでは、ワーカープロセスのエラーログ書き出しを有効にするために行なった設定をログとして残しておく。なお、OS は Ubuntu 16.04、PHP のバージョンは 7.2 である。

# PHP プール設定の変更
PHP7.2 のワーカープロセスに関する設定は、プール用設定ファイル `/etc/php/7.2/fpm/pool.d/www.conf` で設定するようだ。

`sudo vi`で設定ファイル内を見てみると、以下のような記述があった。

```conf:www.conf
; Default Value: nothing is defined by default except the values in php.ini and
;                specified at startup with the -d argument
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
```

このうち、以下の2行を uncomment し、エラーログ出力を有効にする。

```conf:www.conf
php_admin_value[error_log] = /var/log/fpm-php.www.log
php_admin_flag[log_errors] = on
```

修正を保存後、以下のコマンドで PHP-FPM を再起動する。

```console:console
$ sudo systemctl restart php7.2-fpm
```

Web サーバの再起動は特に必要ない。

# ログファイルの権限変更

[こちらのページ](http://www.phppro.jp/qa/3908)によると、上記の設定だけでは実行ユーザ（当環境では`nginx`）から権限の問題でエラーログが出力できないらしい。
なので、予め権限を設定した空のログファイルを作成しておく。

```console:console
$ sudo touch /var/log/fpm-php.www.log
$ sudo chown nginx:nginx /var/log/fpm-php.www.log
```

必要に応じて`chmod`でパーミッションの設定もする。

以上の設定を行なえば、`/var/log/fpm-php.www.log`にエラーログが書き出されるはず。

# 補足
`php_flag[display_errors]`を`on`に設定すれば、エラーが画面に出力される。
Flowを使った静的型検査の導入

Reactをv15->16にアップデートした際、既存プロジェクトへ [Flow](https://flow.org/en/) の導入をしてみたので、
その手順のまとめ。

※今回の記事では導入方法のみを解説して、PropTypesの代わりにpropsの型定義をする方法などは別記事でまとめる予定です。

## 0 - Flowとは？ なぜ導入？

**Flow - https://flow.org/**
JavaScriptの変数に静的な型定義を追加できるようにし、その妥当性をチェックできる仕組み。

Reactには元からPropTypesというコンポーネント属性に対する型チェックの仕組みがあったが、v16からは別パッケージへ切り離されたのとstate等の型もチェックしたかったので今回Flowの導入を行った。
ベンダーはReactと同じfacebookなので少し安心感もある。

## 1 - Flowのインストール

### Flowの本体とコマンドラインインターフェースをインストール
（型検査のためのモジュール）

```
yarn add -D flow-bin
```

### babel-plugin-transform-flow-strip-types プラグインをインストール
（babelビルド時に型宣言の除去を行わせる）

```
yarn add -D babel-plugin-transform-flow-strip-types
```

### eslint-plugin-flowtype プラグインのインストール
（Flowの型定義つきJSをESLintに通るようにする）

```
yarn add -D babel-eslint eslint-plugin-flowtype
```

加えて、parser を babel-eslint に変更する必要あり

`.eslintrc` に

```
{
  "parser": "babel-eslint",
  "plugins": ["flowtype"],
  "rules": {
    ...
  }
}
```
ESLintルール（rules）の設定は [4 - ESLint ルールの設定](https://qiita.com/hrkn123/private/0efb55c33a38ec70082e#4---eslint-%E3%83%AB%E3%83%BC%E3%83%AB%E3%81%AE%E8%A8%AD%E5%AE%9A) にて

### VSCodeにFlow Language Supportプラグインをインストール

```
{
  "flow.pathToFlow": (eg; "${workspaceRoot}/node_modules/.bin/flow")
  "javascript.validate.enable": false,
  "flow.useNPMPackagedFlow": true
}
```

## 2 - node_modulesをチェック対象外にする

`.flowconfig` に

```
[ignore]
.*/node_modules/.*
```

を追加

## 3 - flow-typedで外部モジュールの型定義を読み込む
FlowはReact本体の型定義しか知らないため、外部モジュールを使用しての型検査には定義ファイルを別途読み込む必要がある。
flow-typedというリポジトリーからこれらの定義ファイルの読み込みが可能。

```
yarn global add flow-typed
flow-typed install
```

**flow-typed - https://github.com/flowtype/flow-typed**

モジュールによってはこれでカバーされないため、libsに自分で型定義を記述する。


## 4 - ESLint ルールの設定

`.eslintrc`にflowの設定を行うことにより、どういった状況でエラーを出すのか指定することができる。

### プラグインによる recommended設定
まずは、用意されているrecommended設定を使うのが便利。

`.eslintrc`

```
{

...

  "extends": [
    "plugin:flowtype/recommended"
  ],
  "plugins": [
    "flowtype"
  ]
}
```

### rulesへのカスタマイズルールの設定

また、`"rules":` にエラーを出したいルールを追加することができる。
ここに記述をしないと、変数宣言や関数戻り値などに型定義を忘れても教えてくれないので注意。

### 記述例）

```
{
  ...

  "rules": {

    ...

    "flowtype/require-variable-type": [2],
    "flowtype/require-return-type": [2, "always",
      {
        "excludeArrowFunctions": "expressionsOnly",
        "excludeMatching": ["constructor", "render", "mapStateToProps", "mapDispatchToProps"]
      }
    ],
    "flowtype/no-weak-types": [2, {
      "any": true,
      "Object": true,
      "Function": false
    }]
  }
}
```

#### 解説
##### ・`flowtype/require-variable-type`
変数宣言時に型定義を必須とする

##### ・`flowtype/require-return-type`
関数の戻り値型定義を必須とする
`excludeArrowFunctions`でアロー関数の除外、`excludeMatching `で除外したい関数名を設定できる。

##### ・`flowtype/no-weak-types`
anyなど曖昧な型定義を制限できる
今回のケースでは、any,Objectは不可、Functionは可としている。

その他ルールは公式GitHubを参照：https://github.com/gajus/eslint-plugin-flowtype#eslint-plugin-flowtype-rules


## 5 - Flowの記法

型検査したいファイルの先頭に

```
/* @flow */
```

TypeScriptのように

```
  let a: number = 1;
```

と型定義


公式: https://flow.org/en/docs/react/components/#toc-stateless-functional-components


## 6 - 型検査の実行

```
yarn run flow
```
Chart.jsで円グラフにonclickをつける

#概要
クリックされた要素ごとに違う動きを付けたかった際に苦労したのでメモ代わりに
(初学者なので間違い等あるかもしれません)

#サンプルコード
```sample.html
<!DOCTYPE html>

<head>
    <title>Pie Chart</title>
</head>

<body>
    <canvas id='myChart'></canvas>

    <script src='http://code.jquery.com/jquery-3.3.1.js'></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js'></script>
    <script src='sample.js'></script>
</body>

</html>
```

```sample.js
let myChart = new Chart(ctx, {
    type: 'pie',
    data: data = {
        labels: ['Red', 'Yellow', 'Blue'],
        datasets: [{
            data: [10, 20, 30],
            backgroundColor: ['#FF0000', '#00FF00', '#0000FF']
        }],
    },
});


$('#myChart').on('click', (evt) => {
    // クリックされたアイテムの取得
    const activePoints = myChart.getElementsAtEvent(evt);

    if (activePoints.length > 0) {
        // クリックされた配列の番号
        const clickedElementindex = activePoints[0]['_index'];

        // クリックされた要素の内容
        const label = myChart.data.labels[clickedElementindex];

        if (label === 'Red') {
            console.log('Red');
        }
        else if (label === 'Yellow') {
            console.log('Yellow');
        }
        else if (label === 'Blue') {
            console.log('Blue');
        }
    }
});
```
#結果
![image.png](https://qiita-image-store.s3.amazonaws.com/0/256055/80c06838-da10-5c80-0b95-b7cb41f31e51.png)

#まとめ
labelをif文で判定しているのでやり方としてあんまり美しくないかなぁと思ったり。。。
押された際にmyChart.update()でグラフを更新したりすれば表現の幅が広がりそうですね！
DataBindingでonLongClick() を使うとき

# onClickのイメージで使おうとするとハマる
```Kotlin:HogeActivity.kt
interface HogeDelegate {
    fun onClickElement()
    fun onLongClickElement()
}


class HogeActivity : AppCompatActivity(), HogeDelegate{
  override fun onClickElement() {
    Timber.d("onClickElement")
  }
  override fun onLongClickElement() {
    Timber.d("onLongClickElement")
  }
}

```

```XML:activity_hoge.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        >

    <data>

        <variable
                name="delegate"
                type="HogeDelegate"
                />

    </data>

    <View
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{() -> delegate.onClickElement()}"
            android:onLongClick="@{() -> delegate.onLongClickElement()}"
            >

      <!-- 省略 -->
    </View>

</layout>

```

→ ビルドエラーになる

# LongClickの返り値はBoolean

```Kotlin:HogeActivity.kt
interface HogeDelegate {
    fun onClickElement()
    fun onLongClickElement() : Boolean
}


class HogeActivity : AppCompatActivity(), HogeDelegate{
  override fun onClickElement() {
    Timber.d("onClickElement")
  }
  override fun onLongClickElement() : Boolean {
    Timber.d("onLongClickElement")
    return true
  }
}
```

意外とLongClick使ったことなくて、エラーログ読んでも解決に至らず結構時間使った。
困った時はやっぱりリファレンス

 https://developer.android.com/reference/android/view/View.OnLongClickListener
読んだ論文：差分プライバシを満たすニューラルネットワークモデ ル構築手法の提案

# 差分プライバシを満たすニューラルネットワークモデ ル構築手法の提案

## どんなもの？
差分プライバシを満たすニューラルネットによる学習方法について
1. 学習前に匿名化
2. 学習中に匿名化
3. 学習後に匿名化

の３つについて言及している。実際に評価を取っているのは１の学習前に匿名化のみ。結局先行研究と何も変わらない
## 先行研究と比べてどこがすごい？
学習中、後の匿名化について言及したこと
## 技術や手法のキモはどこ？
特にない
## どうやって有効だと検証した？
匿名化したデータに対してニューラルネットで学習した。匿名度が小さい（差分プライバシのεが大きい）ほど良い学習ができることを確認した
## 議論はある？
２と３の手法については未調査
## 次に読むべき論文は？
ここはからはわからない
debianでNTPサーバ・クライアント

##1.環境
Virtual Boxのdebian9にNTPを3台

##2.NTPサーバ
####NTPのインストール
`apt -y install ntp`

####設定ファイルの編集
`vim /etc/ntp.conf`
・以下を#でコメントアウト化
\#pool 0.debian.pool.ntp.org iburst
\#pool 1.debian.pool.ntp.org iburst
\#pool 2.debian.pool.ntp.org iburst
\#pool 3.debian.pool.ntp.org iburst

・以下を追加
serverに127.127.1.0を指定すると、NTPサーバが時間を合わせる基準として自分自身のローカルクロックを使用する。
`server 127.127.1.0`
50行目に時刻同期を許可する範囲を追記
`restrict 10.0.2.0 mask 255.255.255.0 nomodify notrap`

・再起動
`systemctl restart ntp`

##3.NTPクライアント
####NTPクライアントのインストール
`apt -y install ntp`

####設定ファイルの編集
`vim /etc/ntp.conf`
・以下を#でコメントアウト化
\#pool 0.debian.pool.ntp.org iburst
\#pool 1.debian.pool.ntp.org iburst
\#pool 2.debian.pool.ntp.org iburst
\#pool 3.debian.pool.ntp.org iburst

・以下を追加
serverにNTPサーバのIPアドレスを設定
`server 10.0.2.1`

・再起動
`systemctl restart ntp`

##4.動作確認
サーバ側で`ntpq -p`すると自サーバをサーバとした時刻同期が行われている
クライアント側で`ntpq -p`するとサーバ側と時刻同期が行われている

##4その他
IPアドレスなどは自分の環境に合わせて設定してください。
【puppeteer】foreverで再起動した際に、Chromeのプロセスを残らないようにする

# はじめに

スクレイピングを実施するnode.jsサーバをforeverで稼働させていたのですが、どうもforeverの再起動時にブラウザが終了されず、Chromeのプロセスが残っていました。
forever再起動時に、稼働中のブラウザは終了して新規作成されるのが嬉しいです。ブラウザを終了させる方法を模索したのでメモ。

# 対応方法

node.js側で終了のシグナルを受け取った際に、ブラウザを終了してからnode.jsのプログラムを終了する流れにすることによって解決します。

## forever終了時のシグナルをSIGTERMに変更

foreverが、プロセスを終了させるために送るシグナルのデフォルトは``SIGKILL``です。
node.jsでは、シグナルを受け取った時にイベントを発行できますが、``SIGKILL``は不可なので、送るシグナルを``SIGTERM``に変更します。

foreverで起動するときのオプションで、終了時にプロセスに送るシグナルを変更することができます。

```sh
forever start --killSignal=SIGTERM xxxx.js
```

## puppeteer起動時オプション変更

puppeteerは、SIGTERMのシグナルが送られてくるとブラウザを閉じてくれます…が、その後プログラムを終了してくれません。
終了してくれないと困るので、puppeteer側のSIGTERMシグナル受信時の処理を無効にして、ブラウザを閉じる処理は自分で書くことにしました。

SIGTERMシグナル受信時の処理を実施するかどうかはブラウザ起動時のオプションで指定可能です。

```javascript
const launchOption={handleSIGTERM: false};
browser = await puppeteer.launch(launchOption);
```

## SIGTERMシグナル受信時のイベントをリスナーに登録

最後に、SIGTERMのシグナルが送られてきたら、「ブラウザを終了させてからプログラムを終了する」処理をリスナーに登録すれば完了です。

```javascript
process.on('SIGTERM', async () => {
  console.log('Got SIGTERM. close browser.');
  await browser.close();
  process.exit(0);
});
```

これで再起動するたびにゾンビChromeが増える事態は無くなります。
AE 正三角形の辺と高さの求め方

#計算式
三角形辺の長さ

```jsx
hankei = content("グループ 1").content("多角形パス 1").outerRadius;
a=(Math.sqrt(3)*2)*(hankei/2);//辺の長さ
```

三角形の高さ

```jsx
a=(Math.sqrt(3)*2)*(hankei/2);
h=Math.sqrt(3)/2*a;//高さ
```
[AWS] マネジメントコンソールへのIAMユーザーログイン時に発生するイベント

# 発端
CloudWatch Events を使って、AWSマネジメントコンソールへのIAMユーザーのログイン失敗を検知していました。
ですが、どうやら「非存在ユーザー」のログイン失敗を検知できなくなっているようです。ここ１〜２ヶ月の間に。
というわけで、目的↓

# 目的
IAMユーザーのマネジメントコンソールログイン時、成功/失敗でそれぞれどのようなイベントが発生するかを確認する。


# 調査方法
CloudWatch Events で SignIn のイベントを検知し、Lambdaに流してログ出力します。
※以前のイベントパターンとの比較もできればよかったのですが、わかりやすくログを残してない＆遡って調べる気力は無いので、やりません。

![AWS-Login-Event_Architecture.png](https://qiita-image-store.s3.amazonaws.com/0/193715/5d056b58-bb00-4141-e65e-2032ab4af3b4.png)


## CloudWatch Event Rule のイベントパターン

```
{
  "detail-type": [
    "AWS Console Sign In via CloudTrail"
  ]
}
```

# 調査パターン＆結果

この表で伝わるでしょうか・・・。２行目までヘッダです。

| IAMユーザー |  | 認証 |  |  | 結果（発生イベントから抜粋） |  |
|:----|:----|:----|:----|:----|:----|:----|
| ユーザー有無 | MFA設定 | パスワード | MFA | 結果 | eventName | responseElements |
| 非存在 | - | - | - | ×NG | CheckMfa | {CheckMfa:Failure} |
| 存在 | なし | ◯正 | - | ◯OK | ConsoleLogin | {ConsoleLogin:Success} |
|  |  | ×誤 | - | ×NG | ConsoleLogin | {ConsoleLogin:Failure} |
|  | あり | ◯正 | ◯正 | ◯OK | CheckMfa | {CheckMfa:Success} |
|  |  |  |  |  | ConsoleLogin | {ConsoleLogin:Success} |
|  |  |  | ×誤 | ×NG | CheckMfa | {CheckMfa:Success} |
|  |  |  |  |  | ConsoleLogin | {ConsoleLogin:Failure} |
|  |  | ×誤 | ◯正 | ×NG | CheckMfa | {CheckMfa:Success} |
|  |  |  |  |  | ConsoleLogin | {ConsoleLogin:Failure} |
|  |  |  | ×誤 | ×NG | CheckMfa | {CheckMfa:Success} |
|  |  |  |  |  | ConsoleLogin | {ConsoleLogin:Failure} |



## まとめ
* MFA設定があるIAMユーザーのみ、イベントが２つ発生する。
* `eventName : CheckMfa` イベントは
  * MFAが設定されていれば、入力したワンタイムパスワードが正しくても誤っていても `responseElements : {CheckMfa:Success}` となる。
  * IAMユーザーが存在しない場合のみ`responseElements : {CheckMfa:Failure}` となる。
* `eventName : ConsoleLogin` は
  * IAMユーザーが存在しない場合は発生しない。（以前は発生していたはず！）
  * パスワード認証とMFA認証のどちらが誤であっても結果は `responseElements : {ConsoleLogin:Failure}`
  * それ以外（必要な認証方法すべてが正）の場合に `responseElements : {ConsoleLogin:Success}`

フローチャートも作ってみようと思いましたが、ちょっと面倒だったのでやめました。
IAMユーザーあり＆MFA設定なしの場合に何故 `Success` でイベントが発生しないのかがイマイチ釈然としない。

## ログイン失敗を検知したかったら
下記の判定を行えばよさそうです。

```
responseElements.CheckMfa = Failure
  or
responseElements.ConsoleLogin = Failure
```
FlutterでDart2が使用できなかった時に調べたこと


Dart2ではnewやconstが省略可能らしいので書き換えてみるかとnewを削除して実行したところコンパイルエラーとなった。

```
Error: The Keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
Tab(icon: Icon(Icons.directions_car)),
          ^
```
## 先に結論

FlutterSDKが古かった。 `flutter upgrade` で最新にUpgradeして解決。

## `Flutter dart2` でググる

ヒットした[こちら]("https://qiita.com/rkowase/items/b891cec73896113031fb")や[こちら]("https://qiita.com/sekitaka_1214/items/2a8ef9367752942f7bfc")の記事によると Android Studioを使っている場合、`Preferences` にdart2を使用するための項目があるとのことだったが見当たらなかった。
どうやらFlutter Plugin Version 25.0でその項目は削除されたらしい。

![スクリーンショット 2018-06-14 16.06.34.png](https://qiita-image-store.s3.amazonaws.com/0/6290/0909893d-5804-0274-bb04-7941453d1f44.png)

## flutter docter

困った時の `flutter docter`。v0.2.8...最新じゃない気がする。

```
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v0.2.8, on Mac OS X 10.13.5 17F77, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK 27.0.3)
[✓] iOS toolchain - develop for iOS devices (Xcode 9.4)
[✓] Android Studio (version 3.1)
[!] IntelliJ IDEA Community Edition (version 2018.1.4)
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
[!] VS Code (version 1.24.0)
[✓] Connected devices (2 available)
```
FlutterSDK更新は`flutter upgrade`で行える。
更新して改めて実行すると無事アプリが動いた。

## おわりに
ASがFlutterのVersion古いって知らせてくれたら嬉しいなあと思いました。（気がつなかっただけ？）
NFSのmount設定メモ

WEBサーバーを冗長化しており、新たにファイル共有をしたいディレクトリがでてきたため、NFSの設定で新規ディレクトリを追加したときのメモを残す

## サーバー構成
ELB
WEBサーバー（2台）
NFSサーバー（1台）　※EC2使用

## WEBサーバーでの作業
### ① 新規ディレクトリ作成
mountしたいディレクトリを新規作成する。

```sh
$ mkdir /var/www/hogehoge/public/freepages
```

### ② /etc/fstab 編集
新規に追加したいディレクトリPATHを以下のようにPATHだけ変更して追記する
ここに追記することでEC2再起動した際にも自動的に再mountされるようにするための設定。

```
[追加]
; 記入例）　NFSサーバーPATH　WEBサーバーPATH　nfs rsize=8192,wsize=8192,timeo=14,intr
[host]:/var/www/nfs_shared/freepages /var/www/hogehoge/public/freepages   nfs     rsize=8192,wsize=8192,timeo=14,intr
```

## NFSサーバーでの作業
### ① 新規ディレクトリ作成
NFSしたい新規ディレクトリを作成する。

```
$ mkdir /var/www/nfs_shared/freepages
```

### ② /etc/exports 編集
NFSサーバー側で作成する新規ディレクトリのPATHを追加

```
[追加]
/var/www/nfs_shared/freepages    192.168.14.0/24(rw,all_squash,sync)
```


## AWSマネージメントコンソールでの作業
### ① NFSサーバーreboot
NFSサーバーをrebootし、上記で変更した/etc/exportsを反映させる
起動後はWEBサーバーのmountが壊れていないかを確認する

### ② ELBよりEC2を切り離す※2台構成の場合のみ
公開側に影響を与えないため、ELBよりEC2を切り離して作業を行う

### ③ ELBより切り離したEC2をrebootする
WEBサーバーをrebootし、上記で変更した/etc/fstabを反映させる。
起動後、新規で追加したディレクトリがmountされているか確認する。
新規ファイル、ディレクトリなど作成し動作確認。

作業中にここで1点問題がおきた。
NFSサーバー、WEBサーバーにそれぞれ「/etc/fstab」に追記したディレクトリが存在しないと自動的に紐づけがされなかった（もっと理解が必要…）

### ④ 問題ない場合、ELBにつけ直す
ELB付け直し後、EC2がInServiceになったら公開側に影響がないか確認する。

### ⑤ もう片方のEC2を②〜④の手順で実行する
問題ない場合、新規ファイル、ディレクトリなど作成し、問題なくNFSできていることを確認。

## 今回失敗したこと
WEBサーバーでmountポイントを共有したいディレクトリ毎に紐づけてしまっていたこと。
そのため今後同じような要望が上がった際には同じ手順を踏まなけれればならない。

## 回避策
WEBサーバーにはmountポイント用のディレクトリを別で持っておく。
ポイント用のディレクトリを１つ作成し、紐付けることでWEBサーバー内では共有したいディレクトリ・ファイルはポイント用ディレクトリの配下にシンボリックリンクをはることで対応可能になる。
そのため、今後同じような要望が上がっても、mountポイント用のディレクトリに対してWEBサーバー内でシンボリックリンクを貼るだけでサーバーの再起動などは不要となる。