OmniAICreator/Qiita-1.07M huggingface dataset:
ChromeにTor経由でアクセスする方法

Chromeでいろいろ検索できるのはいいんだけど、いろんな情報が抜き取られているのが気持ち悪かったので、Tor経由でアクセスする方法を調べてみました。

関連する記事
[PyhonのスクレイピングでTorを使用してChromeにアクセスする](https://qiita.com/___xxx_/items/419a86ea2d3d1ab9f415)
[【Pyhon】Torを使用してスクレイピングする](https://qiita.com/___xxx_/items/f0fc3385c2d08eb63f0f)
# 環境

MacOS 10.15.6

## 拡張機能インストール

[Onion Browser Button](https://chrome.google.com/webstore/detail/onion-browser-button/fockhhgebmfjljjmjhbdgibcmofjbpca?hl=en)にアクセスして拡張機能をインストール
![スクリーンショット 2020-09-04 14.42.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319526/fcfeb5ce-5101-edfa-4605-ce48106c10ff.png)

## 設定ファイルをダウンロード

Onion Browser Buttonの[GitHub](https://github.com/jeremy-jr-benthum/onion-browser-button/releases)から、mac.zipってやつをダウンロードする

![スクリーンショット 2020-09-04 14.45.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319526/b2cd3f5e-4c61-a759-b082-de652bc7eafa.png)

## 設定ファイルをファインダーから解凍

mac.zipをファインダーで開いて解凍して、ターミナルでその中に入って

```terminal.
$ cd ~/Downloads/mac
```

## brew経由でTorをインストール

```terminal.
$ brew install tor
```

## yarnをインストール

```terminal.
$ yarn install

// npmだったらnpm installでおk
```

## 起動させる

1.ターミナルで以下のコマンドを実行し、設定ファイルの `run.js` を走らせる

```terminal.
$ node run.js
```
![スクリーンショット 2020-09-04 14.52.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319526/4708779b-654f-dff3-63b3-ddebd5f25dc9.png)

2.`1`を入力してEnter
3.Chromeブラウザに移り、インストールした拡張機能を起動

## Tor経由でアクセスできているか確認

以下のサイトにアクセスして
https://check.torproject.org/

画像のようにお
![スクリーンショット 2020-09-04 15.23.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319526/78af0b6b-d129-f004-1707-f8422d1c4c9f.png)

オニオンが普通に表示されたらTor経由のアクセスだとわかる
以上

関連する記事
[PyhonのスクレイピングでTorを使用してChromeにアクセスする](https://qiita.com/___xxx_/items/419a86ea2d3d1ab9f415)
[【Pyhon】Torを使用してスクレイピングする](https://qiita.com/___xxx_/items/f0fc3385c2d08eb63f0f)
参考
https://www.google.com/search?q=Chrome%E3%81%ABTor%E7%B5%8C%E7%94%B1%E3%81%A7%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95&rlz=1C5CHFA_enJP904JP904&oq=Chrome%E3%81%ABTor%E7%B5%8C%E7%94%B1%E3%81%A7%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95&aqs=chrome..69i57.309j0j7&sourceid=chrome&ie=UTF-8
Azure Databricks クラスター実行履歴確認・費用概算

# はじめに
Azure Databricks 利用に際しあらかじめ運用コストを把握しておきたいところですが、ワークロードの性質や規模によって計算負荷が大きく変わってくるため、見積もりそのものが困難です。

本稿では Azure Databricks Workspace 上でクラスタの実行履歴を確認、その利用料金を概算する手順を示します。※以下の記事で利用したクラスタの履歴/概算

> **金融取引データから異常検知**
1. [導入/環境設定](https://qiita.com/Catetin0310/items/28706cf7e6ae86b55ba1)
2. [Collaborative Notebook でデータ可視化](https://qiita.com/Catetin0310/items/b5bda50982cfc132f75c)
3. [Anomaly Detector をデータ探索ツールとして使ってみる](https://qiita.com/Catetin0310/items/d29b5fb00e047a7c107e)
4. [1つ目のモデル構築 (データの偏り 未考慮)](https://qiita.com/Catetin0310/items/a46ba6b1ee6e6290512a)
5. [2つ目のモデル構築 (データの偏り 考慮)] (https://qiita.com/Catetin0310/items/0780b4e0f1ba07509930)


# クラスタ実行履歴確認
Cluster から Notebook に紐づけたクラスターを選択。
![2020-09-04_13h21_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/acfde3bb-3e3c-2825-37d3-5482399c95ff.png)

赤枠で囲っている履歴の料金を算出してみます。おおよそ 5 時間、Auto Scaling が働かない状態でクラスタが起動していたようです。
![2020-09-04_13h35_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/fabedf12-90a9-f6b5-bfdb-362d8abb064b.png)

この時はクラスタ起動の直前に設定項目を変えています。EDITED をクリックすると、変更前後の設定を確認できます。以下は一部抜粋。Notebook の編集や可視化メインでモデリング処理はやらないつもりだったのでしょう。クラスタのスペックを下げ、Auto Scaling を長めに設定しています。

```json:EventType_EDITED
{
  "previous_attributes": {
    "cluster_name": "cluster_for_demo",
    "node_type_id": "Standard_DS4_v2",
    "driver_node_type_id": "Standard_DS4_v2",
    "autotermination_minutes": 30
  },
  "attributes": {
    "cluster_name": "cluster_for_demo",
    "node_type_id": "Standard_DS3_v2",
    "driver_node_type_id": "Standard_DS3_v2",
    "autotermination_minutes": 120
  },
  "previous_cluster_size": {
    "autoscale": {
      "min_workers": 2,
      "max_workers": 16
    }
  },
  "cluster_size": {
    "autoscale": {
      "min_workers": 1,
      "max_workers": 4
    }
  },
}
```

つまり、

- Standard_DS3_v2 インスタンスが、
- driver と worker で 1 台づつ、
- 5 時間稼働した

ことになります。

# 料金算出
公式サイトから単価を拾い、Azure Databricks の利用料金を算出します。仮想マシン (VM) と、選択した VM インスタンスに基づく Databricks の単位 (DBU) に対して課金されるので、従量課金制の合計額の項目を参照。

**77.448** (インスタンス単価) x **2** (起動台数) x **5** (実行時間) ≒ **800 円弱**
![2020-09-04_14h40_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/aad76337-f3cc-6cdd-d07f-f4784fed15b9.png)


# 備考：メトリクス確認方法
ビッグデータ解析や各種バッチ処理を行う場合には、何回か実験を繰り返して費用対効果の高い構成にする必要があるはずです。Metrics から任意の Name を選択すると、
![2020-09-04_14h16_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/d716c77b-1984-4350-3cf5-42f99cb34559.png)

メトリクスのスナップショットを取得できます。Azure Monitor や Datadog との連携も可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/fad2ac05-c72f-29c7-1192-2df38500b46d.png)


# おわりに
従量課金型なので実際に試してみて利用料金を見てみるのが手っ取り早いです。



# 参考サイト
[Azure Databricks の価格](https://azure.microsoft.com/ja-jp/pricing/details/databricks/)
[databricks configure metrics collection](https://docs.microsoft.com/en-us/azure/databricks/clusters/clusters-manage)
Microsoft Lists を使ってみた

#Microsoft Lists が GA しました。

米国時間2020年9月3日、Microsoft Lists の一般公開(GA)が[公式ブログ](https://techcommunity.microsoft.com/t5/microsoft-teams-blog/microsoft-lists-in-microsoft-teams-is-now-generally-available/ba-p/1621979?fbclid=IwAR3MKJY_zm2Ya1ZQhQS9-G09Vpj5OS0ltnjpslcf7G6DNv68xmvcKXQGWYU)で発表されました。
Microsoft Lists は、Microsoft Teams のタブアプリとしても利用でき、情報の追跡や仕事の整理に役立つMicrosoft 365アプリです。では察作使ってみたいと思います。

#Teams タブから「リスト」を追加
Teams のタブの追加ボタンをクリックし、タブを追加します。**「リスト]**　が表示されますので、**「リスト]** を選択して、Microsoft List を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/9db5ddac-de7e-38e3-8310-58e8266d4b2e.png)

タブに**「リスト]**　が追加されましたので、さそっく**[リストの作成]** のボタンをクリックして、リストを作ってみたい思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/a8585dd3-cae4-0f04-4cae-b05170d40597.png)

#リストのテンプレート

Microsoft Lists には、あらかじめ8種類の標準テンプレートが用意されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/e50b6009-1d13-9508-91d2-924c6a14a68d.png)

#「出張申請」のテンプレート

出張申請のリストを作ってみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/baa364b4-7e9f-4e6b-57e5-29b9efe7443d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/fe86d833-1584-5727-ee1f-8217e855812d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/4191a10f-3773-c42f-b2bb-fecbfe139085.png)

**「新しいアイテム」**を追加してみましょう。

申請者は、Azure ADに登録されているアカウントが入力できます。
目的地やホテルは、入力補完して情報が入力できますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/c415bb26-643c-e4b9-f585-bf9c51b635b7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/2f610b2a-53d2-9fdc-6c41-71bd089890b5.png)

承認のプロセスは別途 Microsoft Flow などで作らないとダメ見たいです。
「Object Detecton Tools」の物体認識サンプルプログラム実行時のOpenCv2で発生したエラー内容と対処内容

Webカメラを利用したリアルタイム物体認識を試みようとして、
躓いた箇所を備忘として残します。
自分と似たようなトラブルがあった場合はご参考までに。


**■参考にしたサイト**
以下のサイトをもとに作業を進めていましたが、OpenCVの部分でエラーが発生してしまいました。

参考にしたサイト：@karaage0703さん <a href="https://qiita.com/karaage0703/items/8c3197d11f61812546a9">
"TensorFlowでの物体検出が超手軽にできる「Object Detection Tools」をTensorFlow 2.xに対応しました"</a>

**■エラー内容**
<状況1>
ObjectDetectonTools内にある物体認識するサンプルプログラムをpythonで実行した際、"OpenCVがインストールしていない"とopenCvのcv2.waitKey(0)で実行時エラーが発生しました。

OpenCVをインストールしているはずが、なぜかインストールしていないよとエラーが発生していました。

<状況2>
pythonで試しに
 "import cv2”  と叩いてもインポートエラーはでませんが、
  cv2.waitKey(0)　と叩いて実行するとエラーになりました。

その時は、何が起きているかさっぱりでした。

**■実行環境**
OS : Ubuntu 18.04.5 LTS
python: python3
      　anacondaを利用

**■原因**
正確な原因は分かりませんが、
根本原因としてはpipとanacondaでインストールしたopenCvなどのライブラリが
ごちゃごちゃしていたようです。
その結果、python3(anaconda環境）を実行した際に、インストールしたはずのopenCvの参照先が見つからなかったようです。

**■解決策**
・anacondaを削除
　anacondaを削除して、pipで一本化しました。
　その後、opencvなどを再度インストールすると、参考にしたサイトと同じ結果がでました。
Android StudioでSHA-1を確認してFirebaseに登録する方法

Firebaseを使って、Google認証を実装する時にAndroid側のSHA-1が必要。
Flutterで確認する方法を共有します。

## 1. Androidモードで起動する
androidディレクトリの上で右クリックするとメニューが現れるので、赤枠の項目を開く。

![スクリーンショット 2020-09-04 14.53.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126370/e8dda956-7002-f760-9e79-19b308b0e63f.png)

## 2. GradleメニューからsigningReportを開く
右上のGradleをクリックするとメニューが展開されるので、その中からsigningReportという項目をクリック

![スクリーンショット 2020-09-04 14.57.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126370/d0ca7ab8-4bcf-1a32-c1a8-89347cfe430b.png)

後は右下にいくつかSHA-1があるのでそいつをコピー。
![スクリーンショット 2020-09-04 15.00.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126370/61478c10-4743-4eea-96c6-ee190ff9d16a.png)

Firebaseのプロジェクトの設定画面の「全般」タブのマイアプリに登録しよう。

![スクリーンショット 2020-09-04 15.04.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126370/8e9cf979-4e42-5173-3ba9-f483fad6d7fc.png)
AWS Chatbot を使ってlambdaにpayloadを渡すときに Unexpected character (''' (code 39)) でハマった

AWS Chatbot を使ってSlackワークフローからlambdaをinvokeするときにpayloadがうまく渡せなかったケース。

slack上で実行したコマンド

```
@aws lambda invoke --log-type Tail --payload '{}' --function-name tempFunctionName --region ap-northeast-1
```

以下のようなエラーが出ました。

```
but unfortunately the service returned an exception:
> Could not parse request body into json: Unexpected character (''' (code 39)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
at [Source: (byte[])"'{}'"; line: 1, column: 2] (Service: AWSLambda; Status Code: 400; Error Code: InvalidRequestContentException; Request ID: 1522ff50-65a8-4d1c-919d-337e837c1ead; Proxy: null)
```

`'''`の意味が一見わからなかったですが、
ASCIIコード表を見るとCode 39はシングルクオート`'`のようです。要するにシングルクオートがよくないようです。

参考にした資料にはシングルクオートでpayloadを囲っていましたが、これを抜くと治りました。

つまり、こうです。

```
@aws lambda invoke --log-type Tail --payload {} --function-name tempFunctionName --region ap-northeast-1
```


# 参考
* https://dev.classmethod.jp/articles/chatbot-lambda-cfn/
* https://qiita.com/kanga/items/9b43ea182b1c2ce07990
Windows -> Linux は改行コードに注意！！

# そもそも改行コードとは？  

こんにちは！バイオインフォマティクス系オタク修士学生のroadricefieldです！今日は改行コードのお話です. みなさんのプログラムを書いたファイルなどのテキストファイルの各行の最後には実は改行コード呼ばれる見えない文字が書かれています. （エディタ側で設定することで可視化することもできます.）コンピュータに改行することを伝える記号なのですがWindowsとLinux, Macで改行コードが違います. このためWindows上のエディタで書いたスクリプトをWSLで動かすと改行コードを理解できなくてエラーを吐いて止まってしまうということがよくあります. ちょっとやってみましょう.  

WindowsでVScodeを開いて新規ファイルを作成して以下のようなshell script, `windows.sh`を書きます. 

```bash:windows.sh
#!/bin/sh
echo "Hello world!!"
```  

ではこれをWSLで実行してみて下さい.  

```
$ bash windows.sh
```  

すると多くの人が以下のように怒られたのではないでしょうか.  

```
windows.sh: line 2: $'\r': command not found
```  

このメッセージが出た人は`windows.sh`をVScodeでもう一度開いてVScodeのウィンドウの右下を確認してみてください.  

![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/9a13c134-901c-79ab-edf9-53f64414b9d2.png)  

![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/555bde45-de17-62eb-b90a-270c8bf45349.png)

このように"CRLF"と表示されていますよね. この"CRLF"はWindowsの改行コードの名前でこの`windows.sh`で改行コードに"CRLF"が使われていることを示しています.  

今回はエラーメッセージの下に一応`Hello world!!`と表示されていると思いますがもっと複雑なスクリプトの場合は処理が正常に実行されません.

# Windowsの改行コードをLinuxの改行コードに置換する方法

## 1. VScodeで保存するときの文字コードを変更する  

さきほどの"CRLF"と書いてあった部分をクリックすると中央最上部に`Select End of Line Sequence`という選択肢が出てきますのでここでLinuxの文字コードである"LF"を選択してスクリプトを保存して下さい. これだけです! これでもう怒られません. 
ちなみに改行コードの表示の左に"UTF-8"と文字コードの表示もありますがここで文字コードの変更もできますので日本語で書かれたコメントなどが文字化けしているときはこれをクリックして`Reopen with Encoding`を選択して次に`Japanese (Shift JIS)`を選択すると読めるようになると思います. 

## 2. sedコマンドで文字コードを置換する  

sedコマンドで置換することもできます. （[参考](https://qiita.com/hirohiro77/items/7fe2f68781c41777e507)）

```
$ sed -i -e 's/\r//g' windows.sh
```  

# さいごに  

改行コード問題は「Windowsで編集したスクリプトをサーバーで実行したら意味のわからないエラーが出た！」といったときに起きていることが多いです. そういうときは落ち着いてVScodeの右下を確認してみましょう. （Windowsのメモ帳など他のエディタでも多くの場合右下に改行コードの表示があると思います.）
Docker HubのPull回数制限はすでに始まっている

# はじめに

2020年11月1日からDocker HubのPull回数制限が始まるのかー。
ログインせずにPullしてるし、それまでに対応しないといけないなーと考えていたのですが、思っていたよりも早く**Docker HubのPull制限に引っかかってしまった**ので、原因と対応方法について調べました。

```console
[Container] 2020/09/02 10:11:15 Running command docker build -t $REPOSITORY_URI:latest .
Sending build context to Docker daemon  122.9kB
Step 1/7 : FROM alpine:3.11
3.11: Pulling from library/alpine
cbdbe7a5bc2a: Pulling fs layer
error pulling image configuration: toomanyrequests: Too Many Requests. Please see https://docs.docker.com/docker-hub/download-rate-limit/
[Container] 2020/09/02 10:11:20 Command did not exit successfully docker build -t $REPOSITORY_URI:latest . exit status 1
```

# 原因

「[Docker Hubがコンテナイメージの保存期間に加えてPull回数にも上限を設定すると発表](https://gigazine.net/news/20200826-docker-hub-update-policy/)」の

> Pull回数の制限は保存期間の制限と同じく、2020年11月1日より適用されます。

を読んで、完全に勘違いしていました :innocent: 
今回問題に遭遇した際に一次ソースを確認したところ、Docker公式サイトの**「[Download rate limit](https://docs.docker.com/docker-hub/download-rate-limit)」**には、以下のように記載されていました。

> Docker will gradually introduce these rate limits, with full effects starting from November 1st, 2020.
> Dockerでは2020年11月1日から本格的な効果が出るように、これらのレート制限を段階的に導入していきます。

**Docker HubのPull回数制限は段階的にではありますが、すでに導入が始まっていた**のです。。。

# 対応方法

**ログインなしの匿名ユーザの場合はIPアドレスをもとに制限される**ため、自分で6時間あたり100回のダウンロードを実行していなかったとしても制限が適用されてしまう可能性があります。
（まさに今回の私がそうでした。。。）

このため、無料ユーザーでも問題ないのでDocker Hubに登録したユーザーでログインして、Pullを実行するようにしましょう。

```console
$docker login
```

登録済みの無料ユーザーの場合は、6時間あたり200回まで無料でPullを実行することができます。
6時間あたり200回以上のPullを実行する必要がある場合は、ProプランもしくはTeamプランの利用を検討しましょう。

|ユーザ|Pullの回数制限|
|:-:|:-:|
|匿名ユーザー<br/>（ログインなし）|6時間あたり100回まで[^1]|
|無料ユーザー|6時間あたり200回まで|
|Proプランユーザー/<br/>Teamプランユーザー|無制限|
[^1]: IPアドレスをもとに制限されるため、6時間あたり100回のダウンロードを実行していなかったとしても制限が適用されてしまう可能性あり。

# あとがき
今回の教訓として、面倒くさがらずに**一次ソースをちゃんと確認することが大事**だなと思いました。
日頃から技術に関して呟いているので、**[Twitter](https://twitter.com/zizi4n5)** もフォローしてもらえると嬉しいです。

# 参考情報
* [Download rate limit](https://docs.docker.com/docker-hub/download-rate-limit)
Rails fields_for体系

## How to use
####Overview
formの中で異なるモデルに値を入力したい時に有効的よん。
####Example
Hotelモデルがあります。さらに、Hotelモデルと多対多の関係にあるFeeモデルがあります。これらは、ホテルとホテル予約料金プラン(複数)の関係性ですねー。

ホテル登録フォームがあります。その中には、ホテル予約料金プランを入力するフォームがありますっ。しかし！ここで問題が発生。通常のform_forを使ったフォームではモデルが1つしか設定できません😥

そこで！fields_for登場。form_forに親モデルであるHotelモデルを指定。そして、form_forの中にfields_forを作りFeeモデルを指定。あとは、通常と同様にオプションを指定すれば、フォームにデータを入力できる！
####Detail
- 親モデル(Hotel)にaccepts_nested_attributes_forメソッドを記述
- fee_attributesをHotelコントローラーのストロングパラメーターに追加

####Putting into practice
登場人物
Hotelモデル(親)
Feeモデル(子)

#####Model
```ruby:hotel.rb
has_many :fees
accepts_nested_attributes_for :fees
```
#####Controller
```ruby:hotels_controller.rb
def hotel_params
  params.require(:hotel).permit(:name, fee_attributes: [:id])
end
```
#####View
```html:hotel.html.erb
<%= form_for @hotel do |f| %>
  <%= f.label :name %>
  <%= f.text_field :name %>
  <%= f.fields_for :fees do |i| %>
    <%= i.label :hotel_fee1 %>
    <%= i.number_field :hotel_fee %>
    <%= i.label :hotel_fee2 %>
    <%= i.number_field :hotel_fee %>
  <% end %>
  <%= f.submit "upload" %>
<% end %>
```

(途中)
rails server が停止できないときの対処法

## はじめに
Railsチュートリアルを進めているときに rails server が起動できないことがありました。
結論として、rails serverを終了していたつもりが終了できておらず、起動しっぱなしだったため新たに起動することができないということでした。
備忘録としてrails server終了できていないケースと、終了させる方法をまとめました。

### 動作環境
* Windows10 （64bit）
* WSL（Ubuntu 18.04.4 LTS）
* ruby 2.7.1
* Rails 6.0.3.2

## rails server が停止できなくなったとき
* **Ctrl + C をせずにターミナルウィンドウを閉じたとき**
ターミナルを閉じてもrails serverはバックグラウンドで動いている。
そのため、下記手順でserver を停止する必要がある。
 1. ps コマンドにオプション aux をつけて rails server のプロセス番号を調べる。
最後のCOMMAND 項目が Rails アプリ名のプロセスが該当プロセス。
 
            $ ps aux 
            USER PID   %CPU  %MEM VSZ     RSS   TTY   STAT START   TIME COMMAND
            ----
            hoge 31701 15.0  0.2  1095324 70456 tty15 Sl   12:00   0:01 puma 4.3.4 (tcp://localhost:3000) [アプリ名]
            ---- 
 1. kill コマンドでこのプロセスを終了する。

            $ kill 31701
 1.  プロセス番号は次のファイルにも記されている。cat コマンドなどで中身を見る。

            $ cat tmp/pids/server.pid
            31701
 1. psの結果をパイプでgrepに渡すとプロセスを探すのが楽
 
            $ ps aux | grep アプリ名 
            USER PID   %CPU  %MEM VSZ     RSS   TTY   STAT START   TIME COMMAND
            hoge 31701 15.0  0.2  1095324 70456 tty15 Sl   12:00   0:01 puma 4.3.4 (tcp://localhost:3000) [アプリ名]
            hoge 243   0.0   0.0  14804   1188  tty25 S    14:15   0:00 grep --color=auto アプリ名
---
* **Ctrl + C 以外で終了**
 1. 誤ってCtrl + Z等で終了したとき、一見終了したように見えるがRails serverは稼働したままである。
        
            $ rails s
            => Booting Puma
            => Rails 6.0.3 application starting in development
            => Run `rails server --help` for more startup options
            Puma starting in single mode...
            * Version 4.3.4 (ruby 2.7.1-p83), codename: Mysterious Traveller
            * Min threads: 5, max threads: 5
            * Environment: development
            * Listening on tcp://127.0.0.1:3000
            * Listening on tcp://[::1]:3000
            Use Ctrl-C to stop
            ^Z
            [1]+  Stopped                 rails s
 1. "Ctrl + C をせずにターミナルウィンドウを閉じたとき"と同様にプロセス番号を調べ kill コマンドにオプション -9 をつけて実行する。オプションをつけないとプロセスが終了しないことがある。

            $ kill -9 31701

## 参考記事

[Rails serverのプロセスを素早く落とす](https://qiita.com/kanuu/items/fd6e33fca6ad6a90d059)

以上。
phpdotenvを使ってみる

環境
初書：2020/09/04
PC：macOS 10.15.6
php 7.4.9
Composer： v1.10.10
phpdotenv： v5.1

# phpdotenvとは
.envファイルで用意した環境変数を簡単に扱えるようにしたもの。
https://github.com/vlucas/phpdotenv

# インストール
※[composerは設定済み](https://qiita.com/yuu_1st/items/23aa44584c2f1f80fbd4)として話を進めていく

ターミナルで以下を実行する

```zsh
% composer require vlucas/phpdotenv
```

# envファイルの準備
適当な位置に```.env```ファイルを用意し、設定したい環境変数を記述していく。

```text
# 何かしらのIDとパスワード
ID="aa"
PASS="password"
```
envファイル内では上記のように、key="value"という書き方が基本になる。
あと#でコメントアウトができる。

# phpで読み込む

```php:index.php
<?php
declare(strict_types=1);

// ファイル名が.envではない場合は、createImmutableの第二引数にファイル名を入れる
Dotenv\Dotenv::createImmutable(__DIR__)->load(); 
echo $_ENV["ID"]; // aa
```
Dotenv\Dotenv::createImmutable(\_\_DIR\_\_)->load();で、$_ENV変数に.envの中身が読み込まれる。
\_\_DIR\_\_は、.envと読み込むフォルダが同じ場合。違う場所に置いている場合は、適時場所を記述する

調べてみると、Dotenv::createとかnew Dotenvを使っているサイトがあったけど、declareを使用している場合は引数が足りない&型が違うと言われ、実行できない。

あとは$_ENVを使って取得するだけ。

# 注意
別にphpdotenvの注意ではないけども。。
.envファイル自体は普通にアクセスできるし、text形式故に読み取れるので、本番環境ではhtaccessなどでアクセスを制御する必要がある。


# 参考サイト
[phpdotenvについて。](https://qiita.com/H40831/items/aaf8ffa727928661ad1d)
[phpdotenv - ララジャパン](https://www.larajapan.com/2020/06/21/phpdotenv/)
Google Fonts で一部の文字のみを利用する


# tl;dr

```html
<link
  href="https://fonts.googleapis.com/css2?family=M+PLUS+1p:wght@400;700&display=swap&text=Hello%2C+world%21"
  rel="stylesheet"
/>
```

もしくは

```scss
@import url("https://fonts.googleapis.com/css2?family=M+PLUS+1p:wght@400;700&display=swap&text=Hello%2C+world%21");
```

のように、 `text=asdf` として必要な文字をURLエンコードして渡せばいい

# 経緯

英字のみを別の日本語フォントに変えたかったが、その日本語フォントには英字のみのセットがなかった

CSSには「英字のみこのフォント」みたいな指定はない（はず）ので、英字のみのフォントを `font-family` の優先順位の高位に置き、次に日本語フォントを指定することにした

# 調査

公式ドキュメント
https://developers.google.com/fonts/docs/getting_started

リポジトリ
https://github.com/typekit/webfontloader

ドキュメントレベルでは、文字コードの範囲指定で渡す方法はなさそうだった  
時間がなかったのでリポジトリは見てない

# 対応

全ての英字は全てのASCII文字を検索した

```
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ 
```

URLエンコードしたものが以下

```
%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E
```

これを `text=` に指定

```html
<link
  href="https://fonts.googleapis.com/css2?family=M+PLUS+1p:wght@400;700&display=swap&text=%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E"
  rel="stylesheet"
/>
```

上記指定のうえ、

```css
body {
  font-family: "M PLUS 1p", "Hiragino Sans", sans-serif;
}
```

とすると、英字のみが正しく別のフォントに置換された
Webサービスのリリース前に挫折してしまった3つの理由

Ruby on Railsをprogateで学習し、いざWebサービスを開発！！....５0%くらい進んだところで挫折してしまいました。今回は、僕が途中で挫折してしまった理由を共有して、反面教師にしてもらいたく、記事を書きました。特に、僕みたいな初心者が陥りやすいポイントが詰まっていると思うので、ぜひ、開発前に読んでいただきたいです。

1.　開発の全体像を把握せずに、開発し始めてしまった

特に開発の経験のない方は、右も左も分からないも分からないと思います。僕は開発経験がなく、ひたすら目の前にあるタスクだけをこなしていました。開発の途中であれもこれもと修正して、その結果、初めに決めたコンセプトからどんどんずれていってしまうのです。

だから、開発の前から「開発のロードマップ」を作るのをお勧めします。「開発のロードマップ」については、Qiitaにとてもためになる記事があったので、ご紹介しておきます。
「個人開発における開発プロセスを公開してみる」
https://qiita.com/himatani/items/3b8301da2e889e962e5e

開発の全体像をアウトプットして、イメージしてから開発に取り組んでみてください！

2.　リリースまでのハードルが高すぎた

最初に開発するなら、「頑張れば作れる」くらいのハードル設定にしましょう。そして期間は１ヶ月~2ヶ月にしましょう。理由は、モチベーションが下がってしまうからです。それに期間が長いと、このサービスがうまくいくかどんどん不安になってきますし、軸がずれていってしまいやすいのです。

僕は開発経験もないのにいきなり、オークションサイトを開発しようとしていました。しかも開発は一人で、質問や相談ができるメンターもいません。逆によく開発できると思ったのか、今思うと不思議なくらいです（笑）
案の定、開発して半分くらい進んだところで挫折してしまいました。

3.　セキュリティーが甘く、不正利用され、AWSのアカウントが停止してしまった

セキュリティーが甘く、AWSのアカウントで世界中から不正利用されてしまいました。2万円の損失はありましたが、サービスをリリースした後に不正利用されなかったのは、不幸中の幸いでした。

この反省を生かし、メンターを探そうかなと思います。セキュリティー面のミスは、許されないので、メンターにチェックしていただこうと思う次第です。

開発経験のない方は、個人で開発するとなったらメンターを見つけることを強く勧めます。

[まとめ]
今回の開発で、1ケ月と２万円を費やしました。しかしポジティブに捉えるなら、それ以上の学びが多くありました。駆け出しエンジニアは、とにかく経験を積むことが大切です。最初はいっぱいミスして、その分成長するものだと思っています。この記事が、そんな駆け出しエンジニアのためになっていただけたら、幸いです！
Lenovo IdeaPad Duet Chromebook（Debian 10）にOBSをインストールした

# 概要

*こちらの記事の内容でインストールしたものの、どこかでOSをアップデートしたタイミングで起動ができないようです。コメント欄参照。*

ChromebookをLinuxモードで利用し、OBSをインストールしました。Debianへのインストールは公式にも記載がありましたが、Debian 9ではなくてDebian 10だったことで若干苦戦したのでその記録です。

# はじめに

Chromebookは当然Linuxモードを有効にしておき、Terminalを使います。

# 公式サイトにはこうしろと書いてあります

https://obsproject.com/wiki/install-instructions#debian-installation-unofficial

```
Debian 9.0 or newer is required.

First make sure you have everything up-to-date.

$ sudo apt update

FFmpeg is required. If you do not have the FFmpeg installed (if you're not sure, then you probably don't have it), you can get it with the following command (or compile it yourself):

$ sudo apt install ffmpeg

Finally, install OBS Studio.

$ sudo apt install obs-studio
```

## そもそもその前にOSのバージョンを確認しておきましょう。

```sh

~$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
```

もしくは

```
$ cat /etc/issue
Debian GNU/Linux 10 \n \l
```

でも良しです。

Debian 10ですね。

# ffmpeg は言われたとおりに入れてOKです

```
$ sudo apt install ffmpeg
```

# 問題はobs-studioです

```
$ sudo apt install obs-studio
```

これでは見つかりませんでした。
そういえばこのChromebookは ARMアーキテクチャだった気がする。

## 確認する

```
$ dpkg --print-architecture
arm64
```

なるほど、busterにはないわけだ。
https://packages.debian.org/buster/obs-studio

## obs-studioのパッケージを探しましょう

というわけで他を探してみるとsidにあった。

https://packages.debian.org/sid/arm64/obs-studio/download

## 書かれているとおりに

```/etc/apt/sources.list
（追記する）
deb http://ftp.de.debian.org/debian sid main 
```

httpsじゃないので注意！

## あとは

```
$ sudo apt-get update
$ sudo apt-get install obs-studio
```

# 入った！

起動は

```
$ obs
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13879/03709d6b-7f5c-025f-409b-dd817b3655a3.png)
エラーバンドリングの出し方


【概要】
----------------------------------------
<b>1.結論</b>

<b>2.エラーバンドリングの出し方</b>

<b>3.詰まったところ</b>



1.結論
----------------------------------------
<b>validates</b>と<b>.errors.any</b>と<b>.errors.full_messages.each</b>を使う！
<br>

2.エラーバンドリングの出し方
----------------------------------------
まずmodelにバリデーションを設定します！

```ruby:app/models/buy_item
  with_options presence: true do
    validates :name
    validates :date
 end
```
with_optionsはdo~endまでのpresence: true（空欄はダメ）というのを一辺に設定できるものです。
こちらの場合はnameカラムとdateカラムの空欄はダメという設定をしています！

そしてcontrollerでは以下のようにしています。
 
```ruby:controllers/buy_items_controller.rb
 def create
    @buy_item = BuyItem.new(buy_item_params)
    if @buy_item.save
      redirect_to root_path
    else
      render :new
    end
  end
```
保存されればトップページに遷移します。もしなにかが正しくなくて保存されなかった場合はrenderでビューのnewに飛ぶようにしています。なぜなら以下のようにしたいからです。


```views/buy_items/new.html.erb
 <%= render 'public/error_messages', model: f.object %>
```

こうすることで、buy_itemsのnewビューに飛んだ時 (render: new)にエラー表示が設定しているプログラムに移動するようにしています。f.objectはform_wtihで設定した@buy_itemの｜f｜で、＠buy_itemの中身を取り出しています！

また'public/error_messages'の中身（エラー文）は以下のようにしています。

```ruby:view/public/_error_messages
<% if model.errors.any? %>
 <div class="error">
  <ul>
     <% model.errors.full_messages.each do |message| %>
      <li class='error-message'><%= message %></li>
    <% end %>
  </ul>
</div>
<% end %>
```
modelを使用しているのは、buy_itemのモデル以外にもuserを使用しているためです。model全部にバリデーションのエラー内容を適用できます。また、その各エラー内容をeachメソッドでそれぞれ取り出し、<%= message %>で表示しています！

下記のURLにはかなり助けられました！

参考URL:<a href="https://qiita.com/nakanishi03/items/d1be27c74c98855423ab">Rails エラーメッセージの出し方　バリデーションエラー</a>
<br>

5.ここから学んだこと（エラーの時に使用）
----------------------------------------
modelを@userや@buy_itemに変えてしまって、@userのエラーが出なかったり、NameErrormethodが発生してしまい、てこずりました。またf.objectも勝手にインスタンス変数にしてしまい余計にエラーを引き起こしてしまっていました。またコントローラーが２つあり指定のコントローラーのindexで表示させたい場合はrender "コントローラー名/アクション名"でいけます。ただ、表示だけしかしていないので、中身のデータの記述をしないといけない事が盲点でした。
<br>
RollbarでGithub issueとの連携を設定しようとしたら躓いた件について

## この記事で書くこと
GithubのOrganizationに紐付いたアカウントで、組織に紐づくprivateリポジトリに対して、
Github issueを作成してもらう設定をしようとしたときの躓いたところ。

## 結論（どうしたら設定できたのか）
Githubのsettingページから、RollbarへOrganization Accessを許可する
言ってしまえば対応済みなら、躓くことはそうそう無いかと思います。

## 躓いた背景
自分が現在所属するチームでは全てのチケットの管理をTrelloにしていて、
GithubのIssue機能をうまく使うことができていませんでした。
また、RollbarをSlackに通知して、それを優先度高いものがくれば対応し、本番に反映された後、
**気づいた人（多くの場合は実装した人）が**手動でRollbarのページにいって、Resolveしていました。

ネットサーフィングしていると、
[エラーモニタリングサービス Rollbar と GitHub Issue を利用したエラー対応フロー](https://engineer.crowdworks.jp/entry/2016/08/29/111434)
こちらの記事を見つけ、早速やってみたいとチームに相談してみました。

> これ設定してみたい気持ちを一昨日くらいから
issueという機能がうちではほとんど機能してないので、使っていくのが、エラーを解消するために活用するのも良いのかな、と思ったのと、
いちいちPRリリースして、resolveする手間も省けるし、手が空いた時にissueから一つシュッととってリリースとか良いなと（箸休め感覚で）
色々書いたけど、楽しそうだから使ってみたい、という気持ちが多い。
一瞬煩わしく感じる部分も出てくるかな、とは思ったけど。 :hatching_chick:

↓

> 良さそう :thumbsup: 

ということで設定に向けて動き出しました。

個人アカウントに紐付かないアカウントでの登録が望ましいだろうということで、メンバー全員がログイン情報を知ってるGithubアカウントでの設定を開始。

[Rollbarドキュメント](https://docs.rollbar.com/docs/github#issue-tracking) に従い
Settingページから、pulldownにGithubアカウント個人に紐付くリポジトリしか表示されないため、対象にしたい組織に紐付くRepository nameを入れると、
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71266/c147181f-0789-5207-1cc4-1a9887e1bd31.png)

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71266/41a7e60b-91bf-2ef6-afcf-ce747141d43c.png)

エラーになってしまいました。 :disappointed: 
調べても情報が見つけられなかったので、サポートにメールを送り、何回かのやり取りのあと、こちらのページを解決策として教えてくださいました。

[Enable GitHub Organization Access for Rollbar](https://help.rollbar.com/en/articles/1232353-enable-github-organization-access-for-rollbar)

UI上だと、inputの中身は何でも自由にリポジトリを指定できるように見えますが、pulldownで表示されてるリポジトリしか入力できないものらしいということにここではじめて気づきました。
設定し直すことで、pulldownの中身に設定したいリポジトリ名が表示され、Github issueとの連携をすることができました。 :tada: 

エラーページに飛ばすようになってるのは、セキュリティ上（そのリポジトリが存在してるかどうかわからない状態にするため）なのかなぁ。
アクセスできないリポジトリなので権限を確認してください。とかメッセージで出たらサポートに連絡しなくても解決できたなぁと少し思いました。 :thinking:
GitHub でブランチの削除をトリガーに何かを実行する

# やりたいこと
- GitHub で、ブランチの削除をトリガーに特定の処理を走らせたいと思いました。

# 実現方法
- GitHub Actions で、ブランチの削除をフックできるらしいので GitHub Actions でやってみました。

## GitHub Actions の設定
以下のような設定をしてみました。

https://github.com/mdoi/branch-delete-hook

```.github/workflows/main.yml
name: do something when branch is deleted

on:
  delete
    
jobs:
  delete_hook:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Run a one-line script
        run: |
          echo Run only when branch "test/*" is deleted
        if: startsWith(github.event.ref, 'test/')
```

- delete をフックに GitHub Action を実行する。
  - on に delete を指定する。
- また、自分の場合は特定のブランチの削除で処理を実行したかった。
  - ただ、delete に branches のフィルタが記述できなさそうだった。
  - ワークアラウンドとして、実行したい処理 (run) を条件付きで実行するようにした。
    - delete はコンテキストが master ブランチになるようなので、github.event.ref で削除されたブランチ名を取得した
    - ↑で取得したブランチ名を if の中で contains とか startsWith を利用して、ブランチのフィルタをかけた。

# 問題点
- どのブランチの delete でもジョブ自体は起動してしまうので、 GitHub Actions の時間を無駄に使ってしまうのが今ひとつだと思っています。
VPN環境だけど余剰ノートPCをモニタ代わりに使いたい

----今日のトピック--------

リモートワークしていて思うのが、やっぱりデュアルモニタしたい、、！
でもモニターは邪魔だし、高いし、調整面倒。(買ったけど重すぎて机グラグラするんで3日で売りました)

そこでyoutuber情報でアプリインストールによってタブレットor2台目PCをサブとして使うことにしました。
だがここでしかし！そのyoutuberが紹介していたサービスが有料と判明、、といっても2000円弱くらいですが、、
お試しに使うにはもったいない(サブのモニターはどちらもサイズが小さく不安でした)
なので、以下いろいろ調べてみた結果連ねてみます。

ちなみにこちらが紹介されてたサービスです↓
Duet Display
https://pc.watch.impress.co.jp/docs/column/yajiuma-mini-review/1247972.html


----本題--------
さてさて、、、どれにしようかなーー
◆候補その1
Miracast
https://pc.watch.impress.co.jp/docs/column/yajiuma-mini-review/1251697.html
MSで提供されてる機能で無線接続可能です。
しかし接続要件を満たすことが前提とのことで(Win8以上など)
私のPCはWin10でしたがハードが対応していなく、実現できませんでした、、とほほ。

◆候補その2
spacedesk
こちらは無料かつ無線のみ対応です。
リモート勤務環境で使うことが前提のためVPN対応しているかという点で
実現不可でした。
VPNつないだ瞬間に接続切れます、、当たり前かー。

◆候補その3
Mouse Without Borders
https://pc.watch.impress.co.jp/docs/column/yajiuma-mini-review/1251697.html
上記spacedeskを調べている際に、無線のため安定性に不安があるという記述があったので
有線対応で見つけたのがコレ。
結果的にはVPN環境では使えませんでしたが、日常使いであれば候補の中で一番使いやすそうでした。
こちらはイメージしていたデュアルディスプレイの形とは違いました。

だってメモなどのアプリが画面を越えて移動できない。。。

調べてみるとデュアル化するのが主な機能でなく、
あくまでキーボードとマウスを越境させることができるツールだそうです。（なーんだ、でも便利。）

logicoolの複数台PC切り替え可能なキーボードを使っているのですが(コレ⇒https://www.logicool.co.jp/ja-jp/product/k370s-k375s-multidevice-keyboard?crid=27)
マウスはうっかり切り替え不可のものを購入し、不便に感じていました。
思わぬ解決方法が見つかってラッキー☆彡

日本語対応していないようなのでオプション設定の部分については
ちょっと戸惑う方もいるかもしれないです、、
設定項目の部分については以下サイトにある程度詳しく書いてありました。
https://mikasaphp.net/mouse_wb.html

----まとめ--------

VPN環境であまりPCをモニタ代わりに使用するのは
なかなかむずかしいとわかりました、、。
しばらくはテレビをモニタ代わりに様子をみているつもりです、、
Nodebrewでnodeのversionの変え方


## Nodebrewでnodeのversionの変え方

####1. Nodebrewをインストールする

```
brew install nodebrew
```

####2.　環境変数を追加
vi ~/.bash_profileで、以下を追加。

```
export PATH=$HOME/.nodebrew/current/bin:$PATH
```

#### 3.　bash_profileを更新して設定を反映させる。

```
source ~/.bash_profile
```

#### 4.　セットアップ。これやらないとインストールできない。
```
nodebrew setup
```

####5. バージョン指定してnodeをインストールするために、インストール可能なバージョンを確認


```
nodebrew ls-remote
```

#### 6.nodeのインストール（versionを指定する）

```
nodebrew install-binary <version>
```


#### 7.　現在自分でインストールしたnodeのversionを確認

```
nodebrew ls

v10.22.0
v14.9.0
```

#### 8.currentに出てくるのが、現在利用中のversion。
例えば10.12をインストールしただけで利用するように設定していない場合、noneになる


```
nodebrew ls

v10.22.0
v14.9.0
current: none
```


#### 9.nodebrew use v14.9.0 で 既にインストール済みのnodeに切り替えられる

```
nodebrew use v14.9.0

use v14.9.0
```


##参考リンク
[NodebrewでNodeをインストールする](https://qiita.com/mame_daifuku/items/373daf5f49ee585ea498)
[Node.jsのversionを管理するためにnodebrewを利用する](https://qiita.com/sinmetal/items/154e81823f386279b33c)
GAS（Google Apps Script）プロジェクトのプロパティ

# 概要
本人もGASを書く時に定数をソース情に以下のようにそのまま書きました。

```
var TOKEN = "TOKEN-ZSDFASDFASDFASDFS";
```

だが、恥ずかしいながら今日になって良い物を見つけました。それが「プロジェクトのプロパティ」との物です。

# 設定の方
こんなところにあったのに分からなかった。私は馬鹿なのかくらい簡単です。「ファイル」　> 「プロジェクトのプロパティ」
![スクリーンショット 2020-09-04 13.26.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489182/f5f2b1d2-ce84-321b-a456-f70f1a14ad8d.png)
「プロジェクトのプロパティ」のタブをクリックしてプロパティ名と値を入れればOKです。
![スクリーンショット 2020-09-04 13.28.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489182/e3d4d6c3-da6c-64a2-681c-371b78a0118a.png)

# 注意点
プロジェクトのプロパティの使用については一点注意があります。
そのスクリプトのオーナー権限があるアカウントでないと、上記の手順でプロパティストアの編集ができません。

複数人でスクリプトを管理・活用する場合は、権限も意識して作業をすすめてくださいね。
コンパイラを作る。 その2

#概要

コンパイラを作る。
俺言語を俺cpuのアセンブラに変換するコンパイラを作る。
下記に、ソースとコンパイル結果を載せる。

#ソース

```
10 a=0
20 a=a+1
30 #=a>100*255
40 b=a%15
50 #=b=0*120
60 b=a%5
70 #=b=0*140
80 b=a%3
90 #=b=0*160
100 ?=a
110 #=20
120 ?="fizzbuzz"
130 #=20
140 ?="buzz"
150 #=20
160 ?="fizz"
170 #=20
```

#コンパイル結果

```
  push  0
  set  a
label20:
  get  a
  push  1
  +
  set  a
  get  a
  push  100
  >
  jz  label255
  get  a
  push  15
  %
  set  b
  get  b
  push  0
  =
  jz  label120
  get  a
  push  5
  %
  set  b
  get  b
  push  0
  =
  jz  label140
  get  a
  push  3
  %
  set  b
  get  b
  push  0
  =
  jz  label160
  get  a
  push  10
  /
  push  48
  +
  out
  get  a
  push  10
  %
  push  48
  +
  out
  push  32
  out
  jmp  label20
label120:
  push  'f'
  out
  push  'i'
  out
  push  'z'
  out
  push  'z'
  out
  push  'b'
  out
  push  'u'
  out
  push  'z'
  out
  push  'z'
  out
  push  32
  out
  jmp  label20
label140:
  push  'b'
  out
  push  'u'
  out
  push  'z'
  out
  push  'z'
  out
  push  32
  out
  jmp  label20
label160:
  push  'f'
  out
  push  'i'
  out
  push  'z'
  out
  push  'z'
  out
  push  32
  out
  jmp  label20
label255:
  end

```

#成果物

https://embed.plnkr.co/plunk/ck8hPP89lqb7bOoQ

#シミュレータ実行結果

```
01 02 fizz 04 buzz fizz 07 08 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 fizz 19 buzz fizz 22 23 fizz buzz 26 fizz 28 29 fizzbuzz 31 32 fizz 34 buzz fizz 37 38 fizz buzz 41 fizz 43 44 fizzbuzz 46 47 fizz 49 buzz fizz 52 53 fizz buzz 56 fizz 58 59 fizzbuzz 61 62 fizz 64 buzz fizz 67 68 fizz buzz 71 fizz 73 74 fizzbuzz 76 77 fizz 79 buzz fizz 82 83 fizz buzz 86 fizz 88 89 fizzbuzz 91 92 fizz 94 buzz fizz 97 98 fizz buzz 
```
以上。
UWA GOT OnlineのMonoメモリ逆順呼び出し分析機能

UWA GOT Onlineは、全体的なパフォーマンス分析、Monoメモリ分析、および実行時アセットの測定という3つの機能を提供するUWAのパフォーマンス最適化サービスです。その中でも、Monoメモリ分析レポートは、Monoの割り当てが使用過大かつオーバースピードという問題を素早く理解し、メモリリークの原因を特定するのに役立ちます。**本日、逆順の呼び出し分析機能を提供することにより、Monoメモリを実際に割り当てる多層なサブ関数が直接強調表示され、開発チームがヒープメモリのボトルネック問題を素早く特定できるようになります。**
![GIF-2019-11-13-13-10-58[1].gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/8e8a09fd-84d4-703f-4298-ae9b863ae735.gif)
現時点では、多数のゲーム開発プロジェクトで呼び出されるスタックレイヤーの数は比較的に深く、一部は30レイヤーを超えることもある。そのため、開発チームが、ヒープメモリ割り当ての特定のサブ機能を展開、検索、特定するには多くの時間を費やす必要がありますが、最後まで展開すると、類似なサブ関数情報が見えます。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/9bd75f97-b034-0773-c7cf-e5e06880c5fa.png)
上の図に示すように、赤、青、緑のボックス内の関数は、呼び出しスタックが異なることにより分離されていますが、実際には同じ関数です。

そのため、UWA GOT OnlineにMonoメモリの逆順呼び出し分析機能を導入しました。 次の図に示すように、「逆順呼び出し分析」モードを選択すると、ゲーム実行中にMonoメモリ割り当てが最も多いTopサブ関数が表示されます。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/5498f15b-8ec3-e109-b1ca-84c67381da5d.png)
同時に、開発チームは各サブ機能をクリックして、さまざまなテストバージョンでどのように変化するかを確認できます。次の図は、関数のヒープメモリ割り当て平均（10Kフレームごとの平均）の傾向を示しています。ヒープメモリの割り当てが増え続けるサブ機能については、開発チームがそれに集中し、回帰テストを使用して特定およびトラブルシューティングすることをお勧めします。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/06eac2ec-9acb-5127-0a9e-25d5007e5b00.png)
**さらに、プロジェクトテスト中のサブ機能、特定の割り当て情報、リバーススタック情報も表示できます。**逆順スタックでは、ノードが展開された後の直接関数のリストは、ノード関数を呼び出してヒープメモリを生成する親関数です。また、開発チームは、これらのヒープメモリ割り当ての特定の呼び出しに関する洞察を得るために、階層関係を順序に展開および表示できます。
![6.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/27351f1d-7c70-af93-1a04-93d7784e17f0.jpeg)
**同時に、UWAは、より実用的な方法は、最初の1〜3層のサブ関数を介してコードを直接検索し、ヒープメモリ割り当てを直接最適化することであることを推奨します。**このモードを適用すると、開発チームはヒープメモリの割り当てをより正確に特定し、コードをより効率的に最適化できます。

---
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、**パフォーマンス分析**と**最適化ソリューション**及び**コンサルティングサービス**を提供している会社でございます。

UWA公式サイト：https://jp.uwa4d.com
UWA公式ブログ：https://blog.jp.uwa4d.com
はじめて学ぶjava入門　＃２

##開発の流れ
1、ソースコードの作成
javaが定める文法をソースコードで記述する

２、コンパイル
ソースコードにコンパイルという処理を行ってバイトコードという状態に変換する

３、実行
コンパイル終了後は、インタプリタと呼ばれるソフトウェアにバイトコードを実行する


##大切な意識

###正確に記述する
英数字は基本的に半角で入力する
似ている文字を間違えないようにする

###上から下ではなく外から内へ
カッコとじたかどうかわからなくなってしまうので開いてすぐ閉じるを意識する

###読みやすいコードを記述する
誰が読んでもわかりやすいソースコードを記述するようにする

##インデント
ブロックの多重構造の見通しをわかりやすくするために字下げを行う

```
public class Main {
  public static void main(String[] args) {
    System.out.println("hello, world!");
	}
}
```

##コメント
ソースコードに解説文を加えることができる
プログラムのコンパイル時を実行時には無視される

```
/*コメント本文（複数行でも可）*/

//コメント本文（行末まで）
```


##変数
変数とはデータを格納するためにコンピューター内部に準備する箱のようなもの

###変数宣言の文
#####型　変数名；
```
public class Main {
	public static void main(String[] args) {
	    int age;
	    age = 30;
		System.out.println(age);
	}
}
```

###定数の宣言方法
#####final 型　定数名　＝　初期値；

```
public class Main {
	public static void main(String[] args) {
	    final double TAX = 1.08;
	    int fax = 5;
		System.out.println(fax * TAX +"万円");
	}
}
```
gitわかんないよ〜 いらすとやで欲しい画像を検索する

# gitわかんないよ〜
この記事ではgitのことは書いてないです、いらすとやの検索方法を書いてます。
登壇などの資料作成時、資料にうるおいを求めるときに活用してみてください。

いらすとやで作った「gitわかんないよ〜」です。
gitわかんないよ〜 第１バージョン（clone忘れ）
https://twitter.com/sapi_kawahara/status/1301391281159983104
gitわかんないよ〜 第２バージョン（clone追加）
https://twitter.com/sapi_kawahara/status/1301523526390751232

gitわかんないよ〜
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77441/859a4729-b89b-75d8-3319-4307f5766f92.png)

# 検索方法
いらすとやを検索したのですが、意外と出なかったので、画像を検索するのは、ちょっとコツがいります。
いらすとやも[検索のコツ](https://www.irasutoya.com/p/kotsu.html)というページを掲載しており、いらすとやでの検索には癖があります。


今回の画像を作ったときの検索は以下の４つのパターンがありました。

* そのまま検索
* 想定したイメージが出ない
* トンチを入れる
* トンチを入れたが想定イメージが出なかった

## そのまま検索

コマンドや背景を、そのままカナや漢字に置き換えて検索しました。

* 集中線（背景）
* fork→フォーク
* SourceTree→ソースと木
* TortoiseGit→亀

## 想定イメージが出なかった

コマンドを、そのままカナや漢字に置き換えて検索しても出なかったり、想定イメージの絵が出なかったので、言葉を変えて検索しました。

* pull→引く（想定イメージじゃない）→開ける
* checkout→チェックアウト（検索結果０）→宿泊（想定イメージじゃない）→ホテル
* status→状態（想定イメージじゃない）→位（近いイメージがある）→ピラミッド
* merge→合成（想定イメージじゃない）→混ぜる

チェックアウトで検索されないのが意外でした。

## トンチを入れる

コマンドから、トンチを思い付き、それをカナや漢字に置き換えて検索しました。

* log→ログハウス
* diff→岐阜
* add→広告
* clone→プルーン
* branch→王様のブランチ→王様


## トンチを入れたが想定イメージが出なかった

コマンドから、トンチを思い付き、それをカナや漢字に置き換えて検索しても出なかったり、想定イメージの絵が出なかったので、言葉を変えて検索しました。

* push→押す（想定イメージじゃない）→応援団
* stash→隠す（想定イメージじゃない）→忍者
* commit→comet→彗星（想定イメージじゃない）→流星（検索結果０）→流れ星
* init→頭文字Ｄ（当然出ない）→レース（想定イメージじゃない）→チキンレース

流星で検索されないけど、流れ星だと検索されるのが、ちょっとした罠だったりします。
これは[検索のコツ](https://www.irasutoya.com/p/kotsu.html)と読むと納得します。

## 落選
表現が難しいです。

* diff→gif

ひねりすぎで伝わらない。

* TortoiseGit→ポストロックのトータス
* log→logging→ハイキング

著作権的に無理です。

* TortoiseGit→トーマス
* commit→コメットさん
* clone→Chrome

# コマンドの追加について
この「gitわかんないよ〜」はいらすとやの素材を１９点使用しております。
もう既に、ぐちゃぐちゃし始めているのと、[よくあるご質問](https://www.irasutoya.com/p/faq.html)にある通り、２0点までとなっているので、増やす予定は無いです。
Logi COMPOSERを試す！（時短に挑戦編）

#今回はCOMPOSERでの時短可視化に挑戦
前回は駆け足でLogi COMPOSERの概要を見てきましたが、今回は以前に検証を行った
**MemSQL**
**Equalum**
と今回の**COMPOSER**を組み合わせた検証を行って見たいと思います。

##検証構成
今回の検証に用いる構成は以下の通りです。
（１）Pythonを使ったランダム自動データ生成ツールを使って、ランダム間隔でデータを生成しオリジナル側のMySQLに挿入します。
（２）Equalumが設定済みのFLOW処理を行い、ターゲット側のMemSQLにデータを挿入します。
（３）COMPOSERで秒間隔の時間粒度を用いて、上流側のMySQLと下流側のMemSQL双方の即時可視化を行います。

![スクリーンショット 2020-09-04 9.35.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197589/315f250b-7250-6f1c-7c64-3bd61fd3b9c7.png)

EqualumやMemSQLの検証の際には、結果のテーブル等を確認する方法で作業を行って来ましたが、今回のCOMPOSER標準機能を活用して、一気にリアルタイムの世界を可視化する事で、３つのソリューションが持っている高い処理性能を体感してみたいと思います。

##EqualumのFLOW設定
今回のEqualum側FLOW設定になります。

![スクリーンショット 2020-09-04 9.38.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197589/93b72d0f-b7ae-037c-3e0b-68ad2e1b79e1.png)

（１）　総計と消費税を計算し、新規に派生カラムを生成・挿入を行う
（２）　幾つかの条件分岐を行い、それぞれに適用するポイント計算と新規派生カラムの生成・挿入を行う
（３）　順番にデータを再構成し、ターゲットのMemSQLにデータを着地させる

という流れで検証してみます。

##実際の可視化状況
ダッシュボードの上側が上流側のMySQLの状況を可視化する様に設定され、下側が下流側のMemSQLの状況を可視化する様に構成してあります。

![ezgif.com-video-to-gif-6.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197589/b741b080-31f0-b126-9992-8fab17ce7edb.gif)

検証は、双方のテーブルにデータが無い状況から開始しますが、CDC処理が始まるとデータベースとしてのインメモリ性能が一気に顕在化し、可視化段階では描画の逆転現象が見られました。
一番右側の折れ線チャートは、最初の1分間が経過すると折れ線チャートの描画を開始し、以後は時系列で双方のデータがシンクロしながら可視化していきます。

###後半部分
![ezgif.com-video-to-gif-5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197589/1c497c1a-e4ea-57fa-ff23-673bc470fb7c.gif)

#今回のまとめ
最終的には、MySQL側のテーブル状況と、MemSQL側のテーブル状況をDBeaverで確認し、

![スクリーンショット 2020-09-04 13.15.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197589/87db17c3-1c71-cac9-8c3b-6d9e2db8700c.png)

両方のTIMESTAMP(6)が揃っている事が検証出来ました。

今回は駆け足でしたが、今まで検証してきた３つのソリューションを組み合わせて、リアルタイム・ストリーミングを実際に可視化して確認する作業を行いました。
COMPOSERの即時可視化性能や、時間情報を活用したライブモードを使うと、Equalum同様に高度なプログラミング等を必要とせずに、リアルタイム・データマイニングを実現する事が出来ます。
また、複数の異なる上流側のサイロDBからリアルタイムでデータをストリーミングし、高性能なインメモリデータベースであるMemSQL上に展開する事で、データベース横断の高度なSQL処理を、圧倒的な処理能力で実現する事ができ、同時にその結果をCOMPOSERのライブモードで即時可視化（利用）する事が出来るという事も解りました。（この部分については、別の検証でRと組み合わせて実施してみたいと思います）

#謝辞
今回の検証環境を提供して頂いたMemSQL社、Logi Analytics社、Equalum社に対して、この場を借りて深く御礼申し上げます。
セッションタイムアウト、明示的なログアウトの機能

応用情報技術者平成30年春期 午前問43

Webシステムにおいて，セッションの乗っ取りの機会を減らすために，利用者のログアウト時にWebサーバ又はWebブラウザにおいて行うべき処理はどれか。ここで，利用者は自分専用のPCにおいて，Webブラウザを利用しているものとする。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/a54c2f58-ac76-2464-31eb-b2116fb2003b.png)


１、セッション乗っ取りの機会を低減させるための予防策
IPAで公開されているセキュアプログラミング講座では、セッション乗っ取りの機会を低減させるための予防策として「セッションタイムアウト」と「明示的なログアウト機能」を挙げています。
　・セッションタイムアウト
　　Webアプリケーションにはセッションタイムアウト機能を設ける。ユーザはログアウト操作をすることを忘れてしまうことがある。

　・明示的なログアウトの機能
　　Webアプリケーションには明示的なログアウトの機能を設ける。できれば、各ページでログアウト操作が行えると良い。
そして利用者がログアウトを要求した場面では、Webアプリケーションは次のような操作を行うべきとしています。
　　１）、Webサーバ側でセッションIDを確実に無効にする。
　　　　　その後同じセッションIDがクライアントから送られてきても受け付けない
　　２）、Webブラウザ側のセッションIDを消去する
　　　　　・一般的なWebページのセッション管理方式では、WebブラウザとWebサーバでセッションIDを共有することで同じ利用者かどうかを判断しています。
　　　　　・セッションIDさえ一致すれば、第三者からのアクセスを正規のアクセスとして判断してしまう可能性があるということですから、不要なセッションIDを有効なままにしておくのはセキュリティ上のリスクになります。
　　　　　・セッションIDを必要とするのはログイン中だけですから、ログアウトが要求された（セッションIDが不要になった）時点でWebサーバ側（可能であればWebブラウザも）のセッションIDを無効化し、それ以降は無効化されたセッションIDを拒否することで、セッション乗っ取りの機会を最小限に減らせます。


上記の詳細説明では、ちょっと長いですが、下記はポイントと思っております。
・セッションタイムアウト　がWebサーバーの設定により違いますが、
　ユーザーが利用終了からセッション無効までは、時間かかります。　例えば、30分、２時間など
・ブラウザのキャッシュを手動で都度削除するのはいいですが、セッションタイムアウトがくるまでリスクがあるので、推奨できません。特に、もしセッションタイムアウトがすごく長く設定されると、リスクが増えますね。
・セッションタイムアウトがリスクがありますので、明示的なログアウトの機能があれば、それを利用した方がリスクが低減できます。すぐにセッションが無効になりますので。一番推奨される方法です。


参照：
https://www.ap-siken.com/kakomon/30_haru/q43.html
Docker・Rails・pumaのローカル環境でSSL化

Docker・Rails・pumaの本番環境でSSL通信でCRUDの一部が上手くできないので、ローカルで色々試すめにローカル環境をSSL化しました。
その時の手順をまとめました。


# 前提

- 既にhttp接続でページが表示できている状態
- 証明書作成にopensslを使用
- Chromeはセキュリティで、接続できないのでfirefoxでアクセスし表示・動作の検証を行う
- ページアクセス時、通信は安全ではないというメッセージが返ってくるが、「詳細情報」→「危険性を承知で続行」で表示できる

# 実装手順

```bash
# 証明書設置ディレクトリに移動
$ cd docker/nginx/ssl

$ openssl genrsa -out server.key 2048

# 登録情報は適当にしてます。。。
$ openssl req -new -key server.key -out server.csr
Country Name (2 letter code) []:JP
State or Province Name (full name) []:Fukuoka prefecture
Locality Name (eg, city) []:Fukuoka city
Organization Name (eg, company) []:oreore
Organizational Unit Name (eg, section) []:oreore
Common Name (eg, fully qualified host name) []:localhost
Email Address []:jungissei@gmail.com
A challenge password []:a123456

$ openssl x509 -days 3650 -req -signkey server.key -in server.csr -out server.crt

```

GitHubにアップロードされるないようにする

```:.gitignore

/docker/nginx/ssl/server.crt
/docker/nginx/ssl/server.csr
/docker/nginx/ssl/server.key
```

443ポートできるようにしたり、証明書のあるパスにマウントをあわせる。

```yaml:docker-compose.yml

nginx:
    build:
      context: .
      dockerfile: ./docker/nginx/Dockerfile
    ports:
      - '80:80'
      - '443:443' #追加
    volumes:
      - sockets:/app/tmp/sockets
      - ./docker/nginx/ssl:/etc/nginx/ssl #追加
```



「ssl_certificate」などに証明書があるディレクトリパスをセットする。
httpにアクセスするとhttpsに301リダイレクトされるようにする。

```docker/nginx/default.conf

upstream app {
  server unix:///app/tmp/sockets/puma.sock;
}

server {
  listen 80;
  server_name  _;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl;
  server_name localhost;

  ssl_certificate     /etc/nginx/ssl/server.crt;
  ssl_certificate_key /etc/nginx/ssl/server.key;
  ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers         HIGH:!aNULL:!MD5;

# ・・・省略
```

```yaml
$ docker-compose up -d
```

# 参考
[pumaサーバーをSSLでアクセス可能にする方法 - ryotaku's Tech Blog](https://www.ryotaku.com/entry/2019/02/11/231513)
[Railsの開発環境でHTTPSを有効にする](https://blog.y-yagi.tech/posts/rails_ssl/)
[Rails + Pumaの開発環境をSSL化 - Qiita](https://qiita.com/tikaranimaru/items/7be6a513410bd863f01c)
[Rails5 + pumaのローカル環境でSSL/HTTPSを有効にする - Qiita](https://qiita.com/zaru/items/ccf328e87c768168134d)
[NginxでSSL（HTTPS）設定！オレオレ（自己署名）証明書を作成しよう！](https://kitsune.blog/nginx-ssl)


# さいごに

肝心のローカルhttps接続下で、CRUDは出来たので、この本番環境用の証明書に置き換えてもう一度検証してみようと思います。
C#とSeleniumでIEを操作する

# はじめに

2020年ももう9月だというのにIEの話で恐縮です。

Selemiumとはブラウザのオートメーションを実現するための製品ですが、それを利用してIEを操作する方法をまとめておきます。ちょっとはまるので・・・

なおSelemiumの本格的な利用法には触れません。あくまでIEを操作するためのポイントのみとなります。

# 事前準備：IEの設定を確認する

IEを開き「インターネットオプション」の「セキュリティ」タブから、各ゾーンの保護モードを有効にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99262/4e297c59-79ea-a247-efd4-8d5b56c9d21f.png)

デフォルトではローカル イントラネットと信頼済みサイトでは無効になっていますが、「すべて」保護モードを有効にしてください。一部のみ変更した場合、Selemiumの実行時に例外が発生します。

その後「詳細設定タブ」を開き、「拡張保護モードを有効にする*」にチェックがつけられていないことを確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99262/6e058243-b9c5-9086-57d3-f0ba9f7c1f14.png)

チェックが入っていた場合は、チェックを外し、PCを再起動してください。

# SelemiumでIEを操作する

まずプロジェクトを作成し、つぎの二つのライブラリをNuGetからインストールしてください。

- Selenium.WebDriver
- Selenium.WebDriver.IEDriver

そして、つぎのように実装し実行してみましょう。

```csharp
var driver = new InternetExplorerDriver();

driver.Navigate().GoToUrl("https://www.google.co.jp/");

var textBox = driver.FindElement(By.Name("q"));
textBox.SendKeys("Selenium");

var button = driver.FindElement(By.Name("btnK"));
button.Click();
```

これでIEが起動し、Googleへ遷移した後にSelemiumというキーワードで検索が実行されるはずです。

以上です。
Swiftでデザインパターン【Strategy】

元ネタ → [ochococo/Design-Patterns-In-Swift](https://github.com/ochococo/Design-Patterns-In-Swift#-strategy)

# クラス図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37598/6e665c75-7aea-29a5-de58-6e1b1d67725f.png)


図の引用元：[Wikipedia: Strategy パターン](https://ja.wikipedia.org/wiki/Strategy_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3)

# 概要
The strategy pattern is used to create an interchangeable family of algorithms from which the required process is chosen at run-time.
Strategyパターンは、アルゴリズムが交換可能なファミリを作成しておき、それらの中から実行時に必要なプロセスが選択されるように利用する。
**ファミリ**は**Strategy**で**必要なプロセス**の定義をしている。**ファミリ**の構成員は**ConcreteStrategyA/B**で**必要なプロセス**を**アルゴリズム**として実装している。

# サンプルコード
```swift
struct TestSubject {
    let pupilDiameter: Double
    let blushResponse: Double
    let isOrganic: Bool
}

// Strategy
protocol RealnessTesting: AnyObject {
    // AlgorithmInterface()
    func testRealness(_ testSubject: TestSubject) -> Bool
}

// ConcreteStrategyA
final class VoightKampffTest: RealnessTesting {
    // AlgorithmInterface()
    func testRealness(_ testSubject: TestSubject) -> Bool {
        return testSubject.pupilDiameter < 30.0 || testSubject.blushResponse == 0.0
    }
}

// ConcreteStrategyB
final class GeneticTest: RealnessTesting {
    // AlgorithmInterface()
    func testRealness(_ testSubject: TestSubject) -> Bool {
        return testSubject.isOrganic
    }
}

// Context
final class BladeRunner {
    // Containment
    private let strategy: RealnessTesting

    init(test: RealnessTesting) {
        self.strategy = test
    }

    // ContextInterface
    func testIfAndroid(_ testSubject: TestSubject) -> Bool {
        return !strategy.testRealness(testSubject)
    }
}


// usage //

let rachel = TestSubject(pupilDiameter: 30.2,
                         blushResponse: 0.3,
                         isOrganic: false)

// Deckard is using a traditional test
let deckard = BladeRunner(test: VoightKampffTest())
let isRachelAndroid = deckard.testIfAndroid(rachel)

// Gaff is using a very precise method
let gaff = BladeRunner(test: GeneticTest())
let isDeckardAndroid = gaff.testIfAndroid(rachel)
```

# クラス図との対応
|  サンプルコード  |  クラス図  |
| ---- | ---- |
|  **RealnessTesting** |  **Strategy**  |
|  testRealness  |  AlgorithmInterface  |

|  サンプルコード  |  クラス図  |
| ---- | ---- |
|  **VoightKampffTest**, **GeneticTest**  |  **ConcreteStrategy**  |
|  testRealness  |  AlgorithmInterface  |

|  サンプルコード  |  クラス図  |
| ---- | ---- |
|  **BladeRunner**  |  **Context**  |
|  strategy  |  Containment（集約）  |
|  testIfAndroid  |  ContextInterface  |

# 考察
Strategyパターンは、アルゴリズムが交換可能なファミリを作成しておき、それらの中から実行時に必要なプロセスが選択されるように利用する。
**ファミリ**は**Strategy**、**必要なプロセス**を定義をしている。**ファミリ**の構成員は**ConcreteStrategyA/B**、**必要なプロセス**の定義に準拠した具体的な**アルゴリズム**として実装することで**交換可能**になっている（ポリモフィズム）。**Context**はプロパティとして**Strategy**のインスタンス**strategy**を持ち（集約/aggregate、[アップキャスト](https://qiita.com/moccow/items/13a9232df69929ca4ae2)）、**ContextInterface**の実態はこの**strategy**の**AlgorithmInterface**である。**Context**のインスタンス生成時（**実行時**）に、集約している**strategy**を決定することで**ContextInterface**の実行内容（**必要なプロセス**）も決定される（ポリモフィズム）。
VDI(Virtual Desktop Infrastructure)

応用情報技術者平成30年春期 午前問41

内部ネットワークのPCからインターネット上のWebサイトを参照するときにDMZ上に用意したVDI(Virtual Desktop Infrastructure)サーバ上のWebブラウザを利用すると，未知のマルウェアがPCにダウンロードされて，PCが感染することを防ぐというセキュリティ上の効果が期待できる。この効果を生み出すVDIサーバの動作の特徴はどれか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/48629bba-9789-0b63-8954-d6f83f7d9292.png)


VDI(Virtual Desktop Infrastructure)は，サーバ内にクライアントごとの仮想マシンを用意して仮想デスクトップ環境を構築する技術です。利用者はネットワークを通じてVDIサーバ上の仮想デスクトップ環境に接続し、クライアントPCにはVDIサーバからの操作結果画面のみが転送される仕組みになっています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/dd73fc23-9492-68d3-dde8-9ce646c9fe4c.png)


参照：

https://www.sc-siken.com/kakomon/30_haru/am1_13.html
画面に収まりきらないコンテンツを折り返し表示する方法

商品一覧表示を実装中、
親要素に display: flex; をかけただけだと
![スクリーンショット 2020-09-04 12.44.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682043/9a037a8f-cca3-ee20-0528-ac58b561dfe0.png)

このように一列に横並びになってしまうためブラウザからはみ出てしまう。
そこで同じ親要素に、flex-wrap: wrap;（画面幅に収まらない場合は折り返すcss）をかけると
![スクリーンショット 2020-09-04 12.48.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682043/dd7d13f7-f9f0-24a8-af66-c857789c891c.png)
のように折り返し処理をしてくれる。

コード