OmniAICreator/Qiita-1.07M huggingface dataset:
AWS re:Invent 2018 に行ってきました

## 概要
MobingiからhatoがAWS re:Inventへ行ってきた感想を綴ります。SessionやKeynoteの内容の話は詳しくしないのでそちらを知りたい方は他の方が詳しい記事を書いているのでそちらを参考にするのが良いと思います。

## Midnight Madness
前日祭に行こうとしたら登録を済ませていなくて参加できませんでした。。。会場の登録は21時までなので行きたい方は事前に登録しておくことをおすすめします。また空港でも登録を受け付けています（自分は無視してホテルへ直行しました）

## 個人的に面白かったHands-On・Workshop
### Management k8s on EKS
 GCPのKubernetes Engineは使っていましたがEKSはまだちゃんとは使ったことがなかったのでワークショップに参加しました。もともと触ったことがあったので簡単に作業できましたね。

### Organization's Redshift Adoption
 Redshiftを触ってみたくて参加しました。AWS　Organizationを使って親から立てたRedshiftを子のアカウントから共有して使うことができたり、Redshiftの操作などが知れてよかったです。

### LEGO hands-on labs 
 ARIAエリアでLEGO hands-onをやっていたのですがピタゴラ装置をすべてLEGOで作っていたり、LEGOで組み上げた車を使ってレース出来たりして楽しかったです。（新レコードは出ませんでした）

### Elasticsearch Service to Visualize and Monitor
 EKSで作成したアプリケーションに対してElasticsearchでログを取得してKibanaでモニタリングしました。

### DynamoDb Deep Dive Session
 DynamoDbのベストプラクティスパターンや実際にAWSで構築していたテーブルデザインを見せたりしていて凄く勉強になりました。またこの場でトランザクションも発表されて是非使ってみたいなと思いました。

## 終わりに
Session、Keynoteはほぼ参加しませんでしたが、後でレポを見るのと実際に会場の雰囲気を味わうのとは違っていて今回参加出来て良かったです。
【サルが書く】phpで2次元配列をソートしようと思います

# phpで2次元配列をソートします

わきゃあ

様々な要素を持った配列を日付順や複合的にソートしたいときに役立つ**(多分)**

