OmniAICreator/Qiita-1.07M huggingface dataset:
Jenkins-SlaveでUnitTestがOutOfMemory

# 前提
- JenkinsはMaster-Slave環境にしている。
- Jenkins側でJUnitのテストを実施している。
- Gradleを利用。

# 問題
Jenkins側でUnitTestが終わらないという報告を受ける。ローカルで実行すると問題ないのとこと。JenkinsfileでTimeoutの設定をしているので、暫定対処としてそれを伸ばしてみたがそれでも解決しない。

Jenkinsのログを見ると、

```
Caused by:
            java.lang.OutOfMemoryError: GC overhead limit exceeded
```
だったり、

```
 java.lang.OutOfMemoryError: Java heap space
```

みたいなログが出てる。

# 解析
topで見たところ、以下のプロセスがCPU負荷が高い。


`jenkins  23101 22201 99 18:54 ?        00:06:34 /usr/java/jdk1.8.0_144/bin/java -Djava.security.manager=worker.org.gradle.process.internal.worker.child.BootstrapSecurityManager -Dorg.gradle.native=false -javaagent:build/tmp/expandedArchives/org.jacoco.agent-0.7.10-SNAPSHOT.jar_xxxxxx/jacocoagent.jar=destfile=build/jacoco/test.exec,append=true,inclnolocationclasses=false,dumponexit=true,output=file,jmx=false -Dfile.encoding=UTF-8 -Duser.country=JP -Duser.language=ja -Duser.variant -ea -cp /xxxxx/gradle-worker.jar worker.org.gradle.process.internal.worker.GradleWorkerMain 'Gradle Test Executor 1`

# 原因判明！

http://kitaru.hatenadiary.com/entry/2014/09/03/Java%E3%82%A2%E3%83%97%E3%83%AA%E3%81%8C%E6%9A%B4%E8%B5%B0%E3%81%97%E3%81%A6CPU%E3%81%8C%E6%AD%BB%E3%82%93%E3%81%A0%E6%99%82%E3%81%AB%E3%82%84%E3%81%A3%E3%81%9F%E3%81%93%E3%81%A8
上記を参考に、当該プロセスをjstackなりなんなりで調査すると、被疑箇所はここ。
`
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f47f801f000 nid=0x6fcc runnable
`
Oh…。GC負荷か。ということはHeapのチューニングですね。

# 対処
https://kamatama41.hatenablog.com/entry/2018/07/15/170125

ローカルで`gradle test`を実行すると、heapを2G強利用していたため、上記と同様build.gradleのtestタスクを変更。

```
test {
    maxHeapSize = "3g"
}
```
こんな感じで解決。20分くらいで終わるようになった。

> Gradle自体はこちらによるとデフォルトでは1024MBヒープサイズを確保するようなのですが、 test タスクはビルドプロセスとは別のJVMを使うようになっており、そこにはこの制限が適用されないようです。

この話は知らなかったよ…。

## 参考
https://docs.gradle.org/current/userguide/java_testing.html
【日記】Pythonで上位階層のモジュールを力技によりimportさせたい

