OmniAICreator/Qiita-1.07M huggingface dataset:
モデリングっておもしろいね


#はじめに
はじめまして。
w_shimizuといいます。絶賛風邪ひきで寝込んでいます。皆さんは体調にお気をつけて年末年始過ごして下さい。
さて、今回は急遽テーマを変更してこんな話題で、「Tech Do Advent Calendar 2018」の16日目の記事を書いてみたいと思います。

モデリングっておもしろいですよね！
アプリケーションが出来上がった後に、モデルを変えると色々な修正をしなくてはいけなくなってしまったり、一旦モデルが決まってしまうと、出来る事と出来ない事が出て来たりして、モデルが決まる事はとても影響力のある事なのだなと感じる事が多いです。
重要視されていないですが、縁の下の力持ちのような役割で、実は陰ながら作業を支配している！そんなモデリングという分野が私はとても大好きです。
一方で、これだけ大事な分野でありながら、モデリングが出来る人とアプリケーションを作れる人が並んだ時、アプリケーションを作れる人を褒めたり、お礼を言ったりする機会は多くありますが、モデリングの分野で作業をしている人が褒められたりお礼を言われたりする機会はとても少なく、軽視されがちな印象ですよね。
やった事の無い人に説明するのも中々難しい！なので、評価しようがなく、出来上がっているアプリケーションに目が向きがちなのが現実です。
かくいう私もモデリングが出来るといえるレベルではないのですが、今回は、こんな私なりにモデルが変わるとどうなっていくのか少しでも書いてモデリングの重要性をお伝えできたらと思いました。
※間違った事等を書いているかもしれません。あたたかくご指摘頂けると幸いです。
※この記事の中では、多重度の表現が出てきます。多重度についての理解がある方ではないと読む事が難しいかもしれません。予めご承知おきください。

#モデリングを説明する題材について
今回は、「会社員」というモデルについて考えてみる事にします。

#いざ、モデリング
##ステップ1
まずは、会社員というテーブル1つだけ作成して全ての要素を詰め込んで見る事にします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/315701/414b0f5c-74d9-8bf0-ba73-6c83027023b0.png)

ステップ1では、1つのテーブルの中に沢山の要素を詰め込んだ結果変更に弱いモデルが出来ました。
少しだけこのモデルの問題を上げると、
・データの変更に弱い
・重複したデータがとても沢山増えてしまう
などなど問題が沢山ありそうですね。

そこで、次のステップでは、「正規化」を意識してモデリングしてみたいと思います。

##ステップ2

ステップ2では、ステップ１で作成したモデルを正規化してみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/315701/ea9a1058-aaff-bbed-4c14-cc0eafaf933b.png)

ステップ2では、正規化する事でステップ１で抱えていた沢山の問題を解決する事が出来るようになりましたね。

例えば、部署名を「開発企画部 から 企画部」へと変更したいというケースを想像した場合に、ステップ１では、全ての会社員の中で、開発企画部に所属する人の部署名を企画部にする必要がありましたが、ステップ2のように正規化しておくことで、部署テーブルの開発企画部を企画部へと変更するだけで変更作業は終わりとなります。
具体的な数字を交えますが、社員が1000万人いるような会社でこんな作業が起きたという事を想像してみてください。
ステップ１の場合は、対象の部署の社員が100万人いたとすると100万人分の情報を書き換える必要がありますが、ステップ2のように管理しておけば１か所の修正で終わりですね。
モデルを正規化すると、柔軟にデータ変更に対応出来たり、重複レコードがなくなるなどとてもメリットが大きいです。

さて、ステップ2を少し変更してみるとモデルの表す意味合いが変わっていきます。
ステップ3では、モデルを少しだけ変えて大きくモデルが変わる様子を見てみましょう。

##ステップ3
ステップ2と少しだけ変えてモデルの持つ意味を変えてみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/315701/2b707534-4c1c-c40c-3768-547da554d2d7.png)

ステップ2との違いが分かりますか？
・
・・
・・・
・・・・
・・・・・
パッと見ですと分からないですが、会社員と部署の多重度が変わっていますね。多重度の説明については、少し複雑になりますので、「多重度」のキーワードで検索をしてみて下さい。
こうなるとステップ2とはまるで違うモデルになっています。
ステップ2では、会社員は1つの部署にしか所属出来ませんでしたが、ステップ3では、会社員は2つ以上の部署に所属する事が出来るようになりました。

ステップ2のモデルを活かしたまま、複数の部署に所属出来るようにする為にはどうすれば良いでしょうか？
モデルは苦しいですが、以下のようにすれば1人の会社員が複数の部署に所属する事を表現出来るかもしれません。
但し、このモデルを選択した場合は、更に追加で対応要望があった場合に柔軟に対応できるのかどうかとても考えさせられる部分があると思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/315701/53f7a408-35ce-db85-2f08-a8d5cd106181.png)

どちらもやりたい事は実現できますね。
モデリングでは、正解が1つではない事がまた面白いなとこんな時に感じます。
人によってやり方や解決方法が変わるのがモデリングだと思います。
ベテランの人から新人の人までみんなが違うモデルをもって色々な解決方法を提案し、色々な正解が導き出される事がすごく楽しい分野ですね。

#終わりに
さて、今回は簡単にモデリングという分野について触り部分をまとめてみました。
今回書かせて頂いた内容は、私が学んだモデリングでもほんの一部でしかないですし、
私はモデリングを覚えて沢山の状況においてモデリングを実践できたわけではありません。
例えばこんな事業を想定してモデリングを行うとどうなるのか、また10年後まで動くシステムを作る為にはこのモデルで行くしかないよねとか
そんなケースでモデリングをしてみると違った視点でモデルを作る事が出来て、面白いかもしれません。
そして、今回はご紹介できませんでしたが、モデルの抽象化を利用すればアプリケーションの修正をなるべく軽微に抑える事が出来たりしますので、ぜひ試してみてください。
こんな記事でも、皆さんが少しでも興味がもてましたらぜひモデリングをしてみてはいかがでしょうか？

#お詫び
書き終わって、改めて見なおすと最初と最後にかけてのレベル差がとてもある事に気づき、とても反省しています。すみませんでした！
次回機会があれば、ちゃんと時間をかけてゆっくりと丁寧に解説出来る記事をまとめてみたいと思います。
そして、あくまで私個人の意見として書いている記事ですので、賛同出来る・出来ないなどのご意見もあるかと思いますが、個人的にご意見頂けると幸いです。
簡単では御座いますが、最後までご一読下さりありがとうございました。
pyenvでWorking with Matplotlib on OSXのバックエンド問題を解決