[array_multisort](http://php.net/manual/ja/function.array-multisort.php)を使用することで、簡単にソートすることができます。

```php
bool array_multisort ( array &$array1 [, mixed $array1_sort_order = SORT_ASC [, mixed $array1_sort_flags = SORT_REGULAR [, mixed $... ]]] )
```

## 単一条件でソート

適当な配列データを用意しました。
"date"を時間が最新日付順に並び替えてみます。

```php

<?php

//サンプルデータ
$sampleArr = array(
    0 => array(
        "date" => '2008-01-04',
        "name" => 'john',
        "age" => 10
    ),
    1 => array(
        "date" => '2008-10-21',
        "name" => 'suzuki',
        "age" => 2
    ),
    2 => array(
        "date" => '2007-07-03',
        "name" => 'sato',
        "age" => 98
    ),
    3 => array(
        "date" => '2017-07-03',
        "name" => 'mochita',
        "age" => 34
    )
);

// 日付のみでソートする場合
foreach ($sampleArr as $key => $row) {
    $date[$key] = $row["date"];
}

// 日付が早い順に並び替える
array_multisort($date, SORT_ASC, $sampleArr);

?>
```
配列のkeyと並び替えをしたい要素のみの配列を用意し、その配列を使用してソートを行います。

```php:並び替え用の配列$dateの中身
Array
(
    [0] => 2008-01-04
    [1] => 2008-10-21
    [2] => 2007-07-03
    [3] => 2017-07-03
)
```

## 複数条件のソート

これを応用した形で、複数条件でソートすることができます。

```php

<?php

$sampleArr = array(
    0 => array(
        "date" => '2008-01-04',
        "name" => 'john',
        "age" => 10
    ),
    1 => array(
        "date" => '2008-10-21',
        "name" => 'suzuki',
        "age" => 2
    ),
    2 => array(
        "date" => '2007-07-03',
        "name" => 'sato',
        "age" => 98
    ),
    3 => array(
        "date" => '2017-07-03',
        "name" => 'mochita',
        "age" => 34
    )
);

// 名前でソートし、年齢でソートし、日付でソートする
foreach ($sampleArr as $key => $row) {
    $name[$key] = $row["name"];
    $age[$key] = $row["age"];
    $date[$key] = $row["date"];
}

array_multisort($name, SORT_DESC, $age, SORT_DESC, $date, SORT_DESC, $sampleArr);

?>
```

```php:中身
Array
(
    [0] => Array
        (
            [date] => 2008-10-21
            [name] => suzuki
            [age] => 2
        )

    [1] => Array
        (
            [date] => 2007-07-03
            [name] => sato
            [age] => 98
        )

    [2] => Array
        (
            [date] => 2017-07-03
            [name] => mochita
            [age] => 34
        )

    [3] => Array
        (
            [date] => 2008-01-04
            [name] => john
            [age] => 10
        )

)
```
node.js を始めるときにつまずいたことまとめ

# はじめに

node.jsを触ってみたいと思い現在勉強中です。
同じことでつまずいているひとがいる（かも）と思ったので
つまずいたことを追記していきます。

## nodist distでエラーが出る。
バージョン管理ツールを入れると便利、windowsならnodistという記事をみたので
nodistをインストール、 nodist distというコマンドを実行時に以下のエラーが発生

```
nodist dist
Could not read response for https://nodejs.org/dist/index.json
Could not read response for https://iojs.org/dist/index.json
Could not read response for https://nodejs.org/dist/index.json.
Sorry.
```

proxyを設定して解決
```
set http_proxy=
```

## express　-- version が実行できない
導入サイトを見て

```
npm install -g express
```

を実行して、

```
express --version
```

を実行しても

```
'express' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
```

とでてバージョンが出てこない。
expressだけでなくexpress-generatorもインストールしないとだめらしい。

```
npm install -g express-generator
```

でインストールしたら上手くいった。

## expressのサンプルが起動できない

```
node app.js 
```

を実行しても何も起こらない。

```
npm start
```

で実行できた。
escape_javascriptメソッドって何ぞや。

# はじめに
railsチュートリアルの非同期通信のところで**escape_javascript**というメソッドがでてきました。公式には、JavaScriptファイル内にHTMLを挿入するときに実行結果をエスケープするために必要ということなのだが良くわからなかったので調べて見ました。

```create.js.erb
$("#follow_form").html("<%= escape_javascript(render('users/unfollow')) %>");
$("#followers").html('<%= @user.followers.count %>');
```

ここでは**create.js.erb**の中で```users/unfollow```　をrenderしているが、javascriptではエスケープが必要らしい。```''```、```""```があるとダメっぽいです。
EgretEngineとUnityを連動させてみる(2) Egret3Dでシーンを表示-失敗編


こちらの記事の続きです

[EgretEngineとUnityを連動させてみる(1)](https://qiita.com/motoyasu-yamada/items/c0edc2e22f235f138bbd)
[EgretEngineとUnityを連動させてみる(2)](https://qiita.com/motoyasu-yamada/items/8e6546056ca471355475)

Unityで作成したシーンを、Egret3DExportToolsでエクスポートし、そのデータをEgretEngineで表示させます。

# プロジェクトを作成する

`Egret Launcer`を起動します。プロジェクトタブから新規プロジェクトを作成します。エンジンのバージョンは5.3.xにしてください。

# Egret3Dモジュールのインクルード
`egretProperties.json`にEgret3DとInspectorモジュールを読み込むように記載します。

今回のケースでは、GitHubからダウンロードしたEgret3Dエンジンの`egret3d-master`フォルダがプロジェクトフォルダの二階層下にある前提です。

```diff
  "modules": [
:
-   }
+   , {
+      "name": "egret3d",
+      "path": "../../egret3d-master/core"
+    },
+    {
+      "name": "inspector",
+      "path": "../../egret3d-master/editor"
+    }
:
   ]
```

# アセット読み込み
作成した`Assets`ディレクトリを、プロジェクトの`resources`ディレクトリ内に配置します。

# 読み込んだアセットリソースをPreloadグループに追加する
まずリソースグループのパネルにあるボタン`AddGroup`から`preload`グループを作成してください。
`preload`グループにassetsディレクトリ内のリソースを追加してください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/302078/e5b38663-bb45-5145-e4b5-687c9921b902.png)

# ビルドscripts修正
デフォルトのビルドscriptsはEgret2D用なので、`egret3d-master\examples\scripts\config.json`ファイルを`scripts\config.json`に上書きしてください。


# ビルド＆起動

```
egret clean
egret bake
egret build
egret run
```

# 結果（失敗）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/302078/3ce49c9d-36c5-c328-963b-522557eead88.png)

ビルトインリソースが読み込めずに失敗しています。
Go+GAE+PubSubで躓いたはなし

### ローカルサーバーのインストール
たいして躓いたわけではないが、Endpointの設定を開発時はどうしてもローカルにしないと不便なので、必須。

```bash
//install
gcloud components install pubsub-emulator
// set env
$(gcloud beta emulators pubsub env-init)
//pubsub server start first
gcloud beta emulators pubsub start
//gae server with env
python  ~/google-cloud-sdk/platform/google_appengine/dev_appserver.py ./app.yaml --env_var PUBSUB_EMULATOR_HOST=${PUBSUB_EMULATOR_HOST}
```
#### localhost:8080をエンドポイントにするとバグるはなし（追記 2018/12/7）
https://stackoverflow.com/questions/38667386/testing-google-cloud-pubsub-push-endpoints-locally
2016年に話題になっている既知のバグのように見えますが、

```bash
eval $(gcloud beta emulators pubsub env-init)
```
これをbash_profileなどに入れておかないと起こります。要注意。

#### too many open files
大量のSubをローカルでテストしていると、OSのファイルオープン上限に達します。

```bash
2018/12/06 19:16:18 http: panic serving 127.0.0.1:63060: dialing: google: error getting credentials using well-known file (.config/gcloud/application_default_credentials.json): open .config/gcloud/application_default_credentials.json: too many open files
```
Macの人はこの記事を読んで設定しましょう。
https://qiita.com/sou_lab/items/1ca051a1f3b906a23dc8

```bash
ulimit -n 524288
```
もお忘れなく。

### Workerでの受け取り方
https://github.com/GoogleCloudPlatform/golang-samples/blob/master/appengine_flexible/pubsub/pubsub.go
ここに書いてあるのだが、癖があるので要注意

```go:sample.go(一部)
type OriginalMessage struct {
  V1 int
  V2 int
}
type pushRequest struct {
  Message struct {
    Attributes map[string]string
    Data       []byte
    ID         string `json:"message_id"`
  }
  Subscription string
}

func handler(w http.ResponseWriter, r *http.Request){
  var msg pushRequest 
  var orig OriginalMessage
  err := json.NewDecoder(r.Body).Decode(&msg);//r.Bodyには、pushRequestのような形で情報がきます
  err = json.Unmarshal(msg.Message.Data, &orig)//msg.Message.Dataをぬきとって、JSONにもどします。
}

func push(){
  var orig OriginalMessage{1,1}
  jsonBytes, err := json.Marshal(orig)
  msg := &pubsub.Message{Data: jsonBytes,}//渡したい構造体のJSONバイト配列をつっこみます
  pubr := topic.Publish(ctx, msg)//それでつくったMessageでPubします
}
```

半日躓きましたので、PubSubビギナー（俺もな）のみなさんは参考にしてください。
メタにまつわる用語解説(リンク集)

前回の記事「[メタって何？](https://qiita.com/bambis13s/items/0353355fec1caa142507)」

プログラミングを始めてから出くわした "メタ" についての用語まとめ(リンク集)です。
こちらも誤りや不足等あればご指摘いただけると幸いです。

## メタ言語
とりあえずWiki。
> メタ言語（メタげんご、英 Metalanguage）とはある言語について何らかの記述をするための言語である。[Wiki](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BF%E8%A8%80%E8%AA%9E)

例えばプログラムがコンパイルされる時、その過程でプログラムは「パーザ」と呼ばれる構文解析器にかけられます。この時、パーザが参照する構文の定義に使用されている言語をメタ言語と呼びます。([goo:パーサとコンパイラの違いって？](https://oshiete.goo.ne.jp/qa/4233428.html))

ここで私が混乱したのは、`高級言語`という言葉との違い。
これは文法が機械に近いか人間に近いかという話で、メタ言語とは全く別です。
言語の高級/低級については[こちら](https://kigenzen-it.com/highlow-lang20170927/)が分かりやすかったです。

## メタプログラミング
> メタプログラミングとはプログラムを操作するプログラムを作成することを意味します。メタプログラミングは他のプログラムを生成するプログラムであるというのが共通の認識となっていますが、メタプログラミングの実例はそれだけに限られません。自身の読み取り、分析、変換、あるいは変更を行うよう意図されているプログラムはすべて、メタプログラミングの例です。[IBM](https://www.ibm.com/developerworks/jp/analytics/library/ba-metaprogramming-python/index.html)

各言語によってどんなメタプログラムが書けるかは異なるようです。
簡単な例を２つほど紹介します。

##### ・　pythonの \_\_metaclass\_\_
 「クラスを生成するクラス」 を定義することができる。
言い換えると、メタクラスとは「クラスをインスタンス化できるクラス」です。

##### 親クラスを作成して承継するのと何が違うのか。

親クラスを作成して承継するのは、親となるクラスを一部変更したインスタンスを作成したいとき、またはあるクラス間で共通させたいものを一箇所で定義したいときなどです。この際、どのクラスもデフォルトの `type` というメタクラスのインスタンスとして生成されます。
メタクラスを定義するということは、このクラス生成の仕様を書き換えるということです。

クラスでそのクラスのインスタンスを定義するように、メタクラスではそのメタクラスのインスタンス(= クラス)を定義しています。

[Pythonのクラスアトリビュートとメタクラスの話](https://qiita.com/pashango2/items/fadc77c8db21c8fd9367)
[Python の メタプログラミング (__metaclass__, メタクラス) を理解する](http://www.yunabe.jp/docs/python_metaclass.html)


##### ・ rubyの eval
引数に与えられた文字列を関数として実行する関数。
文字列から関数を生成して評価する関数とも言えます。

例えば、`eval('10 + 20')` と実行すると `30` が返ってきます。
これは非常に簡単な例ですが、evalを使用することでプログラムによって動的にインスタンス変数が生成できたり、動的に関数を生成できたりします。


## メタデータ
> データについてのデータ。コンピューターのファイルなどについて、そのデータの作成者、作成日時、属性を記録したものをいう。(デジタル大辞泉)

例えば、デジタルカメラで写真を取った際についてくる 撮影日時・ISO・絞り値・フラッシュの有無などなど の情報がメタデータ。文書でも音源でも大体なにかしらのメタデータが付随しています。

## おまけ

#### メタフィクション ≒ メタ発言, メタ表現

私はアニメの話をあまりしないので、最近になってこの言葉を知りました...。
厳密にはメタ発言はメタフィクションと同義ではないのですが、そこから派生したものと思われます。(知らんけど)

> メタフィクション（Metafiction）とは、フィクションについてのフィクション、小説というジャンル自体に言及・批評するような小説のこと。それが作り話であるということを意図的に（しばしば自己言及的に）読者に気付かせることで、虚構と現実の関係について問題を提示する。[Wiki](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BF%E3%83%95%E3%82%A3%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3)

この手法として、作中の登場人物が作者と対話したり、読者に話しかけてきたり、作者が登場人物として作中に入り込んでしまったりというものがあります。漫画やアニメでも、キャラクターが意図的にコマからはみ出ようとしたり、来週も見てくださいね〜！的発言をしていたり といったシーンを見たことがあると思います。

作者のオチャメくらいにしか思っていませんでしたが、虚構と現実の関係についての問題を提起されていたのですね。。。ふむふむ

## 参考

[プログラミング言語はどのように作成されますか？](https://jp.quora.com/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E%E3%81%AF%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E4%BD%9C%E6%88%90%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%81%8B)
[メタクラスと継承の違いについて教えてください](https://ja.stackoverflow.com/questions/16594/%E3%83%A1%E3%82%BF%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E7%B6%99%E6%89%BF%E3%81%AE%E9%81%95%E3%81%84%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84/16605#16605)
あえてAutoLayoutを使わずにUILabelの高さを計算する

iOSエンジニアにとって高さの計算は常に大きな関心の対象でした🔍
AutoLayoutの出現によって高さの自動計算ができる手段が提供されましたが、パフォーマンスの問題や宗教的な理由でAutoLayoutを避ける場合もあります:squirrel:
そんな時のために、AutoLayoutを使わないUILabelの高さの計算方法を紹介します💡

# 文字列の高さの計算
タイトルはUILabelの高さとしましたが、実際に計算するのは文字列の高さになります。
`String`(`NSString`)には`boundingRect`という文字列の描画領域を計算するメソッドが存在します。
[ドキュメント](https://developer.apple.com/documentation/foundation/nsstring/1524729-boundingrect)

```swift:boundingRect
func boundingRect(with size: CGSize, 
          options: NSStringDrawingOptions = [], 
       attributes: [NSAttributedString.Key : Any]? = nil, 
          context: NSStringDrawingContext?) -> CGRect
```

表示させたい幅は決まっていると思うので、第一引数`size`には幅を指定したサイズを渡します。高さはとりあえずとても大きい数値にします。
第二引数`options`には文字描画オプションを渡します。複数行の高さの計算を正確にするには`.usesLineFragmentOrigin`を渡せとドキュメントに書いてあります。フォントによっては`.usesFontLeading`も渡さないと高さが小さく計算されてしまうので、指定しておくのが無難です。
第三引数`attributes`には文字列の属性を渡します。フォントや行間を指定します。
第四引数`context`には文字列描画の環境のようなものを渡します。`nil`を渡せばデフォルトのものが使われます。
戻り値は描画領域がですが、小数値になっているので、`ceil()`を使って整数にしてやります。

今回の目的はUILabelの高さを計算することなので、幅と文字列の属性はUILabelから取得します。文字列のサイズ計算の際は、外から渡ってくる値を使用できるようにします。

以上をまとめて、Stringのextensionを作ります。

```swift:文字列の高さを計算するためのメソッド
extension String {
    
    func makeSize(width: CGFloat, attributes: [NSAttributedString.Key: Any]) -> CGSize {
        let bounds = CGSize(width: width, height: .greatestFiniteMagnitude)
        let options: NSStringDrawingOptions = [.usesLineFragmentOrigin, .usesFontLeading]
        let rect = self.boundingRect(with: bounds, options: options, attributes: attributes, context: nil)
        let size = CGSize(width: rect.size.width, height: ceil(rect.size.height))
        return size
    }
}
```

# UILabelの高さの計算
こちらは自身の幅と属性を上記のメソッドに渡してやるだけです。
プレーンテキスト用と属性付きテキスト用のメソッドをそれぞれ用意します。
それらをUILabelのextensionとして定義します。

```swift:UILabelの高さを計算するためのメソッド
extension UILabel {
    
    func getTextHeight() -> CGFloat {
        guard let text = self.text else {
            return 0.0
        }
        let attributes: [NSAttributedString.Key: Any] = [.font : self.font]
        let size = text.makeSize(width: self.bounds.width, attributes: attributes)
        return size.height
    }
    
    func getAttributedTextHeight() -> CGFloat {
        guard let attributedText = self.attributedText else {
            return 0.0
        }
        var attributes: [NSAttributedString.Key: Any] = attributedText.attributes(at: 0, effectiveRange: nil)
        attributes[.font] = self.font
        let size = attributedText.string.makeSize(width: self.bounds.width, attributes: attributes)
        return size.height
    }
}
```

これでUILabelの高さの計算ができるようになりました！

# 終わりに
ここまで書いて思い出したんですが、`sizeThatFits()`というメソッドがありましたね・・・🙀
まあそっちは`NSStringDrawingOptions`の指定とかできないし、もしうまくいかないという場合は上記の方法を試してみてください👊
NoClassDefFoundError、ClassNotFoundExceptionを解決する

# 前提

Eclipseでコンパイル時、クラス関係でエラーが出る。以下は両方とも、ライブラリ（jarファイル）を見つけれていない。

```
ClassNotFoundException: org.apache.tomcat.dbcp.dbcp2.BasicDataSource
```
jarファイル場所→tomcat/9/lib/tomcat-dbcp.jar（このパッケージにBasicDataSourceクラスが入っている）

```
java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory
```
jarファイル場所→tomcat/9/bin/tomcat-juli.jar

# 解決策

1. プロジェクト名を右クリック→プロパティ
2. Javaのビルド・パス→ライブラリー
3. 「外部JARの追加」をクリック→該当jarを選択→開く
![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/227525/5439b52f-7231-90e6-ac5c-51f697ba56ae.jpeg)
Tinkererのバグにぶち当たったので、手動で手元のスクリプトを改修した話

# はじめに

この記事は[静的サイトジェネレーター Advent Calendar 2018 - Qiita](https://qiita.com/advent-calendar/2018/static-site-generator)の7日目の記事となります。

# はりきって「ドイツのトリ」の記事を書いたのに……

僕自身、Advent Calendarくらいしかブログを書く動機が無いので、久々にTinkererで執筆してビルドすると、何らかのバグにぶち当たることが比較的多いです。

今回もばっちり[ドイツのトリ Advent Calendar 2018 - Adventar](https://adventar.org/calendars/2897)の記事を書いていざビルドしたらコンソールに

    Extension error:
    Config value 'author' already present

って感じの、本来日本語が表示されるはずのメッセージが、日本語エンコードに失敗してるのか、UTF-8コードで吐き出されたわけです。 `\uxxxx\uxxxx……` っていう具合に。

# GitHubにIssue上がってないかなー？ → あったわ……

しかもこの記事を書いている時点で最近上がったやつっぽい。
[Build error with Sphinx-1.8.1 · Issue #112 · vladris/tinkerer](https://github.com/vladris/tinkerer/issues/112)

そして幸いなことに、直し方は「1行削除」で終了する話でしたので、これなら自分でもなんとかなることはわかりました。

しかし、まだPyPlには更新は反映されている様子はなかったため、自分で手元のスクリプトを修正するという手で対応しようと思いました。

# で、スクリプトはどこよ……。

ここで問題が発生しました。
僕のTinkererビルド環境は[Pipenv](https://pipenv-ja.readthedocs.io/ja/translate-ja/)に依存しております。

昔はPython標準の[venv](https://docs.python.jp/3/library/venv.html)を使っていたため、ローカルマシンの何処かにPythonスクリプト群があることは分かっているつもりですが、実際何処にあるのかはよく知りませんでした。

そしてPipenvを構築したときのログも破棄してしまった。
「あ、詰んだわ」
そう思いながら[Pipenvと仮想環境 — pipenv 2018.11.27.dev0 ドキュメント](https://pipenv-ja.readthedocs.io/ja/translate-ja/install.html#installing-packages-for-your-project)のページを読んでいたら、ヒントが……、

    Creating a Pipfile for this project...
    Creating a virtualenv for this project...
    Using base prefix '/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6'
    New python executable in ~/.local/share/virtualenvs/tmp-agwWamBd/bin/python3.6
    Also creating executable in ~/.local/share/virtualenvs/tmp-agwWamBd/bin/python
    Installing setuptools, pip, wheel...done.

たまたま会社のMacで就業時間中にこのトラブルの解決をしようとしていたので、早速 `~/.local/share/virtualenvs/` 配下を調べると。
ありました、ありました。僕の探しているPythonスクリプト群。

そこからそのディレクトリ配下をあちこち行き来して、ようやく `{仮想環境の名前}/lib/python*.*/site-package/` の下に `tinkerer` のディレクトリを見つけました。

# コメントアウト → ビルド

後は[先程のIssue](https://github.com/vladris/tinkerer/issues/112)の通りに、該当行をコメントアウトしてビルドしましたら……、
ちゃんとビルドが実行されました！　やったぜ！

# あとがき

そんな感じで就業時間中に5日遅れで非公式参加ではありますが、[マシュマロにアヒルのような脚が生えているそれに関数をぶん投げて演算させたい — ヒマジンマンガ](https://manzyun.bitbucket.io/blog/html/2018/12/02/german_bird.html)を載っけることができまして。
この喜びを忘れないうちに、また就業時間中にこの記事を書いているのでした。

……仕事しろよ。
Kubernetesでクラスター切り替えやネームスペース切り替えを楽にする方法

# はじめに
最近よく聞くようになったKubernetesを会社でも取り入れ始めてきたので、その際にノウハウを少しまとめようと思います。といっても今回は表題にある2つ「クラスター切り替え」「ネームスペース切り替え」について書いていきます。

# 環境
Mac OS Sierra 10.12.6
Kubernetes 1.10.7

# クラスター切り替え
いろいろなプロジェクトに携わらせていただくと、複数のKubernetesクラスターを切り替えながら作業を行う必要があります。その際は通常のコマンドを使用すると下記のような感じで切り替えを行うことができます。

```
# ①コンテキストに設定されているクラスター一覧を取得
kubectl config get-clusters

# ②現在のクラスター確認
kubectl config current-context

# ③接続クラスター変更
kubectl config use-context [cluster name]
```
※ これらのコマンドは`~/.kube/config`ファイルを書き換えています。

これはこれでいいのですが、頻繁に切り替えが発生するとこれらのコマンドが面倒だったりします。そこで[kubectx](https://github.com/ahmetb/kubectx)を使用するともっと簡単に切り替えをすることができます。

## インストール
MacであればHomebrewで簡単にインストールできます。

```
brew install kubectx
```
## 使用方法

```
USAGE:
  kubectx                   : list the contexts
  kubectx <NAME>            : switch to context <NAME>
  kubectx -                 : switch to the previous context
  kubectx <NEW_NAME>=<NAME> : rename context <NAME> to <NEW_NAME>
  kubectx <NEW_NAME>=.      : rename current-context to <NEW_NAME>
  kubectx -d <NAME>         : delete context <NAME> ('.' for current-context)
                              (this command won't delete the user/cluster entry
                              that is used by the context)
```
僕の場合さらに[fzf](https://github.com/junegunn/fzf)を組み合わせてインタラクティブに操作可能にしています。こちらを使用することで面倒なクラスター切り替えも気にならなくなりました。

# ネームスペース切り替え
クラスター切り替えよりももっと煩わしいのはネームスペースの指定や切り替えです。通常は下記のようにオプション指定するか`~/.kube/config`ファイルを書き換えますが、kubensを使用するともっと簡単行えます。

```
# オプション指定
kubectl get pod --namespace=[namespace name]
kubectl get pod -n=[namespace name]

# configファイル書き換え
kubectl config set-context $(kubectl config current-context) --namespace=[namespace name]
```
オプションを毎回指定するのは煩わしいし、だからといってconfig書き換えも都度やるには長すぎる。僕にはとても覚えられない。

## インストール
kubectxを入れるとkubensも含まれています。

## 使用方法

```
USAGE:
  kubens                    : list the namespaces
  kubens <NAME>             : change the active namespace
  kubens -                  : switch to the previous namespace
```
こちらを使用するとしないとではほんとに作業効率が変わってくるんじゃないかと思います。

# まとめ
今回はkubernetesを使用しているなかで煩わしい環境切り替えについてまとめました。クラスターを複数使用している方はまだ少ないかなと思いますが、それでもテストでローカル(minikube)を使っていたりはすると思うので効果はあると思います。またkubernetesはnamespaceでプロジェクトやenvを分けたりすることが多いので、kubensは多用できればかなり効率的に作業できると思います。そのへんが面倒だなと思っていた方はぜひ使ってみて下さい。


# 参考
青山 真也 (著)の [Kubernetes完全ガイド](https://www.amazon.co.jp/Kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-impress-top-gear-%E9%9D%92%E5%B1%B1/dp/4295004804/ref=sr_1_1?ie=UTF8&qid=1543974710&sr=8-1&keywords=kubernetes+%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89) を参考にさせていただきました。ありがとうございました。
C#をはじめて調べたこと

2018年4月ごろまでは仕事でVB.NETを使っていて、新しい言語仕様も大して取り入れず適当なコードを書いてましたが
2018年9月ごろから趣味でC#を使い始めてよくわからず調べたことをメモ的にまとめています。
なお個人的にVBのときに使っていなかっただけで、C#固有のものというわけではありません。
（ある意味当たり前ですが、ほとんどVBにも同じ構文は存在します。）

個人的なメモとして書いていますので、くだらない記事を読んだと怒らないようお願いします。
随時更新です。

#非同期処理
https://qiita.com/rawr/items/5d49960a4e4d3823722f
https://qiita.com/TsuyoshiUshio@github/items/e9404651c9e48f1b8443

#var（使いどころ）
https://qiita.com/hollydad/items/1516a3f13147a754b9db
https://qiita.com/Nossa/items/e5e50d2fc1ae8b3e2389

#クラスをnewしたときに値をセットする（オブジェクト初期化子）
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers

#null合体演算子、null条件演算子
null合体→ a ?? b 「aがnullならbを返す」
null条件→ a?.property,a?[1]「aがnullでもヌルポにならずnullを返す」
合わせ技 a?.property ?? "default"
https://qiita.com/Nossa/items/1fd4881a0b97a5f32901

#タプル
http://ryuichi111std.hatenablog.com/entry/2017/03/12/175357
http://ryuichi111std.hatenablog.com/entry/2016/12/22/011853

#オプション引数（VBでいうところのOptional）
https://ufcpp.net/study/csharp/sp4_optional.html

#stringの@とか$とか
@は逐語的文字列という
$は補完文字列という
http://csharpvbcomparer.blogspot.com/2016/05/csharp-string-literal-summary-interpolation-and-verbatim.html

#ラムダ式とLINQ
https://qiita.com/m-gen/items/ebe59422affc69a92429
https://qiita.com/stokes_dotnet/items/a70c33911ad96e5d8188

#色々まとめて
https://ufcpp.net/study/csharp/
compareTo の戻り値仕様はリファレンスを見に行かなくても余裕

演算子オーバーロードのないJavaでオブジェクトの大小比較は `.compareTo` メソッドですが、どちらがどちらだと正・0・負が返るのかそらで言えますか？ 私は言えません。
そして戻り値の正・0・負がどうたったかの仕様を見つけたとして、それを参考にしつつif文の条件式を一目で理解できるでしょうか、スムーズに間違いなく書き下ろせるでしょうか？ ⋯それは、とても容易です！

表にしてみましょう

|不等号があった場合|`compareTo`による記述|
|---|---|
|`a < b`|`a.compareTo(b) < 0`|
|`a <= b`|`a.compareTo(b) <= 0`|
|`a > b`|`a.compareTo(b) > 0`|
|`a >= b`|`a.compareTo(b) >= 0`|

あっ。

`compareTo` の**右側に 0 を置くと、不等号の向きが保存**されています。
結果的にそうなるように戻り値仕様が定められていたのですね。
Railsでindexページを作成する一通りの流れ

## DBをmigrationする
まず最初に、入力したデータを格納するDBを作ります。
モデルを作成すると自動的にマイグレーションファイルが作られるので、DBディレクトリから確認しましょう。

そこから型とカラム名を定義します。

マイグレーションファイルのdef changeとendの中に以下のように定義します

```ruby
t.string :name
t.text :body
```

stringが短い文字列、textが長い文字列、integerが数字、booleanがtrue/falseなど二択の時と覚えておけば大体は対応できるかと思います。

Idやcreated_at、updated_atは自動で追加されるのでここでわざわざ定義する必要はありません。

Migrationファイルを編集できたら

```
rake db:migrate
```

にて、DBを構築します。


※DBに項目を足したい場合は以下のコマンドで追加用のマイグレーションファイルが現れます。

```
rails g migration Add(カラム名)To(コントローラー名(複数形))
```

追加する場合はdefとendの中に以下のように書きます

```ruby

add_column :コントローラー名(複数形), :型
add_column :hoges, :title, :string
```


## Controllerの書き方

### アクション　＝　だいたいURL

URLのコントローラー名の次にくるURLとなります
https://アプリ名/コントローラー名/アクション名

対応するviewと同じ名前です
Viewが存在せず、処理だけ行うアクションもあります(createなど）

```ruby
def  #アクション名
 　#この中に処理を書く
end
```

この中でやること

インスタンス変数をいうアットマークがつく変数の中にviewに渡したいデータを入れます。ここでは@fugasがインスタンス変数です。

```ruby
def  index
  @fugas =  Hoge.all
end
```


Indexの場合、一覧でデータを表示したいので複数系担っています。Hogeというクラスオブジェクトのテーブルにある全てのデータを格納します。

### .allについて
これはメソッドといい、オブジェクトに対して命令を行うものです。
自分で作成するメソッドとあらかじめRuby側が作っていて決められているものがあり、allやcreateなどはあらかじめ定められているクラスメソッドです。
※メソッドにはクラスメソッドとインスタンスメソッドというものがあります。

※クラスは設計図、インスタンスが（それを元にして作られた）実体と覚えてください。クラスは集合体ですが、インスタンスがクラスから抽出して実際に取り扱うデータになります。

## Viewの書き方
Indexの場合、インスタンス変数の中にある配列を一つ一つ取り出します

```ruby
<% @fugas.each do |fuga| %>
<% end %>
```


ちなみに%を使った書き方は、htmlの書き方のファイルの中で、Rubyの構文を使用する時に使うものです。
`<%  %>` のように記載する場合は、表示はせず演算だけしたい場合であり
`<%=  %>` のようにイコールをつけて記載する場合は、表示はさせたい場合です

※ないデータを表示しようとするとエラーになるので、仮のデータを入れるか、フォームから入力してデータを入れてください

初心者の方は中身がないオブジェクトにメソッドを使って取り出そうとするためエラーが出るというケースが多発しがちです。

### Routingの書き方

いろいろ細かい指定の方法はありますが、初心者の方はとりあえず

```ruby
resources :コントローラー名(複数形)
```

のように書いておけば一通りルーティングが通って繋がるようになります。これを指定しないとリクエストを受け取った時にどれを表示するかが紐づけられていない状態なので、必ず指定しましょう。

詳しいことや仕組みはこちらを見てください。
https://railsguides.jp/routing.html

これでオブジェクトの中にデータが格納されていれば表示されるはずです。ここでサーバーを起動すると今はおそらくNo Method Errorが出るでしょう。空のオブジェクトに対してメソッド が命令しているので当然です。この後、フォームを作成してデータを入れていきましょう。

## ※Model
Modelはテーブル間を連携させる時に主に使うので今回は記載しません。後ほど説明します。
GoogleBigQueryで÷0を回避する方法

#### 目的
 - GoogleBigQueryで÷0の回避方法です。非エンジニア向けです。
 - 細かくセグメントを切って分析をしていくと、÷0などが発生します。
 - なぜ0で割ってはいけないかはこちらを見てください。
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/NKmGVE85GUU/0.jpg)](https://www.youtube.com/watch?v=NKmGVE85GUU)



#### Query

```sql
SELECT
	IFNULL(SAFE_DIVIDE(1, 0), 0),
	SAFE_DIVIDE(1, 0)
FROM hoge
```

#### 結果 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/45434/016225fe-7cf2-fa9b-d5a6-09b79a8de7d5.png)


#### 考え方
##### SAFE_DIVIDE
計算できない際に `NULL` が返されます。
`NULL`のままで良い場合は下記の`IFNULL`は不要です。

##### IFNULL
`NULL` のときに任意に書き換えができます。
最終アウトプットはグラフをイメージしているので今回は`0`に書き換えます。
カテゴリ別の売上を人数で割るとこんな感じですかね。

```SQL
SELECT
	category,
	IFNULL(SAFE_DIVIDE(sum(revenue), COUNT(distinct user_id), 0) as per
FROM hoge
```

#### 公式ドキュメント
 - SAFE_DIVIDE
https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#safe_divide

 - IFNULL
https://cloud.google.com/dataprep/docs/html/IFNULL-Function_66194064
品質を維持しながらコスト削減ってできるの？


#はじめに
テスト関係の業務の中でテスト費用(コスト)の削減について紹介します。
オンラインゲーム、ソーシャルゲームは、運営が続く為、テストもずっと続くことになるかと思います。
運営が続くプロジェクトほどコストを意識している会社は多いのではないでしょうか。

とはいえ、コストを下げると市場不具合が増加したり、お客様からの信頼を失うことにもなりえる為、
安易にはコスト削減できないのが実情です。

では、どうすれば品質を維持しながらコスト削減できるか、
**毎月開催する施策(イベント)の機能テスト**を削減ケースとして記載します。

※記載している内容は、あくまで一例ですので参考程度にお願いできると嬉しいです！

#削減方針
下記に該当するテスト項目を削減します。
1. 機能ごとに重複する動作確認
2. 前回のテスト時からロジック変更してない機能の動作確認
※ただし、品質を落とさないよう最低一回は動作確認を残す

#削減の流れ
###1. テストケース、テスト観点を精査
テストケース項目の中で重複しているテスト観点を記載します。

事例1)動作確認が重複
![TC画像01.png](https://qiita-image-store.s3.amazonaws.com/0/323008/25f508c7-cf5c-48ac-aae1-a268d728f24f.png)


###2. 削減方針に定めた2点に該当する項目を精査
洗い出したテスト観点をもとに削減方針に該当するか記載します。

事例2)削減方針に該当
![TC画像01_2.png](https://qiita-image-store.s3.amazonaws.com/0/323008/477904a1-d8c4-2e64-d8a1-3880ced1d03a.png)


###3. 削減対象の項目を開発とすり合わせ
削減方針に該当する項目をもとに開発と本当にロジックに変更がないか、新しい設定がないかを確認します。
ロジックに変更もなく、既存の設定であれば削減する方向で開発と合意し、項目を削減していきます。
削減案、そう考える根拠はできるだけテスト担当者から提示できることが望ましいです。

事例3)削減案の提案
![TC画像02.png](https://qiita-image-store.s3.amazonaws.com/0/323008/45ca6011-104b-3879-799e-96ca36815361.png)


###4. 削減して品質が落ちてないか効果測定
実際に削減したテストを実施した後、本当に削減してよかったかを確認する為、
リリースされた施策の市場不具合を測定します。

万が一、削減した動作確認で市場不具合が出てしまった場合、なぜ市場不具合になったのか分析します。
「削減方針は間違いなかったが、実はロジックを変更していて共有されていなかった」ということも
起こり得る為、どこまでの可能性を考慮してテストをするかは事前に開発と合意しておくと良いかと思います。

削減した箇所で不具合が出ていない場合は、コスト削減が成功したと言えるのではないでしょうか。


#最後に
コスト削減を行うには、開発との連携が不可欠になります。
過去削減した箇所にロジック変更する場合、削減したままリリースされて市場不具合になるケースもある為、
削減した項目も含めて精査するのが良いかと思います。
そうしたPDCAを繰り返すことで品質も維持したまま、コスト削減できるのではないでしょうか！
azure pipeline を使った　CIがとても使いやすかった


[Azure DevOps Advent Calendar 2018](https://qiita.com/advent-calendar/2018/azuredevops)　の　6日目です。

## DevOps とは
[DevOps - Wikipedia](https://ja.wikipedia.org/wiki/DevOps)
Wikipedia に書いてあるとちょっと難しいですね。

簡単に言うとソフトを開発する方法（文化）だと思います。
個人的には少人数でリリースまでもっていく
或いは個人でソフト作る際には最適な手法です。

もの（app ソフト　output)をリリースして、改善手法をどんどん繰り返して行く
日本人には向いていると個人的には思っているんですけど

そのための仕組みが azure pipelinesです

## Azure Pipelines とは
Azure DevOps のサービスの一部に組み込まれています。
[Azure DevOps Services \| Microsoft Azure](https://azure.microsoft.com/ja-jp/pricing/details/devops/azure-devops-services/)
価格は5人までレベルで無料です。

Pipelines だけ使うこともできます。
[Azure Pipelines \| Microsoft Azure](https://azure.microsoft.com/ja-jp/pricing/details/devops/azure-pipelines/)
寧ろ　AzurePipelines は　並列ジョブ走らなければ
追加料金なくいくらでも無料です。

個人的には私はPipelinesだけ目当てだったりします。

## 強みは？
- Visual Studio との連携が強い点、
- UIが親しみやすい（心理的ハードルが低め）
- .NETFramework のソフトも使える（ほかのCIサービスだとあんまない？）
- 導入が楽

Windowsネイティブソフトが ビルドできるのはとても大きいです。

＜2018/12月の調査です。破壊的イノベーションが進む領域なのでどんどん便利になると思います＞
<逆にサポート切れの言語は減っていくのかもしれません>
Xcodeもいけるんすね('◇')ゞ（今知った）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/46608/de8d1fb1-d779-8310-f6a5-50d15a15bb3a.png)


## 使い方

まずは bulidを自動化する手順です。
めちゃくちゃいろんな個所のGITを引っ張れます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/46608/47cf1c34-23b7-c84f-0007-ee4316f80f5e.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/46608/5ea5d7cb-7aba-c339-50f6-ab32136f31f7.png)


次にテンプレートを選びます（沢山あってこれが超便利）
yamlでも書けます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/46608/d6ec8db6-0bf6-15a4-9c2a-3501117914ef.png)



テンプレートに沿っていくとだいたいうまくいきます。
恐らくCI まで作るのは最速だと・・・思う

---
### CDの部分は今回は説明省略します。
ざっくりいうと　release タブを使えばいい感じに
デプロイできるとのことです。


そしてデプロイ先はこちら

![image.png](https://qiita-image-store.s3.amazonaws.com/0/46608/7eaf7aa9-2794-f661-d306-27cc7d07f85d.png)



AWSやGCPにももちろんいけます


![image.png](https://qiita-image-store.s3.amazonaws.com/0/46608/58020b01-b376-14a0-b1bc-17f2a22bfda7.png)

[Azure Pipelines is the CI/CD solution for any language, any platform, any cloud \| ブログ | Microsoft Azure](https://azure.microsoft.com/ja-jp/blog/azure-pipelines-is-the-ci-cd-solution-for-any-language-any-platform-any-cloud/)




なんかいい感じじゃないすか？

ではでは
【FileMaker】FileMaker Goで撮る写真サイズに気をつけよう

FileMaker Goのアプリから写真が簡単に撮れますよね。
私も確定申告に備えた医療費アプリ for iPhoneを自作したとき、会計の時に受け取る領収書類などをアプリに保存できるように実装しました。
アプリからカメラを起動し、写真を保存するという簡単な実装でした。

# 事件
その時は何も考えていなかったのですが、1年後、「さて、確定申告用に集計するか」「ついでに気になる所も修正するか」とPCにアプリを送信した時に事件発生です。

異様に送信時間がかかるんです。

AirDropでファイルを送信したので、サクッと終わるはずなのに、30秒ほどかかりました（体感）。

PCに保存されたアプリのファイルサイズを見てびっくりです。
500MBを超えていたんですっ！！！

こんなfat fileを作った覚えはないと調べたら、領収書類の写真サイズでした。

慌ててファイルサイズを調整する修正を入れました。

# ファイルサイズ調整の修正
単純にアプリからカメラを起動すると、iPhoneに自分で設定したサイズが「最大・大・中・小」のうちのどれかで起動します。
カメラを起動した時に設定するのでもいいのですが、別のアプリでカメラを使う時などのことも考えると、写真のサイズをカメラ起動時に自動で設定する方が忘れないだろう、とスクリプトを設定しました。

「[デバイスから挿入](https://fmhelp.filemaker.com/help/17/fmp/ja/index.html#page/FMP_Help/insert-from-device.html)」という関数を使います。
スクリプト中の設定ボタンからは、「カメラ」を選択すると、「カメラオプション」が設定できます。
このオプションの、「解像度」を設定します。
![デバイスから挿入の設定.png](https://qiita-image-store.s3.amazonaws.com/0/60538/b3f2172f-6d16-3be5-ec28-ddf911e7ee01.png)
これは単純にカメラ起動時に自動で調整する解像度なので、カメラを起動した後に自分で解像度を別なものに設定できます。

# 検証
せっかくなので、この設定有り無しでどのくらいファイルサイズが違うかを検証したいと思います。
サイズチェック用に作ったFileMakerアプリには、１テーブルのみ存在し、オブジェクトフィールドに設定ありとなしを用意しました。

それぞれのオブジェクトフィールドからカメラを起動し、写真を保存した時のファイルサイズを確認します。

## データなしのファイルサイズ
ファイルを作り終えた時のファイルサイズは、594KBでした。
![FileSizeCheck1.png](https://qiita-image-store.s3.amazonaws.com/0/60538/36132c18-a498-9970-1036-55c8a24562c0.png)

## ファイルサイズ調整「あり」のファイルサイズ
解像度を「中」にして写真を撮り、保存しました。
77KBですね。
![写真サイズ調整ありの大きさとサイズ.png](https://qiita-image-store.s3.amazonaws.com/0/60538/1a7dad07-f829-3011-8751-f930576c8e82.png)

ファイルサイズも、だいたい写真分の増加です。
![FileSizeCheck2.png](https://qiita-image-store.s3.amazonaws.com/0/60538/81acd958-b902-8e3c-0864-0483d762abab.png)

## ファイルサイズ調整「なし」のファイルサイズ
では、次に解像度をiPhoneの設定、私の場合は最大にして写真を撮り、保存しました。
ぎょえ、1.9MBですって。
![写真サイズ調整なしの大きさとサイズ.png](https://qiita-image-store.s3.amazonaws.com/0/60538/69afc623-d3cd-3b78-91cf-f39afe73f9f0.png)

ファイルサイズも、当然その分増えます。
![FileSizeCheck3.png](https://qiita-image-store.s3.amazonaws.com/0/60538/b3373848-db5d-86fb-7af4-e57d86d6c625.png)

# つまり
今回の医療費アプリでは、診療請求書と明細書の２枚をアプリ経由でカメラで撮影し、納めていました。
割と通院する回数の多い私は、月に2,3回は通院し、調剤薬局で薬を購入します。
さらに、ここ数年は入院・手術も毎年のようにあるのでその分も登録していました。

高解像で保存し続けると、一人分の登録でもかなりのファイルサイズになります。
これを家族分、、、ましてやもらい風邪などをしやすい乳幼児のいる家庭ではどんだけになるんでしょう。。。

ファイルを外部保存する方法もありますが、単純にFileMakerアプリにファイルを保存しての運用をする場合は、オブジェクトのファイルサイズに注意する必要があります。
他のPDFでも、ドキュメント内に写真や絵が盛りだくさんの場合はそれ相当のファイルサイズになりますので、何かしらの対策は必要になります。

ただし、解像度などを小さくファイルサイズを小さく、、、という所に邁進してしまうと、ドキュメントや写真が見難くなります。
解像度が低くてもこの程度なら大丈夫、というようなボーダーラインを自分なりに決めて設定してみてくださいね。
【論文紹介】 FaceNet: 画像のベクトル化と「近さ」の定義

「近さ」をDeepLearningで表現して活用する研究があります。
画像などの高次元のデータから低次元のベクトルに落とし込んで、「距離を使って」人物の照合や類似画像検索などを行う方法です。代表的な論文として、ラベル情報無しで人の顔画像を精度良く分類するFacenetの論文と類似画像検索の論文を紹介します。

### Reference
- [FaceNet: A Unified Embedding for Face Recognition and Clustering](https://www.cv-foundation.org/openaccess/content_cvpr_2015/papers/Schroff_FaceNet_A_Unified_2015_CVPR_paper.pdf)
    - CVPR2015
- [Learning Fine-grained Image Similarity with Deep Ranking](https://arxiv.org/abs/1404.4661)
    - CVPR2014

文中の図表は論文より引用しています。

この記事は、Wantedlyの勉強会で取り上げられた論文・技術をまとめたものです。
[2018年に読んだ機械学習系論文・技術まとめ at Wantedly Advent Calendar 2018 - Qiita](https://qiita.com/advent-calendar/2018/wantedly_ml)

### モチベーション
画像のクラス分類は、DeepLearningによって高精度で行うことができますが、「クラスに依らず同じものが写っているかどうか」を判定することは分類タスクにはできないことです。

この問題を解くために、画像を低次元(1000次元とか)ベクトルに変換し（Embedding）、そのベクトルの距離が近いものは「同じもの」だと学習するという方法があります。

この方法の面白いところは、明示的なクラスのラベルを必要としない点です。以下で見るように、同じペアか違うペアの画像を大量に用意することができれば学習が可能なところが魅力的な点です。

### Facenet
顔の同一性判定は様々な用途があります。例えば、セキュリティーカメラや入退室管理、照合などがあげられます。選挙での重複投票を避けるために顔認識技術を使った国も[あるそうです。](http://archive.is/50EM)

Facenetは、人間の顔を大量に集めて、「同じ人が写っている画像は照明や角度が変わっても距離が近い」ようなモデルを学習します。
モデルの構造は、画像をインプットにして比較的低次元（1000次元とか）の実数値ベクトルを出力します。二つの画像から得られた実数値ベクトルの距離が学習の対象です。

下の図が学習された画像間の距離の例です。ピクセルレベルでは上下の画像のほうが近いように見えます（どちらも横向き）が、実際は左右に同じ人の2枚が表示されています。
数値は学習された距離を表しており、同じ人同士の画像では向きが違くても相対的に近い距離になっています。この例では1.0付近を閾値にしたら同じ人・違う人が分けられそうです。（論文では1.1と言っています）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/64964/8117939c-7ef2-09dd-50f3-33e975311220.png)

#### Triplet Loss
これを実現するための、損失関数がTriplet Lossです。
Triplet Lossでは、3枚の画像を必要とします。

- a: ランダムに選ばれた画像（anchor, 青）
- n: aと違う人物の画像 (negative, 赤)
- p: aと同じ人物の画像 (positive, 緑)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/64964/8671b989-3fdb-23df-a1a7-c83276b2de51.png)

$f(x)$は画像xをネットワークに通したときに得られるベクトルで（絶対値が1になるように正規化されている）、二つの画像の距離は以下で与えられます。
$$
dist(x,y) = ||f(x) - f(y)||^2_2
$$
Triplet Lossの意図を意訳すると、「同じ人のペアより、違う人のペアの方が距離が小さいと言ったらペナルティ。しかもマージン$\alpha$だけちょっと厳しい」というものです。
$$
Loss = \sum^N_i [ dist(a, p) - dist(a, n) + \alpha ]_+
$$
逆に言うと、人のラベルはわからなくても同じか違うかのペアだけがあればこのロス関数は計算できます。

またベースとして使うネットワークは何でもいいので、精度と計算量のトレードオフを選択することが可能です。ネットワークの計算量（横軸）と綺麗な相関があるようです。
![image](https://user-images.githubusercontent.com/2078683/38857826-2f87440a-4265-11e8-8d80-fdd3a2de222f.png)

### 古典的な画像処理手法との比較
顔照合の問題とは離れますが、古典的な画像処理の特徴量ベースの画像類似度と比較していた例として [Learning Fine-grained Image Similarity with Deep Ranking](https://arxiv.org/abs/1404.4661) があります。
ここでは、古典的な画像処理の特徴量（SIFTとかHOGとか）ベースと比べて、画像の類似度の精度を評価しています。

表の上部が古典的な画像処理ベースの手法、
<img src="https://qiita-image-store.s3.amazonaws.com/0/64964/2de61dc0-38ee-056b-1cba-92fbbd3f4906.png" width="50%"></img>

人手の特徴量SIFT-likeとかHOGとか：70%前後に対して、DeepRankingでは精度が大きく向上しています。

### まとめ
「似た画像を探す」や「同一の人物が写っているかどうかを判定する」という問題を、「画像からベクトルを出す」＋「現実問題の関係とベクトル間の距離を近づける」という問題にすりかえたところがこれらの研究の好きなところです。
また、枠組みは画像だけでなく音声や言語にも使えるため応用が数多く考えられます。
とあるAWSアカウントのAZ間のレイテンシ測定(ping / 参考値)

## 現状のZoneNameとZoneId
AZ ID というものがあることを知り現状を確認してみた。

```
$ aws ec2 describe-availability-zones | jq -c '.AvailabilityZones[] | [ .ZoneName, .ZoneId ]'
["ap-northeast-1a","apne1-az4"]
["ap-northeast-1c","apne1-az1"]
["ap-northeast-1d","apne1-az2"]
```
1aがaz1ではないのか...。なるほど。

## レイテンシ測定

### apne1-az4 (1a) → apne1-az4 (1a)

```
$ ping xx.xx.xx.xx -i 0.2 -c 100
：
rtt min/avg/max/mdev = 0.154/0.179/0.215/0.017 ms
```

### apne1-az4 (1a) → apne1-az1 (1c)

```
$ ping xx.xx.xx.xx -i 0.2 -c 100
：
rtt min/avg/max/mdev = 2.352/2.398/2.463/0.069 ms
```

### apne1-az4 (1a) → apne1-az2 (1d)

```
$ ping xx.xx.xx.xx -i 0.2 -c 100
：
rtt min/avg/max/mdev = 1.496/1.522/1.569/0.047 ms
```

### apne1-az1 (1c) → apne1-az2 (1d)

```
$ ping xx.xx.xx.xx -i 0.2 -c 100
：
rtt min/avg/max/mdev = 0.713/0.728/0.779/0.027 ms
```

## 結果
### 異なるAZ間
| Src AZ ID | → | Dst AZ ID | ping avg | memo |
|:---:|:---:|:---:|:---:|:---:|
| apne1-az4 (1a) | → | apne1-az1 (1c) | 2.398 ms | ① |
| apne1-az4 (1a) | → | apne1-az2 (1d) | 1.522 ms | ② |
| apne1-az1 (1c) | → | apne1-az2 (1d) | 0.728 ms | ③ |

### 同一AZ内
| Src AZ ID | → | Dst AZ ID | ping avg | memo |
|:---:|:---:|:---:|:---:|:---:|
| apne1-az4 (1a) | → | apne1-az4 (1a) | 0.179 ms | ④ |


## 所感
当然ながら同一AZ内（④）のレイテンシが最も低かった。
異なるAZはすべて同様にレイテンシが高いと思っていたが
実際は①〜③の通り想定よりレイテンシが低いAZ間通信も存在するため
MultiAZを考慮する際はこのあたりを実測してから検討すると良さそう。
Material Design の Rally を作りたい。

# はじめに

自作の家計簿アプリを刷新したいと思っていた。流行りのマテリアルデザインにしたいなーとか思って、いいデザイン無いかなーと検索していてであったのが [Rally](https://material.io/design/material-studies/rally.html)。

こいつ何者だー！と思って、Material Components for the web 使えばほんとにできるのかー！と思って、挑戦してみる。

そんなメモ。

# 前提条件

ちょっとは、フロントエンド開発ができる。
ちょっとは、英語ができる。でも英語のドキュメントを読みたくない。
Bootstrap くらいはフレームワークつかったことがある。

その程度の技術力。

本当に Rally みたいなものできるのかな。

# 懸念事項

自分のやる気がどこまで続くか。
記事の量がどのくらいになるのか。全然見えません。

# やってみよう - 1

Web なんて 1 からだよ！って初心者になった気持ちで取り組んでみよう。

## はじめてみる

まずは、[Getting Started](https://material.io/develop/web/docs/getting-started/) を読んで環境を作る。

```
https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css
https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js
```

これ読み込めばいいみたい。

・・・。

もう詰んだ。

こういうこと？

```html
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css" />
    <script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>
  </head>
  <body>
    Hello World
  </body>
</html>

```

ボタンでも置いてみようかな。

```html
<button class="foo-button mdc-button">Button</button>
```

おぉ、ボタン配置できた。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81548/7881fa41-ede1-c65e-349e-39b6591cbf90.png)

JS も使ってみようかな。

```html
<script>
  mdc.ripple.MDCRipple.attachTo(document.querySelector('.foo-button'));
</script>
```

おぉ、アニメーションする！

![caret4_win8.1_chrome.gif](https://qiita-image-store.s3.amazonaws.com/0/81548/a5734ba4-60d1-bff8-1206-b727916d4d28.gif)

なんか、Web 界隈では JS 最後に読み込んでること多いな……。

[[JS] JavaScriptの読み込み位置をページ最後にしたほうがよい理由](https://memocarilog.info/jquery/5842)

```html
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css" />
  </head>
  <body>
    Hello World
    <button class="foo-button mdc-button">Button</button>
    <script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>
    <script>
      mdc.ripple.MDCRipple.attachTo(document.querySelector('.foo-button'));
    </script>
  </body>
</html>
```

Rally までの道のりは遠い…。
macOS でシェルを切り替えるメモ

# bash から fish に切り替える

```
$ chsh -s /usr/local/bin/fish
```

## exit せずに今開いているターミナルを fish にする

```
$ exec fish -l
```

# fish から bash に切り替える

```
$ chsh -s /bin/bash
```

## exit せずに今開いているターミナルを bash にする

```
$ exec bash -l
```

# 確認環境

- macOS Mojave (10.14.1)
std::vector間の演算を定義したら快適になった

# std::vector間の演算を定義したら快適になった

C++で行列やベクトルを扱いたいときは, Eigenを使うことが多い. 
しかし, 非常に簡単なプログラムの場合, Eigenを使うまでも無いような場合も多々ある. 
そこで, `#include<vector>`の`std::vector`間の演算を定義することで, シンプルでカスタマイズ性の高い機能を提供する. 

**コメントをいただきました**: [std::valarray](https://cpprefjp.github.io/reference/valarray/valarray.html)という数値演算に特化した一次元配列クラスがあるようです

## vec_op
githubに[vec_op](https://github.com/birdwatcherYT/vec_op)を公開した. 
[vec_op.hpp](https://github.com/birdwatcherYT/vec_op/blob/master/vec_op.hpp)を`#include "vec_op.hpp"`するだけで使用可能. 
使用例は, [sample.cpp](https://github.com/birdwatcherYT/vec_op/blob/master/sample.cpp)を参照. 
その実行結果は, [こちら](https://github.com/birdwatcherYT/vec_op/blob/master/README.md)を参照. 


これらのリンク先のみで理解できるが, 一部抜粋して説明する. 

### vec_op.hpp
例えば, `std::vector`間の`+`は, 以下のように実装されている. 

```c++
template <class T>
std::vector<T> operator+(const std::vector<T> &v1, const std::vector<T> &v2) {
    std::vector<T> ans = v1;
    for (size_t i = 0, size = ans.size(); i < size; ++i)
        ans[i] += v2[i];
    return ans;
}
```

演算子の他に, よく使いそうな機能として名前空間`vec_op`に関数を定義した. 
例えば, 内積`dot`は以下の通り. 

```c++
namespace vec_op {
    // (...略...)
    template <class T>
    T dot(const std::vector<T> &v1, const std::vector<T> &v2) {
        T ans(0);
        for (size_t i = 0, size = v1.size(); i < size; ++i)
            ans += v1[i] * v2[i];
        return ans;
    }
    // (...略...)
}
```

### sample.cpp
四則演算`+`, `-`, `*`, `/`や, べき乗`^`の使用例. 
matlabの`+`, `-`, `.*`, `./`, `.^`に対応している. 

```c++
    cout << "v1 + v2 = " << v1 + v2 << endl;
    cout << "v1 - v2 = " << v1 - v2 << endl;
    cout << "v1 * v2 = " << v1 * v2 << endl;
    cout << "v1 / v2 = " << v1 / v2 << endl;
    cout << "v1 ^ v2 = " << (v1 ^ v2) << endl;
```

ベクトルとスカラーの演算にも対応. 

```c++

    cout << "v1 + c = " << v1 + c << endl;
    cout << "v1 - c = " << v1 - c << endl;
    cout << "v1 * c = " << v1 * c << endl;
    cout << "v1 / c = " << v1 / c << endl;
    cout << "v1 ^ c = " << (v1 ^ c) << endl;
    cout << "c ^ v1 = " << (c ^ v1) << endl;
```

その他機能の利用例. 

```c++

    cout << "dot(v1, v2) = " << vec_op::dot(v1, v2) << endl;
    cout << "sum(v1) = " << vec_op::sum(v1) << endl;
    cout << "prod(v1) = " << vec_op::prod(v1) << endl;
    cout << "cast<double, int>(v1) = " << vec_op::cast<double, int>(v1) << endl;
    cout << "concat(v1, v2) = " << vec_op::concat(v1, v2) << endl;
    cout << "sort(v1) = " << vec_op::sort(v1) << endl;
    cout << "argsort(v1) = " << vec_op::argsort(v1) << endl;
    cout << "randomIndex(10) = " << vec_op::randomIndex(10) << endl;
    cout << "range(10) = " << vec_op::range(10) << endl;
    cout << "range(2,10,2) = " << vec_op::range(2, 10, 2) << endl;
```

[実行結果](https://github.com/birdwatcherYT/vec_op/blob/master/README.md)

## メリット

- Includeするだけで関数/演算が使えるようになる
- カスタマイズ性が高い
   - 並列化したければ自分でoperator定義のforループに[openmp](https://qiita.com/birdwatcher/items/2d89374782a56be04aa1)をつければよい
   - 気軽に関数/演算子を追加していける
平成最後の年越し！おそば食べよう！なアプリつくった

クソアプリカレンダー5日目担当、@issy_s16 と申します。([Twitter](https://twitter.com/issy_s16))

皆さま素晴らしいクソアプリ（ハイクオリティ・褒め言葉）の中、
今回作成したクソアプリ（ロークオリティ・蔑み）を発表させていただきます。

## さて、その前に

2018年ももう12月。そう、年の瀬が近いんです。平成も終わりが近いですね。
進捗いかがでしょうか。

年末といえば、年越しそば。

僕は富士そばが大好きなんですが、きっと今年も富士そばで年越しするでしょう。

で、食券前で悩むんです。
**「あ、なにたべよ」**

それを解決するための素晴らしいソリューション（クソアプリ）がこれです。

## サービス紹介
![スクリーンショット 2018-12-05 10.03.59.png](https://qiita-image-store.s3.amazonaws.com/0/28500/a134f49d-483b-dc06-ffb8-88d817169733.png)

サービス名: **名代 年越しそばきめったー**
https://toshikoshisoba.herokuapp.com/

なにも難しいことはありません。
ページを開いて「決める」ボタンを押すだけで、富士そばレギュラーメニューの中からランダムでメニューを決めてくれます！！

クソアプリがゆえ、たまにカレーとか出ますが気にしないでください。

また、目を惹く機能として、「わかめそば食べます」みたいな生産性のないツイートができるボタンが設置されています。

使ってね！！

## 技術的な話
RailsとHerokuで作られてます！
バックのロジックは皆無に等しいのですが、
CSSアニメーションの勉強をしてみたかったのです！

animation、transitionは奥が深い。

## 宣伝
普段は以下のようなサービスを開発してます！！
こっちも使ってみてね！

- **[QiitaDeck - もっとQiitaで情報収集！](https://qiitadeck.com)**

> [Qiita版TweetDeck！？カラム形式でQiita記事をウォッチできるサービス「QiitaDeck」をリリースしました！](https://qiita.com/kazu1496/items/7ce5043f9128c9ab55f4)

- **[inazuma -リアルタイムコード共有エディタ-](https://inazuma.tech)**

> Webブラウザ上で複数人とリアルタイム共有しながらコーディングできるサービス作りました🤤
> ボタンぽちでルームを作って、できたURLをシェアするだけで使えます

## 最後に
ご覧いただきありがとうございました！！ (富士そばの回し者ではありません！)
（どうしようもないアプリを生み出してしまった…）
docker-composeでADDやCOPYをする際に注意すること

# 概要

docker-composeを利用してADDやCOPYを行いたいときに気をつけることをメモします。

まず、docker-composeでホスト側のファイルをコンテナにマウントする際はDockerfileを利用します。
しかしながら、その際には以下の点に気を付けなければいけません。

- [DockerfileでCOPYかADDをするときにホスト側は絶対パスだとエラーになる](https://qiita.com/hgoehgoeajfljsfalfjladf/items/4a3b6183f2e3fb8e4e53)
- [Docker-composeのDockerfile内で親ディレクトリ参照したいとき](https://qiita.com/katoosky/items/bd24905bca20afdfe745)

これらを踏まえて、AddやCopyをする流れを説明しようと思います。

ここでの例は以下のディレクトリ構成で説明を行います。

```
$ tree
.
├── docker-compose.yml
├── test
|   └── Dockerfile
└── hogehoge

```

# ホストの絶対パスを指定してしまうとダメ

これは先のブログでも紹介をされているので、簡単な説明にとどめますが、絶対パスを指定すると以下のようなエラーメッセージが出てきます。

```
ERROR: Service 'test' failed to build: COPY failed: stat /var/lib/docker/tmp/docker-builderXXXXX/hogehoge: no such file or directory
```

そのため、以下のように相対パスを指定してみます。

```dockerfile:※注意※これは間違っている例です
COPY ../hogehoge /tmp
```

しかし、これでも問題が続きます。

# 現在のコンテキストよりも外部のファイルにアクセスできない

しかし、このようにすると、以下のメッセージが出てきます。

```
ERROR: Service 'test' failed to build: COPY failed: Forbidden path outside the build context: ../hogehoge
```

これは、現在のビルド対象の場所よりも外側のファイルを参照しようとすると発生します。この例では、`../hogehoge`を参照していることが原因です。そのため、ビルドコンテキストを変更する必要があるので、以下のように`docker-compose.yml`を修正します。

```docker:docker-compose.yml
build:
    context: .
    dockerfile: ./php/Dockerfile
```

このように指定をすると、ビルドコンテキストは、phpディレクトリではなく、docker-compose.ymlの階層が現在のビルドコンテキストになります。そして、ビルドコンテキストがdocker-compose.ymlの階層になったため、コピーしたいファイル`hogehoge`の相対パスも変わりますので、dockerfileを修正します。

```dockerfile:これでOK
COPY ./hogehoge /tmp
```

これで、コンテキストにあったファイルのADDとCOPYをすることができます。

# 参考

- [DockerfileでCOPYかADDをするときにホスト側は絶対パスだとエラーになる](https://qiita.com/hgoehgoeajfljsfalfjladf/items/4a3b6183f2e3fb8e4e53)
- [Docker-composeのDockerfile内で親ディレクトリ参照したいとき](https://qiita.com/katoosky/items/bd24905bca20afdfe745)
- https://github.com/docker/compose/issues/5969
- https://github.com/docker/compose/issues/5823
Vue コンポーネントを自動で全部読み込む方法

この記事は [ShoTime Advent Calendar 2018](https://qiita.com/advent-calendar/2018/shotime) の 5 日目の記事です。


```js
const requireComponent = require.context('../components', true, /^.\/(The|Base)[A-Z][a-zA-Z0-9]{0,}\.vue/)
requireComponent.keys().forEach(fileName => {
  let baseComponentConfig = requireComponent(fileName)
  baseComponentConfig = baseComponentConfig.default || baseComponentConfig
  const baseComponentName = baseComponentConfig.name || (
    fileName
      .replace(/^.+\//, '')
      .replace(/\.\w+$/, '')
  )
  Vue.component(baseComponentName, baseComponentConfig)
})
```

`/^.\/(The|Base)[A-Z][a-zA-Z0-9]{0,}\.vue/` が正規表現で書かれています。上記に挙げたコードでは、 `BaseApp.vue` `TheHeader` のようなコンポーネント名を全て自動で読み込むようなコードになっています。

プロジェクトにあわせ適宜書き換えれば良い感じに Component を読み込めると思います。

## 参照
https://vuejs.org/v2/guide/components-registration.html#Automatic-Global-Registration-of-Base-Components
ビジネス基礎

### 企画書・提案書の基礎
#### 説得力ある企画書の書き方
* PASONAの法則
* 新・PASONAの法則
* https://swingroot.com/pasona-formula/

### ミッション・ビジョン・バリュー
* 企画や戦略を建てる際の基礎。
* ドラッカー提唱。
* https://nomad-journal.jp/archives/6244#i-2
* 桃太郎で置き換えた説明（わかりやすい）
* http://www.crassone.co.jp/blog/3644/

###経営基礎
* 事業戦略とは
* * 環境分析、経営課題特定、戦略立案、戦略実行のプロセスで整理できる。それぞれのステップで利用できるフレームワークとその使い方について記載する。
1. 環境分析

環境分析は、顧客分析と業界・領域分析の主に２つにわけて考えることができる。
1. 顧客分析
　　市場調査、潜在顧客の特定、DMU
2. 業界分析
　　PEST、5F、アドバンテージマトリクス
2. 経営課題特定
3. 戦略立案
4. 戦略実行

###マーケティング
* 3C、STP、4P
* SWOT、クロスSWOT、6R
* 価格設計の方法
* Product, Proce, Place, Promotion
* 各フレームワークを全て使う必要はなく、目的や解決すべき問題に合わせて適宜使用する。
GoogleAppsScriptでサイトが落ちていないかを確認してSlack通知するスクリプト（ベーシック認証付き）

# 検証環境が落ちてると、みんな困る

良かれと思って検証環境を構築し、お客さんとかに教えると
デプロイミスって落ちてるときとかに文句を言われて辛いので
先手を取れるスクリプトを作成しました。

## 前準備
SlackのWebhookでIncoming Webhooks からURLを発行してね。

## GoogleAppsScriptに下記スクリプトを配置する。
postUrl、postUrl2はwebhooksのURLです。

* 一度エラー通知して、次もエラーだった場合は通知しません。
* エラーの後エラーが解消されていたら通知します。

```javascript
var postUrl = 'https://hooks.slack.com/services/*****/****/43Fr******zmr';
var postUrl2 = 'https://hooks.slack.com/services/*****/****/3m6*****cN7r';
var username = '検証環境落ちてるよ君';  // 通知時に表示されるユーザー名
var icon = ':hatching_chick:';  // 通知時に表示されるアイコン
var url = 'https://oneframe.co.jp'; // 調べたいURL
var error_message = url + ' が落ちてるよー確認してー';  // 投稿メッセージ

function myFunction() {
  var user = "basic-auth-user"; // ベーシック認証のユーザ
  var pass = "basic-auth-pass"; // ベーシック認証のパスワード
  var options = {
    "headers" : {
      "Authorization" : " Basic " + Utilities.base64Encode(user + ":" + pass), 
    },
    "muteHttpExceptions" : true,
  };
  var f;
  var code = 500;
  try {
    f = UrlFetchApp.fetch(url, options)
    code = f.getResponseCode();
    Logger.info(url + ":responscode>>>" + response.getResponseCode()); 
  } catch(e) {
    Logger.log("message:" + e.message + "\nfileName:" + e.fileName + "\nlineNumber:" + e.lineNumber + "\nstack:" + e.stack);
  }
  
  // 直前のステータスを取得
  var status = PropertiesService.getScriptProperties().getProperty('status');  
  // エラーの場合で直前のステータスがngの場合は送信しない。
  if (code != 200) {
    if (status != "ng") {
      message = error_message + "　ステータスコード：" + code;
      sendMessage(message);
      PropertiesService.getScriptProperties().setProperty("status", "ng");
    }
  } else {
    // 正常の場合で直前のステータスがngの場合は改善した旨を通知する。
    if (status == "ng") {
      message = "エラーは解除されました！よかったよかった。";
      sendMessage(message);
    }
    PropertiesService.getScriptProperties().setProperty("status", "ok");
  }
}

function sendMessage(message) {
  var jsonData =
      {
        "username" : username,
        "icon_emoji": icon,
        "text" : message + "　ステータスコード：" + code
      };
  var payload = JSON.stringify(jsonData);
  
  var options =
      {
        "method" : "post",
        "contentType" : "application/json",
        "payload" : payload
      };
  
  UrlFetchApp.fetch(postUrl, options);
  UrlFetchApp.fetch(postUrl2, options);
  
}
```

## GoogleAppsScriptでトリガー設定
5分おきくらいに設定しましょう。
めでたしめでたし。

## 技術的なポイント
UrlFetchApp.fetch ちゃんは便利なんだけど指定したサイトが500の場合は
例外を返すメンヘラな一面を持つ。
なのでこの子はtry 〜 catch の優しさで包み込んであげましょう。