※2019年07月18日：もっと有用な方法を続編の記事にて紹介しています→[Pythonの自作モジュールをimportしたいならsys.pathを設定しよう](https://qiita.com/Anaakikutsushit/items/49d1eff7e5da082edad1)

Pythonは自作のスクリプトでもモジュールとして別ファイルから読み込んで使うことができます。便利ですね。
公式ドキュメント → [6. モジュール (module)](https://docs.python.org/ja/3/tutorial/modules.html?highlight=import#modules)

基本的には（？）同階層や下位階層に存在するファイルからモジュールを読み込んで使うようです。
**しかし、上位階層にあるモジュールを普通に読み込もうとするとエラーになります。**
出力されるエラー内容は `Attempted relative import beyond top-level package` です。
スクリプト自身が存在する階層を、最上位のルート階層としてそれぞれ解釈するという挙動をしているのが原因のようですね。

```こういう階層構造があるとする.txt
最上位フォルダ
├ 上位フォルダ
│ ├ 下位フォルダ
│ │ └ C.py
│ ├ A.py
│ └ B.py
└ D.py
```

```A.py
from B import hoge # 同階層。出来る
from .下位フォルダ.C import foo # 下位階層。出来る
from ..D import bar # `..`は上位階層を示すらしい。なのに出来ない。出来ない。出来ない。出来ない。
```

しかし、これは各階層がパッケージ化（？）されていれば上位階層でも読み込めるんだそうです。
階層をパッケージ化するための要件はよくわかっていないんですが、**とりあえず`__init__.py`という名前の空ファイルを全階層に置いておけば良い**という理解で私は解決しました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">全階層に__init__.pyを置くことで解決させました。絶対これ間違ってるよね（でも解決したから） <a href="https://t.co/lfhaPJYmOm">pic.twitter.com/lfhaPJYmOm</a></p>&mdash; あつし⛅ヒト🏃‍♀️速バラ撒きおじさん (@Anaakikutsushit) <a href="https://twitter.com/Anaakikutsushit/status/1148528297464102912?ref_src=twsrc%5Etfw">July 9, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

```つまりこういうことです.txt
最上位フォルダ
├ 上位フォルダ
│ ├ 下位フォルダ
│ │ ├ __init__.py # 追加
│ │ └ C.py
│ ├ __init__.py # 追加
│ ├ A.py
│ └ B.py
├ __init__.py # 追加
└ D.py
```

ウッソだろお前ｗｗｗｗって目を疑いたくなるような光景ですが、事実これで上手くいったので~~……って書こうとしたらうまく行ってませんでした。とてもつらい。~~いや、やっぱり上手くいきました。う～～ん？？？？？？
上手くいったときは、最上位階層でターミナルを開いて、`py -m スクリプト.py`の形式で実行しました。この辺り関係あるかも。

とまあ、最後よく分かんなくなっちゃいましたけど、このように`__init__.py`さえ置いておけば、先ほどの`A.py`の記述のままで上位階層のモジュールも読むことができるようになります。なるみたいなんです。

ホントは同階層か下層に配置してキレイになるようなパッケージの設計をすべきなんでしょうけど、今日のところはとりあえずこれで。
Macアプリ配布用の.dmgの作成方法（2021 Big Sur版）

自作アプリがどうも AppStore 経由では配信できなさそうなので、よくある`.dmg`形式で配布しようと思いやり方を探したら、[カスタマイズした.dmg を作成する方法](https://qiita.com/econa77/items/d0e7d3a75d8fd3bb7777)という記事を見つけました。しかし、どうやら現在はほんの少しやり方が変わっていたようので、改めてここに書き残します。

# 環境

~~macOS Mojave: 10.14.5~~
macOS Big Sur 11.2.3

# 素材の準備

## 配布用アプリ

アプリが完成したら、Developer ID としてアプリをエクスポートしてください。
<img width="1000" alt="へ.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/087be305-fa3c-775b-11b9-c78e8fada457.png">
<img width="1000" alt="ほ.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/4752789b-b5fe-2d1b-cb9f-cbdfaf1558cd.png">
あとは流れでよいしょ。
`〜.app`が生成されれば OK

もちろん Upload して Apple に署名してもらうのでも OK です。

## 背景画像

dmg の背景に使用する画像を作成してください。
![Screen Shot 2021-05-22 at 16.38.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/3f0eb9c4-c13e-42aa-eff2-b026e918b32c.png)

Retina に対応するために、１倍のものと ２倍のもの（1200px × 750px くらい？）を用意します。そうしたら、Terminal を使って以下のコマンドで背景用画像の`.tiff`ファイルを生成します。

```plaintext
$ tiffutil -cathidpicheck １倍の背景画像 2倍の背景画像 -out backImage.tiff
```

## Applications フォルダのエイリアス

`Macintosh HD`の中の`アプリケーション`フォルダのエイリアスを作ります。

# dmg の作成

ディスクユーティリティを開いてメニューバーのファイル>新規イメージ>空のイメージを作成を押します。
![Screen Shot 2021-05-22 at 16.40.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/da205dd0-3795-0afe-232c-de2863769aba.png)

編集する項目は名前だけで大丈夫です。保存する方の名前が`.dmg`ファイルの名前でボリュームの名前がdmgを展開した時のボリューム名になります。ボリューム名にはわかりやすくInstallerとか書いておくといいかもしれません。
![Screen Shot 2021-05-22 at 16.41.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/5cc35068-d1e7-d001-0e19-a6e9d283b0a8.png)

そうすると、デスクトップに`。dmg`と`ボリューム`が生成表示されます。
![Screen Shot 2021-05-22 at 16.32.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/30910ede-857c-d999-be38-650528e63dbf.png)

ボリュームを開いて、ボリュームの中に配布用アプリとアプリケーションフォルダのエイリアスをコピーします。続いて Terminal を用いてボリュームの中に`.resource`という名前の隠しフォルダを作り、中に背景用画像を入れます。

ここまでできたらあともう少し、ボリュームのウィンドウを選択した状態で表示オプションを編集します。

- 常にアイコン表示で開くにチェックを入れる
- アイコンのサイズを設定する
- 上手に配置できるならグリッドの設定をする
- 背景画像を設定（背景画像は`.resource`フォルダの中のものをドラッグ&ドロップ）
- アイコンの位置とウィンドウサイズを微調整

![Screen Shot 2021-05-22 at 16.42.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/a84dc69b-2294-98c6-2180-c3f71c070bfc.png)

最後にボリュームのマウントを外せば`.dmg`の完成です。確認のために出来上がった`.dmg`を一度展開してボリュームを開いて見た目を確認しましょう。（`.dmg`を直接編集していないので不思議な気持ちになるかもしれませんが、これで OK なのです）

# 所感

背景画像を用意するのは面倒ですが、案外簡単に作ることができますね。

# 参考

- [カスタマイズした.dmg を作成する方法](https://qiita.com/econa77/items/d0e7d3a75d8fd3bb7777)
- [Xcode : Mac 用アプリを Mac App Store を使用せずに個人配布する|配布用.dmg ファイルの作成](https://hikaruapp.jpn.com/xcode/osx/post-645)
Google Drive API Set File Permission（GoogleDriveのファイルにパーミッションを設定しよう）

やあ！

AndroidアプリでファイルをGoogleDriveにアップロードして
そのファイルを他の人たちと共有したいときがあると思います。

今回はアップロードしたファイルに対して権限を付与する処理を書きますわよ！

権限は複数設定(setType)できるぞ！！
・ユーザ(user)ごと。（GoogleAccount名やemailを設定）
・グループ(group)ごと。（Google Groupのemail）
・ドメイン(domain)ごと。（com.jpとか）
・そのほか(anyone)。

※今回のソースコードは
　リンクを知っているすべてのユーザがそのファイルにアクセスできるようになりますわよ！

```java:CreatePermission.java
    /**
     * 権限の設定
     * @param driveService drive
     * @param fileId fileID
     * @throws IOException create permission happen IOException
     */
    private void createPermission(Drive driveService,String fileId) throws IOException{
        JsonBatchCallback<Permission> callback = new JsonBatchCallback<Permission>() {
            @Override
            public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
                // Handle error
                System.err.println(e.getMessage());
            }
            @Override
            public void onSuccess(Permission permission, HttpHeaders responseHeaders) {
                // Handle success
                System.out.println("Permission ID: " + permission.getId());
            }
        };
        BatchRequest batch = driveService.batch();
        Permission userPermission = new Permission()
                .setType("anyone")
                .setRole("reader");
        driveService.permissions().create(fileId, userPermission)
                .setFields("id")
                .queue(batch, callback);
        batch.execute();
    }
```

！権限を削除するとき！
あらかじめ削除に必要なIDを取得する必要がある。


```java:DeletePermissions.java
    File fileData; // 削除したいGoogleDriveのFile情報
    for(Permission permission : fileData.getPermissions()){
        driveService.permissions()
        // 権限を削除するファイルID、権限のID。
        .delete(fileData.getId() , permission.getId())
        .queue(batch,callback);
    }
```

！その他！
Googleフォルダ（親分）に権限を設定すると、
その親分に所属しているファイル（子分たち）はおなじ権限がつきます。
ですが、その権限を子分たちに対してDelete処理しても意味ないから気を付けてね！！
親分倒すか、別の親分を用意して！

あとは雰囲気で何とか調整してください。
何かあったらコメントください。より詳細は以下URLにあるよ。

<サンプル元>
https://developers.google.com/drive/api/v3/manage-sharing
概念図の書き方

#概念図とは
私は概念図を書くことになりました。色んな解釈があるかもしれませんがググると、どうやら関係性を明らかにする図のことで、アイコンや矢印など用いてとにかく見やすくしたもの（らしいです）。

##エクセル使う
とりあえずエクセルを使うことにしました。またググるとSmartArtを使うと速いようです。（挿入タブ→図→SmartArt）

[【Excel】もう組織図や作業フロー図の作成に苦労しない！エクセルのSmartArtでラクして概念図を作成するテクニック](https://forest.watch.impress.co.jp/docs/serial/exceltips/1157109.html)



実際、SmartArtの便利さを実感しながら２時間弱で作成できました。

おわり
[備忘録]TwitterDeveloperアカウントの申請

###はじめに
GAS(GoogleAppsScript)なんかを使ってTwitterのbotを作る際に，2018年の夏頃からDeveloperアカウントの申請が必要になったらしく,その手順を備忘録として記録しておきます．


#####1.  botを作成したいアカウントにログインした状態で[Twitter Developer Platform](https://developer.twitter.com/en.html)にアクセスし，右上の*Apply*をクリック
botを作成するアカウントの電話番号登録，メアド登録をしておくとスムーズ
<img src="https://i.imgur.com/oTekFAG.png" width="800">


#####2.  *Apply for developer account*をクリック
<img src="https://i.imgur.com/0CkYdE6.png" width="800">

#####3.使用用途を選択
今回はbotを作るためMaking a botを選択
<img src="https://i.imgur.com/nK09rf6.png" width="800">

#####4.もろもろの入力
ここまでは楽勝
<img src="https://i.imgur.com/gRdF7GT.png" width="800">

#####5.一番大変
ここがDeveloperアカウント申請の鬼門．
回答を記録しておきますが，くれぐれもコピペはやめてね．
（）内はGoogle翻訳さんを使ってなんとなくの翻訳．

>In English, please describe how you plan to use Twitter data and/or APIs. The more detailed the response, the easier it is to review and approve.
(TwitterのデータやAPIをどのように使用するかを説明してください．回答が詳細になればなるほど，承認が早いです．英語でよろ．)
>>I will use this account to notify myself of website updates. 
The program automatically accesses the website, and when the update is confirmed, 
it will tweet. It is also for practicing javascript programming. 
This account will be used for personal purposes only.
(このアカウントはwebサイトの更新を知らせるために個人的に使用します．プログラムが自動でwebサイトにアクセスし，更新が確認されればツイートします．また，javascriptの勉強するためでもあります．このアカウントは個人的な目的でのみ用います．)

>Are you planning to analyze Twitter data?
(Twitterのデータを分析する予定ですか？)
>>No.
(よくわからんからNo)

>Will your app use Tweet, Retweet, like, follow, or Direct Message functionality?
(ツイート，リツイート，お気に入り，フォロー，またはダイレクトメッセージ機能を使用しますか？)
>>Yes.Bot uses only the tweet function. If a particular website update is confirmed, 
this bot will tweet that.
(はい．Botはツイート機能のみを使用します．もし，特定のwebサイト更新が確認されれば，このBotがツイートします．)

>Do you plan to display Tweets or aggregate data about Twitter content outside of Twitter?
(Twitter以外のTwitterコンテンツに関するツイートを表示したり，集計データを表示したりしますか？)
>>No.
(Twitter以外のTwitterコンテンツってなに…)

>Will your product, service or analysis make Twitter content or derived information available to a government entity?
(あなたの製品，サービス，または分析によって，Twitterコンテンツまたは派生情報が政府機関に利用可能になりますか？)
>>No.
(政府機関とは)

<img src="https://i.imgur.com/RvOi71f.png" width="800">


これで*Next*押して進んだら下の画像のようなメールがきて*Confirm your email*クリックで
<img src="https://i.imgur.com/yX6ExT1.jpg" width="800">
再び[Twitter Developer Platform](https://developer.twitter.com/en.html)にアクセスすると
<img src="https://i.imgur.com/4KTnVUc.png" width="800">
なんか通ったっぽかったです．あっさり．無事アプリ作成してbotも作れました．

Developerアカウントの申請についての記事はいくつか見ましたが，どれも申請通るまで１週間くらいはかかってるようだったので，申請した時(2019年7月)は申請が通りやすいのかも．~~文章も適当に書いたやつなのに．~~
もしかしたらすでにガバガバになっちゃったのかもしれないが．
nvmでインストールしたNode-REDをdaemon起動する方法

nvmでNode.jsのバージョンを管理しつつ、Node-REDをインストールして、daemon起動する方法のメモです。

nvmのインストールは[nvmの公式サイト](https://github.com/nvm-sh/nvm)を参照してください。
ここでインストールしたNode.jsのバージョンでNode-REDを動かして、さらにdaemon起動できる状態にしていきます。

### Node-REDのインストール
インストールはこれだけ

```bash
npm install -g node-red
```

### Node-REDの起動方法

Raspberry Piの場合：

```bash
node-red
```

### daemon起動をする

通常のnodered.serviceを読み込ませると、「npmコマンドが見つかりません」というメッセージが表示され、「パレットの管理」のメニューが表示されません。

```
Jul  9 17:40:25 raspberrypi Node-RED[6405]: 9 Jul 17:40:25 - [info] パレットエディタを無効化 : npmコマンドが見つかりません
```
rootにもnvmをインストールすれば解決するのですがスマートではないので、systemctlが参照するPATHに、npmがインストールされているPATHを追加します。

以下のようなコマンドでPATHを出力して、PATHの指定をするファイルを作成します。

```
echo $PATH
```

作成したファイルがこちら
(gamesはいらないだろ...)

```/home/pi/pi.conf
PATH=/home/pi/.config/versions/node/v10.16.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
```

作成したPATHの設定ファイルを、nodered.serviceのEnvironmentFileのパラメータで指定します。

```/etc/systemd/system/nodered.service
[Unit]
After=network.target
Documentation=http://nodered.org/

[Service]
Environment="NODE_OPTIONS=--max-old-space-size=128"
#Environment="NODE_RED_OPTIONS=-v"
EnvironmentFile=/home/pi/pi.conf
ExecStart=/home/pi/.config/versions/node/v10.16.0/bin/node $NODE_OPTIONS /home/pi/node_modules/node-red/red.js $NODE_RED_OPTIONS
WorkingDirectory=/home/pi/.node-red/
User=pi
Group=pi
Nice=10
SyslogIdentifier=Node-RED
StandardOutput=syslog
Restart=on-failure
KillSignal=SIGINT

[Install]
WantedBy=network.target
```

```sudo systemctl start nodered```でdaemon起動すれば、npmのPATHも設定されているので、正常に動作します。

2020.5.20:
```2020-02-13-rasbian-buster```のカーネルでは```network-online.target```の設定だと電源起動時に自動起動しないため```network.target```に変更しました。
Tokyo HoloLens ミートアップ vol.16 フォトレポート

2019年7月8日（月）の夜に [Tokyo HoloLens ミートアップ vol.16](https://hololens.connpass.com/event/135956/) に参加したので記録しておきます。

会場は品川のマイクロソフトさん31階のセミナールーム。この日は他にも開発者コミュニティのイベントがあったようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/3f5eb2b5-ddcc-bd88-d449-47ae0b270515.png)

HoloLensアプリの開発者 [Julia Schwarzさん](https://www.linkedin.com/in/juliaschwarz/) によるHoloLens2インタラクションのデモ。
インターフェースは100にもおよぶプロトタイプを作ってその中から決定されたそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/8f5a5187-f1df-3339-b9a3-26ada163b3ce.png)

ここは写真NGだったので、翌日公開された [YouTubeの動画](https://www.youtube.com/watch?v=djF_M3inh5A) をご紹介します。私も背景フリー素材として映り込んでいます。

お二人目のゲスト、デザインを担当されている [Dong Yoon Parkさん](http://dongyoonpark.com/)、丁寧な説明で分かりやすかったです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/b45ab7ce-fdfd-161f-ccbf-a0cbd7ba1158.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/787cb27d-e20f-b60d-1cdf-9bf6a64de676.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/c3cfeb75-b7ff-a0a9-e33f-215eae2ea10e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/193a798e-82c6-5770-b5e3-2970f28b4f55.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/48ea7439-67c6-d4ea-11c0-24ab185d8b66.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/6127dd8e-f47b-3b80-fc6e-4d0944992c07.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/5f1b6eba-aedf-2c65-9f59-315b717441a4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/a8efe535-c9b5-f5d7-8e5f-ba22d89fdd4e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/386c4d78-2ab3-4d9f-c4af-33dec8a9c4e7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/f7bc20b4-5d0c-f2f2-33dd-41911e49f64a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/a6a55531-097f-5c4c-a152-c3b249da2aa5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/15237e2c-42a0-6e31-3d91-88af382ad5ac.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/a119dbd7-a3db-07f0-57c0-bcac58f26e27.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/0478135b-f8b2-a8bd-024a-3eb76237d034.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/96b21831-489b-136c-3d05-323a3d7dcd79.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/b4848b20-4025-588c-e8c5-78786ffdf9b2.png)

日本に来てくれてありがとうございました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/1e577331-862e-3219-4f57-13d8c84bffcd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/f60f90b8-0d01-b806-c5fe-70fbfb3ed2a3.png)
[Dong Yoon ParkさんのFB](https://facebook.com/photo.php?fbid=10219023713242110&id=1183286078&set=a.1573248769477)、みんな大喜びで盛り上がっています。

用事があって懇親会に参加できなかったので、レポートはここまでです。
運営の皆様、ありがとうございました。
【AWS】terraformとCloudformationを比較してみた【IaC】

## はじめに
クラウドのインフラの運用コストとか管理コストとかの削減のために
インフラのコード化(Infrastructure as Code)の重要性がどんどん上がってきています。

AWSでそれを実現するツールとして有名なのが
terraform、cloudformationあたりだと思います。

IaC導入したい、けどどっちを使ったらいいの？っていうのが疑問としてずっとありました。
ただ調べてもなかなか理解できなかったので
実際にどっちも使ってみて、その比較をしてみました。あくまで感想です。

今回ツールそのものの使い方については記載していません。

## 感想
|       terraform                    |         cloudformation              |
|-------------------------|-------------------------|
|OSSである。情報が多い<br>バージョンが上がるごとにどんどん使いやすくなっている。機能も増えている<br>コミュニティmoduleの存在|AWSのサービスである。サポートをしっかり受けられる  |
|基本的にCLIで実行```terraform```コマンド ```terraform plan``` ```terraform apply```だけ覚えておけばなんとかなる|基本的にGUIで実行。```aws cloudformation```コマンドもあるが、オプションが多いので学習コストが高い。|
|IAMの認証で実行する。<br>それぞれのローカル環境で実行することが基本のためセキュリティを意識する必要がある。  |AWSで閉じられるのでセキュリティで考えることが少ない  |
|少しずつ始められる |最初の設計が大事<br>stackの連携、管理する範囲をしっかり決めておく必要がある<br>一度stack化すると削除⇒作成という流れを踏まなければいけないため|
|独自のスクリプト言語(.tf)を用いる |json、yaml形式を用いる|
|複数プラットフォームに対応<br>AWSに縛られない|AWS専用サービス<br>他のAWSサービスと連携がスムーズ|
|インポートが簡単。```terraform import```コマンドを利用。|import機能がある。|
|CI/CD始めやすい。JenkinsやCircleCI等外部ツールとも連携しやすい|Code4兄弟と連携させてCI/CD化できる。|

## まとめ
AWSサービスのみの利用、1から作成するのであればCloudFormation
他のクラウドも使ってる、外部ツールの利用が多い、既存環境をコード化したいのであればTerraform

個人的にはTerraformを押します。自由度が高いため。

ちなみに個人環境ではterraform + cloudformationのハイブリット構成をとっています。
IAMの管理とかセキュリティに関わる部分はcloudformationにして
VPC、EC2等インフラに関わる部分はterraformにしています。

間違いあったらすみません。
いろんなご意見募集します！

## 追記(2019/11/18)
CloudFormationにインポート機能が追加されました。

参考：
https://dev.classmethod.jp/cloud/aws/cloudformation-import-existing-resources/

かなりイケてます。AWS強い。
イテレータ


[JavaScript本格入門](https://www.amazon.co.jp/dp/477418411X/ref=cm_sw_r_tw_dp_U_x_wxAJCbT3GGKT9)(ISBN 978-4774184111)で基礎からJavaScriptを勉強するシリーズです。
今回はChapter5からイテレータについてです。

# イテレータ

オブジェクトの内容を列挙するための仕組みを備えたオブジェクトのことです。

例えばArrayオブジェクトはイテレータを備えているので、for...ofで呼ぶたびに指しているオブジェクトが変わり、走査することが出来ます。

```js
let team = ['Giorno', 'Bucciarati', 'Mista', 'Fugo', 'Narancia', 'Abbacchio'];

for(let d of team) {
  console.log(d);
}
```

```:実行結果
Giorno
Bucciarati
Mista
Fugo
Narancia
Abbacchio
```

イテレータを備えた組み込みオブジェクトには以下のようなものがあります。

- [Array](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array)
- [String](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String)
- [Map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map)
- [Set](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set)
CSSキャッシュを自動で読み直す

# スーパーリロード無しで、CSSを自動更新したい！

### クエリをdate()関数でコントロールする


hoge.css の後ろに

`?<?php echo date('Ymd-Hi'); ?>
`

を下記のように記述する。



```HTML
<link type="text/css" rel="stylesheet" href="style.css?<?php echo date('Ymd-Hi'); ?>">
```


## 参考
https://www.merges.co.jp/archives/745
私が実際に使っている、コードやコンテンツの品質を上げたい時に便利なツール集

# 無料ですぐ使えるチェックツール
コード品質は上げたいけれど、チェックにかかる手間はなるべく省きたい。
ツール自体は色々あるため自分に合ったものを選ぶべきですが、ここでは網羅的にではなく、私が実際に使っている物を中心にまとめました。
見出しをクリックすると、該当の外部サイトに飛びます。

**※ツールやプラグインは随時追加予定です。**

## [CSScomb](https://www.npmjs.com/package/csscomb)
![bcb3e7d6-043f-459f-a5db-fd8ba1fac43c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298037/7534fe54-2855-9596-5782-de20d26779f0.png)
CSScombはSassおよびCSSのコーディングスタイルフォーマッタです。
改行やセミコロン、スペースといったコード整形に加えて、スタイルシートの各プロパティと値のセットを指定のルールに従って並びかえてくれます。

CSSは気付くと膨大な行のファイルになることが多いため、少しでも管理しやすい形にするために導入しています。一定の並びに合わせることで、同セレクタに対するプロパティの重複を防げるなど、手軽に使える割にメリットが多いと感じています。

ユーザの設定ファイルをカスタマイズすることで、独自の設定のコード整形や並べ替えルールを指定できます。

ちなみに私は Windows7、Sublime Text で同プラグインを使用しています。
調べたところ VS CODE でも使えるようです。扱いに関しては以下の記事が参考になります。

参考：
・[CSScomb JS を Sublime Text 3 で使ってみる](http://www.webdesignleaves.com/wp/htmlcss/788/)
・[VS CODEでCSSのフォーマットをするまで](https://qiita.com/EigenPort_M/items/799533cfccfded860130)

上記以外にも、CSScombの使い方に関する情報はたくさんあるため、必要に応じて検索してみてください。

CSScombが正常に動作せずエラーが出る場合は、SassまたはCSSの記述にミスがあるためかもしれません。
どのファイルのどこにエラーがあるのかまでは教えてくれないため、使用しているSass・CSSファイルのどこが間違っているのか確認してみてください。私が経験したパターンは以下です。

**エラーでよくあるパターン**

 - プロパティの後ろに **;(セミコロン)** がない
 - セレクタのみ指定され、プロパティや値が空

## [HTML 5 Outliner](https://gsnedders.html5.org/outliner/)
HTML5文書のアウトラインを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298037/f4a744e6-5d51-f7c2-12ca-786f09b6cc04.png)

Chrome用プラグインもあります。
チェックのたびに上記ページを開く必要がないため、使い勝手の良さは優れています。
### [Chromeプラグイン:HTML5 Outliner](https://chrome.google.com/webstore/detail/html5-outliner/afoibpobokebhgfnknfndkgemglggomo?hl=ja)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298037/8623fbf4-2cef-45bc-9de2-745d5e29f74c.png)

## [CSS Validation Service](http://www.css-validator.org/validator.html.ja)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298037/295c7618-6f66-5887-126d-97dfc96dc7b5.png)
検証方法は「URL」「アップロード」「直接入力」の3つです。
作成途中でファイルがまだローカルにある場合は、コードをそのままコピペしてチェックできる「**直接入力**」を使うとよいでしょう。

## [PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights/?hl=ja)
![0ba9cc20-4be6-4207-bc20-ee14762cf320.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298037/8b3898cc-4b65-a1bf-ece1-97ce29757f72.png)
Webページの読み込み時間を測定します。
また、診断結果としてページの読み込み時間を短くするための方法を提案します。

## [モバイルフレンドリーテスト](https://search.google.com/test/mobile-friendly?hl=ja)
![04cb930f-7a7a-4795-9261-8edff19f2be6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298037/3cf2859a-585f-1158-3f56-a69e1cbff7cc.png)
モバイルデバイスでのページの使いやすさをテストします。
ページの URL を入力するだけで、使いやすさのスコアが表示されます(原文ママ)。

## [Nibbler](http://nibbler.silktide.com/en_US)
![dd871ce2-e04d-42d5-a807-78d61112972f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298037/218d22a3-f70a-1498-9f2f-90a23f5ee6c8.png)
NibblerはWebサイトをテストするための無料ツールです。
任意のWebサイトのアドレスを入力すると、アクセシビリティ、SEO、ソーシャルメディア、テクノロジなどの主要分野について、Webサイトのスコアを10点満点で評価します。

注意点としては、解析に数分程度時間がかかることと、サブディレクトリ以下のサイトを指定して解析できない点が挙げられます。

##
HTMLでデスクトップアプリっぽい画面構造を構築するベスト(?)プラクティス

# Webでデスクトップアプリっぽい画面構造を構築するベスト(?)プラクティス

最近、仕事でWeb屋さんのまねごとをした(あるツールを作ったが、そのUIをWebアプリにする必要があった)。
デスクトップアプリのような画面を多数作る必要があったので、効率を求めていろいろな方法を試した中で、一番良かったと思う方法をまとめる。

## デスクトップアプリっぽい画面構造とは？

以下のようなスタイルを持った画面構造。

*   ブラウザの画面全体を使い切る。
*   画面が縦横のペイン分割で構成されている。
*   固定サイズで表示されるペインと、画面サイズに応じて拡縮されるペインがある。
*   画面にコンテンツが収まりきらない場合、画面全体がスクロールするのではなく、ペインごとにスクロールする。

Qiitaの投稿画面もそういう構造ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426308/a866534d-76df-3d76-43cc-5376c0eea03b.png)

## ねらい

*   少数のCSSクラスを定義するだけで、大半の画面レイアウトに対応できること。

    開発効率も保守性も下がるので、できるだけ画面ごとにCSSを書きわけたくない。

*   HTML(DOM)構造が複雑にならないこと。

    DOMが複雑になると、やっぱり開発効率も保守性も下がる。

*   ブラウザ個別対策が最小限で済むこと

    トリッキーなことをしない。ある程度枯れた技術を使う。

## 手法

FlexBoxを使う。

最近のブラウザであれば[ほぼ対応](https://caniuse.com/#search=flex)。ベンダープレフィックスもつけなくていいくらい。

IEも11は対応。IE 10も(怪しいながら一応)FlexBox対応。

## 実装

最終的に、こんな感じにした。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="html,result" data-user="hogegex" data-slug-hash="zVaqGN" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="DesktopAppLike">
  <span>See the Pen <a href="https://codepen.io/hogegex/pen/zVaqGN/">
  DesktopAppLike</a> by hogegex (<a href="https://codepen.io/hogegex">@hogegex</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 解説

*    画面全体を覆うため、最上位要素にmatchParentクラスを指定する。

*    画面を縦に分割したい場合はstackVerticalクラス、横に分割したい場合はstackHorizontalクラスを指定し、ペインとなる子要素を追加する。

*    通常のペインは、内容によってサイズが決まる。サイズを固定もしくは制約したい場合は、対象要素に(max- / min-) width / heightを指定する。

*    stretchableクラスを指定すると、そのペインは、余白いっぱいに広がる。複数に指定した場合は、余白を等分に分け合う。

*    ペインの内容をスクロールさせたい場合は、verticalScrollableクラスを指定する。

*    ペインを再分割したい場合は、ペインの要素にstackVertical / stackHorizontalを指定する。

## 注意事項

ブラウザによっては、ペイン内の一部の要素(textarea, selectなど)が妙に伸び縮みすることがあった。
これは、一部の要素にデフォルトでflex-shrinkが設定されているためだった。

以下のように明示的にキャンセルするか、リセットCSSを適用するとよさそう。

```css
textarea, select {
    flex-shrink: 0;
}
```
Hello JavaScript!

[JavaScript本格入門](https://www.amazon.co.jp/dp/477418411X/ref=cm_sw_r_tw_dp_U_x_wxAJCbT3GGKT9)(ISBN 978-4774184111)で基礎からJavaScriptを勉強するシリーズです。今回はChapter1からです。そもそもJavaScriptとは？という当たり前だけど大事な話。

# JavaScriptの特徴

下記のような特徴があるようです。

- スクリプト言語
    - 自然言語に近くてとっつきやすいということらしいです
- インタープリター型言語
    - 命令を逐次マシン語に変更しながら動作する
- 色々な環境で動作する
    - サーバ側であったりクライアント側であったり

# ECMAScriptとは

ECMAScriptはJavaScriptの標準のことです。（ESと略したりします）
JavaScriptは、数あるブラウザによりそれぞれで仕様が異なったり方言が乱立していたという歴史があるようです。
そこでEcma Internationalという組織がなんとかせんといかんと言って標準化を始めたということのようです。

執筆時点での最新版は [ECMAScript 9(ECMAScript 2018)](https://www.ecma-international.org/ecma-262/9.0/index.html) です。

どこから学ぼうかという気持ちになりますが、ECMAScript6(ECMAScript2015)がこれまでの標準化の中で非常に大きな変更となったようですので筆者はここから勉強することにしました。

ES2015で何が追加されたかについて、詳しくは [ECMAScript6の新機能について](http://es6-features.org/) が参考になると思います。

# Hello world!

```js
console.log('Hello world!');
```
__pycache__とはいったいなんなのか?

#\_\_pycache__とはいったいなんなのか?
開発中に幾度となく目にします。
知らぬ間に追加されていて、消してよいのか悪いのかわからず放って置くものの、目障りでしょうがない。

**一体誰なんだお前は！**

![atom.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397212/1690308a-70a6-b49e-c312-9a451144e864.png)

#そもそも読み方わからない問題
pycache?なんだそれ？
pyはわかるけどせめてぱっと見で意味が通る名前にしてくれよ～

しかし私はただの馬鹿だったようです。
![cache.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397212/41cf420f-01a5-7056-39ba-3887f0517586.png)

>キャッシュ

>よく使うデータへのアクセスを速くするために、より高速な記憶装置に一時的に保存する仕組み。

>ASCII.jpデジタル用語辞典より


プログラマなら当然知っているべき単語でした。

今まで「パイケイク」と読んでいましたが「パイキャッシュ」が正解であるようですね…

#\_\_pycache__が何してるかわからない問題
もうgoogle翻訳にかけた時点でほとんどわかっているのですが、続けましょう。

pythonファイルを実行したとき、コンパイルされたモジュールが\_\_pycache__の中pycファイルにキャッシュされます。

これを残しておけばコンパイルを経ずにプログラムを実行することができるので実行が速くなります。
プログラムを変更するたびに書き換えられます。
消しても問題ありませんが、実行が少し遅くなります。

#\_\_pycache__君、帰っていいよ

頑張ってくれてはいるんだけどね。
たまにおせっかいだなぁ…なんて。

どうしても邪魔だと思う方へ

##\_\_pycache__を消す方法1(コマンドで指定)

```
$ python -h
```
を実行すると方法を教えてくれます。

```
-B     : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x

```

例えば、hoge.pyを実行するときにキャッシュを作られたくなければ

```command
$ python -B hoge.py
```

このように-Bを付けることで解決します。


##\_\_pycache__を消す方法2(環境変数)
環境変数の変数名をPYTHONDONTWRITEBYTECODEに、値を適当に設定することでキャッシュを作るのをやめるようです。
値は1が無難でしょう。

実際にやったことはない。

##\_\_pycache__を消す方法3(プログラムで指定する)

```py
import sys
sys.dont_write_bytecode = True
```
このように書けばキャッシュを作らなくなります。
C++14で超ミニマルなスレッドプール

ミニマルにスレッドプールを実装した例があまり見当たらないためサクッとスレッドプール実装したいという方の参考になれば幸いです。
並列コードは書き慣れていないのでミスがあったらご教示ください。

とりあえずコード全文。手元でC++14で開発していたので14と書いてありますが11でも行ける気がします（確認はしてません）。

```cpp
#ifndef __KTNYT_THREAD_POOL_HPP__
#define __KTNYT_THREAD_POOL_HPP__

#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <vector>

namespace ktnyt {

class thread_pool {
 public:
  thread_pool(std::size_t size) : stop(false) {
    for (std::size_t i = 0; i < size; ++i) {
      workers.emplace_back([this] { spawn(); });
    }
  }

  virtual ~thread_pool() {
    if (!stop) join();
  }

  void post(std::function<void()> f) {
    {
      std::unique_lock<std::mutex> lock(mutex);
      tasks.push(f);
    }

    condition.notify_one();
  }

  void join() {
    {
      std::unique_lock<std::mutex> lock(mutex);
      stop = true;
    }

    condition.notify_all();

    for (std::size_t i = 0; i < workers.size(); ++i) {
      workers[i].join();
    }
  }

 private:
  void spawn() {
    for (;;) {
      std::function<void()> task;
      {
        std::unique_lock<std::mutex> lock(mutex);
        condition.wait(lock, [this] { return !tasks.empty() || stop; });
        if (stop && tasks.empty()) return;
        task = std::move(tasks.front());
        tasks.pop();
      }
      task();
    }
  }

  std::vector<std::thread> workers;
  std::queue<std::function<void()>> tasks;

  std::mutex mutex;
  std::condition_variable condition;
  bool stop;
};

}  // namespace ktnyt

#endif  // __KTNYT_THREAD_POOL_HPP__
```

## コード解説
この実装のキモは`spawn()`メソッドにあります。

```cpp
  void spawn() {
    for (;;) {
```

スレッドプールがjoinされているかどうかは`bool stop`で表現しているので偽の間はループします。

```cpp
      std::function<void()> task;
      {
        std::unique_lock<std::mutex> lock(mutex);
        std::unique_lock<std::mutex> lock(mutex);
        condition.wait(lock, [this] { return !tasks.empty() || stop; });
```

まずキュー先頭のタスクを代入するための`std::function<void()>`を定義しておきます。
タスクキューの中身を確認するためにロックして次の条件のいずれかが満たされるのを待ちます。
1. タスクキューにタスクが追加される。
2. スレッドプールがjoinされる。

```cpp
        if (stop && tasks.empty()) return;
        task = std::move(tasks.front());
        tasks.pop();
      }
      task();
    }
  }
```

この時にjoinされていてかつタスクキューが空の場合にはreturnします。
そうでなければタスクキューが空ではないので、先頭のタスクを取得してロックのスコープ外で実行します。
このメソッドをワーカスレッドの数の分だけコンストラクタ内で立ち上げます。

```cpp
  thread_pool(std::size_t size) : stop(false) {
    for (std::size_t i = 0; i < size; ++i) {
      workers.emplace_back([this] { spawn(); });
    }
  }
```

あとでjoinする必要があるためワーカスレッドはベクトルに保持しておきます。

```cpp
  void join() {
    {
      std::unique_lock<std::mutex> lock(mutex);
      stop = true;
    }

    condition.notify_all();
```

まず無名スコープでロックして全スレッドにjoinが呼ばれたことを通知します。

```cpp
    for (std::size_t i = 0; i < workers.size(); ++i) {
      workers[i].join();
    }
  }
```

これで各ワーカスレッドがループから抜けるのであとは個別にjoinします。

```cpp
  virtual ~thread_pool() {
    if (!stop) join();
  }
```

デストラクタはすでにjoinされていなければjoinします。

```cpp
  void post(std::function<void()> f) {
    {
      std::unique_lock<std::mutex> lock(mutex);
      tasks.push(f);
    }

    condition.notify_one();
  }
```

タスクの追加のときにはしっかりtasksを排他制御します。
`push`したら通知して待っているスレッドを起こします。
Webアプリで音声入力を実装する

Webアプリで音声入力を実装したい場合のメモです。

# 無償

## iOS
- キーボードの音声入力を使う

https://support.apple.com/ja-jp/HT208343

ただし、キーボード入力を音声に自動的に切り替える制御はできない。自動にするには、アプリ化して制御するしか無い模様（2019/7現在)

## Chrome (iOSを除く)

- WebSpeech API (Speech Recognition)を使う

https://qiita.com/hmmrjn/items/4b77a86030ed0071f548

<img width="1267" alt="スクリーンショット 2019-07-09 17.28.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14768/2aeb7bfd-b8d6-6f40-d633-f9603d3876fe.png">
https://caniuse.com/#feat=speech-recognition

対応状況としてはChrome & Android Chromeだけですが、Edgeの新しいバージョン（Chrome互換）のものには実装されているようですね。

バックエンドはGoole Speech-to-Textのようです。Safariが実装すれば、ほぼこれ一択なんですが...。

# 有償

- Google Speech-to-Text (GCP)
https://cloud.google.com/speech-to-text/?hl=ja

- AmiVoice cloud (アドバンスドメディア）
https://www.advanced-media.co.jp/products/service/amivoice-cloud-2

- Speech to Text (IBM)
https://www.ibm.com/watson/jp-ja/developercloud/speech-to-text.html

# まとめ

- 特に制限がなければ、iOS標準もしくはChromeを必須とする事で無償で対応可
- 音声入力になんらかのこだわりのある場合や、各種デバイスで共通実装や同じ認識精度が欲しい場合は有償のものが良いのかも。
- GCPはすぐ使え価格も明瞭なので使いやすいかと思います。従量課金なのでリアルタイム認識みたいな用途だと無限にコストがかかってしまうのが難点か。

個人的には無償のもので作ってみて、反響や利用状況によって有償の物への移行を考える方が良いと思います。
CSSで2つの要素を重ねる

#2つの要素を重ねる

`position: absolute;`で要素同士を重ねて表示できる。
topやleftを指定して、表示位置を調整できる。
その場合、サイト全体の左上部分が基準位置となる。

基準としたい親要素に`position: absolute;`を指定すると、
基準位置を、親要素の左上に変更できる。

```html:index.html
<div class="parent">
  <img class="child">
</div>
```

```css:stylesheet.css
.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 20px;
  left: 15px;
}

```
EspressoでRecyclerViewのチェックを行うカスタムMatcherを作成

# 背景
RecyclerViewのUIテストを作ろうとすると、どうしても標準APIでは満たせないテスト項目が出てきます。
https://qiita.com/AAkira/items/26ee7b18b11635cfc621 を参考にさせていただき、独自の`RecyclerViewMatcher`を作成しました。
下記の項目ではそれぞれバラバラに記載していますが、全てのメソッドは１つの`RecyclerViewMatcher`の中に定義されています。

# 実装
## 【isExist】RecyclerViewの指定した位置に、指定したViewHolderが存在すること

```kotlin:RecyclerViewMatcher.kt
object RecyclerViewMatcher {
    inline fun <reified T : RecyclerView.ViewHolder> isExist(position: Int) = object : TypeSafeMatcher<View>() {
        override fun describeTo(description: Description) {
            description.appendText("RecyclerViewの指定した位置に、指定したViewHolderが存在すること")
        }

        override fun matchesSafely(view: View): Boolean {
            if (view !is RecyclerView) return false
            return view.findViewHolderForAdapterPosition(position) is T
        }
    }
}
```

## 【contains】RecyclerViewの指定した範囲内に、指定したViewHolderが存在すること

```kotlin:RecyclerViewMatcher.kt
object RecyclerViewMatcher {
    inline fun <reified T : RecyclerView.ViewHolder> contains(range: IntRange) = object : TypeSafeMatcher<View>() {
        override fun describeTo(description: Description) {
            description.appendText("RecyclerViewの指定した範囲内に、指定したViewHolderが存在すること")
        }

        override fun matchesSafely(view: View): Boolean {
            if (view !is RecyclerView) return false
            return range.any { position ->
                view.findViewHolderForAdapterPosition(position) is T
            }
        }
    }
}
```

## 【isVisible】RecyclerViewの指定した位置のViewHolderに、指定したViewが表示されていること

```kotlin:RecyclerViewMatcher.kt
object RecyclerViewMatcher {
    inline fun <reified T : RecyclerView.ViewHolder> isVisible(position: Int, @IdRes id: Int) = object : TypeSafeMatcher<View>() {
        override fun describeTo(description: Description) {
            description.appendText("RecyclerViewの指定した位置のViewHolderに、指定したViewが表示されていること")
        }

        override fun matchesSafely(view: View): Boolean {
            if (view !is RecyclerView) return false
            val viewHolder = view.findViewHolderForAdapterPosition(position) as? T ?: return false

            return viewHolder.itemView.findViewById<View>(id)?.visibility == View.VISIBLE
        }
    }
}
```
オブジェクトを放物線を描いて移動させる【Unity】

#はじめに
終了地点と開始地点を指定し、放物線を描きながら物体が移動する方法の紹介です。
放物線の方程式は高校数学の範囲ですし、もちろんすでに先人の方々が紹介済みですからググれば情報は山のようにヒットします。
でも、せっかくUnityを使うのならもっと簡単にそれっぽい動きが表現できそうだと思ったのでまとめてみました。

環境は以下の通りです
win10 64bit, Unity2018.3.3f1

#方法
やり方は至ってシンプルです。
まず、開始地点p0と終了地点p2の中点p1を求めます。
次に、中点p1に高さを足し、弧を描いて飛んでいく途中の最高到達地点を求めます。
最後に、２次ベジェ曲線を使ってp0～p2の３点を補間します。
ベジェ曲線を使った補間に関する参考リンク：「[一から学ぶベジェ曲線](https://postd.cc/bezier-curves/)」

#実装
###中点を求める
StartThrow()の引数には、
1. 飛ばす対象
2. 大体の高さ
3. 開始地点
4. 終了地点
5. 補間スピード(フレーム数)
を指定しています。

```C#:
public void StartThrow(GameObject target, float height, Vector3 start, Vector3 end, float duration) {
    // 中点を求める
    Vector3 half = end - start * 0.50f + start;
    half.y += Vector3.up.y + height;
    
    StartCoroutine(LerpThrow(target, start, half, end, duration));
}
```

###ベジェ曲線で補間
LerpThrow()はtargetがdurationフレーム数をかけて、start地点から始まり、half地点を通過して、end地点にたどり着くためのコルーチンです。
CalcLerpPoint()はp0とp1を１次補間した位置aと、p1とp2を１次補間した位置bを求め、そのaとbをさらに２次補間して最終的な位置を求めます。

```C#:コルーチン
IEnumerator LerpThrow(GameObject target, Vector3 start, Vector3 half, Vector3 end, float duration) {
    float startTime = Time.timeSinceLevelLoad;
    float rate = 0f;
    while(true) {
    	if(rate >= 1.0f)
    		yield break;

        float diff = Time.timeSinceLevelLoad - startTime;
        rate = diff / (duration / 60f);
        target.transform.position = CalcLerpPoint(start, half, end, rate);

        yield return null;
    }
}
```
```C#:補間
Vector3 CalcLerpPoint(Vector3 p0, Vector3 p1, Vector3 p2, float t) {
    var a = Vector3.Lerp(p0, p1, t);
    var b = Vector3.Lerp(p1, p2, t);
    return Vector3.Lerp(a, b, t);
}
```

#最後に
放物線の最高地点を求めると書きましたが、ベジェ曲線の性質上、３点の補間では正確にp1が最高地点とは言えないので、なんちゃって放物線ですね。でも複雑な計算式を必要としない、なんとなく弧を描いているように見せたい場合にはこれで十分な気もします。
次回はオンライン関係の記事が書けるようにがんばります。
私が考えるJavascriptでの配列操作ベストプラクティス2019

## 目的と前提
* 実装するときにいつもひと手間かかってしまうので、配列の比較ロジックの備忘録です。
* ES2015（ES6）のバージョンを想定。

## 比較パターン
### （1） オブジェクトと配列を比較 → 値が重複するオブジェクトをそのまま取り出す

```js

const array = ["test1", "test2", "test3", "test4"];
const objectArray = [
    {param: "ちがうよ"},
    {param: "ちがうよ"},
    {param: "test1"},
    {param: "ちがうよ"},
    {param: "test2"}
];


const newArray = [];
for (const targetValue of array) {
    const sameValue = objectArray.find(obj => obj.param === targetValue);
    newArray.push(sameValue);
}

console.log(newArray); //[ { param: 'test1' }, { param: 'test2' } ]

```

### （2）オブジェクトと配列を比較 → 値が重複するオブジェクトの値を取り出す
```js

const newValueArray = newArray.map(data => data.param);
console.log(newValueArray);  // [ 'test1', 'test2' ]
```

### （3） 配列どうしを比較 → 重複する値を取り出す
```js

const compareArray = ["test1", "test2"];

const arrayOfDupulicates = array.filter(value => compareArray.includes(value));
console.log(arrayOfDupulicates); //[ 'test1', 'test2' ]
```

### （4） 配列どうしを比較 → 重複しない値を取り出す
```js

const arrayRemovedDupulicates = array.filter(value => !compareArray.includes(value));
console.log(arrayRemovedDupulicates); //[ 'test3', 'test4' ]
```
テレワーク用のPC遠隔操作アプリ

>PCを遠隔操作することは「リモートデスクトップ」、「リモートアクセス」、「リモートコントロール」など、様々な名前で呼ばれています。テレワークの需要が増す昨今において欠かせないものとなっています。ここでは私が検討したPC遠隔操作サービスを紹介します。

## はじめに

私の勤務先では、今年からテレワークを積極的に展開することが決まりました。
そして先日、私は上司にテレワーク用のPC遠隔操作ツールの検討を任されるに至りました。

早速「PC遠隔操作」をググってみたところ、膨大な数の製品があることを知りました。
無料アプリなども混ざっているので、正直どの製品が良いのか判断するのに困りました。
各製品のライセンス形態が多岐にわたるため、比較するのも難しかったです。

私と同じような状況の人も少なくないと思うので、皆さんの参考になると思い、この記事を作成しました。

ところで、弊社の条件は合計40人分のPCをリモート可能にすることでした。
この用途に該当する法人向けリモートソリューションを探したところ、以下4製品（全てクラウドサービス）が候補に上がりました。

## 1) ConnectWise Control
**長所**

- 日本語化が上手くできている
- ユーザー数の制限がない
- 同時接続数の制限がない
- 接続元端末の数に制限がない
- ユーザー権限設定可能
- ログがきれいに整理されていて、ウェブから見ることができる
- シングルサインオン対応
- リモートプリント対応（しかもドライバー不要）
- 遠隔PCのモンターを黒塗りにできる（しかもドライバー不要）

**短所**

- PC登録可能数は自由に指定できず、25、50、100、250、500、750、1,000のみとなる

**価格**

- 年額324,000円 (PC50台)

[**WEBサイト**](https://service.allconnect.jp/)

## 2) Splashtop
**長所**

- ユーザー数の制限なし
- ユーザー権限設定可能
- リモートプリント対応（ただし特別なドライバーが必要）
- 遠隔PCのモンターを黒塗りにできる（ただし特別なドライバーが必要）


**短所**

- シングルサインオン非対応
- 日本語化が中途半端（一部英語のまま）

**価格**

- 年額600,000円 (PC40台)

[**WEBサイト**](https://www.splashtop.co.jp/)

## 3) Remoteview
**長所**

- リモートプリント対応（ただし特別なドライバーが必要）

**短所**

- シングルサインオン非対応
- クライアントアプリの容量が大きい（50MB以上ある）

**価格**

- 年額480,000円 (PC40台)

[**WEBサイト**](https://www.rsupport.com/ja-jp/product/remoteview/)

## 4) TeamViewer
**長所**

- シングルサインオン対応


**短所**

- ユーザー数の制限あり
- 接続元端末の数に制限あり
- GUIがごちゃごちゃしていて使いにくい
- 日本語化が中途半端（一部英語のまま）
- ログが複雑で、解読しにくい

**価格**

- 年額992,000円 (PC40台)

[**WEBサイト**](https://www.teamviewer.com/ja/)

## 結論
**価格**

- ConnectWise Control: 324,000円 (PC50台)
- Splashtop: 600,000円 (PC40台)
- RemoteView: 480,000円 (PC40台)
- TeamViewer: 992,000円 (PC40台)

結論として、ConnectWise Controlが一番コストを抑えられ、その上PC50台の契約になるのでコスパも抜群です。10台分のライセンスが余るので在宅勤務だけではなく、サーバー管理など他の用途にも利用できそうです。

**機能**

弊社では既にOffice 365を展開しているので、リモートツールとOffice 365を連携して、シングルサインオンを実現することが理想でした。

上記4製品つのうち、SAML認証に対応しているのはConnectWise ControlとTeamViewerだけでしたので、最終的にこの2つからの選択となりました。

価格と使いやすさを考慮すると、ConnectWise Controlが最適なツールと判断し、導入が決定されました。
Nuxtでredirectする方法

https://github.com/nuxt/nuxt.js/issues/1843 によると、設定ベースでやる方法はない。

- A. 空のページを配置して、fetchでprogrammaticallyにrecirectさせる
- B. middlewareで似たようなことする



## A. 空のページを配置して、fetchでprogrammaticallyにrecirectさせる

例: ```/```にアクセスすると```/posts```にリダイレクトさせたい場合

- pages/
    - index.vue
    - posts/
        - index.vue


```vue:pages/index.vue
<script lang="ts">
import Vue from 'Vue'
export default Vue.extend({
  fetch({ redirect }) {
    redirect(301, '/posts')
  }
})
</script>
```

(vue-class-component上ではどう書くのかわからなかった)

## B. middlewareで似たようなことする

https://github.com/nuxt/nuxt.js/issues/1843#issuecomment-360416960
切り捨てたほうがいいエンジニアの特徴

# はじめに

私がここ数年でフリーランスエンジニアを大多数みた中で感じたことをまとめて書いておきます。ここに書いているのは私含めてのことで自分への戒めでもあります。

# 仕事ができないフリーランスエンジニアの特徴

- 勤怠を守らない（守れない）
- 複数の仕事は頭が混乱するので無理
- 5分で終わることを忙しいから出来ないと言う
- 作業時間の割り出しに暗黙でネットサーフィンの時間を加味している
- 人に言われたことを素直に受け止められない
- 暇なくせに仕事をしない
- 社員に対して態度がでかい
- 何事も自分の先入観で判断するため行動力が弱い
- 受動的で仕事を自分から探しに行かない
- 愚痴は言うが自ら直そうとはしない
- メールの返信が異様に遅い
- 仕事が進まない理由探しに時間を使う
- 大した仕事じゃないことを工数がかかると一応言う
- 四則演算に弱い
- 最悪辞めればいいと思っている

# 出来るだけ早く見極めて切り捨てる力

使えないエンジニアは躊躇せずに切り捨てて生産性をあげていきましょう。

# 最後に

多くのフリーランスは需要に値する器を持ち合わせていません。
HARMAN UPDATED PRICING STRATEGY – ADOBE AIR SDK July 2019 適当翻訳

2019年7月8日にきた HARMAN からのメールに添付されたpdfを適当に翻訳したものです。
勉強程度にしたものなので、精度は保証しかねます。

### ステートメント

先に発表した価格に関して、我々はいただいたフィードバックを考慮し、価格の変更を行う事にしました。
主な変更は下記のものになります。


• アプリケーションを配布する限り、サブスクリプションを保持し続ける必要はなくなりました
サブスクリプションはツールの使用時のみ要求されます。作成されるアプリケーションとサブスクリプションは独立しています


• 収入による契約区分は、会社/個人の全ての収入に基づくようになります
当初はAIRアプリケーションに関連した収入のみに基づこうと考えていましたが、多くの方からどうやってその額を算出していいのかわからないという懸念を持っているようです
ですので、我々はシンプルに各プランの収入額の上限をあげる事でこの変更に対応しました
会計検査へ言及したことで、多くの懸念をいただきましたが、我々は全てのサブスクライバーの会計を確認する予定はありません
その代わり、我々が契約区分が異なっていると確信的に疑問に思った場合は、収入の詳細を要求できる条項を設けます



• `個人` と `会社` の区別を無くします
年間の収益がさほどない会社は、より安い契約区分を購入(購読)出来ます


• `プロフェッショナル` と `エンタープライズ` 向けの価格を少し安くします
我々はサブスクリプションを年単位のみにします。これは、より長い期間の見通せるロードマップを作成する為に必要です
AIR SDK v33 for Android はもうすぐ準備出来ます。そして、その他のプラットフォームへの注視も開始します
我々はより多くのプランをシェア出来る事と共にAIRの開発環境をサポートに従事する事を楽しみにしています


### 新価格

#### 無料プラン

AIR SDK、ビルドツールなどのダウンロードと使用、アプリケーションの配布は無料です
- スプラッシュ画面がアプリケーション起動時に挿入されます
- $50k/年の個人/会社の方の利用に限ります


### 商用利用

#### ベーシック

収益上限 $100K/年
- 年間利用料 $199
- ウェブサポートあり

#### プロフェッショナル

収益上限 $500k/年
- 年間利用料 $799
- ウェブサポートあり

#### エンタープライズ

収益上限なし
- 年間利用料 $1199
- 優先的メールサポートあり



### 注意事項

- 契約料金は、AIR Developer Tool を使っての再配布可能なアプリケーション作成時にかかります
- 当初は(AIR v33.0)はAndroidのみをターゲットとします。 iOS/デスクトップはAIR ver32 と同じものなので無料のままです
- AIR Native Extensionsを作成するための、AIR Developer Tool は無料です
- SDKのダウンロード前に明示的に利用規約に同意する必要があります
- HARMAN はベータ/プレリリース版のSDKを配布しますが、これはエンドユーザー向けのアプリケーション作成に使うべきではありません。開発/テスト用途のみに使用してください
- 収入は会社の過去12ヶ月の収益に基づきます。料金区分は1年間は変更されません

### ロードマップ

多くの我々が予定している多くの機能更新や追加と同様のリクエスト、さらに調査/分析が必要なリクエストがありました
我々の現在の開発予定は下記になります。しかし、我々はAIRの将来に役立つようなコミュニティを残したいと思います

- 短期目標(2019年)
    - Android(64bit対応含む), iOS, Windows, MacOS 向けのAIR SDKの配布
    - Android/iOS向けのノッチディスプレイ情報
    - オブジェクトプールAS3 API
    - テキスチャメモリの増加、テキスチャ管理API
    - ANEの改良(Androidアセット,ANEのSwift対応の調査)
    - Windows 64-bit対応、パフォーマンスの改善
- 長期目標(時期は資金による)
    - デスクトップ向けのWebkitの更新
    - SQLiteの更新
    - マルチメディア対応の向上(新たしいプロトコルやコーデック)
    - Linuxサポートの調査、WebAssembly対応など
PlantUMLでER図を作成してみた

ER図を作成するために、[PlantUML](http://plantuml.com/ja/) を使ってみました。

## PlantUMLとは
UMLなどのダイアグラムを、DSL(ドメイン固有言語)で作成してくれるツールです。
※ DSL:特定領域に特化した言語


以下、公式ページより。
>PlantUML は、以下のようなダイアグラムを素早く作成するためのコンポーネントです。
・シーケンス図
・ユースケース図
・クラス図
・アクティビティ図（古い文法はこちら）
・コンポーネント図
・状態遷移図（ステートマシン図）
・オブジェクト図
・配置図 
・タイミング図 

## PlantUMLの導入手順
### 必要環境
- Homebrew
- VSCode

### PlantUMLのインストール
```bash
$ brew install graphviz
$ brew install plantuml
```

### VSCode に PlantUML のプラグインをインストール
- VSCodeを起動します
- Marketplace より、**PlantUML** をインストールします。
![スクリーンショット 2019-07-09 15.53.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215847/086492b1-fc34-a9bd-905f-9b9829c430bf.png)


### PlantUMLのファイル作成/編集
- 拡張子 **.pu** のファイルを作成します。
- PlantUML記法で、puファイルを編集します。
- VSCode上で **[Alt] + [D]** でプレビュー画面が開きます.

例 ：ER図

```:EntityRelationship.pu
@startuml EntityRelationship

package "MySQL" as target_system <<Database>> {

    entity "USERS" as users {
        + USER_ID [PK]
        --
        USER_NAME
        UID
        INSERT_DATA
        UPDATE_DATE
        DELETE_FLAG
       }

    entity "PORTFOLIOS" as portfolios {
        + PORTFOLIO_ID [PK]
        --
        # USER_ID [FK]
        --
        PORTFOLIO_NAME
        PORTFOLIO_URL
        REPOSITORY_URL
        PORTFOLIO_OVERVIEW
        PORTFOLIO_APPEAL
        PORTFOLIO_TERM
        PORTFOLIO_STATE
        NICE_COUNT
        INSERT_DATA
        UPDATE_DATE
        DELETE_FLAG
    }

    entity "PORTFOLIOS_IMAGES" as portfolios_images {
        + IMAGE_ID [PK]
        --
        # PORTFOLIO_ID [FK]
        --
        PORTFOLIO_IMAGE
        INSERT_DATA
        UPDATE_DATE
        DELETE_FLAG
    }

    entity "PORTFOLIOS_SKILLS" as portfolios_skills {
        + SKILL_ID [PK]
        --
        # SKILL_CD [FK]
        # PORTFOLIO_ID [FK]
        --
        INSERT_DATA
        UPDATE_DATE
        DELETE_FLAG
    }

    entity "PORTFOLIOS_URLS" as portfolios_urls {
        + URL_ID [PK]
        --
        # PORTFOLIO_ID [FK]
        # URL_CATEGORY_ID [FK]
        --
        URL
        INSERT_DATA
        UPDATE_DATE
        DELETE_FLAG
    }

users --right--o{ portfolios
portfolios -down-|{ portfolios_images
portfolios -down-|{ portfolios_skills
portfolios --|{ portfolios_urls

@enduml
```

Entityで各テーブルを定義して、最後にそれぞれのリレーション情報を記載するだけです。

### 画像出力
- 以下コマンドで、puフォルダと同じディレクトリにpngファイルが出力されます。

```bash
$ plantuml EntityRelationship.pu
```

出力画像↓
![EntityRelationship.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215847/4d02adfc-b591-0e8a-6dcf-7c39bf2ef1ea.png)

## まとめ
Excelや他の描画ツールのGUIで図形をペタペタ貼って作成するより、コードでかける方がだいぶ楽に感じました。
記法もシンプルで簡単でした。

あと、コード管理できるのは便利だと思いました。
Git等で管理すれば、コード差分や変更履歴がわかるので、設計周りのドキュメント管理がしやすくなると思います。

## 参考
- [PlantUML で ER 図（ERD）を描く（似非ではないです）](https://qiita.com/Tachy_Pochy/items/752ef6e3d38e970378f0)
- [UMLの爆速プレビュー環境をVisual Studio Code + PlantUML Server on Dockerで簡単に構築する](https://dev.classmethod.jp/tool/plantuml-server-on-docker/)
Google Coral 比較 Raspberry Pi 4 と Jetson Nano

最先端の推論に対する私の賭けは、tpu（コーラル）またはcpu-only（ラズベリー）のソリューションにあります。

![unnamed-_2_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/6eaa452b-6022-1587-bec3-f0a44726ffe4.jpeg)

サンゴの場合：TPUは1ワットあたり非常に魅力的な性能を発揮します。多くの軽量推論タスク（顔検出、セグメンテーション、オブジェクト検出など）では、サンゴが最善の解決策になります。 Googleは、[tf-lite] （https://www.tensorflow.org/lite） を使用したモデリングと[mediapipe] （https://github.com/google/mediapipe/） を使用した推論の両方をサポートしています。ごく短期間でシステム全体をトレーニング、最適化、および展開し、生産品質を期待できます。

 
![微信图片_20190606175850.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/a2a357de-a89e-474c-fdbc-84e0162991f6.jpeg)


NANO
もう一方の端は、私が非常に興奮しているCPUのみの推論です。 CPUでは、高度に量子化された特殊なモデルが必要です。いくつかのスタートアップ（例えばxnor.ai）がこれに取り組んでいますが、彼らはあなたにハードウェアではなくモデルを売りたいと思っています。ソフトウェアツールキットがコモディティ化されれば、これらのソリューションは非常に普及するでしょう。

 

Jetsonの最大の問題は、同じ会社によってエンドツーエンドで開発されていないことです。 Facebookは組み込みシステムを気にしていないし、NvidiaがGPUを売るのを手助けすることも望んでいない。そのため、Jetsonは常にPytorchコミュニティの2番目の市民です。それに加えて、組み込みシステムでGPUを使用することは、非常に特殊なユースケースがない限り、悪い選択です。

![raspberry-pi-4-1gb.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/2eae2e0f-b543-1cee-7aa6-c6edb200c2b9.jpeg)


Rasp pi 4


RPi 4 +コーラルUSBアクセラレータを検討しましたか？ それは良い組み合わせかもしれません。

しかし、私自身の意見を述べるために：

Google Coral - お勧めしません。 ソフトウェアエコシステムのため、RPi 4 + USBアクセラレータをお勧めします。 デメリットは、テンソルフローライトのみのサポートです。
RPi 4自体 - 十分に強力ではありません。

Jetson - 良い妥協案 RPi 4自体よりも強力な、より多くのライブラリーをサポートします。

![微信截图_20190520145825.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/f8d34874-8739-95a3-7086-4365c53708c2.png)


Coral開発ボード

![微信截图_20190520145835.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/45a9e435-bb75-48cb-6ae0-7f110b0a2ad3.png)


Coral USB 加速器
 

Google Coralインターネットでの購入：https://store.gravitylink.com