[pyenvを構築して](https://qiita.com/pumbaacave/items/c7f1cc01168ef50f8d6a)matplotlibを使おうとしたら、このpythonはMacOSでframeworkとしてインストールされていません、みたいなものエラーが出てきた。
ググって、良い対策法見つかった
##一行で解決してみた

```

PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install x.x.x
```

###補足
詳しくは：
```x.x.x　```のところに3.7.1のようにバージョン指定して、インストールすれば、インストールされたpythonがframeworkビルドになります

###参照

[matplotlib2.2.3んのドキュメント](https://matplotlib.org/2.2.3/faq/osx_framework.html)
最新の3.0.2のドキュメントではpyenvの対策を書いていません
ばらつきを示す指標(分散や標準偏差)

# ばらつきを示す指標(分散や標準偏差)

* 問題提起
   * ばらつき(分散と標準偏差)とは何か。
   * 何に使うのか、どういうときに使うのか。

* ばらつきの説明
   * 統計学では、個々のデータの平均からの差をばらつきの指標に用いる。

* ばらつきの図解
   * 下記の図1は、10個のデータをプロットしたもの。
      * 横軸: データ番号
      * 縦軸: データの値
      * 図1
      ![ばらつき_図1.png](https://qiita-image-store.s3.amazonaws.com/0/321994/b1d581d3-7482-70b7-5ce7-562a294b3fa5.png)

   * 下記の図2は、図1に平均と平均と個々のデータのと差を書き入れたもの。
      * 茶色い線が、個々のデータと平均との差。これによってデータのばらつきを表現する。
      * 図2
      ![ばらつき_図2.png](https://qiita-image-store.s3.amazonaws.com/0/321994/4b560f2f-b179-e110-c380-1ce92ca76956.png)


* 定義式
   * 分散
      * 分散の定義式
         * $s^2=\displaystyle \frac{\displaystyle \sum_{i=1}^{n}(x_i-\bar{x})}{n}$
      * $(x_i-\bar{x})$ の部分が、個々のデータと平均との差(図2の赤線の部分)。それを二乗して総和を取り、データ数で割ったものが分散。
      * 特徴
         * 分散は、平均との差を二乗したものからできる数値なので、スケールがデータと比べてとても大きい。
   * 標準偏差
      * 定義式
         * $s^2=\sqrt{\displaystyle \frac{\displaystyle \sum_{i=1}^{n}(x_i-\bar{x})}{n}}$
      * 分散のルート(平方根)を取ったもの。
      * 特徴
         * 標準偏差のスケールは、データと同じになる。
         * 例えばデータが正規分布に従う場合、平均値プラスマイナス標準偏差の範囲に、データ全体の68%が入る。
   * その他
      * 分母をnではなく(n-1)として分散や標準偏差を計算する場合もある。
         * 不偏分散、標準偏差の不偏推定量などという。
         * 少ないデータから全体の傾向を推測する推測統計学では、これも使用する。
         * 今回は`データのばらつき`という概念を伝えることに集中するので、それには触れない。

* 分散や標準偏差の使いどころ
   * 管理の際の指標とする。
      * ばらつきの少ないデータ: いつも同じような値なので、予測や管理が容易。
      * ばらつきの多いデータ: 予測がつかないので管理が難しい。

* 分散や標準偏差の使い方の例(生産管理における例)
   * 下に3つの製品(製品A, B, C)の月ごとの発注量のグラフを書く。
   * ばらつきが大きい製品は、管理方法をどうするべきだろうか？
* 製品Aの発注量のグラフ
   * 図3
   ![ばらつき_製品Aの発注量.png](https://qiita-image-store.s3.amazonaws.com/0/321994/c83b2e64-b138-b018-5c07-57599fd4ffad.png)

   * グラフの説明
      * 横軸に月、縦軸に月ごとの製品の発注量をとる。
   * 特徴
      * 毎月大体同じ量の発注量がある。(データのばらつきが小さい)
      * 標準偏差 = 6.44
   * 在庫の管理方法
      * 手間のかからない機械的な管理方法でよい。
      * 在庫が一定の水準を下回ったら、毎回同じ量だけ発注するなど。
* 製品Bの発注量(売れる季節がある)
   * 図4
   ![ばらつき_製品Bの発注量.png](https://qiita-image-store.s3.amazonaws.com/0/321994/73e68f77-d16c-c83a-913a-f93d4b478464.png)

   * 特徴
      * 時期に発注量が左右される。(年度末、年末に増える傾向がある)
      * 標準偏差 = 37.12
   * 在庫の管理方法
      * この製品独自の管理方法を考え、実行する。
      * 売れる季節は在庫を多く置いたり、その季節の直前に在庫の数を調べて必要な在庫を予想して発注するなど。
* 製品Cの発注量
   * 図5
   ![ばらつき_製品Cの発注量.png](https://qiita-image-store.s3.amazonaws.com/0/321994/e1c28882-3ca3-01f9-723d-4294b1fb36ce.png)

   * 特徴
      * 発注量がてんでばらばらで傾向が読めない
      * 標準偏差 = 33.22
   * 在庫の管理方法
      * この製品独自の管理方法を考え、実行する。
         * 各種データとの相関を見たり、売り先に尋ねたりして、売れ行きの要因を調査する。
         * 調査でわかったことを、在庫量や発注タイミングに反映させる。
         * 多めの在庫をおいて対処する。

* おまけ(変動係数)
   * 変動係数とは何か？
      * 標準偏差を平均で割ったもの。
      * スケールの異なる値を比べるときに使う。
         * 例: クジラとサバのサイズのばらつきを比べる
   * 上記例の変動係数
      * 製品A: 0.064
      * 製品B: 0.314
      * 製品C: 0.312
   * 定義式
      * $C.V.=\displaystyle \frac{s}{\bar{x}}$
         * $C.V.$ :Coefficient of Variation
shellからsimulator操作

# 目的

appiumでテストするときに、simulatorのキーボードがmacに接続するようになってると、入力ができないため、コマンドでデフォルト解除したい
その他、simulatorをコマンドで操作する的なものがあれば載せていく。

## 以下でよかった

```
➜ defaults write com.apple.iphonesimulator ConnectHardwareKeyboard -bool NO
```

## shellからアプリ削除 on simulator
```
xcrun simctl uninstall booted アプリのバンドルID
```

## 参考

https://stackoverflow.com/questions/38010494/is-it-possible-to-toggle-software-keyboard-via-the-code-in-ui-test
iOSでメモリーリークを簡単に検知できるようにする方法

## はじめに
- メモリーリークはアプリの挙動を不安定にする要因となる
- Xcode の `Debug Memory Graph`などを使う方法もあるが毎回調べるのにコストがかかる
- [krzysztofzablocki/LifetimeTracker](https://github.com/krzysztofzablocki/LifetimeTracker)を導入することでアプリがメモリーリークをしていることに開発者が気が付きやすくなる

- 今回は`LifetimeTracker`について詳しくまとめます

## LifetimeTrackerとは
>Find retain cycles / memory leaks sooner.

- LifetimeTrackerはメモリーリークをアプリ実行時に把握できるようにするツールです
- 導入することでアプリ実行時にUI上で確認できるようになります
- [krzysztofzablocki/Sourcery](https://github.com/krzysztofzablocki/Sourcery)のコントリビュータでもある[krzysztofzablocki](https://github.com/krzysztofzablocki)が作者である

## 環境
```sh
Xcode 10.1
Build version 10B61
Apple Swift version 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1)
Target: x86_64-apple-darwin18.2.0
```
## 導入方法
#### 1. pods or carthageでLifetimeTrackerをインストール

#### pods
```
pod 'LifetimeTracker'
```

#### carthage
```
github "krzysztofzablocki/LifetimeTracker"
```
#### 2.セットアップの処理をAppDelegateに追加

```swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
     LifetimeTracker.setup(onUpdate: LifetimeTrackerDashboardIntegration(visibility: .alwaysVisible, style: .bar).refreshUI)
     return true
}
```

#### 3.メモリーリークを調べたいViewControllerに実装を追加

```swift
import UIKit
import LifetimeTracker

class ViewController: UIViewController {
    static var lifetimeConfiguration = LifetimeConfiguration(maxCount: 1, groupName: "VC")
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        trackLifetime()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        trackLifetime()
    }
}

extension ViewController: LifetimeTrackable {}
```


## 実際の画面
<img src="https://qiita-image-store.s3.amazonaws.com/0/63985/19f3ffb6-551a-17dd-696f-7310540cb53c.gif" width="320">

- [サンプルコード](https://github.com/takuchantuyoshi/LifetimeTracker-Sample/tree/master)
- メモリに保持されているインスタンスの数がメニュー画面で確認できます
- `maxCount`を設定することでインスタンスの数が`maxCount`を超えた場合メニューに警告として表示される
- `groupName`を指定することでメニューで別のグループとして、まとめて表示されます
- メニューの出し方も色々と選べるので実装時に邪魔にならないようになっています

## 参考リンク
- [krzysztofzablocki/LifetimeTracker](https://github.com/krzysztofzablocki/LifetimeTracker)
ストアド・プロシージャの実行速度についてベンチマークをとってみました

#はじめに 

この記事はユニークビジョン株式会社 Advent Calendar 2018の16日目の記事です。
弊社ではSQLを書く際に良くストアド・プロシージャを使用します。
使用する理由として自分が理解しているところでは、以下の2点です。
①通常のSQLやORマッパーに比較してパフォーマンスが向上する。
②複雑な処理などを書きやすい
そこで今回①について、どのくらい速いのかを検証してみたいと考えています。


#準備
###適当なTABLEとレコードを用意
なんとなくECサイトっぽく、顧客、注文、注文に紐づく明細、それから商品のテーブルを用意します。
<img width="576" alt="スクリーンショット 2018-12-16 20.46.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/315768/7fbfd2d6-c694-b8c3-0580-a43d66341872.png">

###ストアド・プロシージャを用意
①明細テーブルのレコード全件の数を取得する単純なストアド・プロシージャ
<img width="520" alt="スクリーンショット 2018-12-16 20.52.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/315768/03563a31-50a1-6ae5-2ff4-9997b7a85608.png">

②全てのテーブルを結合し、明細が複数ある注文の件数を取得するストアド・プロシージャ
<img width="769" alt="スクリーンショット 2018-12-16 20.55.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/315768/bc89bab9-42db-bae4-991a-4ecbf6f2ed49.png">

###ベンチマークを計測するクラスを用意（１枚にまとまりませんでした）
<img width="858" alt="スクリーンショット 2018-12-16 20.59.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/315768/22103bfb-cd82-0420-6d65-8364b91f05d5.png">
<img width="908" alt="スクリーンショット 2018-12-16 20.59.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/315768/4360d18c-e39d-f8a0-295d-4c3458cd6056.png">
<img width="1017" alt="スクリーンショット 2018-12-16 21.00.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/315768/04996c8f-e403-9b27-6545-1162217ec52a.png">
<img width="989" alt="スクリーンショット 2018-12-16 21.00.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/315768/c33948d1-ca7b-8ec6-612f-91e320bbf32d.png">

一応画面上に出力されるA,B,C,D,Eは以下のとおりとなります。
①A：生SQLで明細テーブルのレコード全件の数を取得
②B：ストアド・プロシージャで明細テーブルのレコード全件の数を取得
③C：Active Recordの機能で明細テーブルのレコード全件の数を取得
④D：生SQLで全てのテーブルを結合し、明細が複数ある注文の件数を取得
⑤E：ストアド・プロシージャで全てのテーブルを結合し、明細が複数ある注文の件数を取得

#実行結果
<img width="816" alt="スクリーンショット 2018-12-16 21.09.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/315768/a62bc6fb-96e6-f95a-5fd8-7ab98f6505fb.png">

計測に使用したのはBenchmarkというRuby標準のライブラリーとなります。
詳しい使い方や結果の見方などは[こちらの記事](https://qiita.com/scivola/items/c5b2aeaf7d67a9ef310a)になり、参考にさせていただきました。

今回はそれぞれでuserの欄を見ればいいのですが、結果としてストアド・プロシージャを使用したほうが生SQLより若干処理速度が速く、また生SQL、ストアド・プロシージャ共にActive Recordよりかなり速いという結果がわかりました。
（Active Recordで複雑な条件のレコード数を取得する方法がわからなかったので行っておりません）

#まとめ
ということでやはりストアド・プロシージャは速かったという結果になります。
ただ自分のストアド・プロシージャについての理解などが間違っている可能性もあるため、ご指摘等いただければ幸いです。

次回は@s_itoさんです！
ddとhdparmで簡易的なディスク性能の調査


# 概要

ddコマンドとhdparmコマンドを使って、Linuxマシンのディスク性能を調べる。
GCE(ComputeEngine)インスタンスに対して調べる必要があったので、その時のメモ。

# 環境

* GCE
* Debian GNU/Linux 9
* n1-standard-1（vCPU x 1、メモリ 3.75 GB）
* Disk: SSD 永続ディスク 50GB

# 調査
## Write

```
$ dd if=/dev/zero of=tmp.data bs=1M count=3000 oflag=direct
3000+0 records in
3000+0 records out
3145728000 bytes (3.1 GB, 2.9 GiB) copied, 82.3658 s, 38.2 MB/s
```

`oflag=direct`を指定する意味

> データに対してダイレクト I/O を使用し、バッファ・キャッシュを介さないようにする。
https://linuxjm.osdn.jp/info/GNU_coreutils/coreutils-ja_79.html


## Read

コマンドインストール

```
$ sudo apt install hdparm
```

```
$ sudo hdparm -t /dev/sda1

/dev/sda1:
 Timing buffered disk reads: 744 MB in  3.01 seconds = 247.39 MB/sec
```

### 余談
hdparmで何を調べているかはmanを読むのが良い。

> This measurement is an indication of how fast the drive can sustain sequential data reads under Linux, without any filesystem overhead.

# 雑談

GCEインスタンスの性能を見るのが目的だったが、特にReadで結果が安定しなかった。（56.78 MB/s ~ 247.39 MB/secまでバラツキが大きい）

GCEの上限のIOパフォーマンスはディスクの種類とサイズによって下記のように決まるはずだが、WriteもReadもそれを超える結果がでた。（理由はわかっていない）
https://cloud.google.com/compute/docs/disks/performance?hl=ja#type_comparison
ElasticsearchのReindex APIで小ネタ紹介

# はじめに
こんにちは。この記事は[Elastic stack(Elasticsearch) Adventclendar](https://qiita.com/advent-calendar/2018/elasticsearch)の16日目です。
今回はElasticsearchのReindex APIの小ネタを紹介していきます。

# Reindex APIとは
ElasticsearchのAPIでIndexからIndexへデータを転送するAPIです。
このAPIを使うことで、IndexのMappingを更新して新しいIndexを作成するといったことがElasticsearch内で完結してできます。
そんなReindex APIでできることを小ネタとして紹介していきます。

# scriptを使ってIndex名の数字をインクリメントする。
Index名でバージョンを管理する際に便利な技です。
例えば「*-1」という命名規則のIndexを「*-2」にReindexするとします。*の部分にはさまざまなIndex名が入ります。
このようなときに一つずつIndex名を指定してReindexするのではなく、一括でReindexしてみます。
この動作をscriptを使って実現すると以下のようになります。

```
POST _reindex
{
  "source": {
    "index": "adventcalendar-1"
  },
  "dest": {
    "index": "xxx"
  },
  "script": {
    "source": """
    int version = Integer.parseInt(ctx._index.substring(ctx._index.indexOf("-")+1, ctx._index.length()));
    version = version + 1;
    ctx._index = ctx._index.substring(0, ctx._index.indexOf("-")+1) + String.valueOf(version);
    """
  }
}
```
やっていることとしては、ctx._indexでIndex名にアクセスして、version番号を取得したのち、インクリメントしてctx._indexに戻しているだけです。
scriptの中身はpainlessなのでこのような処理も可能になります。

# Reindexが長すぎてTimeoutする場合の対処
Reindex APIを使用した際に対象のIndexのサイズが大きいとReindexが終わらずにGateway Timeoutを返されてしまうことがあります。
この場合、対処法としてはリクエストに`wait_for_completion=false`をつけて実行することです。
そうすると、Reindex APIにリクエストを受け付けた段階で、すぐにレスポンスを返し、バックエンドでReindex処理を実行し続けます。

# Reindexの処理を中断する
長いReindexを走らせたあと、自分のミスに気が付いて中断したくなることもよくあることです。
その場合はTask APIを使って処理を中断できます。

まずは、Task APIでReindex処理のIDを調べます。
リクエスト
`GET _cat/tasks`
結果

```
indices:data/write/reindex          Hu66H8zuSeSsyHql434ClA:208844 -                             transport 1544961647974 12:00:47 11.6s   127.0.0.1 Hu66H8z
indices:data/write/bulk             Hu66H8zuSeSsyHql434ClA:208989 Hu66H8zuSeSsyHql434ClA:208844 transport 1544961658339 12:00:58 1.3s    127.0.0.1 Hu66H8z
indices:data/write/bulk[s]          Hu66H8zuSeSsyHql434ClA:208994 Hu66H8zuSeSsyHql434ClA:208989 transport 1544961658340 12:00:58 1.3s    127.0.0.1 Hu66H8z
indices:data/write/bulk[s]          Hu66H8zuSeSsyHql434ClA:208993 Hu66H8zuSeSsyHql434ClA:208989 transport 1544961658340 12:00:58 1.3s    127.0.0.1 Hu66H8z
indices:data/write/bulk[s]          Hu66H8zuSeSsyHql434ClA:208992 Hu66H8zuSeSsyHql434ClA:208989 transport 1544961658340 12:00:58 1.3s    127.0.0.1 Hu66H8z
indices:data/write/bulk[s][p]       Hu66H8zuSeSsyHql434ClA:209006 Hu66H8zuSeSsyHql434ClA:208992 direct    1544961659439 12:00:59 221.6ms 127.0.0.1 Hu66H8z
```
Reindex処理のIDが`Hu66H8zuSeSsyHql434ClA:208844`であることがわかります。
では、上のIDの処理をキャンセルしましょう。

リクエスト
`POST _tasks/Hu66H8zuSeSsyHql434ClA:208844/_cancel`

そして、もう一度taskを調べると、、、

```
cluster:monitor/tasks/lists    Hu66H8zuSeSsyHql434ClA:212440 -                             transport 1544962017169 12:06:57 116.7micros 127.0.0.1 Hu66H8z
cluster:monitor/tasks/lists[n] Hu66H8zuSeSsyHql434ClA:212441 Hu66H8zuSeSsyHql434ClA:212440 direct    1544962017169 12:06:57 56.7micros  127.0.0.1 Hu66H8z
```

無事キャンセルされていることがわかります。

# まとめ
以上、Reindex APIの小ネタを紹介していきました。
日頃の開発やIndexの管理などで非常に便利なAPIなので、皆さんもぜひ活用してみてください。
それではまた。
時系列コンペでよく使用されるsin, cosへの変換とは


塩コンペに関しては、大会1位を飾ったphalanxさんが[記事](http://phalanks.hatenablog.jp/entry/2018/12/23/195354)を書いているのでぜひとも参照してください！自分もやったことは記事内の２ヶ月〜最終日以外はほぼ同じです。

## 本題

時系列のコンペでは、特徴量として各訓練例が取得された時間や日付を組み込むことがあります。
しかし`hour`を例に考えてみると、23時の次は0時ですがこの間には数値的なつながりがありません。そこで循環性を考慮できるように三角関数を各特徴量に適用させます。

```python
%matplotlib inline
import pandas as pd
import numpy as np

dates = pd.date_range(start='2017-01-01', end='2017-12-31', freq='H')
df = pd.DataFrame(data=np.zeros(len(dates)), index=dates, columns=['test'])
df.head()
```

![使用DF.PNG](https://qiita-image-store.s3.amazonaws.com/0/194085/4e4a171e-b43b-7d8e-27e1-0b4f52a3d240.png)


これで2017年1月から12月まで24時間ごとの特徴量を作成することができました。
インデックスから時系列の情報を抽出します。

```python
df['year']  = df.index.year
df['month'] = df.index.month
df['day']   = df.index.day
df['hour']  = df.index.hour
df['dow']   = df.index.dayofweek
```

これで時系列の情報を抽出できました。

```python
df[df.index.month == 1]['dow'].plot(grid=True)
```

![通常のdow.png](https://qiita-image-store.s3.amazonaws.com/0/194085/05bcc6f6-01ce-48c9-967a-fc5e27fd3b37.png)


これで1月の曜日の情報を見てみると、日曜日（dow==6）の次が月曜日（dow==0）になっており、隣り合った日であっても数値的には隣り合っていません。
そこで循環性を持つように三角関数を使用して特徴量を変換します。

```python
def encode(df, col):
    # この方法だと場合によって最大値が変化するデータでは正確な値は出ない
    # 例：月の日数が30日や31日の場合がある
    df[col + '_cos'] = np.cos(2 * np.pi * df[col] / df[col].max())
    df[col + '_sin'] = np.sin(2 * np.pi * df[col] / df[col].max())
    return df

df = encode(df, 'dow')
df = encode(df, 'hour')
df = encode(df, 'day')
df = encode(df, 'month')
```

実際に高校でやったように三角関数を図に出力してみると、各特徴量が循環性を持っていることがわかります。

```python
# 例：月の循環性
df.plot.scatter('month_sin', 'month_cos').set_aspect('equal')
```

![通常のdowの円.png](https://qiita-image-store.s3.amazonaws.com/0/194085/9e5acd37-6c9b-65a4-57e7-0e0551b1cd21.png)

なおよりデータを細かくしたいときは、一つ小さな時系列情報を組み込めば表現はできます。

```python
df['dow+hour'] = df['dow'] + df['hour'] / 24
df = encode(df, 'dow+hour')
df.plot.scatter('dow+hour_sin', 'dow+hour_cos').set_aspect('equal')
```

![通常のdowhourの円.png](https://qiita-image-store.s3.amazonaws.com/0/194085/c68229a0-3ed0-974b-e4d8-ec49fe3a24b7.png)


## 参考文献

- [Encoding cyclical continuous features - 24-hour time](https://ianlondon.github.io/blog/encoding-cyclical-features-24hour-time/)
- [Optimal construction of day feature in neural networks](https://stats.stackexchange.com/questions/126230/optimal-construction-of-day-feature-in-neural-networks)
- [What is a good way to transform Cyclic Ordinal attributes?](https://datascience.stackexchange.com/questions/5990/what-is-a-good-way-to-transform-cyclic-ordinal-attributes)
ASP.NET Core Web アプリケーションをdockerで動かす

こちらの記事を読んで、少しC#サーバーに興味が出てきたので試して見ようと思いました。

http://tech.cygames.co.jp/archives/3181/

まずはASP.NET Core Webをdockerで動かすことからはじめようと思います。

## 開発環境

- os: macOSX Mojave
- macのdotnet: version 2.2.101
- docker: version 18.09.0

windowsではなくmacで開発を行います。
macでの開発に慣れているのでmacで開発します！
また、プロジェクトの作成などはmacで行います。
なので事前にmacに.NET Coreをインストールしています。
バージョンは上に示した通りです。

## プロジェクトの用意

まずは[こちら](https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-new?tabs=netcore21)の「ASP.NET Core 空」を作成します。
この時macで作成しています。

```console
$ dotnet new web
```

これで完成です。

## dockerの準備

次に`Dockerfile`を準備します。
[microsoft/dotnet](https://hub.docker.com/r/microsoft/dotnet)のコンテナを使用します。

```dockerfile:Dockerfile
FROM microsoft/dotnet

WORKDIR /app
COPY . /app
```

次に`docker-compose.yml`を作成します。

```yaml:docker-compose.yml
version: "3"
services:
  app:
    build: .
    container_name: "csharp-dotnet-server-docker"
    ports:
      - 5000:5000
    volumes:
      - .:/app
    command: ["dotnet", "watch", "run"]
```

特に特別なことはしていません。
 `command`を`["dotnet", "watch", "run"]`にしています。
こうすることでコードを編集した時に自動で変更を検知して、再ビルド・実行してくれます。
開発の際には便利なので、このようにしています。

次に`Program.cs`に`UseUrls("http://*:5000")`を追加します。

```csharp:Program.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace csharp_dotnet_server_docker
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseUrls("http://*:5000")  // <- ここの行を追加
                .UseStartup<Startup>();
    }
}
```

このようにすることで、localhost以外からのアクセスが可能になります。
[ASP.NET Core の Web ホスト # サーバーの URL](https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/host/web-host?view=aspnetcore-2.2#server-urls)

これで準備完了です。

## dockerを起動させる

ここからは普通にdocker composeを起動させます。

```console
$ docker-compose build
# build を待つ
$ docker-compose up -d
# 起動を待つ
$ docker logs csharp-dotnet-server-docker
watch : Polling file watcher is enabled
watch : Started
Hosting environment: Development
Content root path: /app
Now listening on: http://[::]:5000
Application started. Press Ctrl+C to shut down.
```

起動したら、ブラウザから`http://localhost:5000`にアクセスします。

![hello_net_core.png](https://qiita-image-store.s3.amazonaws.com/0/83495/0a12d0df-4c3a-382f-35d0-01c56ab4127e.png)

上のような感じで表示出来たら成功です。

完成したものは以下のリポジトリにおいてあります。

https://github.com/orange634nty/csharp-dotnet-server-docker

## 感想

かなり簡単にASP.NETのwebアプリケーションをdockerで動かことができました。
今後はwebフレームワークやDBを使った開発のサンプルを作ってみたいと思います。
hiveqlでのサンプリングの方法について

この記事は、MicroAd Advent Calendar 2018の17日目の記事です。
#はじめに
不均衡なデータを扱かう際に、データのサンプリングが必要になることがよくあります。
このような時、対象とするデータが小さい場合には分析するPCに必要なデータを全件持ってきてサンプリングすることが一般的です。しかし、対象とするデータが大きく、全件のデータを持ってくることができない場合には上記の方法は使えません。そのため、事前にサンプリングし、サンプリング後のデータを持ってきて利用することになります。
今回はこのような状況になった場合に、hiveで自由度高くサンプリングする方法を紹介したいと思います。
#方法
基本的な方法について説明したのちに、自由度の高い方法を紹介したいと思います。
##1.基本的な方法
hiveのTABLESAMPLEを利用する方法です。

```
-- 1.一定の割合、件数、容量分サンプリングする場合
SELECT *
FROM <source> TABLESAMPLE(0.1 PERCENT/　1000 ROWS/ 100M) source_alias;
-- 2.特定のカラムについてサンプリングする場合
SELECT *
FROM <source> TABLESAMPLE(BUCKET 3 OUT OF 32 [ON <colname>]) source_alias;
```

こちらを利用するメリットとしては、下記の点があげられると思います。

* サンプリングする意図が明確になりクエリがわかりやすくなる
* sourceのテーブルがBUCKETED TABLEの場合、上記２のサンプリング方式において処理が高速になる

一方でデメリットとしては、下記の点があげられます。

* サブクエリに対して適用ができない
* サンプリング前のデータに対してソートするなど、細かい調整ができない

##2.自由度の高い方法
[こちら](https://docs.microsoft.com/ja-jp/azure/machine-learning/team-data-science-process/sample-data-hive)などにも紹介がある手法のちょっとした拡張です。（リンク先の手法だとデータ件数が多くなった時に対応しきれません。window関数内のorder by部分でタイムアウトして落ちます。）
下記が自由度を高めた方法です。

```
SELECT
  *
FROM
    (
        SELECT
          *,
          ROW_NUMBER() OVER (PARTITION BY < colname >) AS key_rank,
          COUNT(1) OVER (PARTITION BY < colname >) AS upper_limit
        FROM
            (
                SELECT
                  *
                FROM
                  < source > 
                DISTRIBUTE BY < colname >
                SORT BY < colname >
            ) alias1
    ) alias2
WHERE
    key_rank <= upper_limit * < sample_rate >
```

抽象的な書き方をしているのでわかりづらいですが、上記クエリで埋めるべき部分は<>で囲われた部分になります。
[こちら](https://docs.microsoft.com/ja-jp/azure/machine-learning/team-data-science-process/sample-data-hive)との差分はwindow関数内のorder　byを排除するためにデータを前もってDISTRIBUTE BYとSORT BYを用いてソートしている部分になります。これにより、ある程度大きなデータも１クエリで自由度高くサンプリングできるようになります。
ただ、こちらの方法には、下記のようなデメリットがあります。

* 可読性が低い
* window関数を利用しているため大規模なデータに適用すると処理が重くなる

１つのクエリで書く必要がなく、基盤に空きのある場合は、中間BUCKETED TABLEを作成した上で基本的な方法を利用した方が処理が速くなるので、そちらを試した方がいいと思います。(BUCKETED TABLEの作り方は[こちら](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-BucketedSortedTables)から確認できます。)
#まとめ
今回、大きなデータをサンプリングする方法として、基本的な方法と自由度の大きな方法を紹介しました。
何かの参考にしていただけると嬉しいです。

最後に簡単な宣伝ですが、マイクロアドでは技術ブログを公開しています。下記のリンクから確認できますので、興味のある方は是非ご覧ください。
https://developers.microad.co.jp/
#参考
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Sampling
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-BucketedSortedTables
[PyTorch]不均衡データのを扱うための損失関数

# 不均衡データとは
正例と負例の比率が、**1:99**のように偏っているデータを不均衡データと呼びます。
全てのデータを負例と予測すれば精度は99%となるわけですが、PrecisionとRecallを考慮すると良くないモデルであることがわかります。

|              |Positive  |Negative  |
|---           |---|---|
|**True**      |0  |10  |
|**False**  |0  |990 |

```math
Precision = \frac{TP}{TP + FP} \\
Recall    = \frac{TP}{TP + FN}
```
上式より、Recall, Precisionともにゼロとなります。

# 対策

対策方針としては大きくふたつあります。
- トレーニングデータからのサンプリング方法調整 (アンダーサンプリング・オーバーサンプリング)
- 損失関数の中でクラスの重みを調整

今回は、損失関数の中でクラスの重みを調整する方法を紹介します。

```python
# [0,1]の二値分類タスクを解く想定
# 正例:1の発生頻度が少ないので、重みを付けたい

weights = torch.tensor([1.0, 100.0]).cuda()
cross_entropy_loss = nn.CrossEntropyLoss(weight=weights)
```

これだけです。簡単ですね。
PyTorchの損失関数に関する[公式ドキュメント](https://pytorch.org/docs/stable/nn.html#loss-functions)を見るとほとんどのメソッドにweight引数が設定されています。

不均衡データを扱っていてLossが減っているのにRecallが上がらない！という場合はぜひクラスの重みづけを検討してみてください。

以上です。
HoloLens用の注視入力-GazeSelector-をunitypackageにして公開しました 

#はじめに
今回の記事は去年のアドカレ「[HoloLensに注視入力を追加してみる～エアータップを使わないUIに挑戦～](https://qiita.com/decchi/items/b8afda3a756edec7f2c7)」の続編となります。
昨年度の記事では作ってみたところまでで終わってしまい、使うためにはそれなり手順が必要な状態でした。このUIは今年も複数のアプリで採用しており、未だ需要はそれなりにありそうなため、今回はそれを使いやすく改善しました（あと、このUIの名前をGazeSelectorとしました）。

#環境
- Unity 2017.4
- Visual Studio 2017
- MixedRealityToolkit-Unity 2017.4.1.0

（近い環境であれば大抵動くと思います）

#使い方
GazeSelectorは以下のリポジトリで公開してます。

https://github.com/decchi/GazeSelectorForHoloLens

GazeSelectorを使う手順は以下の通りです。
1. MixedRealityToolkit-Unityをインポート
2. GazeSelectorのunitypackageをインポート（[releases](https://github.com/decchi/GazeSelectorForHoloLens/releases)にあります）
3. GazeSelectorフォルダ内のDefaultCursorWithGazeSelectorのプレハブをシーンに追加します。
4. GazeSelectorの対象とするオブジェクトにGazeSelectorTarget.csをアタッチし、選択時にしたい処理をUnityEventとして登録します。

と、シンプルになるようにしてありますが、サンプルも用意しました。

#サンプルシーン
サンプルシーンはMixedRealityToolkit-UnitytとGazeSelectorがインポート済みの状態でGazeSelectorSampleのunitypackageをインポートすればよいです。 （これも[releases](https://github.com/decchi/GazeSelectorForHoloLens/releases)にあります）
インポートしたらHoloToolkitExtensionSampleのフォルダにあるGazeSelectorのシーンを開きます

開いた結果は以下です
![image.png](https://qiita-image-store.s3.amazonaws.com/0/60734/06770f81-d5a3-7dd7-8c36-93ea371d13b0.png)

シーンにはGazeSelectorが設定されたカーソルとターゲットとしてGazeSelectorTargetが設定されたオブジェクトが３つあります。
Cubeには青色に変更する、Sphereには緑色に変更する、Capsuleには非表示にするようにUnityEventを登録してあります。
Cubeは例として以下のように設定してあります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/60734/c8916a4b-0c92-442d-085a-bcc591db051d.png)

そのまま動かすとこんな感じになります。
![GazeSelectorでも.gif](https://qiita-image-store.s3.amazonaws.com/0/60734/b3882d85-a875-c627-a730-0de924aea5b8.gif)

#おわりに
HoloLensのジェスチャーは初見の方には特に難しい操作です。3Dモデルを見るだけのコンテンツであればGazeSelectorで置きかえれる部分も多いと思います。もし、この記事を読んで頂いて使えそうだなと思っていただけたら幸いです。これからもHoloLensの開発が楽になるツールを作って公開していきたいと思います。
【設計時の見落とし】関連項目値の変更について

# はじめに
これは[設計時の見落とし Advent Calendar 2018](https://qiita.com/advent-calendar/2018/overlook)の16日目の記事となります。

業務アプリケーションの設計をするときに、見落としがちなところに焦点をあてて紹介します。 
下流工程からの手戻りを少なくして 双方の負担を減らしましょう。

業務用アプリケーションを作成していると、受注入力画面などヘッダー部と明細部が一緒になっている画面が多いです。 
簡易な例としては、ヘッダー部に請求先コードを入力し、明細部に数量、単価、金額などの項目があるとかです。

# 自動計算項目が入力可能
明細入力などで、数量、単価、金額の項目があり、金額項目は「数量ｘ単価」として自動計算でセットします。
一般的には自動計算する項目は入力不可となっている場合が多いです。
しかし、ユーザーの要望で金額を手動で調整出来るように入力項目になることがあります。 

|数量|単価|金額| 
|--:|--:|--:|
|5|100|500|

## 問題点
自動計算された金額を訂正後に数量または単価を変えた場合、手動で入力した金額が書き換わってしまう。※システム的に金額が重要値とする。

|数量|単価|金額|コメント| 
|--:|--:|--:|:--|
|5|100|500|  |
|5|100|550|金額を訂正|
|6|100|600|書き換えた金額が訂正されてしまう。|

この問題点を良しとするか悪いとするかは、ユーザーとの確認が必要となります。

## 対応
当時の対応では、金額が 0 の場合に自動計算した結果をセットする仕様となりました。
他にも、再計算ボタンを用意して再計算させる方法もあります。

# 関連項目値の変更
請求先コードをキーに請求先マスタを参照し、端数区分(切り上げ、四捨五入、切り捨て)を取得します。
そして、明細入力の金額を自動計算(数量ｘ単価)する際の端数処理として使用します。

## 問題点
明細を何件か入力後にヘッダー部にて先ほどとは違う請求先コードに変更した場合、端数区分が「四捨五入」から「切り捨て」など違う場合があります。
では、その時に入力されている明細の金額についてはどうするべきなのか？

1. 何もしない
2. 自動計算
3. 明細をクリアーする

などなど
※請求書コードを変更する段階で確認メッセージを出力するものとする

### 端数区分「四捨五入」
|日付|個数|計算|端数処理|結果|
|:--|:--|:--|:--|:--|
|11/2|5個|5 x 20.5 = 102.5|四捨五入|103|
|11/3|5個|5 x 20.5 = 102.5|四捨五入|103|
| |  | |**計**|**206**|

### 端数区分「切り捨て」
|日付|個数|計算|端数処理|結果|
|:--|:--|:--|:--|:--|
|11/2|5個|5 x 20.5 = 102.5|切り捨て|102|
|11/3|5個|5 x 20.5 = 102.5|切り捨て|102|
| |  | |**計**|**204**|

自動計算の選択した場合は再計算しますが、先述した自動計算項目が入力可能項目になっている場合には書き換えてしまう問題があります。
明細をクリアーするとなると、ユーザーが明細を再入力し直しとなってしまいます。
何もしないとすると、計算が合わなくなる問題がありえます。

# 端数処理の仕方
販売管理系システムの場合など請求先または支払先ごとに計算方法の指定がある場合がほとんどです。
よくあるのは消費税計算で、明細単位、請求単位、請求明細単位、合計請求単位などがあります。

## 問題点
明細毎に端数処理するのか明細集計後に端数処理するのかによって誤差が発生します。

### 明細毎に端数処理
|日付|個数|計算|端数処理|結果|
|:--|:--|:--|:--|:--|
|11/2|5個|5 x 20.25 = 101.25|四捨五入|101|
|11/3|5個|5 x 20.25 = 101.25|四捨五入|101|
| |  | |**計**|**202**|

### 明細集計後に端数処理
|日付|個数|計算|端数処理|結果|
|:--|:--|:--|:--|:--|
|11/2|5個| | | |
|11/3|5個|(5+5) x 20.25 = 202.5|四捨五入|203|
| |  | |**計**|**203**|

このように集計レベルによる端数処理により誤差が出るため、仕様者およびユーザーに確認が必要となります。

# 最後に
このように関連する項目が変更された場合、幾つかの方法が考えられるわけですが、詳細設計書上にその旨の記述があったことがなかなかありません。
かといって、共通仕様書上にあるのかというと無いわけです。そうすると、たいがい指摘するはめになります。
Django のカスタムコマンドの作り方

カスタムコマンドの作り方です。
次のページを参考にしました。
[How to Create Custom Django Management Commands](https://simpleisbetterthancomplex.com/tutorial/2018/08/27/how-to-create-custom-django-management-commands.html#basic-example)

次のようにユーザーがある状況で　カスタムコマンドでユーザー一覧を表示してみます。
![users_dec15.png](https://qiita-image-store.s3.amazonaws.com/0/179446/b1b769c2-fa42-2883-527c-5d6b60af77e2.png)

プロジェクト　proj01
アプリ　home
とします。

１）まず、コマンドを入れるフォルダーを用意します。

```bash
mkdir home/management
mkdir home/management/commands
```

2) 時刻を表示するコマンドを作成してみます。

```py:home/management/commands/what_time_is_it.py
from django.core.management.base import BaseCommand
from django.utils import timezone

class Command(BaseCommand):
    help = 'Displays current time'

    def handle(self, *args, **kwargs):
        time = timezone.now().strftime('%X')
        self.stdout.write("It's now %s" % time)
```

実行します。

```bash
python manage.py what_time_is_it
```

実行結果

```text
$ python manage.py what_time_is_it
It's now 11:53:25
```

3) ユーザー一覧のコマンドを作成します。

```py:home/management/commands/list_users.py
from django.core.management.base import BaseCommand
from django.contrib.auth.models import User

class Command(BaseCommand):
	def handle(self, *args, **kwargs):
		for user in User.objects.all():
			print(user.id,"\t", end="")
			print(user.username,"\t", end="")
			print(user.email)
```

実行します。

```bash
python manage.py list_users
```

実行結果

```text
$ python manage.py list_users
1 	admin 	test@test.com
2 	test01 	
3 	test02 	
4 	test03
```
Pythonでdocomoの音声合成APIを利用する

# はじめに

docomoの音声合成APIには、日本語の声のパターンが一通り揃っています。
今回はPythonから喋らせたい内容をAPIに叩いて、帰ってきた結果を音声ファイルとして保存して再生することにしました。このシステムだと何度も同じ内容を喋らせる際に、処理を早く済ませられます。

# 事前準備

あらかじめAPIキーを取得しておいてください。私は[こちら](https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=text_to_speech&p_name=api_7#tag01)のAPIを利用しましたが、他にもいろいろあります。

# コード

他の機能と組み合わせて作ったので、喋らせる部分だけ抜粋しました。
関数は、talk(音声ファイルのタイトル, 喋らせたい文字列)となっています。

```python:talk.py
import os
import requests
import json

#引数で指定した文字列を再生する
def talk(title, message, path="./"):

    if not os.path.isfile(path+title+".wav"): # 既に音声ファイルがあるかどうかを確認する
        url = 'https://api.apigw.smt.docomo.ne.jp/crayon/v1/textToSpeech?APIKEY=2e6d4e6b645342562f6858396b59634d626a6a356d79424a6b43433654386f4558656d76676a7242336344'

        params = {
              "Command":"AP_Synth",
              "SpeakerID":"1",
              "StyleID":"1",
              "SpeechRate":"1.15",
              "AudioFileFormat":"2",
              "TextData":message
            }

        r = requests.post(url, data=json.dumps(params))
        if r.status_code == requests.codes.ok:
            wav = r.content
            with open(path+title+".wav","wb") as fout:
                fout.write(wav)

	# APIでエラーが発生し、音声ファイルが生成されないときのため
    if os.path.isfile(path+title+".wav"): 
        char = "aplay {}{}.wav".format(path, title)
        os.system(char)

try:
    while True:
        
        #中略
        
        #画像認識の結果からデータベースを検索しその内容（説明文）を喋らせる
        talk(result,desc)
```
Ubuntu 18.04.1 LTSにdockerをインストール

```
$ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common

$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
OK
$ sudo apt-key fingerprint 0EBFCD88
pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [ unknown] Docker Release (CE deb) <docker@docker.com>
sub   rsa4096 2017-02-22 [S]
 
$ sudo apt-get install -y docker-ce
$ docker version
Client:
 Version:           18.09.0
 API version:       1.39
 Go version:        go1.10.4
 Git commit:        4d60db4
 Built:             Wed Nov  7 00:49:01 2018
 OS/Arch:           linux/amd64
 Experimental:      false
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.39/version: dial unix /var/run/docker.sock: connect: permission denied
$ sudo usermod -G docker -a saru
```

## 参考

[Ubuntuにdockerをインストールする - Qiita](https://qiita.com/tkyonezu/items/0f6da57eb2d823d2611d)
東大五月祭でARKitを用いたネットワークゲームの展示をした話

#はじめに

どうもみなさんこんにちは．これは[U-TOKYO AP Advent Calendar 2018](https://qiita.com/advent-calendar/2018/ut_ap) の25日目の記事です．

僕は東京大学計数工学科B4のDipというものです．
クリスマスですね．いかがお過ごしですか．独り身エンジニアですか？リア充エンジニアですか？僕はクリスマスに記事を書いているなぞなぞエンジニアです．

東京大学五月祭工学博覧会という学科同期でいろんな出し物をしようというコーナーがあるのですが，僕はそこで画像処理班としてARの街づくりゲームを出していました(半年以上前)

引き継ぎのついでに書いています
#作ったもの
動画を見てもらった方が早いと思います...ARを使った街づくりゲームを展示しました。
https://twitter.com/dipukamin/status/996741589031469057
このデモではソロプレイをしていますが、本番ではマルチプレイでみんなで街づくりする感じになっています。
ここでは実際にUnityでどのような実装をしたのか書いていきます

#開発環境
・MacbookPro(2017) 15inch
・iPad(2017~)
・Unity 2018.1beta
基本的には、Macであり、Unityが動かせれば大丈夫です。

#実装に用いたライブラリ
##AR
ARについては、ARKit1.5を使いました。(Swift諦めた勢)
https://bitbucket.org/Unity-Technologies/unity-arkit-plugin/downloads/?tab=branches
ここから最新のブランチをダウンロードしてUnityに入れれば大丈夫です。
ARKitの機能としては、以下の機能を使いました。
・トラッキング(いわゆるSLAM)
・ワールドアンカー(任意のtransformに原点を設定する)
・画像認識

平面認識もできれば使いたかったのですが、別々のデバイスで別々の平面を作ってしまうのは共有上あまり意味がないし、共有するのがめんどくさいので諦めました。

#具体的な実装
##AR街づくり機能
ここに関してはあまり大したことはしていません．世の中にはARkitの使い方の記事がポロポロと出ているので，その辺を参考にしました．ARkitでは使うゲームオブジェクトとスクリプトの配置さえできていれば通常の３Dゲームと同じように動かせます．その辺はサンプルシーンからコピーすればいいと思います．
街づくり機能においては，建物を建てる，移動，回転，拡大縮小を行うの2機能をメインとして実装しました．建物を建てる機能においては，メニュー画面から建物を選択し，建てたい場所をタップしてもしその場所に地面があればその場所に建物が出現します．一度建てた建物をタップすると座標変更系のメニューが出現します．移動を選択するとタップした場所に移動，回転を選択すると建物が回転します．一度建てた建物は5分経つと消失するが，いいねボタンを押すと延長することができます．
この辺の機能は，UIを作ってメニューを選択したら編集モードになり，タップした点から地面に向けてRayCastを打って衝突判定をして．．．等をスクリプトに書いて実装しました．普通の３Dゲームを作るのとだいたい一緒の発想です．ただ，ARKitにおいてはスケールを普通の1/10で扱わないといけないのでタップの速度などをうまいこと調整しないと建てた建物が遥か遠くに吹っ飛びます．

##ネットワーク機能
この辺が一からの勉強だったので一番しんどかった気がします．ネットワークの実装にあたってはUNETとういうUnity用の高レベルAPIを使いました．UNETはローカルLANで動かす向けで，あまりオンラインゲームでは見ない気がします．というかUNET廃止されるらしいですね．
UNETの勉強はhttp://edom18.hateblo.jp/entry/2017/05/30/120811
などのサイトを参考にしました．結構慎重に読み込まないと詰みます．
サーバとクライアントですが，サーバにはMacbook Proを使用しました．iPadだけでは重い処理をこなすのに限界があるので，重い処理はすごく頭のいいパソコンに投げてこなしてもらうことで出来るだけiPadのFPSを上げます．
基本的な流れですが，ローカルなオブジェクトなのか共有するオブジェクトなのかしっかり分けます．
例えば，ローカルなオブジェクトなら
・UI
・カメラ
共有するオブジェクトなら
・建物
・地面の状態
等があります．ローカルなオブジェクトはそこまで苦労しなかったですが，共有するオブジェクトは必ず
```クライアントがアクションを起こす→サーバにアクションを送信→サーバからアクションの実行命令を送る
```

という流れを守るようにします．これを守らないとちゃんと共有されなかったりエラーを吐きます．例えば建物の位置を変更したい時，
```クライアントがサーバに建物を移動する権限を問い合わせる→サーバは誰もその建物を操作していなかったらクライアントに権限を付与する→クライアントは操作が終了したら権限を放棄する
```

という流れが必要です．クライアントから変更する位置を送りつけてサーバから変更命令を出してもらうこともできないことはないのですが，いちいちサーバーを介しているとめちゃくちゃ遅いです．10FPSくらいしか出ませんでした．クライアントとサーバで作業を同期させるためには権限がすごく大事になってくるという話でした．

##ワールド共有
せっかくのマルチプレイですからきちっと各プレイヤー間の座標を共有させたいものです．プレイヤー間で共有させるにあたっていくつかアプローチはあるのですが，僕は一番簡単（だと思われる）な方法を取りました．

ARKitには画像を認識してその画像の位置と回転を取得する機能，そして指定したtransformを原点に設定する機能があります．画像をマーカーとして設置しておいてそのtransformを取得し，そのtransformからの差分をクライアントの座標とすることで全クライアントのワールド座標を合わせることができます．画像を認識するのはこの座標合わせ1回でしか使わないので，ゲームをプレイしているときにずっと画像を画面に収めていなくてもちゃんとゲームができるのが魅力的ですね．

ほんとは全部マーカーレスにしたかったんですが，GPSがミリ単位の精度になるまで進化しなかったりiPadが常に自分の座標の差分を計算しない限りは実現しません．どれくらい先の未来に実現するんでしょうか...

#終わりに
五月くらいの記憶を無理やり手繰り寄せて書いたのでかなり適当になってしまいました...アンカーがこんなんでいいのか...
モダンなWebアプリ開発に必要なツール10選

MacBookProにWebアプリ（Vue.js）の開発環境を構築するにあたりインストールしたツール一覧

# 仕事
- [Google Chrome](https://www.google.com/intl/ja_ALL/chrome/)
  - 言わずと知れた高速で高機能なブラウザ
  - デベロッパーツールを使えばJSのデバッグやHTMLの解析を簡単に行える
  - プラグインをインストールすれば機能拡張も可能

- [Slack](https://slack.com/intl/ja-jp/)
  - チャットツールのデファクトスタンダード
  - チーム開発でコミュニケーションをとるときに重宝します
  - アプリ連携をすればGitHubからの通知も受信できます

- [Evernote](https://evernote.com/intl/jp)
  - メモ管理アプリの定番
  - 情報収集した内容をWebクリップで保存・検索できる
  - コードはgist、情報はEvernoteと使い分けるのが良いかも

# 開発
- [Visual Studio Code](https://code.visualstudio.com/)
  - Microsoft製テキストエディタ
  - 様々な言語に対応している
  - プラグインを追加することで機能拡張が可能

- [GitHub Desktop](https://desktop.github.com/)
  - GitHubを使った開発を簡単に行えるアプリケーション
  - クローンやコミットなどGUIで操作できる

- [TeamSQL](https://teamsql.io/)
  - DB接続のクライアントツール
  - メジャーなDBに対応しているため複数のクライアントを一つに統合できる

- [Node.js](https://nodejs.org/ja/)
  - サーバーサイドのJavaScriptプラットフォーム
  - JavaScriptで動くWebアプリを開発するなら必須
    - Ex. Vue.js、Angular、React

- [Yarn](https://yarnpkg.com/lang/ja/)
  - JavaScriptパッケージ管理ツール
  - Node.jsをインストールすればnpmが入ってますが、個人的にはYarnが好きなのでこちらで管理しています
    - パッケージがキャッシュされるのでインストールが高速といったメリットがあります

# インフラ
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
  - 最近はCloud Nativeの気運が高まっているためWebアプリをコンテナ化するなら必須でしょう
  - 仮想環境にDocker環境を構築するよりも簡単にコンテナを動かせます

- [Kitematic](https://kitematic.com/)
  - GUI上でDockerを操作できるツール
  - 簡単にpostgreSQLなどを起動できる
GCP未経験者が1ヶ月でGoogleCloud認定資格「Associate Cloud Engineer」を取ってみた

# はじめに
自分のパブリッククラウド歴はAWS5年・Azure2年を緩く、GCP未経験。
仕事でGCPを触ることになりそうだったので、体系的に学びたくGoogle Cloud 認定資格「Associate Cloud Engineer」を受験してみた。

# Google Cloud 認定資格
2018/12/16時点で下記5つある。参考：[Google Cloud Certified](https://cloud.google.com/certification/)

|資格名|受講料(米ドル)|
|---|---|
|G Suite|75|
|Associate Cloud Engineer|125|
|Professional Cloud Architect|200|
|Professional Data Engineer|200|
|Professional Cloud Developer|200(β期間中は120)|

G Suiteは毛色が違うので除くと、「Associate Cloud Engineer」が入門編の立ち位置にあるのでターゲットとした。

# 学習方法
## 本を読んだ
[Google Cloud Platform エンタープライズ設計ガイド](https://www.amazon.co.jp/dp/4822257908)

良著。
特徴としてはWhy（なぜGCPが生まれたか？なぜ○○サービスが生まれたか）とWhat（GCPで何ができるか？○○サービスで何ができるか）に特化していて、How（具体的な操作手順）がほぼない。
AWSとの比較が多く、AWS経験者であればこれを一冊読むだけで「GCPとは何か」・「GCPで何ができるのか」・「AWSとどう違うのか」が理解できると思う。
GCPはサービス数がAWSに比べて少ないため、現時点（2018/12）でのサービスをほぼ網羅できている。

## Qwiklabsのハンズオンをオンラインで受講した
[Qwiklabs](https://google.qwiklabs.com/)

Google公式のオンラインハンズオン。
本でWhy、Whatを学んだのでHowを習得するために受講した。
GCPの公式から飛ぶと英語版しかないようで不安になるが、アカウントを作ってログインすると日本語のコースが用意されていた。
資格に対して受講するクエストが明確になっており、「Associate Cloud Engineer」の対象は[GCP の基礎](https://google.qwiklabs.com/quests/23)と[クラウド アーキテクチャ](https://google.qwiklabs.com/quests/24)の2つで、全て受けると$80強でかかった時間は10時間程度。
各クエストを受講するとGCPの使い捨てアカウントのようなものが発行され、時間内は使い放題というシステム。
クエスト通りに進めていくと各サービスのブラウザコンソールからの使い方とgcloudを用いたターミナルからの使い方を一通り学べて理解できる。

## 模擬試験を受けた
[Associate Cloud Engineer 模擬試験](https://cloud.google.com/certification/practice-exam/cloud-engineer)

無料で受けられる20問強の模擬試験。
何度受けても同じ問題だったのは残念だが、AWS資格の模擬試験と異なり点数だけでなく設問に対する解説があるのは良かった。
ただ、例によって本番の試験のレベルより低かったので最低ラインと捉えるべき。

# 受験結果
合格。
同じく入門編の[AWS認定 Cloud Practitioner](https://aws.amazon.com/jp/certification/certified-cloud-practitioner/)と比べると知識だけを問う問題が少なくケーススタディに関する実践的な設問が多かったと思う。
この勢いで次の資格も取ろうと思うがソフトウェアエンジニア向けの「Professional Cloud Developer」はまだβ版で受講料は格安となっているものの、対象ハンズオンや模擬試験が無く試験も英語版しかない。
「Professional Cloud Architect」が現実的か。

# まとめ
「Associate Cloud Engineer」の資格取得にあたり、順序良く学習していくことで効率的に体系的な知識とスキルが習得できたと思う。
[AWS認定 Cloud Practitioner](https://aws.amazon.com/jp/certification/certified-cloud-practitioner/)の公式学習コースとしては[AWS Cloud Practitioner Essentials](https://aws.amazon.com/jp/training/course-descriptions/cloud-practitioner-essentials/)という無料デジタルトレーニングで体系的に学べてさすがAmazonと思ったが、GCPではより実践を重視したハンズオン形式の学習過程になっていてさすがGoogleと感じた。
サービスが増えすぎて全体のキャッチアップが難しくなってきたAWSに比べて、GCPはGoogleのベストプラクティスをユーザーに提供するというスタンスでサービス数が抑えられており使いやすい。
今後は仕事でもプライベートでも積極的にGCPのサービスを活用していこうと思う。

# 受験時に参考にした記事
- [Google 認定資格「Associate Cloud Engineer」を受けて来た！](https://qiita.com/bee3/items/19628d54112d9eb875c2)
- [【記録】Associate Cloud Engineer 試験に合格](https://qiita.com/sky0621/items/d0721390aa4120f22275)
- [[GCP] Associate Cloud Engineer 合格メモ](https://qiita.com/ao_log/items/1fad7bec286c4d908d4b)
LINE ClovaでSDKなしでオーディオファイルを再生する

ごきげんよう

この記事は
**「するめごはんのVUI・スマートスピーカー Advent Calendar 2018」**
の16日目の記事です。

今回はClovaの話です。

LINE Clovaでスキルを作成する時、SDKを用いることは多いと思います。

けれども、SDKがなくとも自分でJSONを作成してしまえばスキルを作成できます。

このアドベントカレンダーの10日目の記事
https://qiita.com/surumegohan/items/e2488b5eee4c1bd5bfe8

にも記載している、この本からスタートするとClovaのスキルを動かすことが非常に素早くできます。

![DSC_1826.JPG](https://qiita-image-store.s3.amazonaws.com/0/67398/fc5740bd-5213-2a39-f10f-3c5af8470483.jpeg)

#Clovaのテキストスピーチは本に書いてある

上記の本には既にAPI GatewayとLambdaを使って挨拶をするスキルの作り方、および、ソースコードが記載されておりダウンロード可能です。

#ほぼ同様の記述でオーディオファイルを再生する

音声ファイルとしてmp3を作っておいて、例えばAWSならそのままS3に置いておくとします。

```javascript:オーディオ再生するコード

'use strict';

exports.handler = function (event, context, callback) {
    var response = {
        statusCode: 200,
        headers: {},
        body: ""
    };
    
    var speechText = "";
    var requestJson = JSON.parse(event.body).request;
    var endFlg = false;
    
    if (requestJson.type === 'LaunchRequest') {
        // 起動時処理
        speechText = 'https://s3-ap-northeast-1.amazonaws.com/起動時に再生したいオーディオファイル.mp3';

    } else if (requestJson.type === 'SessionEndedRequest') {
        // セッション切れ
        speechText = 'https://s3-ap-northeast-1.amazonaws.com/セッションが切れたら再生したいオーディオファイル.mp3';
        endFlg = true;
    
    } else if (requestJson.type === 'IntentRequest') {

        if (requestJson.intent.name === 'EndIntent' || requestJson.intent.name === 'Clova.NoIntent') {
            // 終了処理
            speechText = 'https://s3-ap-northeast-1.amazonaws.com/終了時に再生したいオーディオファイル.mp3';
            endFlg = true;
        
        } else if (requestJson.intent.name === 'Clova.GuideIntent') {
            // ヘルプ用
            speechText = 'https://s3-ap-northeast-1.amazonaws.com/ヘルプの時に再生したいオーディオファイル.mp3';
            
        } else if (requestJson.intent.name === 'HelloIntent') {
            
            speechText = 'https://s3-ap-northeast-1.amazonaws.com/ハローと言われたの時に再生したいオーディオファイル.mp3';

        } else if (requestJson.intent.name === 'MorningIntent') {
            
            （略）
    }

    var responseJson = JSON.stringify({
        "version": "1.0",
        "response": {
            "outputSpeech": {
                "type": "SimpleSpeech",
                "values": {
                    "type":"URL",　//ここを「URL」にする
                    "lang":"ja", //ここはjaである必要すら本当はない
                    "value": speechText
                }
            },
            "card": {},
            "directives": [],
            "shouldEndSession": endFlg
        }
    });
    
    response.body = responseJson;
    
    callback(null, response);

};


```

要するに、JSONを組み立てられればそれでOKなわけです。

実際に公式のSDKのコードを読めばすぐに気づきます。
https://github.com/line/clova-cek-sdk-nodejs

ド直球に言うと以下で気づくことができます。
https://github.com/line/clova-cek-sdk-nodejs/blob/master/src/speechBuilder.ts

#まとめ

Clovaに限らず、要するにJSONが組み立てられればそれで良くて、SDKはJSONの生成をわかりやすく補助するためのものでしかありません。

それは他のプラットフォームでも、もっというとどんなアプリやサービスでも、対応するプロトコルに合えばそれでいいのです。

#後から気づいたおまけ

本の著者がそのまま書いてるじゃん・・ｗ

https://qiita.com/h-takauma/items/9162aebe42e358538442
いまさらAdobe AIRでアプリ内課金実装

大分前にAdobeAIRでアプリ内課金を実装したんですけど、流石に今頃書くのもどうかなぁと思いつつ、やっぱり書くことにしました。iOSかつ一番簡単な非消耗型です:expressionless:

#1.App Store Connectで必要な設定周りを行う。
ここらへんは他言語と変わらないので適当にググって下さい。アイテム登録だけでなくSandboxテスター登録もしましょう。

# 2.ANEを調達する
ここが難問。安牌とされているのは[Milkman Games](https://www.milkmanplugins.com/ios-in-app-purchase-air-ane)のANEですが有料です。何とか無料で出来ないかフリーのやつ試したりとか模索していたのですが、結局Adobe公式のGamingSDK内にあるアプリ内課金用のANE(productStore.ane)になりました。
ただ公式に普通に置いてあるのは（多分まだ）32bit版のままで今となっては使えません。[公式フォーラム](https://forums.adobe.com/thread/1679953)とか[64bit対応の告知記事](https://www.adobe.com/devnet/air/articles/gaming-sdk-anes-64-bit-support.html)から64bit版を落としてください。

# 3.実装する
後はパブリッシュ設定からANEを組み込み、SDKに同梱されてるリファレンス（英語）を読みながら実装します。上記で64bit版を落としなさいと指示しといてなんですが、リファレンスは32bit版にしかついてないので結局両方落とした方がいいっていう:sweat_smile:　ANEのクラスのメソッド名等、ほとんどネイティブに被せてあるので、他言語の実装ガイドを見ながらやれば大丈夫かと。

* 注意事項
    * トランザクション内のレシート（検証用にトークンみたいな文字列入ってるやつ）と、レシート検証で帰ってくるレシート（Appleが仕様公開してるやつ）は別物なので注意
    * 購入してない時に復元すると、SUCCESSもFAILも飛ばずにいきなりCOMPLETEが呼ばれるというトラップがあるので注意
    * 復元時にレシートプロパティが空になってしまう。
        * 本来はレシートもついてくるっぽいんですが、ANEが処理しきれずreceiptプロパティが空文字だったりnullだったりします。
            * このため復元はトランザクション内の商品idを元にするしかありません。

参考:
[ANE でアプリ内課金（In App Purchase）を Flash CC (Animate CC) で導入する手順](http://note.pandako.com/2016/03/ane-in-app-purchase-flash-cc-animate-cc.html)
他多数
H2O のインストール手順

見つけたのでメモ

# 前提条件
CentOS7にインストール

# 手順
1. リポジトリ情報を登録する

    ```
    # vi /etc/yum.repos.d/bintray-tatsushid-h2o-rpm.repo
    ```
    
    ```bintray-tatsushid-h2o-rpm.repo
    #bintray-tatsushid-h2o-rpm - packages by tatsushid from Bintray
    [bintray-tatsushid-h2o-rpm]
    name=bintray-tatsushid-h2o-rpm
    #If your system is CentOS
    baseurl=https://dl.bintray.com/tatsushid/h2o-rpm/centos/$releasever/$basearch/
    #If your system is Fedora
    #baseurl=https://dl.bintray.com/tatsushid/h2o-rpm/fedora/$releasever/$basearch/
    gpgcheck=0
    repo_gpgcheck=0
    enabled=1
    ```

2. yum コマンドでインストールする

    ```
    # yum install h2o
    ```

# 参考
- [公式ドキュメント - Install](https://h2o.examp1e.net/install.html)
- [H2O Unofficial RPM package builder](https://github.com/tatsushid/h2o-rpm)
Heroku のアドオンを自作する方法を見てみた

あまり試せていないですが、Heroku のアドオンの作り方についての情報が少なかったので、ざっと調べられる範囲で書いてみました。

# はじめに
Heroku のアドオンは次の条件を満たしている必要があるんだそう

1. HTTPSのリクエストを受信できること
2. JSONをパースすることができる

# アドオンパートナーに登録する
Herokuのアドオンを作るためにはアドオンパートナーになる必要があるため、次の手順を行います

1. Herokuの無料アカウントを作成
2. addons-next.heroku.com にアクセス
![Herokuパートナーポータル.png](https://qiita-image-store.s3.amazonaws.com/0/34297/0d8fa314-5b28-eea0-847b-6a5352349035.png)

3. 規約に同意するよう求められるので、内容を確認してAcceptボタンをクリック

これでパートナーポータルの画面に遷移することができます。

# 手順
ここからアドオンの開発手順に移っていきます。

1. addon-adminプラグインをインストール

    ```
    $ heroku plugins:install addons-admin
    ```

2. addon-adminプラグインを使用してマニフェストファイルを作成

    ```
    $ heroku addons:admin:manifest:generate
    Input manifest information below: 
    ? Enter slugname/manifest id: my-addon
    ? Addon name (Name displayed to on addon dashboard): MyAddon
    ? Choose regions to support
      <space> - select
      <a> - toggle all
      <i> - invert all 
      ↑↓ use arrow keys to navigate
     tokyo
    ? Would you like to generate the password and sso_salt? Yes
    ? This prompt will create/replace addon-manifest.json. Is that okay with you? Yes
    Generating add-on manifest... done
    The file addon-manifest.json has been saved!
    ```

3. Add-on Partner APIを使用してアドオンインスタンスの作成・追加・削除などの実装を行う
4. 次のコマンドでアドオンをプッシュする

    ```
    $ heroku addons:admin:manifest:push
    ```

だいぶアレですが、ざっくりだとこんな感じみたいです。
以前は Provider API というものを使っていたみたいですが、今だと名前が変わっていました。
また、2018年4月からAdd-on Partner API のバージョンも変わっているみたいでした。

# 参考
- [公式ドキュメント - Building an Add-on](https://devcenter.heroku.com/articles/building-an-add-on)
- [公式ドキュメント - Add-on Manifest](https://devcenter.heroku.com/articles/add-on-manifest)
- [公式ドキュメント - Add-on Partner API Reference](https://devcenter.heroku.com/articles/add-on-partner-api-reference)
- [heroku/heroku-cli-addons-admin
](https://github.com/heroku/heroku-cli-addons-admin)
- [heroku/addon-template](https://github.com/heroku/addon-template)
Visual Studio Codeでメモ帳！ (拡張機能VS Notesについて)

# はじめに
Visual Studio Code(以下VSCode)をよく使ているのですが、
メモもできたら、一つの環境でできていい感じだなと思っていました。
いい感じのメモ用拡張機能VSNotesがあると知ったので、それの導入・使い方をまとめます。
下のページで紹介されていたので、自分自身の導入までの流れを整理します。

 - https://www.karelie.net/vscode-notes/

# 環境
- Windows 10
- Visual Studio Code 1.30

# 入れ方
![vs-install_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/202955/eed74e4c-5718-21d4-56a5-c2ec14552c70.jpeg)

拡張機能であるVSNotesを入れる
入れると、左のリストにノートっぽいアイコンが追加される

\#再起動は適宜

![vs-install_2.jpg](https://qiita-image-store.s3.amazonaws.com/0/202955/1bd616b6-1a73-1bbd-5e79-a9c998f504be.jpeg)

[F1]キー=>ウィンドウに[VS Notes: Run setup]
でディレクトリを選択
右下に
[Welcom to VSNotes. To begin, choose a location to save your notes Click Start to continue ->]

と出るので、[start]を押すと、
見慣れたWindowsのエクスプローラーが出てくるので、ディレクトリを選択すれば設定完了

選んだディレクトリの中にマークダウン(md)形式のファイルを入れるだけでOK

# 使い方
## 基本的な使い方
ファイルは先ほど選んだディレクトリ直下に `*.md` で入れればOK
タグ機能もあり、

```
---
tags:
 - Qiita投稿
 - VS Code
 - Visual Studio Code
---
```
のように先頭に記載すれば`Tags`内に表示することも可能
## おすすめする点
### Markdownのプレビュー
[F1]キー=>ウィンドウに[Markdown : Open Preview]と入れるとプレビューが見れるので、便利。

### ノートの生成
[F1]キー=>ウィンドウに[VSNote : Create a New Note]と入れると新規でノートさ作成されて、便利。

ほかにも[F1]でタグ一覧取得やフォルダ生成ができるので、触ってみるといいかも

## うーんな点
 - 自動でファイルリストやタグが更新されない。
 - スマホでは見れない
    - Google Driveとかと連携したら可能かもしれないが...
 - タグが階層化出来たらうれしいのにな… 

# 終わりに
VScodeはいろいろできるんだねと感じる今日この頃。
メモ帳専用のものに比べると足りない点はあるが、VSCodeで完結したいならおすすめです。
ちなみにこの記事もVSCodeで書いてからこちらに移したものです。
\#Markdownのフォーマットがちょっと違うので、修正はしましたが...

MacでもUbuntuでもWindowsでも動くエディタは貴重なので、
VSCodeをもうちょい使いこなしたいと思う。

# 参考
 - https://www.karelie.net/vscode-notes/
    - この記事であること知りました。
 - https://marketplace.visualstudio.com/items?itemName=patricklee.vsnotes