OmniAICreator/Qiita-1.07M huggingface dataset:
Postman で API Document を作る

[Postman | The Collaboration Platform for API Development](https://www.getpostman.com/)

API Request 以外にも、実は API Document を作る機能がある Postman.
比較的簡単に作れて管理も出来るので、 API Document を作る選択肢の一つにしてみてはどうでしょうか 🚀

## シンプルな作り方

Documentation を選択します。

[![Image from Gyazo](https://i.gyazo.com/d12298d819a6091dcd0a588718961d57.png)](https://gyazo.com/d12298d819a6091dcd0a588718961d57)

新しいコレクションを作って URL を入力します。今回は GitHub API から適当に一つだけ持ってきました。もし既に API をコレクション管理している場合は、既にあるコレクションを設定可能です。

[![Image from Gyazo](https://i.gyazo.com/caf2af3e6cdc0f27a812c5afa567cd7b.png)](https://gyazo.com/caf2af3e6cdc0f27a812c5afa567cd7b)

コレクションの名前を入力します。ドキュメントの説明は設定を省略してデフォルトのままにしておきます。

[![Image from Gyazo](https://i.gyazo.com/75a6a6d43e546db3debde4d2c39e2778.png)](https://gyazo.com/75a6a6d43e546db3debde4d2c39e2778)

こんな感じで出来上がります。 View in web を押して中身を開いてみましょう。

[![Image from Gyazo](https://i.gyazo.com/1fccdb4d5bb21ae2bd89768c304d255a.png)](https://gyazo.com/1fccdb4d5bb21ae2bd89768c304d255a)

中身はこんな感じです。 URL だけ入力した状態だとドキュメントとして微妙なので、次は Request と Response を書いてみようと思います。

[![Image from Gyazo](https://i.gyazo.com/7953f4c72b6b837a30d5fe5fcca0a864.png)](https://gyazo.com/7953f4c72b6b837a30d5fe5fcca0a864)

Postman に戻って作った API URL を開き、画面右上の Examples から Default を選択します。

[![Image from Gyazo](https://i.gyazo.com/cfa299a80481c595c6a34e5c7933283c.png)](https://gyazo.com/cfa299a80481c595c6a34e5c7933283c)

Request と Response のサンプルを入力して保存します。

[![Image from Gyazo](https://i.gyazo.com/de7f9bd9a64f78212312a1bd978da56d.png)](https://gyazo.com/de7f9bd9a64f78212312a1bd978da56d)

Web で開いている API Document に戻ります。いい感じに Request と Response のサンプルが設定されています。

[![Image from Gyazo](https://i.gyazo.com/e22e7de7722a31e637f3fa26965c7357.png)](https://gyazo.com/e22e7de7722a31e637f3fa26965c7357)

## Note

- 認証情報などもまとめてドキュメント管理できる。
- コレクション管理しておけば API Request のテストをするときも簡単に出来る。
- Swagger や API Blueprint に比べて GUI から書きやすい。
- 環境設定を複数持てるので Develop / Staging / Production などを分けることが出来る。
- 制約はあるけど Web 上で簡単に公開できる。 \*逆に言うと簡単すぎるのでセキュリティには気をつけてください。
- コレクションを json でエクスポートできるので Git 管理も可能。
- 使ったことはないけど Mock Server としても使えるらしい。
- スクリプトも書けるらしい。

## リンク

40 秒の動画説明があるトップページ: [Postman | API Documentation Generator](https://www.getpostman.com/api-documentation-generator)

Postman Document: [Documenting your API | Postman Learning Center](https://learning.getpostman.com/docs/postman/api-documentation/documenting-your-api/)
Homebrew使用後、GitHubから「Deprecation Notice」メールが来た話

## 環境

Mac OS X: 10.14.6
Homebrew: 2.2.1

## 事象

Homebrew使用後、GitHubから `[GitHub] Deprecation Notice` という件名のメールが届きました。
（brewはbundleコマンドが存在しない状態で `brew bundle dump` を実行しました）

GitHubからのメールは以下のような内容でした。
> You recently used a password to access an endpoint through the GitHub API using Homebrew/2.2.1 (Macintosh; Intel Mac OS X 10.14.6) curl/7.54.0. We will deprecate basic authentication using password to this endpoint soon:
>
> https://api.github.com/repositories/XXXXXXX
>
> We recommend using a personal access token (PAT) with the appropriate scope to access this endpoint instead. Visit https://github.com/settings/tokens for more information.

適当に訳すと、
> Homebrew, curlからBasic認証を使ってGitHub APIにアクセスがあったよ。
Basic認証は廃止になる予定だから、代わりにパーソナルアクセストークンを取得してAPIにアクセスしてね。

という内容かと思います。

## 原因

Homebrewのいくつかの機能はGitHub APIを使用しています（例：brew tapでのリポジトリ取得）。

GitHub APIの利用制限を超えた場合、APIの利用制限を拡張するために、Homebrewは環境変数`HOMEBREW_GITHUB_API_TOKEN`からパーソナルアクセストークンを取得しようとします。
パーソナルアクセストークンが存在しない場合は、Macのキーチェーンからユーザ名とパスワードを取得し、Basic認証を行います。

しかし2019/11/05、GitHubはAPIアクセスのBasic認証を廃止予定としました（[URL](https://developer.github.com/changes/2019-11-05-deprecated-passwords-and-authorizations-api/)）。Basic認証が行われるとメールが届くようになっているようです。

## 解決法
### 方法1：パーソナルアクセストークンを取得・設定する（要 GitHubアカウント）

1. https://github.com/settings/tokens から 「Generate new token」ボタンを選択し、パスワード入力。

2. 「New personal access token」画面。Noteに用途を記入。Select scopesは選択せず、「Generate token」ボタンを選択。

3. 生成されたトークンをコピーし、環境変数 `HOMEBREW_GITHUB_API_TOKEN` に設定します。
   `~/.bash_profile`に以下の行を追加します。`${YOUR_TOKEN}` は生成されたトークンを入力してください。

    ```bash:~/.bash_profile
    HOMEBREW_GITHUB_API_TOKEN=${YOUR_TOKEN}
    ```

### 方法2：キーチェーンアクセスから github.com の情報を削除する

- キーチェーンに情報が無ければBasic認証できませんので、削除してしまうのも手かと思います。

1. 名前: github.com、種類: インターネットパスワードの項目を削除。

## 参考URL

### 原因について

https://github.com/Homebrew/brew/issues/6862

https://stackoverflow.com/questions/20130681/setting-github-api-token-for-homebrew

### アクセストークン取得・設定方法について

https://docs.brew.sh/Manpage#environment
Windows×vagrant×VirtualBox環境のファイルをローカル環境で編集しよう(WinFsp)


この記事の目的

**・VM上のファイルをローカル上ネットワークドライブとしてマウントしてファイル編集する**

今までwin-sshfsを使用していたが最近動作が非常に不安定だったためとても困っていた。

[参考記事はここをクリック](https://qiita.com/onomame/items/342bc9025ac209cab34b)
使ってみるとわかりますが、すげー便利。

簡単に言うとVM上のファイルをネットワークドライブ（EとかKとか）にマウントしてまるでローカルのファイルをいじるがごとくファイルを編集できていたのでとても愛用していました。

が！！VScodeでファイルをいじっていると突然エディタが固まり、、エクスプローラーも固まり、、何もできなくなる・・・
という現象が最近発生してとてもとても困りました。

なにが原因かわからずVScodeのバージョンを落としてみたり、VirtualBoxのバージョンを変えてみたりCentOsのバージョンを変えてみたり、いじるファイルの権限を変えてみたり、いろいろ試しましたがどれもダメで突然ファイルに触れなくなったと思たらどれも動かなくなってしまう状況でどうしたもんかといろいろ試した結果WinFspというものがwin-sshfsと同じようにVM上のファイルをローカルのネットワークドライブにマウントできると知って使ってみました。

前置き長くなりましたが
[ここからWinFspをダウンロードしてください](http://www.secfs.net/winfsp/download/)（Download WinFsp Installerをクリック）

[公式のGitHubはここから](https://github.com/billziss-gh/winfsp)

設定は以下の通り（vagrant×VirtualBox前提です）
エクスプローラーからPCを右クリック「ネットワークドライブの割り当て・・」
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295552/deb471d2-308b-55b6-5c02-f70c91d69967.png)

以下をフォルダ参照先に入力（マウントするドライブはどこでもいいです）
ユーザー名やIPはvagrantのデフォルトで作成するとこれのはずです。

![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295552/3059482f-5ef5-91a7-fa07-d78b84fbb087.png)

パスワードを変えていなければデフォルトのパスワードvagrantを入力

![3無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295552/e0bdf5de-53c1-2392-96c4-5c1f33f5d8ce.png)

うまくいけば以下のように表示されます
![4無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295552/a0569ac0-ebdb-24dd-6f18-6dfd8d6876be.png)

あとはVScodeでフォルダを開いてVM上のファイルをローカルファイルのようにいじれます
今のところ特に問題なく使えておりとても快適に使えてます。
VM上のファイルをいじるのって意外と設定が大変だったりするので困っている方の手助けになれば幸いです。
Visual Studio C++を使って、Vrep上のモデルを動かす


###やりたいこと
3DmodelをVisualStudio community 2017を使って操作したい。

この要求を満たすものとして、Vrepを選びました。
**Vrepを選んだ理由**
1. 新規Robotの順運動学計算の確認をするため
2. メカ屋が作った3Dモデルを使って、簡単に動作確認ができる
3. 無料で使用できる　※商用使用ではないという条件下で無料

キーワード：Vrep,remoteApi,Visual Studio
このキーワード検索で、ヒットした過去の記事として、以下があります。
(http://moryu-io-studio.hatenablog.com/entry/2017/12/16/221623) 
但し、２年前の記事とは言え、その通りに実施しても、コンパイルエラー、Linkエラーなど動かせないという状況だったので、動作できるようにしました。
##準備
・Visual Studio community 2017のインストール
・Copellia Sim Vrepのインストール (CoppeliaSim Edu V4.0.0 rev1)
 (http://www.coppeliarobotics.com/downloads)
・サンプルに必要となるモデルの取り込み
 (https://gallery.autodesk.com/fusion360/projects/1-dof-arm-for-v-rep)
　※記事の内容を実現するには、1-DoF Arm for V-REPモデルが必要です。また、Fusion360をインストールし、モデルをVrepで読み込めるSTL、またはOBJに変更する必要があります。

##結果
Vrepのシミュレーション実行ボタンを押し、Visual Studioでデバッグ実行すると、画面上のアームが、垂直姿勢を中心にして左右に揺れます。
![Vrep_SimpleArm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305726/9aa947c2-dc9e-c542-3d32-5671621bc67f.png)
本当は、映像を出したかったのですが、分かったら、再度編集予定。
##手順
###Vrep側の設定
本設定は、モデルをインストールでき、こちらの方の作業を実施した後の話になります。(http://moryu-io-studio.hatenablog.com/entry/2017/12/16/221623)
モデルは、BaseとArmに変更しました。BaseとArmの間にJointを追加するとともに、名前をJoint1としています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305726/c794c5d8-8d27-8b8b-b0f7-bb2c98a43d1e.png)
Baseの横には、Child Scriptを埋め込んでいます。
これは、下のように、Baseで右クリックし、>Add>Associated Child Script>Non Threadedを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305726/570e9218-3d95-8e82-557f-d64d3b6791d6.png)
Child Scriptには、以下のみを記述します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305726/8bf4ff78-3e4f-a03d-6cad-602f5b649017.png)
これは、remoteAPIを使って、Visual StudioからVrepを動かすための設定(Port番号）です。
###Visual Studio側の設定
C++のコードは、以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305726/1508dbef-af3d-ea9a-0e13-19c44315173a.png)
プロジェクトの構成は、以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305726/c8ae31a9-17cc-cf3e-8718-c60154ebb31e.png)
ソースファイル、及びヘッダーファイルにextApi.*、expApiPlatform.*、expApiApiInternal.hをソリューションに追加しています。

**その他(Visual Studioのプロジェクトのプロパティの設定)**

**構成プロパティ>全般**
この中で、
共通言語ランタイムサポート：共通言語ランタイムサポートを使用しないを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305726/684eb907-fdac-6154-733e-5dc252fead30.png)

**C/C++>全般**
CoppeliaRobotics\CoppeliaSimEdu\Programming\の下のremoteApiフォルダと
includeフォルダを追加します。※インストールした場所の確認をお願いします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305726/5b961d47-d1f5-24b2-ad76-1d62362cf712.png)

**C/C++>プリプロセッサ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305726/f66048dc-fd80-a69a-27e2-c95b1ef0a758.png)

以上。
AtCoder Beginner Contest 148 参戦記

# AtCoder Beginner Contest 148 参戦記

## [ABC148A - Round One](https://atcoder.jp/contests/abc148/tasks/abc148_a)

2分半で突破. 簡単なんだけど、なんかシンプルに書こうと思うと難しいなあと思った.

```python
A = int(input())
B = int(input())

print(*(set([1, 2, 3]) - set([A, B])))
```

## [ABC148B - Strings with the Same Length](https://atcoder.jp/contests/abc148/tasks/abc148_b)

1分半で突破. 書くだけ. zip かなあと思いつつ使わなかった.

```python
N = int(input())
S, T = input().split()

print(''.join(S[i] + T[i] for i in range(N)))
```

## [ABC148C - Snack](https://atcoder.jp/contests/abc148/tasks/abc148_c)

3分で突破. 最小公倍数が答えだけど、どう解けばいいんだっけ、最大公約数が分かれば分かる?と思いつつ、Google に「最小公倍数 Python」ってググったら `lcm(a, b) = a * b / gcd(a, b)` って出てきたので書いて終わり.

```python
from fractions import gcd

A, B = map(int, input().split())

print(A * B // gcd(A, B))
```

## [ABC148E - Double Factorial](https://atcoder.jp/contests/abc148/tasks/abc148_e)

20分くらい?で突破. WA1. Dをちょっと考えたけど難しかったので、飛ばしてこっちをやってみた. とりあえずナイーブに f(n) を実装して、動かしてみた. N が奇数のときは常に0はすぐ分かった.
`N // 10` で入力例3を流すとだいぶズレたので、n 増やして試してみたところ、f(50) で数字がずれて、50には5が含まれるからカーとなる. `N // 10 + N // 50` でも入力例3とは合わず、脳内で次は250カーとなってようやくからくりが分かって実装. `while t <= N:` を `while t < N:` と書いて WA を食らったが無事AC.

```python
from sys import exit

N = int(input())

if N % 2 == 1:
    print(0)
    exit()

result = 0
t = 10
while t <= N:
    result += N // t
    t *= 5
print(result)
```

## [ABC148D - Brick Break](https://atcoder.jp/contests/abc148/tasks/abc148_d)

27分くらい?で突破. 右から処理することばっかり考えてて、難しいなと飛ばしてEからやって戻ってきたんだけど、順位表の状況から明らかに簡単なので、多分考えすぎてると左から処理することを考えたら簡単だった orz.

```python
N = int(input())
a = [int(s) - 1 for s in input().split()]

result = 0
for i in range(N):
    if a[i] != (i - result):
        result += 1

if result == N:
    print(-1)
else:
    print(result)
```

## [ABC148F - Playing Tag on Tree](https://atcoder.jp/contests/abc148/tasks/abc148_f)

突破できず. ミニマックス法なのは分かったけど、過去問であたったのは一回だけで、幅優先だとどうなるんだろうと考えているうちに終わった. 精進不足.

追記: ミニマックス法じゃなかった(爆). 解説PDF通りで、青木さんから一番遠いところかつ高橋さんのほうが一番近いところの一個手前で捕まる感じで実装すれば良い.

```python
from sys import exit

N, u, v = map(int, input().split())

if u == v:
    print(0)
    exit()

edges = [[] for _ in range(N + 1)]
for _ in range(N - 1):
    A, B = map(int, input().split())
    edges[A].append(B)
    edges[B].append(A)


def calc_destination(start, edges):
    destination = [-1] * (N + 1)
    destination[start] = 0
    q = [start]
    while len(q) != 0:
        current = q.pop()
        for n in edges[current]:
            if destination[n] != -1:
                continue
            destination[n] = destination[current] + 1
            q.append(n)
    return destination


tak = calc_destination(u, edges)
aok = calc_destination(v, edges)

result = 0
for i in range(1, N + 1):
    aoki = aok[i]
    if tak[i] >= aoki:
        continue
    if aoki > result:
        result = aoki
print(result - 1)
```
pythonのseleniumで`arguments[0].scrollIntoView();`が失敗するときの対応

## 概要

pythonのseleniumで**arguments[0].scrollIntoView();** を使って画面の表示位置を調整していたスクリプトを久しぶりに動かしたときにエラーで落ちてしまったのでその対応方法

## 対処方法

```python
self.driver.execute_script("arguments[0].scrollIntoView();", inputLabel)
```
から

```python
inputLabel.location_once_scrolled_into_view
```

に変更しました。
`inputLabel`はwebdriverのfind_element_by_XXX のメソッドで取得した要素になります。

## 状況

* seleniumの処理中画面の範囲外の要素を操作しようとすると`MoveTargetOutOfBoundsException`が発生してしまうので、対処として**arguments[0].scrollIntoView();**を使って画面をスクロールしてから動かすようにしていました。
* そのスクリプトはしばらく動かしていなかったのですが、最近使うかもということで動作確認をしたところ`javascript error: arguments[0].scrollIntoView is not a function`
とエラーが・・・
* いろいろしらべたところ[stackoverflow](https://stackoverflow.com/questions/55492695/javascript-error-arguments0-scrollintoview-is-not-a-function-using-selenium-o)の状況のようなのでこちらの方法を採用
* 公式ドキュメントでは勝手に変更するかも？とあったのでださいですがtry,exceptで失敗したときのみ動作するようにしました。
Google public Dns

###### tags: `Advent calendar`
# Google public DNSについて

### はじめに

### DNSとは
DNS(Domain Name System): ドメインとIPアドレスを対応付けて管理するシステムのことをいう。
〜　わかりやすくいうと ~
コンピュータの住所である<strong>IPアドレス</strong>を、人が理解しやすい住所へと変換するための仕組み。

~ 例えば　~
```
www.google.com = 172.217.31.164
                 172.217.26.14
```
など

 ## Google Public DNSとは
 その名の通りGoogle社が提供している<strong>無料</strong>のDNSキャッシュサーバサービス。
 
 >> DNSキャッシュサーバ：DNSキャッシュサーバが保持している名前解決データベースから情報があれば、DNSコンテンツサーバに問い合わせをせずにクライアントにサイト情報を返す。なければ、DNSコンテンツサーバに問い合わせをする。
 
## Google Public DNSのここがすごい！
<ol>
<li>ブランド力がすごい！</li>
<li>セキュリティが強い</li>
<li>応答速度が速い</li>
</ol>

<ol>
<li>ブランド力がすごい</li>
<p>googleという大企業が提供しているだけあり、ブランドがあるところがすごい
<li>セキュリティが強い</li>
<p>googleは色々な攻撃に対応している。カミンスキー攻撃や、Dos攻撃など</p>

## なぜこのテーマにしたのか。
avastでフルスキャンでnetwork管理をセッティングしたところ、下記のような画像が、、、、、、
![スクリーンショット 2019-12-03 20.41.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541740/2838a07a-e98c-69a8-d512-235916c13067.png)

対応策の一つが、
DNSをGoogle public dnsに変更しろとのこと

Google public dnsのDNSserverのアドレスは(IPV4)
```
優先server: 8.8.8.8
代替server; 8.8.4.4
```
覚えやすいですね。基本的には、初期設定では、プロバイダが指定しているDNSserverを使っています。
java　条件分岐

今日は条件分岐について書きます。

# 条件分岐とは
　条件を満たした場合と満たさなかった場合の処理を行う
　コードのこと


# if文
　最も基本的な条件分岐式

基本形はこのような形です。

if()の中に条件式(a=1,a>2など)を設定し
成立した場合最初の{}の中の処理を行い
成立しなかった場合else後の{}の中の処理を行います。

※else以降のコードがなくても動作しますが
　何も出力されないだけなので。原則設定します。

```java:if文基本構文
  if(条件){
    //条件と合致した場合の処理
  }else{
    //条件と合致しなかった場合の処理
  }

```

例文はこちら
numberを1と設定してるので
正解と出力
1以外の場合が設定されると
不正解
さらに不正解と出力されます。

```java:if文
public class Main {
	public static void main(String[] args) {
      int number = 1;
      if(number == 1){
          System.out.println("正解");
      }else{
          System.out.println("不正解");
          System.out.println("さらに不正解");
      }
	}
}
```

## else if文　(条件の追加)
さらに細かい条件分岐をしたい場合はelseif文を間に書きます。

if()を条件1とし
else if()を条件2とします。
さらに続けてelse if()を書けば
条件3
同上
条件4
と増やして行けます。


```java:if文基本構文
  if(条件1){
    //条件1と合致した場合の処理
  }else if(条件2){
    //条件2と合致した場合の処理
  }else{
    //条件1,2どちらとも合致しなかった場合の処理
  }

```

例文はこちら
numberを1と設定してるので
スキ!と出力
numberが2と設定されたら
❓と出力
1以外の場合が設定されると
キライと出力されます。

```java:if文
public class Main {
 public static void main(String[] args) {
      int number = 1;
      if (number == 1) {
        System.out.println("スキ！"); // 条件1が成立した場合の処理
      }else if(number ==2){
        System.out.println("❓") ;  //条件2が成立した場合の処理
      }else {
       System.out.println("キライ"); // 条件式が成立しなかったときの処理
      }
  }
}
```

# 比較演算子
条件という単語がでてきていますが。
その中で数値を扱う場合の処理を紹介します。

ざっくりいうと下のように書きます。
==で同じ
!=でそれ以外など
珍しい形が多いので注目すべきです。

```java:比較演算子
if(例==1)//等しい場合
if(例>1)//1を超える場合
if(例>=1)//1以上の場合
if(例!=1)//1以外の場合
```

一覧を作ったので参考までに見て下さい。

| 比較演算子 | 条件成立する時 |
|:-:|:-:|
| a==b  | aとb等しい  |
|  a>b |  aがbを超える場合 |
|  a<b |  aがb未満の場合 |
|  a>=b |  aがb以上の場合 |
|  a<=b |  aがb以下の場合 |
|  a!=b |  aがb以外の場合 |
Webpackで出力したbundleのハッシュ値を抽出して使う

個人的に開発しているサイトではWordPressのPHP上にReactを載せており、そこではbundleのハッシュ値をPHP側で参照できるようにしています。[extract-hash-webpack-plugin](https://github.com/shallinta/extract-hash-webpack-plugin)を使うと任意のテキスト形式でハッシュ値を含んだファイルを出力できます。今回はPHPから参照したいので`.php`の形式で出力してみます。以下が`webpack.config.js`の例です。


```js
var path = require('path');

var ExtractHashWebpackPlugin = require('extract-hash-webpack-plugin').default;
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

const DIST_PATH = "theme/dist";

module.exports = {
    entry: "./src/index.tsx",
    output: {
        filename: "index.[hash].js",
        path: path.resolve(__dirname, DIST_PATH)
    },
    /* ... */
    plugins: [
        new ExtractHashWebpackPlugin({
            dest: DIST_PATH,
            filename: 'version.php',
            fn: hash => `<? $JS_HASH = '${hash}'; ?>`
        }),
        /* ... */
    ]
};
```

プラグインの`fn`オプションでハッシュ値を使った出力を定義できます。今回は変数`$JS_HASH`にハッシュ値を保存するPHPのコードを出力するようにしています。
D言語でBDDするcucumber-dの使い方

# はじめに

[cucumber-d](https://github.com/simdnyan/cucumber-d/)を作ったので、簡単に使い方を紹介します。

![cucumber-man.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98084/c6df15fe-cec3-0394-5c64-16b2540e256b.png)

# cucumber-d

読んで字のごとく、CucumberのD言語実装です。
以下のことができます。

- Gherkinで書かれたfeatureファイルのパース
- D言語で書かれたStepファイルの実行

# 使い方

[httpbin](https://github.com/simdnyan/cucumber-d/tree/develop/examples/httpbin)を例に解説します。

```
$ tree examples/httpbin/
examples/httpbin/
|-- bin
|   `-- .gitkeep
|-- features
|   |-- step_definitions
|   |   `-- steps.d
|   |-- support
|   |   `-- env.d
|   `-- httpbin.feature
|-- .gitignore
|-- dub.json
`-- dub.selections.json
```

以下のfeatureファイルでhttpbin.orgにアクセスし、ステータスコードを検証します。

```gherkin:features/httpbin.feature
Feature: Assert httpbin response

  Scenario: httpbin returns 200 OK
     When the user sends a GET request to http://httpbin.org/
     Then the response status should be 200

  Scenario Outline: httpbin returns 4xx
     When the user sends a GET request to http://httpbin.org/status/<codes>
     Then the response status should be <status>

    Examples:
     | codes | status |
     | 400   | 400    |
     | 404   | 404    |
```

## Stepファイル

StepファイルをD言語で書きます。
`@Given`, `@When`, `@Then` のUDAが付与されているメソッドがStepのキーワードに対応します。
ここでは値の検証に[unit-threaded](https://code.dlang.org/packages/unit-threaded)を使っています。
cucumber-dは実行時に`Exception`のみcatchするため、値の検証に`assert`が使えないので注意が必要です。


```d:features/step_definitions/steps.d
module step_definitions.steps;

import cucumber.keywords : When, Then;
import requests : Request, Response;
import unit_threaded.assertions : should;

///
Response response;

///
@When("^the user sends a GET request to (?P<url>.*)$")
void sendAGetRequestTo(string url)
{
    response = Request().get(url);
}

///
@Then("^the response status should be (?P<code>[0-9]+)$")
void theResponseStatusShouldBe(int code)
{
    response.code.should == code;
}
```

## app.dに相当するもの

ここでは、`features/support/env.d` に配置しています。
CucumberのRuby実装等は必要に応じてファイルを作成しますが、cucumber-dでは必須です。
先ほどの`step_definitions.steps`を指定して`CucumberCommandline`クラスのrunを呼び出します。

```d:features/support/env.d
module env;

import cucumber.commandline : CucumberCommandline;

int main(string[] args)
{
    return (new CucumberCommandline).run!("step_definitions.steps")(args);
}
```

## コンパイルと実行

上記のapp.dに相当するものが実行され、features/ディレクトリ以下のfeatureファイルが実行されます。

![compile_and_run](https://github.com/simdnyan/cucumber-d/blob/develop/img/httpbin_example.gif?raw=true)

# おわりに

Cucumberの主たる機能の内、以下の機能が未実装なので今後実装予定です。

- StepへのTableData渡し
- StepへのDocString渡し
- `--format json`
- Rule:
- Language:


未実装の機能がいくつかあるため本家と同じようには動かせませんが、Cucumberの基本的な機能は使える状態です。
是非使ってみてください。
Glueのデフォルト値が不親切な件

最近AWSのGlueを使ったETLを作って実行してみました。単純なCSVをRDSにインサートするだけの処理だったので非常に軽いジョブです。何度かジョブの成功失敗を繰り返し、翌日請求ページで確認したら1000円くらいの課金になっていました。ほとんどCPUを使わないはずなのになぜ？？？と思い、調べたところデフォルト値が不親切だったのでそのメモです。

#Glueとは
プログラミングレスでETLジョブやデータカタログを作成できるAWSのフルマネージドサービスです。CSVをそのままRDBにインサートするだけであれば、ウィザードに沿ってポチポチ押していけばできちゃいます。

#Glueジョブの料金体系
公式ページより
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191613/d63b209a-dda1-8f21-f09d-9255b0937e93.png)

ちょっと分かりにくいですが、DPUがCPUみたいなものでデフォルト10、軽いジョブを実行しても最小10分が課金対象となるので0.44USD × 10DPU × 10/60時間 = 0.733USD
どんなに軽いジョブでも1回あたり100円弱かかるということです。

#Glueのデフォルト値
ジョブ作成の画面では以下のように「セキュリティ設定、スクリプトライブラリおよびジョブパラメータ (任意)」が閉じられています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191613/3209ad9e-1087-8701-f9ed-da5d061055af.png)

これを開くとわかりますが、最大容量が10になってます。何も知らずにウィザードを進めていくとデフォルト10になってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191613/5d5fd803-e823-8eb8-27d7-8cf7455472bf.png)

#対策
DPUは最小2に設定できるのでジョブ作成の時に「セキュリティ設定、スクリプトライブラリおよびジョブパラメータ (任意)」を開いて2に設定すれば1ジョブあたり20円弱に抑えられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191613/61edcc99-bb4e-bc98-1c39-0a1c55fac26e.png)
Cloud Functions for FirebaseでRequest has invalid method. GETかBad Request, INVALID_ARGUMENTならこれかも？

#Overview

私はFunctionsからBigQueryに問い合わせて、結果をただ返したかっただけだった。
しかし、```"message:"Bad Request", status:"INVALID_ARGUMENT"```の闇に遭難することになる。
今回はその中で、Functionsのログに```Request has invalid method. GET```と出るケースを扱う。
Bad Requestは様々な理由が考えられるため、Functionsのログをみて該当するケースか確認してほしい。
（巨大なオブジェクトが出力されているため冒頭のエラーを見るのはなかなか大変だが）

#Target reader

```Request has invalid method. GET```が解決できないユーザー

#Body

##いきなり結論

結論的には似たようなケースを扱ったことがあるのでそこから抜粋する。
https://qiita.com/qrusadorz/items/40234ac0b5c5c2315cad

>FirebaseのCloud Functionsには2つの関数があります。
1. functions.https.onCall
2. functions.https.onRequest
>
1はSDKが用意されているAndroid,iOS,Javascriptから呼び出されるタイプ。
https://firebase.google.com/docs/functions/callable?hl=ja
2はSDKがない場合、汎用のWebAPIとして作成するタイプ。
https://firebase.google.com/docs/functions/http-events?hl=ja

```functions.https.onCall```で作っている場合、汎用のWebAPIとは異なり```https.onCall のプロトコルの仕様```に従わなくてはならない。
どういう縛りがあるのか、公式ドキュメントから仕様を抜粋する。
https://firebase.google.com/docs/functions/callable-reference?hl=ja

>リクエストの形式: ヘッダー
>呼び出し可能なトリガー エンドポイントへの HTTP リクエストは、次のヘッダーが含まれる POST にする必要があります。
>
>必須: Content-Type: application/json
>オプション: Authorization: Bearer <token>
>オプション: Firebase-Instance-ID-Token: <iid>
>
>その他のヘッダーが含まれる場合は、下記のレスポンスに関するドキュメントで説明されているように、リクエストは拒否されます。

まずヘッダーにapplication/jsonが必須。
日本語がおかしいが、リクエストは**GETではなくPOSTでなくてはならない。**

>リクエスト本文
>HTTP リクエストの本文は、次のいずれかのフィールドが含まれる JSON オブジェクトにする必要があります。
>
>必須: data - 関数に渡される引数です。これには任意の有効な JSON 値を使用できます。これは、以下で説明するシリアル化形式に従って、>JavaScript のネイティブ型に自動的にデコードされます。
>リクエストに他のフィールドが存在する場合、バックエンドはそのリクエストの形式を不正とみなし、リクエストは拒否されます。

そして本体にはdataフィールドが必須。

私がどうやってAPIにアクセスしていたか、確認しよう。
```serve```コマンドでローカルサーバーを立てる。
準備ができると、以下のようなログがVSCodeのターミナルに出力される。（Function名はsearchItems）

```
functions[searchItems]: http function initialized (http://localhost:5000/<project-Id>/asia-northeast1/searchItems).
```

ここでツールチップの通り、Ctrl+クリックで()n内のURLにアクセスしていた。
つまり```https.onCall のプロトコルの仕様```を完全に無視したわけだ。
それは1時間たっても解決するはずないですわ:joy:

POSTでリクエストを送るため、POSTMAN…、ここはVSCodeでお手軽なやつを探して、@toshi0607さんの紹介されているREST Clientを採用。
https://qiita.com/toshi0607/items/c4440d3fbfa72eac840c

request.httpというファイルを作って、下記のリクエストを作成。
```<projectId>```は自身のものを利用すること。
Content-TypeとBodyの間に1行の空行は必須。

```text:request.http
POST https://asia-northeast1-<projectId>.cloudfunctions.net/searchItems
Content-Type: application/json

{
	"data": {}
}

```

Send Requestボタンをクリックすると正常に応答が来る。
めでたくBigQueryよりデータが取れている。

```text:response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
（中略）

{
  "result": [
    {
      "id": 1,
      "text": "item1",
      "timestamp": 1
    },
    {
      "id": 2,
      "text": "item2",
      "timestamp": 2
    }
  ]
}
```

#Conclusion

VSCodeの甘い誘いにより、泥沼に引き込まれた話でした。
```functions.https.onCall```はクライアントからコールする際は便利ですが、WebAPIとして利用する場合には隠蔽されている部分に準拠する必要があるので注意しましょう。
今回は認証を使っていないため軽傷でしたが、認証が必須のFunctionでは```Authorization```にログイン後にuserオブジェクトが持つトークンが必要になります。
トークンは1時間で無効になるおまけ付きなので、REST Clientからコールするよりアプリからコールすることを検討したほうがいいでしょう。
（アプリでは自動的にトークンの期限が延長されるため、期限切れの心配が不要です）
Ovtoの課題

このエントリは[Opal Advent Calendar 2019](https://qiita.com/advent-calendar/2019/opal)の8日目のエントリです。

## Ovtoとは

私が作っているOpal用のWebフレームワークです。

- https://rubykaigi.org/2019/presentations/yhara.html#apr19

## Ovtoの課題

設計時にあまり考えてなかったのですが、ミドルウェアを作るときに記述が煩雑になるという問題がありそうです。

例えばpockeさんが作ってくれた[ovto-router](https://github.com/pocke/ovto-router)を見ると、stateとactionのそれぞれに`ovto_router`というprefixを付けていることが分かります。現状のOvtoではstate・actionの名前空間が一つしかないので、衝突を回避するためにprefixを付ける必要があります。

このへんを簡潔に書けるようになるとミドルウェアがより作りやすくなるかなと思っています。何かうまくやる方法があるといいですね(まだノーアイデア)。
ポケモンGOを記録する技術

この記事は[なんか布教したいエンジニア Advent Calendar 2019 \- Qiita](https://qiita.com/advent-calendar/2019/engineer_tail) 23日目の記事です。

## ポケモンGOの何を記録するのか

夫婦でポケモンGOをプレイしているのですが、タマゴを孵化させたときに、お互いのアカウントによって生まれてくるポケモンに偏りがある気がしたので、孵化させたポケモンを記録することにしました。2017年の1月から始めたので、もう3年近く記録を取り続けたことになりますね。すごい。

## ポケGO知らない人向け：タマゴについての補足

ポケモンGOにはガチャがありませんが、唯一ガチャっぽい要素として「ポケモンのタマゴ」というものがあります。ポケモンのタマゴは通常のアイテムのようにポケストップ（マップ上に存在するアイテム回収スポット）から回収し、特定の距離をリアル世界で歩くことで、タマゴからポケモンが生まれる仕様です。タマゴに入っているポケモンはランダムで、かつ、どのポケモンが生まれてくるかはタマゴを孵化させないとわかりません。タマゴは「2km」「5km」「7km」「10km」の4種類あり、それぞれ孵化に必要な歩行距離が異なります。

## どうやって記録するか

LINE Messaging APIとSQLite3（とMojolicious::LiteというWebフレームワーク）を使用して記録しています。

ポケモンが孵化するたびに、LINEに`タマゴの種類 生まれたポケモンの名前`の書式で投稿することで、DBに以下の情報が記録されます。

* 投稿したユーザーの名前（妻/夫）
* タマゴの種類（2km/5km/7km/10km）
* ポケモンの名前
* ポケモンの世代（初代のポケモンなら1、金銀のポケモンなら2、RSEなら3...）
* 投稿日時

実際の投稿画面はこんな感じです。
![screen1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321603/f01f3f42-9089-6fe4-f9cd-3cf3a37fa5ed.png)
LINEを使うことで、わざわざ記録用にAndroidアプリを作成しなくても良いのと、サーバサイドだけ考えればいいので実装がめちゃくちゃ楽という恩恵が受けられます。

## どうやって記録を見るのか

蓄積した情報から統計が取れないと意味がないので、我が家では以下2種類の方法で統計が見られるようにしています。

* LINE botに問い合わせする
* Metabaseを使う


###  LINE botに問い合わせする
今まで孵ったポケモンの数や、孵化した数のランキングなんかが取得できるようになっています。
![screen3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321603/eb01bc22-f6ba-ec88-d667-2dc072221d04.png)

###  Metabaseを使う
LINEでも用が足りるといえば足りるのですが、テキストベースなので、いまいち数が実感としてわからないという問題がありました。
そこで[Metabase](https://www.metabase.com/)です。MetabaseはOSSのデータ可視化ツールで、**SQLite3に対応しています**（ここ重要）。Elasticsearchが前提のKibanaと違い、それ単体で動作することと、インストールとセットアップがめちゃくちゃ簡単という理由で採用されています。
![screen2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321603/80793641-3709-6264-cf35-aba9c84242b9.png)
めちゃくちゃわかりやすいダッシュボードが起動から10分位でつくれます。すごい。
各データが可視化されることで、例えば「なぜかわからないがヨーギラスが突然すごい勢いで生まれるようになった」とかの情報が、体感ではなくデータからわかるわけです。

途中から実装された3世代（RSE）のポケモンのほうが2世代（金銀）のポケモンより生まれてるとか、BWのポケモンは全然生まれないとかもわかるようになりました。（スクショ中段の左から1番目のグラフが夫のグラフ、3番目が妻のグラフ。）
![screen4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321603/608a072a-e399-cdc3-cfc8-82b66e3ae5fb.png)

フィルターが使えるので、例えば「4世代（ダイパ）実装後に、10kmタマゴから生まれたポケモン」も調べられます。
![screen5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321603/6c7b1332-7d32-52fd-e8ce-bcf54c854f55.png)
左が夫のグラフ、右が妻のグラフ…なのですが、フカマル生まれてなさすぎてやばいですね。7/702で出現率が1%を切ってしまってるんですが、有利誤認表示とかにならないんでしょうか。

## まとめ

LINE Message APIとMetabaseの組み合わせの布教記事でした。
ポケモンGOやゲームの結果に限らず、買い物を頼んだ回数とか、帰宅時間をLINE経由で記録してMetabaseで可視化したり、使い方は無限大なので、ご家庭に合わせてぜひ導入してみてください。
OpenFOAMのpostProcessコマンドでVTK出力

# 概要
OpenFOAM 4以前ではsampleコマンドで分布やコンターのデータを取得できてましたが，ver 4以降ではsampleコマンドに代わってpostProcessで処理するようになりました。postProcessコマンドでのデータ出力の手法についてまとめます。

ここではコンターをかくことを想定して，vtkデータを出力します。LES等の解析でデータ量が大きいと，paraFoamで開くのに時間が非常にかかります。またさらにそこからコンターを書こうとしても時間がかかります。そこでvtkではじめからコンター用のデータを出力しておいて，可視化にかかる時間節約を行います。

# 手順
## foamGet
公式の説明（ https://cfd.direct/openfoam/user-guide/v6-graphs-monitoring/ ）にあるとおりですが，はじめにfoamGetコマンドでサンプルを作るのが手っ取り早いです。コンター出力にはオプションでsurfacesを指定します。

``` bash
$ foamGet surfaces
```

これでsystem以下にsurfacesというファイルが作成されます。
caseDicts/postProcessing/visualization/surfaces.cfg（特に設定を変えていない場合はOpenFOAM内のetc以下にcaseDictsがあります）がリファレンスとして使われます。なので$cuttingPlaneなどはsurfaces.cfgですでに定義されている値に置き換わります。

cuttingPlaneがサンプルファイルでのtypeになっています。type planeの方がデータを節約できるので，以下のように修正します。


``` c++
/*--------------------------------*- C++ -*----------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     | Website:  https://openfoam.org
    \\  /    A nd           | Version:  6
     \\/     M anipulation  |
-------------------------------------------------------------------------------
Description
    Writes out surface files with interpolated field data in VTK format, e.g.
    cutting planes, iso-surfaces and patch boundary surfaces.

    This file includes a selection of example surfaces, each of which the user
    should configure and/or remove.

\*---------------------------------------------------------------------------*/

#includeEtc "caseDicts/postProcessing/visualization/surfaces.cfg"

fields       (T U p);

surfaces
(
    yz
    {
        type                 plane;
        planeType            pointAndNormal;    // always triangulated
        pointAndNormalDict
        {
            basePoint       (0 0 0);
            normalVector    (1 0 0);
        }
    }
);

// ************************************************************************* //
```

+ fieldsが出力する変数
+ OpenFOAM 4より前だと，type planeを指定するときににplaneTypeのオプションは必要なかったみたいですが，今は必要です。

## postProcess
surfacesのファイルが修正できたら，postProcessを実行します。オプションにsurfacesを与えます。

``` bash
$ postProcess -func surfaces
```

うまく行けば，postProcessing/surfaces以下にデータが出力されます。

caseDicts/postProcessing/visualization/surfaces.cfgで出力形式がvtkになっているので，vtkファイルが作成されます。gnuplotでプロットするならsurfaceFormat   raw;にします。（多分。確かめてないけど）ただし，pm3d使ってコンターを書くときにgnuplotだと，データに適当なところで空白行がないとpm3dの処理で失敗します。データサイズが大きいと，手で修正するのもつらいので，gnuplotによるコンター作図はやめました。vtk出力にして，matplotlibでの作図に乗り換えました。

# 蛇足：OpenFOAMで出力されるVTKファイルの精度
これでVTKファイルが出力できました。ここで若干問題が発生するときがあります。というか問題が出ました。
多成分気体の計算をしてますが，この解析では各ガス種の質量分率が変数として出てくるので，そのデータをVTKを作りました。VTKデータ自体は特に問題なく生成されるのに，いざparaviewでVTKを見てみると，値が1e33とかになっているところがあります。分率なので0から1の値にしかならないはずなのにとてもおかしい。

結論からいうと，VTKでのcell dataの精度がfloatなのが原因でした。0に非常に近い値として1e-39オーダーのデータが含まれていたため，単精度浮動小数のレンジからはみ出すので，paraviewで可視化するとおかしなことになるという結果でした。cell dataの精度をdoubleにしたら無事解決。OpenFOAMの計算では倍精度にしてますが，可視化用のデータ出力の精度は元の計算結果とリンクしてないっぽいです。

単精度浮動小数点で表現できる最小の正の数が1e-38オーダーだってのを初めて知りました。https://ja.wikipedia.org/wiki/単精度浮動小数点数
2019年のOpal

このエントリは[Opal Advent Calendar 2019](https://qiita.com/advent-calendar/2019/opal)の1日目のエントリです。

## 2019年のOpal

今年のニュースはなんといっても[Opal 1.0.0](https://github.com/opal/opal/releases/tag/v1.0.0)がリリースされたことでしょう:tada:
0.11の頃から、もう1.0と言っていいくらい安定して動いていましたが、正式に1.0が出るとやはり嬉しいですね。

そのあと小さな修正が入って、最新版は[Opal 1.0.2](https://github.com/opal/opal/releases)となっています。

## 2019年のOpalと私

個人的なところでは、4月のRubyKaigi 2019 福岡で[Ovto](https://github.com/yhara/ovto)というOpal用フレームワークを発表しました。

- [Ovto: Frontend web framework for Rubyists \- RubyKaigi 2019](https://rubykaigi.org/2019/presentations/yhara.html#apr19)

Ovtoについてはこのカレンダーの別の日にまた書くかもしれません。
Java8 リスト変換を Stream map で

リスト変換について、for 文を使う場合と Stream map を使う場合で比較していきます。
以下のリストを使います。

```java:stream-map.java
final List<String> months = 
Arrays.asList("January", "February", "March", "April", "May", "June", "July", "Augast", "September", "October", "November", "December");
```

それぞれの要素の一文字目だけで構成されるリストを作ります。
#### 1. for 文を使う
一文字目を格納する空のリストを宣言し、for ループ内で一文字ずつ格納しています。

```java:for.java
final List<String> firstChars = new ArrayList<>();
for (String c : months) {
  firstChars.add(c.substring(0,1));
}
for (String fc : firstChars) {
  System.out.print(fc);
}
```
以下のように出力されます。
JFMAMJJASOND

#### 2. forEach 文を使う
関数型に書き換えたものの、空のリストをプログラマ側で用意する必要があります。

```java:forEach.java
final List<String> firstChars = new ArrayList<>();
months.forEach(c -> firstChars.add(c.substring(0,1)));
firstChars.forEach(System.out::print);
```

#### 3. Stream map() を使う
空のリストを用意するステップはなく、リストから最初の一文字ずつ取り出した結果が、そのまま新しいリストに格納されるように見えます。
Stream の map() メソッドは連続した入力を連続した出力に変換します。

```java:stream-map.java
final List<String> firstChars = months.stream().map(c -> c.substring(0,1)).collect(Collectors.toList());
firstChars3.forEach(System.out::print);
```

map() メソッドは、入力のリストと出力のリストの要素数が同じになることを保証しますが、データ型については同じになるとは限りません。
もし、各要素の文字数を取得したい場合、文字列型から数値型に変換されて出力されます。

以下は変換後のリストは用意せずに、forEach で要素の内容を直接出力しています。
その程度であれば、1行で記述が可能となります。

```java:stream-map2.java
months.stream().map(c -> c.length()).forEach(cnt -> System.out.print(cnt + " "));
// 7 8 5 5 3 4 4 6 9 7 8 8 と出力される
```
#Rails の ActionMailer で利用するテンプレートのパス・ファイルをデフォルト以外で指定する (  ActionView::MissingTemplate: ))

`app/view/path/to/directory/file.text.erb` を使いたい場合

template_path にディレクトリを
template_name に拡張子を除くファイルを指定すれば良いらしい

わかりにくいな

```rb
    mail(
      to: email,
      subject: subject,
      template_path: 'path/to/directory',
      template_name: 'file'
    )
```

# Ref

Action Mailer Basics — Ruby on Rails Guides
https://guides.rubyonrails.org/action_mailer_basics.html

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2862








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【Angular Material】`mat-icon`を動的に表示したい

## はじめに
今回はAngular Materialの「[MatIcon](https://material.angular.io/components/icon/overview)」を動的に表示する方法を共有する。

## 今回使用するソースコード
```html:icon-example.component.html
<h2>アイコン増殖バグ</h2>

<button mat-flat-button (click)="addIcon()" color="accent">Add Button</button>

<div class="icon-area">
    <mat-icon>bug_report</mat-icon>
</div>
```

```typescript:icon-example.component.ts
import { Component, ElementRef, Renderer2 } from '@angular/core';

@Component({
    selector: 'app-icon-example',
    templateUrl: './icon-example.component.html',
    styleUrls: ['./icon-example.component.scss'],
})
export class IconExampleComponent {
    constructor(private renderer: Renderer2, private elRef: ElementRef) {}

    /**
     * アイコンを追加する
     */
    public addIcon() {
        const addIcon = this.createIcon('bug_report');

        const iconDiv = this.elRef.nativeElement.querySelector('.icon-area');
        this.renderer.appendChild(iconDiv, addIcon);
    }

    /**
     * アイコンを作成する
     * @param iconName
     */
    private createIcon(iconName: string) {
        const icon = this.renderer.createElement('mat-icon');
        const text = this.renderer.createText(iconName);
        this.renderer.appendChild(icon, text);
        return icon;
    }
}
```

「Add Button」がクリックされるたびに虫のアイコンが増えるようにした。
これで実際にボタンを押してみる。
![icon-add.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316318/dc73a711-19ea-b051-16f2-b49eddfb8a85.gif)

ありゃ、文字だけ追加されてアイコンが表示されない。

## Classの追加も必要
`mat-icon`を追加するだけではダメで、Classも追加する必要がある。
追加するClassは`mat-icon`, `material-icons`だ。

```typescript:icon-example.component.ts
    /**
     * アイコンを作成する
     * @param iconName
     */
    private createIcon(iconName: string) {
        const icon = this.renderer.createElement('mat-icon');
        const text = this.renderer.createText(iconName);
        this.renderer.appendChild(icon, text);
        this.renderer.addClass(icon, 'mat-icon'); // ←追加
        this.renderer.addClass(icon, 'material-icons'); // ←追加
        return icon;
    }
```

実際に動かしてみる。
![add-icon-success.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316318/78ea56de-e6ab-2bf5-0916-9f494e84b215.gif)
正常にアイコンが追加されるようになった。

## まとめ
- MatIconを動的に追加する場合は、Classも一緒につけよう。
- つけるClassは、`mat-icon`, `material-icons`

## 参考
- [How to dynamically add mat-icon to divs with angular renderer2?](https://stackoverflow.com/a/53914261)
mong続報 - Dockerの名前生成ツールは2年前にPythonに移植されていた-

[mong - Dockerのコンテナ名をランダム生成するコードをPythonに移植してみた -](https://qiita.com/toshihikoyanase/items/85aa03d4e20fd6fe45f4)の続きです．

# TL;DR

- [namesgenerator](https://pypi.org/project/namesgenerator/) というパッケージが見つかりました．[mong](https://github.com/toshihikoyanase/mong)は見事に車輪の再発明でした．
- 一方`namesgenerator`は2017年12月からアップデートされていないので辞書が古く，生成できるパターンが本家や`mong`より少ないです．
- `mong`でインスタンス生成が必須なのは使いにくかったので `namesgenerator`を見習って`mong.get_random_name()`を追加してみました

# namesgenerator

Google, pypiで検索していて Dockerの名前生成ツールのPython版はないなぁと思っていました．しかしGitHubのコード検索をしてみたら，一瞬で下記が見つかりました．GitHubすごい．

https://github.com/shamrin/namesgenerator

上記のレポジトリにはPython版のほか，JavaScript/TypeScript版も含まれています．
pypiにも登録してあったので，インストールも一瞬です．
[pypiの統計](https://pypistats.org/packages/namesgenerator)を見ると，月間1,000ダウンロードあるので，それなりに需要もあるようです．

もう，これを使えばいいじゃん，と思ったのですが，反省も兼ねてコードリーディングしてみました

# namesgenerator と mong の違い

大きく下記の４点が違います
1. 辞書の持ち方
2. 関数 or クラス
3. `boring_wozniak` のときの再生成の方法
4. `get_random_name`の引数

## 辞書の持ち方

`mong`は辞書を別ファイルにしているのに対して， `namesgenerator`はpythonコード中にべた書きしています．べた書きすると，データ読み込み処理が不要で楽なのですが，メンテがつらそうです．

`namesgenerator`は２年前に更新がとまっているので，それから本家に追加された語もあるかと思い，辞書のエントリ数で比べてみました：
- `namesgenerator`の辞書は形容詞が93語で人名が160語
- `mong`の辞書（現在のmobyと同じはず）は形容詞が108語, 人名が235語

`mong`の方が形容詞で15語，人名で75語多いです．追加された語を調べる際に，べた書き方式だとGoのコードとPythonのコードを比較する必要があります．単純なdiffはできません．

一方で`mong`では`mong/create_dict.py`を実行してGoコードからJSON形式の辞書を抜き出します．１行１単語にしてあるので，diffで差分が確認できます．もっとも，Goコードのフォーマットが大きく変わると辞書を抜き出すコードの修正が必要になるわけですが，mobyはそれなりに枯れているっぽいので大丈夫だと思います（思いたい）．

以上から，メンテは`mong`の方が楽かもしれません．

## 関数 or クラス

`namesgenerator`は名前生成を関数`get_random_name`で提供していて，`mong`は`NameGenerator`クラスの`get_random_name`で提供しています．クラスだといったんインスタンスを生成しないといけないので面倒です．`mong`を作り始めたときに，辞書を変更可能に，とか乱数シードの管理を別にできた方がよいのでは，などと考えてクラスにしましたが，一晩頭を冷やしてみるとそんなことはありませんでした．`namesgenerator`の方式が良いです．

## `boring_wozniak` のときの再生成の方法

`namesgenerator`は`while`ループで生成ロジックを回している一方で`mong`は`get_random_name`メソッドを再帰呼び出しています．`boring_wozniak`が生成される確率は1/25,380なので，どちらでもいいかなと思います．

## `get_random_name`の引数

`namesgenerator`は`retry`関係のロジックがありません．ここ２年で追加されたのでしょうか．また，その代わりに形容詞と名詞をつなぐ`sep`を変更できます．これも仕様変更でしょうか？

# mongへの反映と今後の方針

いやー，見事に車輪の再発明をしてしまいました．

ただ，`namesgenerator`の実装と比較することで良い点，悪い点の答え合わせができましたので，経験値が溜まってよかったかなと思います．また，良いところは見習おう，ということで関数方式を取り入れて`mong.get_random_name`を追加しました．

つまり，今は下記のように書けるようになりました．

```python
import mong
mong.get_random_name()  # 'trusting_engelbart'
mong.get_random_name()  # 'thirsty_brahmagupta'
```


今後ですが，`namesgenerator`はメンテされていないので，`mong`をメンテしていくとそれなりに需要あるのかもと思います．

# 参考文献

- [mong@GitHub](https://github.com/toshihikoyanase/mong)
- [mong - Dockerのコンテナ名をランダム生成するコードをPythonに移植してみた -](https://qiita.com/toshihikoyanase/items/85aa03d4e20fd6fe45f4)
- [namesgenerator](https://pypi.org/project/namesgenerator/)
- [namesgenerator@GitHub](https://github.com/shamrin/namesgenerator)
Zabbix のメンテナンス設定について

#メンテナンス設定とは
Zabbixには監視対象システムがデプロイや再起動などの作業中である事を示すメンテナンス設定があります。

多くの監視ツールではこれらの機能は通知抑止機能やとして実装される
あるいはツール自体では実装せずにPagerDutyのような通知制御システムを介して実現する方針がとられています。

しかし、重要なことはZabbixにおけるメンテナンス設定は単なる通知抑止設定ではないという事です。

#メンテンナンス設定はフラグである
Zabbixのメンテナンス設定の基本は「メンテンナンス中」という事を示すフラグであるということです。
メンテナンスタイプで 「データ収集なし」を選んだ場合は値の取得が停止しますが、
デフォルトの「データ収集あり」の場合は挙動としてはフラグが立つだけで、収集・判定・通知まで普通に動作します。
あくまでも「メンテナンス中」というフラグが立っているだけです。

これは、Zabbixのメンテナンス機能を理解する上で重要なポイントです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102020/6c8b2d8b-391b-b134-738b-d4edcf3a8e05.png)

#メンテナンス設定の構造
Zabbixのメンテナンス設定は期間を指定するために2つの設定が存在します。
これは、繰り返し設定を行う場合に重要な機能となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102020/1b9e9376-0314-0b81-001b-107fec84320b.png)

「メンテナンス」と「監視対象のメンテナンス期間」の意味を理解するには以下の図をご覧ください。

 ![メンテナンス設定の構造](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102020/d8b26b99-6f1a-0d93-2e9b-392298bad556.png)

期間の設定が2重構造となっていることで、1回限りではのメンテナンス設定ではなく繰り返しメンテナンスの設定に柔軟性を持たす事が可能となります。
画像内に記載している通り
①の「メンテナンス設定」には②の「監視対象のメンテンス期間」の設定を反映させる期間を設定します。
②の「監視対象のメンテンス期間」には実際のメンテナンスが予定される期間を設定します。
1回だけのメンテナンス日時の他
日次、週次、月次での繰り返し設定を設定することができます。

例えば
1つのメンテナンス設定で
①メンテナンス設定の期間に2019年1月1日から2019年12月31日と設定し
②監視対象のメンテナンス期間に
毎週日曜日の3時からのような繰り返し設定をおこない

別のメンテナンス設定で
①2020年1月1日から2020年12月31日
②監視対象のメンテナンス期間に
毎週土曜日の22時からのような繰り返し設定を行う事でメンテナンスタイミングの切り替えを行う事ができます。

#メンテナンス設定はフラグである
Zabbixのメンテナンス設定はフラグです。
このため、「データ収集あり」のメンテナンス設定であればそのまま値収集、判定が継続されます。
判定の結果障害と判断された場合にはメンテナンス中の表示付きで障害が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102020/e1c45b68-c65c-919e-2f52-c48af17a0973.png)

概要ページでは設定によって表示が切り替わります。

* メンテナンス中の障害を非表示
<img width="691" alt="2019-12-22_18h52_40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102020/ea3bbb02-8489-cf91-3527-70bf09a597fd.png">

* メンテナンス中の障害を表示
<img width="693" alt="2019-12-22_18h53_14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102020/ce452765-c68a-f974-eb0c-01aa052dcdb6.png">

この設定により、メンテナンス中にZabbixが正しく判定しているかどうかを確認する事が可能となります。

#メンテナンス設定による通知の動作
Zabbixのメンテナンスはフラグなので、通知抑止を行いたい場合はこのメンテナンス中というフラグを利用します。
<img width="591" alt="2019-12-21_18h26_20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102020/44d0d3a9-fb6b-8c4e-2c38-214febca947a.png">

`「メンテナンス期間中以外は動作する」`という意味で

`「メンテナンス期間中＝いいえ」` という条件を付与する事でメンテナンス中であれば動作しないアクションが作成できます。
つまりこれが通知抑止として機能します。

逆に
`「メンテナンス期間中＝はい」` という条件を付与してアクションを作成すればメンテナンス期間中のみ動作するアクションを作る事ができます。

これによって、例えば通知の投げ分けを設定することができます。


1. `「メンテナンス期間中＝いいえ」` の条件でアクションを作成し通知先を監視センターにする。
1. `「メンテナンス期間中＝はい」` という条件でアクションを作成し通知先をメンテナンス実施者にする。

このようにするとこで、メンテナンス作業を実施しているメンバーが自分自身の実施している作業が正常に進行している事を確認する事ができます。

#まとめ
Zabbixのメンテナンス設定は単なる通知抑止設定ではなく、メンテナンス中であるというフラグであるからこそ、単なる定常監視のみではなく、作業計画の正しさ確認にも利用する事が可能となります。
Check! Azure Cosmos DB Emulator のポートが競合しているときの対処

こんばんは！ @dz_ こと大平かづみです。

Azure Cosmos DB Emulator のポートが競合しているときの解消方法です。

## Prologue - はじめに

Azure Functions などをローカルで開発するとき、ローカルで Azure Cosmos DB を利用できる Azure Cosmos DB Emulator を併用すると便利ですよね。

- [Azure Cosmos Emulator を使用してローカルで開発する | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/cosmos-db/local-emulator)

でも、いざ起動したときにこのようなポート競合エラーに遭うことはありませんか？

> Port 10250 is already in use.
> Use /mongoport=port to specify a different port

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812/440d1165-4a16-5506-5518-913d1f2d4b67.png)

## 解決方法

### 解決方法1: 競合しているタスクを停める

私の場合は、 PowerShell でそのポートを使っているプロセス、アプリケーションを特定して止めます。ここでは、 `9999` というPIDのタスクが利用しているようです。

```ps1
# 競合しているポート 10250 を LISTEN しているプロセスIDを取得する
netstat -ano | findstr "10250"
```
```ps1
  Proto  Local Address          Foreign Address        State           PID
  TCP    0.0.0.0:10250          0.0.0.0:0              LISTENING       9999
```

次に、そのそのプロセスIDのタスクを確認します。私の場合は _NFCProxyService.exe_ が使ってました。

```ps1
# そのプロセスIDのタスクを確認する
tasklist |findstr "9999"
```
```ps1
NFCProxyService.exe           6412 Services                   0      4,904 K
```

### 解決方法1: 競合しているタスクを停止する

この場合においては、 _NFCProxyService.exe_ は PaSoRi 由来のサービスで今は使わないので、サービスを停止します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812/cb9b7931-1f03-e7e3-7440-d00b12f0235d.png)

サービスでなくとも、そのアプリケーションを終了するなどタスクを停止します。

### 解決方法2: Azure Cosmos DB Emulator の起動ポートを変更する

Azure Cosmos DB Emulator はコマンドラインでも操作できます。下記のように、ポートを変更して起動することも可能です。指定するポートがすでに使われないか確認の上、実行してください。

```ps1
& 'C:\Program Files\Azure Cosmos DB Emulator\CosmosDB.Emulator.exe' /MongoPort=10251
```

- [コマンドライン ツールのリファレンス - Azure Cosmos Emulator を使用してローカルで開発する | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/cosmos-db/local-emulator#command-line)

## Epilogue - おわりに

コマンドをメモしておきたかったので、書きましたー :robot: 

その後、 Azure Cosmos DB Emulator を起動すると、無事に起動できました :clap:
AWS上にCentOSでrocket chatを構築してみる

## EC2でインスタンスを立てる

* AMI：CentOS 7 (x86_64) - with Updates HVM
* タイプ：t2.micro
* セキュリティグループ：22,80,3000

## 必要な依存パッケージをインストール
* Rocket.Chat 1.0.2
* OS：CentOS 7.6
* Mongodb 4.0.9
* NodeJS 8.11.4


```
# sudo yum -y check-update

# cat << EOF | sudo tee -a /etc/yum.repos.d/mongodb-org-4.0.repo
[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/7/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc
EOF

※catからEOFまで全て入力

# sudo yum install -y curl && curl -sL https://rpm.nodesource.com/setup_8.x | sudo bash -

# sudo yum install -y gcc-c++ make mongodb-org nodejs

# sudo yum install -y epel-release && sudo yum install -y GraphicsMagick

# sudo npm install -g inherits n && sudo n 8.11.4
```

## Rocket.Chatサービスを構成
```
# sudo useradd -M rocketchat && sudo usermod -L rocketchat

# sudo chown -R rocketchat:rocketchat /opt/Rocket.Chat

# cat << EOF |sudo tee -a /lib/systemd/system/rocketchat.service
[Unit]
Description=The Rocket.Chat server
After=network.target remote-fs.target nss-lookup.target nginx.target mongod.target
[Service]
ExecStart=/usr/local/bin/node /opt/Rocket.Chat/main.js
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=rocketchat
User=rocketchat
Environment=MONGO_URL=mongodb://localhost:27017/rocketchat?replicaSet=rs01 MONGO_OPLOG_URL=mongodb://localhost:27017/local?replicaSet=rs01
###########################################
ROOT_URL=http://"パブリックDNSを入力":3000/
###########################################
PORT=3000
[Install]
WantedBy=multi-user.target
EOF

※catからEOFまで全て入力
```

## rocket.chatにログイン & アカウント登録
ログインするためのアカウント情報を登録

* ユーザ名
* メールアドレス
* パスワード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266988/2d5dd81e-8da8-6820-95c9-9cda313b0ff1.png)

## ログイン完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266988/8f21594c-1ce9-8a48-6be7-b546ae0069d7.png)

使用感はSlackと遜色無いかと思います。

## 備考
得に難しい事はしていませんが、今まで情報発信をしていなかったので、これからOUTPUTを出すための
切っ掛けになればと投稿してみました。

これから頑張って行こうと思います。
Nuxt.jsでhover/activeのレスポンシブ対応



一般的にWebアプリではクリックできることを示すために要素に `:hober`を付けます。
モバイル版のアプリではマウスがないため、長押しをした際に `:hover`のような変化を付けるとタップ(クリック)できることが伝わるかと思います。これはTwitterなど多くのアプリに見られる実装です。

この動作を実装したのでおこなったことをまとめます。


## hover/activeの仕様
PCの `:hover`
![hoverGif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/1846266e-2035-7f49-509b-ae8e7f38cbcf.gif)

Mobileの `:hover`
![mobileHoverGif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/09da57db-7ff3-2412-7c29-4ee1e9e193f5.gif)

これではMobileで長押し後、別の場所をタップするまで `:hover`で設定したCSSが続いてしまいます。
これは想定している動作ではありません。

PCの `:active`
![activeGif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/e349c148-b61b-32e4-5440-daa5564b9c51.gif)

mobileの `:active`
![mobileActiveGif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/39fd982f-cf26-b64f-2de5-fe9274186d84.gif)

Mobileはいいのですが、PCではクリックしないと適用されませんでした。

なので、

- PCでは `:hover`
- mobileでは `:active`

とする必要があります。


## デバイスを判別する
`nuxt-user-agent`というパッケージでユーザーのデバイスを判別し、対応するCSSを適用することにします。

github
[https://github.com/fukuiretu/nuxt-user-agent](https://github.com/fukuiretu/nuxt-user-agent)

`nuxt-user-agent`をgithubのREADMEに従ってNuxtにインストールし、PCとmobileの判別をしていきます。

先ほどの例に導入したものがこちら
![pcGif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/235bbbdd-272b-e73e-985c-c5f54967bf77.gif)
![mobileGif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/53522f9d-d1a5-53fe-b659-353d1b30bdea.gif)

```vuejs
<template>
  <div class="card-container">
    <div
      class="card"
      :class="{
        'card-pc': $ua.deviceType() === 'pc',
        'card-mob': $ua.deviceType() !== 'pc'
      }"
    >
      Sample
    </div>
  </div>
</template>

<style lang="scss" scoped>
.card-container {
  display: flex;
  justify-content: center;
}

.card {
  width: 80%;
  height: 200px;
  background: white;
  border: 1px solid black;
  border-radius: 10px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 20px;
  &-pc{
    &:hover {
      background: #78c4db;
    }
  }
  &-mob {
    &:active {
      background: #78c4db;
    }
  }
}
</style>
```

これで

- PCでは `:hover`
- mobileでは `:active`

を実装することができました。


以下のように画面サイズで判別することも可能ではあります。

```
@media screen and (min-width: PhoneSize) { 
  &:hover {
    background: #78c4db;
  }
}
```

ただしiPad Pro等の大型タブレットまで考慮すると難しくなってしまうので、今回はデバイスを取得する実装になりました。
#Ruby で gem install や #Rails で bundle install  すると Could not find xxx in any of the sources  とエラーが出る場合は gem 名をタイポしてない？

# どんな時のエラー？

gem が見つからなかった時のエラー。

# 例


"Could not find gem 'email-spec' in any of the gem sources listed in your Gemfile."

# 解決

例えばこのgem

例えばgithub での レポジトリ名がハイフン区切りだというからと言って安心してはいけない。
https://github.com/email-spec/email-spec

gem名はアンダースコア区切りだ。

名前を間違っていたらinstallできるはずないよね。

![image](https://user-images.githubusercontent.com/13635059/71307699-697eb680-2435-11ea-8fdd-50e7562939a8.png)

# Ref


"Could not find gem 'email-spec' in any of the gem sources listed in your Gemfile."


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2861








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
opal-rspecのOpal 1.0対応状況

このエントリは[Opal Advent Calendar 2019](https://qiita.com/advent-calendar/2019/opal)の23日目の記事です。

2019年はOpalの1.0がリリースされました(めでたい！)。それに伴いopal-rails等は1.0対応した新バージョンが出ているのですが、opal-rspecはいまのところ未対応となっています。

が、アルファ版であるopal-rspec v0.8.0.alpha2は、Opal 1.0と混ぜて使えるようバージョン指定が緩められています。まだ[1.0完全対応ではない？](https://github.com/opal/opal-rspec/pull/82)ようですが、[Ovto](https://github.com/yhara/ovto)のテストくらいなら普通に動いています。

ということでopal-rspecのOpal 1.0対応状況でした。