OmniAICreator/Qiita-1.07M huggingface dataset:
EC-CUBE3 での支払方法設定

少しEC-CUBEを触る機会があり、全くの素人ですので備忘録的に参考になればと思います。
（意外とQiita記事が検索で引っかからないことが多かったので、簡単な内容ですが誰かの参考になれば幸いです。）

## やりたいこと
現状ページの支払方法が「クレジットカード」のみだったため、そこに銀行振込を追加したいとの仕様変更。
最初の作成者は別だったため改修部分からの着手

## 結論
コントロールパネルから設定することが可能

## 支払い方法の設定
### STEP1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55894/46654e6c-e061-362a-8644-135d6b30a770.png)

デフォルトで「銀行振込」の設定はされているので　
設定 > 基本情報設定 > **配送方法設定**
を選択。

*任意の支払方法をカスタマイズや追加をしたい場合は 設定>基本情報設定>支払方法設定 から設定が可能です。

### STEP2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55894/ef9d7176-6fe6-8a08-39ea-cabb5b434856.png)
配送方法一覧から銀行振込を設定したい配送方法を選択します。


### STEP3 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55894/9d561f8d-4361-7847-0ce7-d0cfabe18aea.png)
支払方法設定にて選択できるようになってるので、今回は銀行振込にチェックを入れる。

### STEP4
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55894/8bbc2c61-c977-ed88-34f5-99a6e2da8adb.png)
変更を確認すると銀行振込が追加されてます。


### 参考資料
https://www.web-f.net/2015/10/ec-cube-2.html
Uncaught Error: Cannot find module 'bootstrap-form'と出た場合はコメントアウト

自分用忘備録
### 環境
* macOS Catalina
* ruby 2.6.6
* Rails 6.0.3.2
* gem 'bootstrap_form'
* Google chrome

管理者一覧画面から管理者を削除
すると以下のエラーがブラウザ上に出現。

>Unknown action
The action 'show' could not be found for Administrator::AdminsController

と出る。
destroy actionのはずが何故show??

controller,view,pathの確認をするも異常なし。

web developer consoleでerror logを確認すると、

```
Uncaught Error: Cannot find module 'bootstrap-form'
    at webpackMissingModule (application.js:1)
    at Module../app/javascript/packs/application.js (application.js:1)
    at __webpack_require__ (bootstrap:19)
    at bootstrap:83
    at bootstrap:83
```
bootstrap-formのmoduleでエラーが発生していることを確認。

app/javascript/packs/application.jsの
import 'bootstrap-form';
をコメントアウト。

動作確認すると無事削除出来た。
サクラエディタで先頭0埋め

#はじめに
サクラエディタで数値先頭0埋めする方法。

#手順
正規表現で置換を行う。

以下、例。
1
12
123
1234
を前４桁で0埋めする

正規表現で最低でも４桁になるように先頭に0を入れる
^
→
000
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317488/21d1f0b3-1d23-30ee-5306-a63e25fbba57.png)

下４桁で切り出し
^0*(\d{4,})
→
$1
※先頭の余分な0を除いた４桁の数字
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317488/958c7ba3-ad64-a6e9-a23c-a7ad464119bb.png)


0001
0012
0123
1234
となる。
Virtual Chara開発 - その5

店舗接客などに使える仮想のキャラクターが扱えるアプリ開発をしました。そちらの説明はこちらになります。
https://qiita.com/NestVisual/items/fe4dd168178e27156682

環境：
Windows 10
Unity 2018.4.1
RealSense D435i

###キャラのアニメーション:
利用者の骨格が検出されなかったり、カメラと利用者の距離が遠すぎたり近すぎたりなど、様々な理由で骨格トラッキングが反映されないときに、モデルはその場で止まってしまいます。これは人形のように見えます。そして、モデルが不自然な状態にある場合は特に悪い。

これを変更するには、まずモデルの四肢の回転を元の状態にリセットしました。Quaternion.Lerp() メソッドを使用すると、スムーズに動きましたが、人間らしくありませんでした。人間は完全に静止していることはほとんどないので、少しだけ揺れる待機状態のループ再生アニメーションが必要だと思いました。

最大の問題は、モデルのトラッキング反映ポーズから、アニメーションの開始ポーズまでを自然に移動させることでした。単純にアニメーションを再生するだけでは、急に変化してしまいます。

現行のプロジェクトでは、アニメーションはすぐに再生されます。そして、再生前の四肢の回転を保存します。これからLateUpdate()でまたLerp()を使用して、関節の回転を設定します。これを行うには、Quaternion.Slerp()を使用します。これは2つの回転と、それらの影響を決定するブレンド比を受け取ります。この比率は、アニメーションの再生が始まったからの経過時間を基準にしています。保存した回転の影響が徐々に少なくなっていきます。

```C#:sample1.cs
private void LateUpdate()
{ BlendToMecanim(); }

/// <summary> トラッキング反映からスムーズにMecanimにブレンド移行。Mecanimによってオーバーライドされないように、LateUpdateで呼ぶ </summary>
private void BlendToMecanim()
{
    _animator.SetBool("Idle", false);
    if (STATE != ControlState.BLEND_TO_ANIM)    return;

    // Mecanimに移行したら過ごした時間
    float timePassed = Time.time - reflectTrackingEndTime;                             
    // どれぐらい最後のトラッキングポーズを表す
    float trackingBlendRatio = 1.0f - timePassed / trackingToMecanimBlendTime; 
    // 0から1まで
    trackingBlendRatio = Mathf.Clamp01(trackingBlendRatio);

    // 関節をtrackingBlendRatioぐらいで最後のトラッキング回転にオフセットする
    foreach (KeyValuePair<nuitrack.JointType, Quaternion> rotation in _jointRotationsBeforeMecanim)
    {
        ModelJoint modelJoint = _jointsRigged[rotation.Key];
        modelJoint.bone.rotation = Quaternion.Slerp(modelJoint.bone.rotation, rotation.Value, trackingBlendRatio);
    }

    if (trackingBlendRatio == 0)    STATE = ControlState.ANIMATED;
}

```

上記プログラムでは、カメラのトラッキングデータを、キャラのアニメーションに反映させます。同じシステムを他のアニメーションにも使用ができます。例えば、複雑な手のジェスチャーのようなトラッキングが難しいものです。BlendToMechAnimメソッドがUpdate()ではなくLateUpdate()で呼ばれるのは、アニメーションの次のフレームが更新されたの後に回転を設定するためです。Updateを使用した場合、アニメーションはブレンドされた回転を上書きしてしまいます。同じスクリプトには 「ControlState」という列挙もあります。これはキャラクターが骨格トラッキング、Unityでのアニメーション（mecanim）、mecanimに向かってブレンドされているときの状態を持っています。

次回はフェイストラッキングで顔を操るに関して投稿します。それではまた
Latexメモ

すぐ忘れるのでメモ(自分用)
よい書き方かどうかは知らない。
メモなのでどんどん増えていきます。

###実ベクトルの集合
太字は基本 {\bf x} と書く。
\mathbb{R}と書くとRがいい感じになる。

{\bf x}\in\mathbb{R}^D

```math
{\bf x}\in\mathbb{R}^D
```
###多変量正規分布
{\mathcal N}と書くとNがいい感じになる。
\muは{\boldsymbol \mu}と書く。\bfが効かないギリシャ文字がある。
中括弧は\\{,\\}と書く。\\をつける必要がある。
\left\\{ ... \right\\} のように書くと括弧が式に合わせて大きくなる。これ便利。

{\mathcal N}({\bf x}|{\boldsymbol \mu},{\bf \Sigma})
=\frac{1}{(2\pi)^{\frac{D}{2}}|{\bf \Sigma}|^{\frac{1}{2}}}
\exp\left\{-\frac{1}{2}({\bf x}-{\boldsymbol \mu})^T{\bf \Sigma}^{-1}({\bf x}-{\boldsymbol \mu})\right\}

```math
{\mathcal N}({\bf x}|{\boldsymbol \mu},{\bf \Sigma})
=\frac{1}{(2\pi)^{\frac{D}{2}}|{\bf \Sigma}|^{\frac{1}{2}}}
\exp\left\{-\frac{1}{2}({\bf x}-{\boldsymbol \mu})^T{\bf \Sigma}^{-1}({\bf x}-{\boldsymbol \mu})\right\}
```

###=を揃える、ベクトル、行列
ベクトル、行列は \begin{pmatrix}...\end{pmatrix} で囲む。
\begin{eqnarray}...\end{eqnarray}で囲んで&&,&=&で揃う。
\vdots 3点リーダ縦
\cdots 3点リーダ横
\ddots 3点リーダ斜め

\begin{eqnarray}
{\bf x}&=&\begin{pmatrix}x_{1}\\ \vdots\\ x_{D}\end{pmatrix}\\
&=&\begin{pmatrix}x_{1}\ \cdots\ x_{D}\end{pmatrix}^T
\end{eqnarray}

```math
\begin{eqnarray}
{\bf x}&=&\begin{pmatrix}x_{1}\\ \vdots\\ x_{D}\end{pmatrix}\\
&=&\begin{pmatrix}x_{1}\ \cdots\ x_{D}\end{pmatrix}^T
\end{eqnarray}
```

###置換
置換のシグマは \mathrm{sgn} このように書くとよい。

\begin{eqnarray}
  &&|{\bf A}|=\sum_{\sigma\in S_n} \mathrm{sgn}(\sigma)a_{1\sigma(1)}a_{2\sigma(2)}\hdots a_{n\sigma(n)}\\
  &&|{\bf A}|=\sum_{} \mathrm{sgn}
  \begin{pmatrix}
  1 & 2 & 3 & \hdots & n\\
  i_{1} & i_{2} & i_{3} &  \hdots & i_{n}\\
  \end{pmatrix}
  a_{1i_1}a_{2i_1}a_{3i_1} \hdots a_{ni_n}\\
\end{eqnarray}

```math
\begin{eqnarray}
  &&|{\bf A}|=\sum_{\sigma\in S_n} \mathrm{sgn}(\sigma)a_{1\sigma(1)}a_{2\sigma(2)}\cdots a_{n\sigma(n)}\\
  &&|{\bf A}|=\sum \mathrm{sgn}
  \begin{pmatrix}
  1 & 2 & 3 & \cdots & n\\
  i_{1} & i_{2} & i_{3} &  \cdots & i_{n}\\
  \end{pmatrix}
  a_{1i_1}a_{2i_1}a_{3i_1} \cdots a_{ni_n}\\
\end{eqnarray}
```

###行列式
\begin{eqnarray}
  &&{\bf A}__{ij}=(-1)^{i+j}\left|
    \begin{array}{ccccc}
  a_{11} & \cdots & a_{1j} & \cdots & a_{1n}\\
  \vdots & & \vdots & & \vdots\\
  a_{i1} & \cdots & a_{ij} & \cdots & a_{in}\\
  \vdots & & \vdots & & \vdots\\
  a_{n1} & \cdots & a_{nj} & \cdots & a_{nn}\\
  \end{array}
  \right|
\end{eqnarray}

```math
\begin{eqnarray}
  &&{\bf A}_{ij}=(-1)^{i+j}\left|
    \begin{array}{ccccc}
  a_{11} & \cdots & a_{1j} & \cdots & a_{1n}\\
  \vdots & & \vdots & & \vdots\\
  a_{i1} & \cdots & a_{ij} & \cdots & a_{in}\\
  \vdots & & \vdots & & \vdots\\
  a_{n1} & \cdots & a_{nj} & \cdots & a_{nn}\\
  \end{array}
  \right|
\end{eqnarray}
```

#集合
mathcalというのはカリグラフィーフォントの略。

\sum_{{\bf x}\in\mathcal{X}_i}\\
\sum_{{\bf y}\in\mathcal{Y}_i}

```math
\sum_{{\bf x}\in\mathcal{X}_i}\\
\sum_{{\bf y}\in\mathcal{Y}_i}
```
【GCP概要編】Google Cloud Platform Fundamentals: Core Infrastructure 受講まとめ①

# この記事の目的とゴール

近々、[Associate Cloud Engineer](https://cloud.google.com/certification/cloud-engineer?hl=ja)を受験する予定です。

その受験対策として受講した[Google Cloud Platform Fundamentals: Core Infrastructure](https://www.coursera.org/learn/gcp-fundamentals-jp)の内容をまとめていきたいと思います。
講座以外の内容についても、試験に役立ちそうな内容を記載していきます。

受験のためではありますが、この講座を通してGCPの概要や各プロダクトの特徴が体系的に理解できて非常に良い勉強となりました。

# GCPの紹介
## クラウドコンピューティングの重要な特性

以下がGCPにかかわらず、クラウド全般に言えるメリットです。

1. 必要に応じて自分自身でリソースを取得できる　→　サーバを買わなくてOK
2. 場所を問わずリソースにアクセスできる　→　ネット経由でどこからでも
3. プロバイダは巨大なリソースの中から、顧客に割り当てる　→　規模の経済性
4. リソースは必要に応じて増減できる　→　スケールアップ、スケールアウトが簡単
5. 費用は発生した分だけ支払う　→　初期コストが不要

## GCPの４つの操作方法

- 以下4つがある。主に使うのは1と2
    1. GCP Console
        - GUIベース
        - ブラウザからアクセス可能。
    2. Cloud Shell
        - ブラウザベースの対話型シェル環境。
        - 実体としては一時的な仮想マシン。
        - SDKがプリインストールされている。
    3. API
    4. モバイルアプリ

## GCPアーキテクチャ

- IaaS(Conpute Engine)ではこれまでの仮想化同様、構成が自由。
- PaaS(App Engine)では必要なライブラリがインストールされているため、コードをデプロイするだけ。
- FaaS(Cloud Function)は、サーバレスで処理（関数）を実行できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100978/978e3fa9-2e18-b04a-0035-5aa55b5a32ca.png)
(https://cloud.google.com/blog/products/gcp/time-to-hello-world-vms-vs-containers-vs-paas-vs-faas)

## リージョンとゾーン

- リージョン（地域）の中に、複数のゾーンが存在する。
- 東京リージョンの中にゾーンが複数ある。データセンターが何箇所かに分かれてるイメージ。
- リソースを複数のゾーンに分散することにより耐障害性が増す。
- さらに、マルチリージョン（複数のリージョン）に分散することにより、リージョンレベルの大規模災害時にも対応できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100978/05721427-ad34-0275-9955-308effacaa9e.png)
(https://cloud.google.com/about/locations?hl=ja#regions)

- コマンドラインで、作業するリージョンを設定したいときは以下コマンドを使う。
    - `gcloud config set compute/region リージョン名`

## 料金設定

- Compute Engineなど、多くのサービスでは秒単位で課金される。
- Compute EngineではVM(Virtual Machine)の実行時間が一定を超えると割引される。
- **料金の見積もりをしたいときは、料金見積もりツールを使う。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100978/c281819c-d7cb-ae96-be26-a3cc7bd281d5.png)
https://cloud.google.com/products/calculator/?hl=ja

## 多額の請求を回避する方法

想定外の費用がかからないように、以下を参考に適切に管理する。

1. 予算とアラート
    - 予算をアカウント毎かプロジェクト毎に設定できる。（アカウントやプロジェクトの詳細については別途）
    - 予算に上限を設定することができる。
    - **アラートを50％、90％、100％に設定できる（変更可能）。**
2. 課金データエクスポート
    - BigQueryやCloud Storageなど、分析用としてエクスポートできる。
3. レポート
    - GCP Console内でビジュアルで確認できる。
4. 割り当て
    - 「頻度」と「数量」の割当で悪意のある攻撃を防ぐ
        - 「頻度」は一定時間のAPI呼び出し数など
        - 「数量」はVPCのネットワーク数など
    - 増やしたいときはGoogleにリクエストできる
SpringBoot2.3.0以降で@PropertySourceのvalueに使用しているプレースホルダの解決に失敗する

# 内容

タイトルそのままです。
SpringBoot2.3.0 以降で`@PropertySource` の value の指定に `classpath:/something-config-${spring.profiles.active}.yml` のようにプレースホルダを使っていると、解決できずに例外が発生する。
現在の Boot の最新バージョンは 2.3.1 です。

ソース

```java:SomethingConfig.java
@Configuration
@ConfigurationProperties(prefix = "something")
@Component
@PropertySource(value = {"classpath:/something-config.yml","classpath:/something-config-${spring.profiles.active}.yml"}, factory = YamlPropertySourceFactory.class)
@Data
public class SomethingConfig {

    private String setting1;
    private String setting2;
}
```

結果

```bash
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.profiles.active' in value "classpath:/somethign-config-${spring.profiles.active}.yml"
```

# 解決方法

とりあえず 2.2 系を使いました。

# issue

https://github.com/spring-projects/spring-boot/issues/21631
演算子の使い方

# 記事の内容
プログラム内における演算子の使い方を記録する。

## 演算子 || &&
`!(a || b) ` = `!a && !b`
上のふたつは同じ条件を表している。
条件が多くなってきたら後者の方が分かりやすくなる可能性がある。
どこに`()`を付けるか`!`を付けるかで読みやすさが変わってくるので工夫が必要。


## インクリメント演算子

前置と後置の２パターンある。

- 前置：  ++変数
- 後置：  変数++

どちらも1増加させる点では同じだけど、増加させるタイミングが違う。


```前置.
num = 10;
System.out.println(++num); -> 11
System.out.println(num);   -> 11
```

```後置.
num = 10;
System.out.println(num++); -> 10
System.out.println(num);   -> 11
```
AWS Batchでスポットインスタンスを使ってハマった話

## 概要
AWS Batchで使用するコンピューティング環境でスポットインスタンスを使用する事ができます。これによってコスト削減が狙えるのですが、配分戦略で`BEST_FIT`を選ぶ際に指定する`スポットフリートロール`でめちゃくちゃハマりました。
具体的にはスポットフリートロールをドキュメントの通りに作成しても、エラーとなってスポットインスタンスリクエストが失敗しました。

`Linux/UNIX: The provided credentials do not have permission to create the service-linked role for EC2 Spot Instances.`

こんな感じです。ドキュメントの通りにロールを作ったのですが、それだと権限が足りないようです。検索して出てくる解決策もバラバラで、ようやく解決したので記録として残しておきます。

## 結論
- ロール作成で選ぶユースケースは [EC2 Spot Fleet Role]です。`arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetTaggingRole`が付与されているはずです。
- この状態でロールを作成します。名前は [AmazonEC2SpotFleetRole]とします。
- 作成したロールに、`iam:CreateServiceLinkedRole`アクションをアタッチして下さい。

これで作成した[AmazonEC2SpotFleetRole]を、AWS Batchのコンピューティング環境で、`スポットフリートロール`で指定します。

## 経緯
AWS Batch環境のアップデートに伴い、別環境で色々検証していた際、少しでもコストを下げるためにスポットインスタンスを利用してみようと思ったのがそもそもの始まりでした。
別環境ではすでに成功しているので、それをそのまま持っていけば良いと思ったのですが、AWS Batchコンピューティングリソースのスポットインスタンスにタグ付けがサポートされた際、推奨されていた管理ポリシーが変更され、別環境で使っていたポリシーが使えなくなっていました。
そこで新しい方法として紹介されていたロールを作成し、コンピューティング環境にアタッチしても、スポットインスタンスリクエスト自体はできるがエラーになってしまい、色々試しまくった結果、今回の結論にたどり着きました。
冒頭で「解決策がバラバラ」と書きましたが、このアップデートに関連しています。管理ポリシーの変更前と後の両方の解決策が出てくる状態なので、探すのにえらい苦労しました。

AWS Batchとスポットインスタンスは非常に相性が良く、ジョブキューにオンデマンドコンピューティング環境も入れておけばより安全にスポットインスタンスを利用する事ができるので、効率よくコストを削減できます。
もし今回と同じ事例で引っかかっている人の助けになれば幸いです。

## 参考
[AWS Batch で INVALID コンピューティング環境を修正する方法は?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/batch-invalid-compute-environment/) 

- こちらの`無効なスポットフリートロールを修正する`を参考にロールを作成

[Bamboo fails to lodge spot instance request since the provided credentials do not have permission to create the service-linked role](https://confluence.atlassian.com/bamkb/bamboo-fails-to-lodge-spot-instance-request-since-the-provided-credentials-do-not-have-permission-to-create-the-service-linked-role-950809842.html)

- ここに足りない権限に関する情報が記載されていました。
Unityでスクリプトを作成し、Hello, Worldを表示する

# やりたいこと
Unity上で実行ボタンを押すと、Hello, Worldが表示されるスクリプトを作成します。
Unityの画面構成、マウス操作、C#の基本などは以下の投稿を参考にしてください。
[Unityとc#の超入門 ～基礎編～](https://qiita.com/harufuji/items/6eeaab3624de914495bb)

# 流れ

1. オブジェクトを作成
2. スクリプトを作成
3. ゲームオブジェクトを作成
4. スクリプトをアタッチ
5. スクリプトを編集
6. Hello Worldを表示

# 詳細

### 1. オブジェクトを作成
HierarchyウィンドウのCreate -> 3D Object -> Cube の順にクリックして、立方体のオブジェクトを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262601/1831d656-d2ce-0355-3bd7-730b414ed906.png)

### 2. スクリプトを作成
Projectウィンドウ内で右クリックし、Create -> C# Scriptを選択します。Scriptの名称をtestに変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262601/ed10a115-cd2c-16e0-45d0-b4f3a57d9c88.png)

### 3. ゲームオブジェクトを作成
スクリプトを動かすには、何らかのゲームオブジェクトと結びつける（アタッチする）必要があります。作成したスクリプトを動かすためにゲームオブジェクトを追加します。
HierarchyウィンドウのCreate -> Create Emptyを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262601/e19cdcc4-7671-ddfa-b048-964b584a3dae.png)

### 4. スクリプトをアタッチ
testスクリプトを、HierarchyウィンドウのGameObjectにドラッグ&ドロップします。これで、スクリプトをゲームオブジェクトに結び付ける（アタッチする）ことができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262601/ec3cbf63-abd7-d13b-e460-79139bf317cb.png)

### 5. スクリプトを編集
testスクリプトをダブルクリックすると、Visual Studioが起動し、スクリプトを編集できるようにになります。Hello, Worldと表示されるよう10行目にソースコードを追記します。Visual Studio上でスクリプトを保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262601/3c2fcf19-bf89-1f19-ecd1-3927ce107d2d.png)


```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class test : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("Hello, World");
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
```

### 6. Hello Worldを表示
Unityに戻り、SceneビューにあるPlayボタンを押します。ConsoleウィンドウにHello, Worldが表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262601/e07c3793-390e-f28e-66c1-c5ec5a1b6632.png)
Laravel ビューファイルで作成する画面にYoutubeの動画を埋め込む

# 目的

- Youtubeの再生画面をLaravelのビューファイルに埋め込む方法をまとめる。

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 7.0.8 | commposerを用いてこちらの方法で導入→[Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08) |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9) |

# 前提条件

- 実施環境のLaravelアプリ動作環境が構築できていること。

# 前提情報

- 特になし

# 読後感

- Laravelのビューファイルを用いた画面の表示にYoutubeの再生ウインドウを埋め込むことができる。

# 概要

1. 埋め込みリンクのコピー
1. ビューファイルの記載

# 詳細

1. 埋め込みリンクのコピー
    1. ブラウザにてYoutubeのページを開く。
    1. 埋め込みたい動画の「共有」をクリックする。
    
        <img width="1420" alt="Awesome_City_Club_–_今夜だけ間違いじゃないことにしてあげる__Music_Video__-_YouTube.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/7f09bf2c-e6f7-fc41-57fe-4c865dc21d75.png">

    1. 「埋め込む」をクリックする。

        <img width="1680" alt="Awesome_City_Club_–_今夜だけ間違いじゃないことにしてあげる__Music_Video__-_YouTube_🔊.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/ff0af55b-5485-823c-71fe-40fecafbaaa0.png">

    1. 表示されたhtml形式のリンクをコピーする。

        <img width="1420" alt="Awesome_City_Club_–_今夜だけ間違いじゃないことにしてあげる__Music_Video__-_YouTube-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/9daf2e2d-a9ed-61ea-a765-5015bec6b260.png">

1. ビューファイルの記載
    1. Youtubeを埋め込みたいビューファイルを開き、埋め込みたい箇所に先にコピーしたリンクを貼り付ける。
Nuxt で router.beforeEach 内に next()を 使うと 404 になる件


## 結論

> In nuxt.js, we do some special stuff before mounting the app in SPA mode, so some things differs, also, we don't recommend to use router.beforeEach and using next because of our internal logic with fetch/asyncData.

> You can do the same behaviour with the nuxt middleware.

```
Nuxtではrouter.beforeEachのなかでnext()使うのは推奨してないよ
nuxt.configのrouterプロパティで設定できるmiddlewareを使うといいよ、ハハッ
```

※hada の主観による意訳です

https://github.com/nuxt/nuxt.js/issues/3621

## 発端

local storage に持ってるユーザー情報が古い場合は update するみたいな処理を plugin の`app.router.beforeEach`内で実装してると、なんか 404(This page could not be found) が出てくる

## 元のコード

まんまではないですが

```typescript:plugins/router.ts
export default function ({ app, store }: Context): void {
  await app.router.beforeEach(async (to: Route, from: Route, next) => {
    // local storageにある特定のプロパティの値が1時間以上立っている場合はステータスをapiから取得し更新する的なサムシング
    if(moment(localDateTime).diff(lastUpdatedAt, 'hours') <= 1) {
      next()
      return
    }

    await updateUserStatus()
  }
}
```

## やったこと

plugin で router.beforeEach してたのを、nuxt config の router に middleware 設定する方法に変更した

具体的には

- router.beforeEach 内で next を使うのをやめる
- router.beforeEach でやってた処理をミドルウェアにする
- nuxt.config.ts にてミドルウェアを設定する

```typescript:middleware/update-status.ts
export default async function ({ app, store }: Context): Promise<void> {
  if (moment(localDateTime).diff(lastUpdatedAt, "hours") <= 1) {
    return;
  }

  await updateUserStatus();
}
```

```typescript:nuxt.config.ts
const nuxtConfig: Configuration = {
  // ...

  router: {
    middleware: ["update-status"],
  },
};
```
[備忘録] VSCodeでLaTeXを保存時に自動でコンパイルする方法

# はじめに
VSCodeでLaTeXの環境構築に苦労したため、備忘録として書いている。

# 想定環境
次のソフトをインストールしていることを想定している。
- VSCode
- TeX Live

# 手順

## 拡張機能のインストール
VSCodeで拡張機能のLaTeX Workshopをインストールする。

## VSCodeの設定
settings.jsonを開き[^1]、以下のように書く。
[^1]: Ctrl+,で設定を開いた後、設定 (JSON) を開く


>```settings.json
{
    "latex-workshop.latex.autoBuild.run": "onFileChange",
    "latex-workshop.latex.recipes": [
      {
        "name": "latexmk",
        "tools": ["latexmk"]
      }
    ],
    "latex-workshop.latex.tools": [
      {
        "name": "latexmk",
        "command": "latexmk",
        "args": [
          "-synctex=1",
          "-interaction=nonstopmode",
          "-file-line-error",
          "-pdfdvi",
          "%DOC%"
        ]
      }
    ],
    "latex-workshop.view.pdf.viewer": "tab"
  }
```

### 参考
[VSCodeのLaTeX Workshopの設定について](https://blog.sh4869.net/post/2019/10/10/vscode-latexmk-setting/)

[VSCodeでTeXをビルドしてpdf表示までする](http://msz006aeug.hatenablog.com/entry/2019/02/08/160404)

## latexmkの設定
LaTeXのファイルがあるディレクトリにlatexmkrcというファイルを
作成、またはホームディレクトリに.latexmkrcというファイルを作成し
以下のように書く。

(参照: [オンラインLaTeXエディタ](https://doi.org/10.3169/itej.71.499) 図4)

>```~/.latexmkrc
$latex = 'platex';
$bibtex = 'pbibtex';
$dvipdf = 'dvipdfmx %O -o %D %S';
$makeindex = 'mendex -U %O -o %D %S';
$pdf_mode = 3;
```


## コンパイル方法
LaTeXファイルを上書き保存すると、自動でコンパイルされる。
PATH名に日本語が含まれているとエラーとなるため、全て半角にする。
Searchkickでのデバッグ術

Railsコンソールで`dubug: true`属性？を付与して検索を実行してやると、そのときに使われた Search Option, Setting, Mapping, Results（検索スコアとか）を見れていい。

[Searchkick Dubug](https://github.com/ankane/searchkick#debugging-queries)

```.rb
> Post.search "日本の絶景", fields: [:name, :description, :category_name], operator: "or", debug: true
```

```
Model Searchkick Options
{:language=>"japanese",
 :_type=>
  #<Proc:0x00007f96bd9f4858 /Users/takuya/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/searchkick-4.4.1/lib/searchkick/model.rb:17 (lambda)>,
 :class_name=>"Post"}

Search Options
{:fields=>[:name, :description, :category_name], :operator=>"or", :debug=>true}

Elasticsearch Query
curl http://localhost:9200/posts_development/_search?pretty -H 'Content-Type: application/json' -d '{"query":{"bool":{"should":[{"dis_max":{"queries":[{"match":{"name.analyzed":{"query":"日本の絶景","boost":10,"operator":"or","analyzer":"searchkick_search"}}},{"match":{"name.analyzed":{"query":"日本の絶景","boost":1,"operator":"or","analyzer":"searchkick_search","fuzziness":1,"prefix_length":0,"max_expansions":3,"fuzzy_transpositions":true}}}]}},{"dis_max":{"queries":[{"match":{"description.analyzed":{"query":"日本の絶景","boost":10,"operator":"or","analyzer":"searchkick_search"}}},{"match":{"description.analyzed":{"query":"日本の絶景","boost":1,"operator":"or","analyzer":"searchkick_search","fuzziness":1,"prefix_length":0,"max_expansions":3,"fuzzy_transpositions":true}}}]}},{"dis_max":{"queries":[{"match":{"category_name.analyzed":{"query":"日本の絶景","boost":10,"operator":"or","analyzer":"searchkick_search"}}},{"match":{"category_name.analyzed":{"query":"日本の絶景","boost":1,"operator":"or","analyzer":"searchkick_search","fuzziness":1,"prefix_length":0,"max_expansions":3,"fuzzy_transpositions":true}}}]}}]}},"timeout":"11s","_source":false,"size":10000}'

Elasticsearch Results
{
  "took": 10,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 21,
      "relation": "eq"
    },
    "max_score": 57.485226,
    "hits": [
      {
        "_index": "posts_development_20200709213129463",
        "_type": "_doc",
        "_id": "28",
        "_score": 57.485226
      },
      {
        "_index": "posts_development_20200709213129463",
        "_type": "_doc",
        "_id": "20",
        "_score": 46.743748
      }
    ]
  }
}
```
Oracleパスワードの有効期限切れの対処方法

#　背景

自分の勉強用に用意したORACLEサーバを久しぶりに触ろうとしたところ「ORA-28001:パスワードが期限切れです。」
とエラーメッセージが表示されたので、対処した際の手順をまとめます。

#　原因
Oracle10gまではユーザのパスワードの有効期限はデフォルトで無期限だったが、
Oracle11gからはデフォルトで180日に設定されているため、180日たったときに起きてしまうらしい。


もう少し詳しく調べてみたところパスワードポリシーは次のようになっているみたいです。
>引用：[Oracle® Database 2日でデータベース管理者 12c リリース1 (12.1) 7.6.1 パスワード・ポリシーについて](https://docs.oracle.com/cd/E57425_01/121/ADMQS/GUID-9F5FFAF2-4BC9-401B-BDA9-352460620D37.htm)
>・ユーザー・アカウントのパスワードは180日で自動的に期限切れとなります。
>・パスワードの期限切れの7日後にユーザー・アカウントがロックされます。
>・10回ログインに失敗すると、ユーザー・アカウントが1日ロックされます。

# 対処方法

デフォルトのプロファイルのパスワード有効期限を無期限にする。
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;

ユーザーパスワードの再設定
ALTER USER ユーザ名 IDENTIFIED BY 新パスワード

ユーザーアカウントロックの解除
ALTER USER ユーザ名　ACCOUNT UNLOCK

# まとめ
お客様先で10g以上のORACLE使ってて、そこで発生しちゃったとかじゃなくてよかったなと思いました。
GCP アップデート (7/3-7/9 2020)

### Monitoring: [July 7, 2020](https://cloud.google.com/stackdriver/docs/release-notes#July_07_2020)
- Monitoring Query Language (MQL)がGAになったよ！
  - [MQL](https://cloud.google.com/monitoring/mql/)はMonitoringのタイムシリーズデータをテキストで操作できるようにするためのもの。

### Config Connector: [July 9, 2020](https://cloud.google.com/config-connector/docs/release-notes#July_09_2020)
- SecretManagerSecretのサポートが新しく追加されたよ！

### Cloud SQL (PostgreSQL): [JUly 9, 2020](https://cloud.google.com/sql/docs/release-notes#July_09_2020)
- [ポイントインタイムリカバリ(PITR)](https://cloud.google.com/sql/docs/postgres/backup-recovery/pitr)がサポートされるようになったよ！

### ディスクレーマ
- アップデートの内容はあくまでも個人の理解していることを書いています。正しい内容はリリースノート等を確認下さい。
- リリース内容できるだけ拾うようにしているのですが、抜けていそうなリリースノートが追加するのでぜひ教えて下さい！(一覧[ここ](https://qiita.com/kenzkenz/items/ac18a359b803dbb6b490)で更新してます。)
【自分用メモ】JavaScript

# Node.js

## Note

### npmとYarnの違い
* Yarn：Facebook発のパッケージマネジャーはnpmに代わるスタンダードになるか
  * https://www.webprofessional.jp/yarn-vs-npm/

## Snippets

### zero padding

```javascript
/**
 * zeroPadding(123, 5) -> '00123'
 */
function zeroPadding (value, digit) {
  return ('0'.repeat(digit) + value).slice(-digit);
}
```
確認ダイアログがiPad Safariだと出ない？

### はじめに

普段からNuxt x TSで業務アプリケーションを開発しており、IEからスマホ対応まで幅広く見てますが、今回はiPadOSで起きた事象と解決策を備忘録として残しておきます

### 何があった？

確認ダイアログ（window.confirm）がiPad Safariだと動いてくれないようで、リリースが見送りになってしまいました。またiPad Safariかよ〜

### 調査＆対応

ちなみに手元のiPadOSのバージョンは**13.3**です。

[MDN](https://developer.mozilla.org/ja/docs/Web/API/Window/confirm)では、Safariも対応している
<img width="1041" alt="スクリーンショット 2020-07-10 8.52.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252687/4203de48-18d0-cb2b-e9dc-1a41fa07238c.png">
ということで、PCからSafariを開いて確認します。
すると、確かに問題なく確認ダイアログが出現します。


つまりOS依存？


ということで、OSのアップデートをしてみました。

現時点の最新版が13.5.1なので、ソフトウェアアップデートを行います。
<img width="300" alt="IMG_0070.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252687/fac608e2-7812-98ae-d8d7-12b140c5ab44.png">



15分ほど待ってみる...


そして、確認してみると....
お、無事に、問題なく確認ダイアログが出るようになった！

### ちなみに..

[Apple セキュリティアップデート](https://support.apple.com/ja-jp/HT201222)を確認して、どのタイミングで修正されたのか見ようとしたのですが、該当のエントリは見つかりませんでした。おそらくこれかな？（詳細が見れない...）
<img width="888" alt="スクリーンショット_2020-07-10_9_04_35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252687/3924cb34-b067-809f-fe70-826c72e9615c.png">


### さいごに

iPadOSはたまにちょくちょくこういうことが起きます。
なので、不具合のようなものを見つけたら

1. MDNでSafari対応かどうか確認する
2. PC Safariで確認する
3. iPadOSのバージョンを最新にする

などして冷静に対応してみましょう
（アプリケーション側の不具合でなかったりするので）

*実は、恐ろしいことにブラウザバックと組み合わせるとまた別の不具合に遭遇します。そちらはこちらの記事がわかりやすかったので参考にどうぞ

[ブラウザの「戻る」ボタンでキャッシュが表示されてしまう際の対策](https://qiita.com/shibe23/items/79f950061457ff1a7687)
collections.deque

```py
import collections
import queue

collections.deque

q = queue.Queue()
lq = queue.LifoQueue()
l = []
d = collections.deque()

for i in range(3):
    q.put(i)
    lq.put(i)
    l.append(i)
    d.append(i)

for _ in range(3):
    print('FIFO queue = {}'.format(q.get()))
    print('LIFO queue = {}'.format(lq.get()))
    print('list       = {}'.format(l.pop())) #pop(0)でFIFO
    print('deque      = {}'.format(d.pop())) #d.popleft()でFIFO
    print()
```
実行結果：

```txt
FIFO queue = 0
LIFO queue = 2
list       = 2
deque      = 2

FIFO queue = 1
LIFO queue = 1
list       = 1
deque      = 1

FIFO queue = 2
LIFO queue = 0
list       = 0
deque      = 0
```

```py
import collections
import queue

collections.deque

d = collections.deque()

for i in range(3):
    d.append(i)

print(d)
d.extendleft('x')
d.extend('y')
print(d)
d.rotate()
print(d)
d.clear()
print(d)
```
実行結果：

```txt
deque([0, 1, 2])
deque(['x', 0, 1, 2, 'y'])
deque(['y', 'x', 0, 1, 2])
deque([])
```
探索的テスト

# 1 探索的テストとは

　探索的テスト（Exploratory Testing）とは、事前にテストケースを準備せずに、テスト対象の学習・テストの設計・テスト実施を同時に行いながらテストを実施する技法のことです。
　私はテストケースベースドテストを実施する前に実施したり、テストケースベースドテスト実施後に実施することが多いです。
　似たような技法にアドホックテストがあります。これも、テストケースを準備せずにテストを実施する技法になります。
２つの違いは、事前にテストケースを作成せずに、テスターの経験と直感に基づいてテストを実施する点では同じですが、テスト設計を行わない点で異なります。
テスト設計とテスト実施を同時に行うテスト手法が探索的テストだと思います。
テスト設計を行わないため、アドホックテストは探索的テストよりテスター個人の能力や経験に依存します。探索的テストはできるだけ個人の能力に影響されないように、テスト指示書によるガイドラインの提示やセッションシートによるテスト管理の技法が導入されています。

## 1.1 探索的テスト結果のフィードバック

　一般的に探索的テストはテストケースベースドテストよりも欠陥を多く検出できます。欠陥を検出のには有効なテスト技法となりますが、テストケースがないため、第三者に品質を保証するための説明を行うのは難しいかと思います。
　そのため、探索的テストの結果をテストケースにフィードバックするのがベストです。これにより、テストケースのカバレッジも上がります。カバレッジが上昇したテストケースベースドテストの後に探索的テストを実施すれば、異なる観点でのテストが実施できます。
このように探索的テストとテストケースベースドテストを相互に補完させて実施すれば、高品質なテストが実現できるようになります。

## 1.2 探索的テストのメリット
* テストにドキュメントをあまり必要としない
* 少ない準備でテストを実行できる
* テストを繰り返しても欠陥を検出できる
* テストの実行結果をテスト設計に即時反映できる

## 1.3 探索的テストのデメリット
* テスト開始前に欠陥を予防できない
* 品質を保証する公式なテストではない
* テストカバレッジの管理が難しい

# 2 ラージ探索的テストとスモールテスト

　探索的テストでは欠陥が潜んでいそうな範囲を探索しますが、指標が何もないと難しい作業になります。

ソフトウェア探索の指標として不正な入力のパターンを探るスモールと、機能の限界を探るラージの2種類の方法があります。

## 2.1 スモール探索的テスト
　入力として不正になる値を探索するテストです。ソフトウェアが不正終了する入力値を探索する、出力がオーバフローする入力値を探索する、などが該当します。

## 2.2 ラージ探索的テスト
　テスト対象ソフトウェアのあるべき姿を想定し、そのとおりに動作するかを探索するテストです。ブラックボックステスト手法を用いたシステムテスト、受入テストがこれに該当します。

ユースケースや要求仕様が存在するなら、それをガイドラインにすることで探索が容易になります。



# 参考文献
参考資料は以下。ありがとうございます。
https://booth.pm/ja/items/1305980
USBカメラをDockerから使いたい



## 概要
UVC対応のUSBカメラ（BUFFALO BSW200MBK）をDockerから使おうとしてつまずいたので、試したことをまとめます。
本記事ではROSを利用していますが、ROS側の問題では無いはずです。

## ホスト
- HP Spectre x360 2019年モデル
  - intel i7-1065G7
  - intel CPU内蔵グラフィック
- Ubuntu 18.04
- Docker version 19.03.12, build 48a66213fe
- 一般ユーザーは`sudo gpasswd -a $USER docker`として、`sudo `なしで起動できるように設定済み

## 試したこと
次のようなDockerfileを作成して、

```Dockerfile
FROM ubuntu:16.04

# 中略　ROS kinetic のインストール

RUN apt-get update && apt-get install -y \
  ros-kinetic-uvc-camera

RUN useradd -m -d /home/myubuntu16 myubuntu16 -p $(perl -e 'print crypt("myubuntu16", "salt"),"\n"') && \
    echo "myubuntu16 ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

RUN \
  apt-get update && \
  apt-get -y install libgl1-mesa-glx libgl1-mesa-dri && \
  rm -rf /var/lib/apt/lists/*

ENV QT_X11_NO_MITSHM 1

ENV USER myubuntu16
USER myubuntu16

CMD ["bash"]

```

次のコマンドでコンテナを起動しました。

```bash
docker build -t myubuntu:16 .

docker run  -it \
	--name myubuntu_test \
	--volume=/tmp/.X11-unix:/tmp/.X11-unix \
	--volume=$(pwd)/myubuntu16:/home/myubuntu16  \
	--device=/dev/dri:/dev/dri \
	--device=/dev/video0:/dev/video0 \
	--env="DISPLAY=$DISPLAY"   \
	myubuntu:16
```

立ち上がったコンテナで`roscore`を起動して、別のターミナルから同じコンテナに入って、カメラを起動するノードを立ち上げたところでエラーが発生。

```bash
# ターミナル2
$ docker exec -it myubuntu_test bash
$ rosrun uvc_camera uvc_camera_node 
[ INFO] [1594303093.006722031]: using default calibration URL
[ INFO] [1594303093.006790555]: camera calibration URL: file:///home/myubuntu16/.ros/camera_info/camera.yaml
[ INFO] [1594303093.006832237]: Unable to open camera calibration file [/home/myubuntu16/.ros/camera_info/camera.yaml]
[ WARN] [1594303093.006850909]: Camera calibration file /home/myubuntu16/.ros/camera_info/camera.yaml not found.
opening /dev/video0
terminate called after throwing an instance of 'std::runtime_error'
  what():  couldn't open /dev/video0
Aborted

```

couldn't open /dev/video0と出たので、カメラの状態を取得するツール（？）を実行


```
$ sudo apt install v4l-utils
$ v4l2-ctl --list-device
Failed to open /dev/video0: Permission denied
```

権限を確認して、変更してみると`Permission denied`は解消された。

```
$ ls -la /dev/video*
crw-rw---- 1 root video 81, 0 Jul  9 13:48 /dev/video0

$ sudo chmod 777 /dev/video0
$ v4l2-ctl --list-device
USB_Camera: USB_Camera (usb-0000:00:14.0-1):
	/dev/video0
```

ふたたび、同じコンテナ内の3個のターミナルで以下をそれぞれ実行

```bash
$ roscore
$ rosrun uvc_camera uvc_camera_node
$ rosrun image_view image_view image:=/image_raw
```

動いた
Gatsby で Picturefill

なんだかんだで、IE11まだ対応しますよね :angel:
で、Picturefill が必要だったんですね。

Gatsby と一緒に使おうと思ってググったけど、どストライクなの見つからなかったの :poop:

いくつか見つかった記事を参考に色々試したけども、なんか違う。

`useEffect` で `picturefill()` しようとしたら、
`import 'picturefill'` 書いた時点で `window` がないとビルドでこける。（開発時は大丈夫）

`gatsby-browser.js` の `onClientEntry` や `onRouteUpdate` で `picturefill()` 呼ぶと動く。けど、動的に `picture` 要素足した（変更した）場合、適応されない。

などなど、紆余曲折ありつつ、 `picturefill` の `mutation plugin` を使う方法にたどり着いた。
このプラグインは `picturefill()` を自動でやってくれるというもの。


`gatsby-browser.js` でインポートするだけ :rocket:

```js
import 'picturefill'
import 'picturefill/dist/plugins/mutation/pf.mutation'
```
[JavaScript]お手軽に文字列を（ほぼ）衝突させないで生成する方法

例えば、ユーザ登録用のダミー値を複数かつ衝突させないで用意したい場合がありますよね。
そんな時に**ちょっと**した工夫で、文字列を生成できる方法を紹介します。

## 実装

```js
new Date().getTime().toString(36); // => 「kcexh9g6」などの文字列
```

## 解説
ミリ秒をX進数に変換するだけで。お手軽に文字列を生成することができます。
`toString()`に2-36の間の数を与えるとその進数へ変換できます。
また、`Date().getTime()`は1970年1月1日00:00:00から経過したミリ秒を返すので、
この二つを利用すれば桁数も自由に変えることも可能です。
[flutter]はじめてのflutter3[端末設定編]

#目的

WEBとアプリの比較から自分のやりたい方向性を掴む。

##今日やること

Androidのビルド

##Androidのビルド

Start a new Flutter projectを押下
<img width="666" alt="Screen Shot 2020-07-10 at 8.45.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/17425b9e-3393-7a04-1174-4c8ef10d8e0b.png">

Flutter ApplicationでNext
<img width="898" alt="Screen Shot 2020-07-10 at 8.46.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/14a20157-50f8-5f01-9d58-2a7da41d3d7a.png">

名前や格納先を決めて、NextしてFinish
<img width="894" alt="Screen Shot 2020-07-10 at 8.48.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/cbc4967e-be5f-cccc-b79e-e454c4cb1a2b.png">

右上のSDK Managerから端末を触れるようにします
<img width="1440" alt="Screen Shot 2020-07-10 at 8.51.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/65d362ae-ec45-d94d-92ff-ceb6cdd84e3c.png">

Create new device

<img width="631" alt="Screen Shot 2020-07-10 at 8.57.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/e8bb6035-55a6-ba0a-8a09-001aa37298ae.png">

試したい端末のplaystoreのマークをクリック、Next
<img width="1238" alt="Screen Shot 2020-07-10 at 8.54.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/04ce67be-0289-f2d8-e3a7-4c5569491f0b.png">

Androidのverを選ぶ、Next、finish
<img width="998" alt="Screen Shot 2020-07-10 at 8.59.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/78df15e1-c182-dd94-6e3a-2fab96c04f9e.png">

この画面になる。端末情報があればOK。アクションの▶︎マークをクリックすると端末が現れる

<img width="1251" alt="Screen Shot 2020-07-10 at 9.01.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/707ecf1a-7f04-5ab9-1c1f-80db50dcc8f4.png">

ででん！
<img width="341" alt="Screen Shot 2020-07-10 at 9.03.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/ee4939b2-1f7f-a52f-9020-b243857567c5.png">

端末情報を選択した状態で、ctr + D もしくは、虫みたいなアイコンDebug 'main.dart'をクリック
<img width="1439" alt="Screen Shot 2020-07-10 at 9.04.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/3b016213-f948-03c3-b0a5-de449b6d6e59.png">

これでちゃかちゃか遊べます！
<img width="1440" alt="Screen Shot 2020-07-10 at 9.07.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/609bcb1c-d78d-9357-a768-9035f18763e0.png">
AIZU ONLINE JUDGE の問題をSwiftでやってみた(プログラミング入門 構造化プログラムⅠ編)

##トピック #1　構造化プログラムⅠ
[AIZU ONLINE JUDGE](https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/1/ITP1_1_D)の問題にSwiftで解答したものになります。競技プログラミングは普段やりませんので、こうしたほうが簡単！などがあればコメントで教えて下さい。
###5_A　長方形の描画

**問題**
入力される二つの数字の組み合わせに対して以下のような長方形を出力して下さい。
＃＃＃＃
＃＃＃＃
＃＃＃＃
(3,4)
入力は複数のデータセットから構成されています。
H W
H, W がともに 0 のとき、入力の終わりとします。



**解答**


```Swift
let a = readLine()!.split(separator: " ").map({Int($0)!})
while a[0] != 0 && a[1] != 0 {
    for _ in 0 ..< a[0] {
        print(String(repeating: "#", count: a[1]))
    }
}
```

```Swift
let a = readLine()!.split(separator: " ").map({Int($0)!})
while a[0] != 0 && a[1] != 0 {
    for _ in 0 ..< a[0] {
        for _ in 0 ..< a[1] {
            print("#")
        }
    }
}
```

が模範解答に近い形なのですが、出力に改行が含まれてしまうため`String(repeating: , count: )`を用いました。



###5_B フレームの描画

**問題**
5_Aの続き
(3,4)に対して
＃＃＃＃
＃。。＃
＃＃＃＃
となるようにして下さい。
**解答**

```Swift
let a = readLine()!.split(separator: " ").map({Int($0)!})
while a[0] != 0 && a[1] != 0 {
    for i in 0 ..< a[0] {
        if i == 0  || i == a[0] - 1{
            print(String(repeating: "#", count: a[1]))
        } else {
            var b = String(repeating: ".", count: a[1] - 2)
            print("#\(b)#")
        }
    }
}
```
###5_C　チェスボードの描画

**問題**
5_Bの続き
(3,4)に対して
＃。＃。
。＃。＃
＃。＃。
となるように出力してください。
**解答**

```Swift
let a = readLine()!.split(separator: " ").map({Int($0)!})
while a[0] != 0 && a[1] != 0 {
    for i in 0 ..< a[0] {
        if i.isMultiple(of: 2) {
            if a[1].isMultiple(of: 2) {
            print(String(repeating: "#.", count: a[1]/2))
            } else {
                var b = String(repeating: "#.", count: a[1]/2 - 1)
                print("\(b).")
            }
        } else {
            if a[1].isMultiple(of: 2) {
            print(String(repeating: ".#", count: a[1]/2))
            } else {
                var b = String(repeating: ".#", count: a[1]/2 - 1)
                print("\(b)#")
            }
        }
    }
}
```


###5_D　構造化プログラミング
**問題**
入力された数字nに対しnまでに含まれる3の倍数または3を含む数字を出力して下さい。（世界のナベアツ）
**解答**

```Swift
let a = Int(readLine()!)!
var arr:[String] = []

for i in 1 ... a {
    arr.append(String(i))
}

func check(_ num: [String]) -> [Int] {
    var resultArr:[String] = []
    for i in num {
        if Int(i)!.isMultiple(of: 3){
            resultArr.append(i)
        }
    }
    print(resultArr)
    var arr = num.filter({Int($0)! % 3 != 0}).map({String($0)})
    print(arr)
    for i in arr {
        if i.contains("3") {
            resultArr.append(i)
        }
    }
    return resultArr.map({Int($0)!})

}
print(check(arr).sorted())
```
[Rails]初学者によるRubocopの導入

# はじめに
Rubocopとは、Rubyの静的コード解析ツール。
[ruby-style-guide
](https://github.com/rubocop-hq/ruby-style-guide)に従って、ソースコードの修正・改善点を指摘してくれます。

また、インデントのずれや、不必要なスペース・改行などは特定のコマンドを打つことで自動で修正してくれるので、自分にとってはもちろん、他の人が見ても読みやすいコードに整形することが出来ます。
※あくまで初学者の観点で設定等を決めています。

# 導入

```ruby:gemfile
gem 'rubocop', require: false
```
```:ターミナル
bundle install
```

# 使ってみる

```:ターミナル
bundle exec rubocop
```
実行すると、以下のような出力が得られます。
<img width="1155" alt="スクリーンショット 2020-07-10 8.06.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652806/6270c9eb-27d4-588d-2161-060b59c9dfb3.png">

これらがRubocopが検知した修正点になります。
しかし、デフォルトのルール全てに従っていると、コードを書く際に気を配る点があまりにも増えてしまうので、自分やチーム内で許容するルールを設定することが出来ます。

# 設定をカスタマイズする
アプリケーションのディレクトリに
.rubocop.yml というファイルを作成し、その中に設定を記述します。

```.rubocop.yml
AllCops:
  # 除外するディレクトリを設定。例えばschemaやmigrationファイルなどは書き直すことが少ないため、検知対象外に
  Exclude:
    - bin/*
    - db/schema.rb
    - node_modules/**/*
    - db/migrate/*
    - vendor/**/*
  # Rails向けのチェックを行う
  Rails:
    enabled: true

# "Missing top-level class documentation comment."を無効
Style/Documentation:
  Enabled: false

# "Prefer single-quoted strings when you don't need string interpolation or special symbols."を無効
Style/StringLiterals:
  Enabled: false

# "Line is too long"を無効
Metrics/LineLength:
  Enabled: false

#'frozen_string_literal: true'を無効
Style/FrozenStringLiteralComment:
  Enabled: false
```
など様々な設定が可能です。
[デフォルトの設定](https://github.com/rubocop-hq/rubocop/blob/master/config/default.yml)を参考にいろいろいじってみようと思います。

設定後、もう一度

```:ターミナル
bundle exec rubocop
```
<img width="1155" alt="スクリーンショット 2020-07-10 8.29.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652806/994639dd-7639-21bb-ec72-e37398ae8caa.png">
すると、72filesが56filesと、先ほどよりも修正点が減っていることがわかります。

# 修正する
```:ターミナル
bundle exec rubocop --auto-gen-config
```
.rubocop.todo.yml というファイルが自動生成されます。
これにより、一時的に修正点を全て無効とみなされます。
ここでrubocopを実行すると、修正点がない状態になります。

```ruby:.rubocop.todo.yml
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include.
# Include: **/*.gemfile, **/Gemfile, **/gems.rb
Bundler/OrderedGems:
  Exclude:
    - 'Gemfile'
```
一例として、上記のような記述があります。
この記述を削除すると、該当部分の無効化していた修正点が復活します。
早速修正して行きますが、
```Cop supports --auto-correct.```
という記述がある場合、Rubocopが以下のコマンドで自動で修正してくれます。

```:ターミナル
bundle exec rubocop -a
```
今回修正したのは、Gemfileのgemの記述がアルファベット順になっていないのを正しい順番に並べ替えました。

# まとめ
1.gemを導入し、```.rubocop.yml```に設定をカスタマイズする
2.```bundle exec rubocop --auto-gen-config```を実行し、
　```.rubocop.todo.yml```を生成する。
3.```.rubocop.todo.yml```に書かれている記述を1つ消し、修正する
4.3.を繰り返す。

実際の現場では、自動化されていてあまり自分で修正することはなさそうですが、
まだまだ初学者ですので、一つ一つ改善していって規約を確認し、
初めから読みやすいコードを書けるエンジニアになれるよう心がけます。
【C#】throw式

★throw式が記述できる箇所は以下の3か所
1:ラムダ式、式形式メンバーの「=>」の右辺
2:Null合体演算子(??)の右辺
3:条件演算子の2,3つ目の引数
上記以外での記述はコンパイルエラーとなる。

```C#:throw式記述場所
//1:ラムダor式形式のメンバーの中
static void test1() => throw new NotImplementeException();
static string test2(string ex)
{
    //2：Null合体演算子(??)の右辺
    var a = ex as string ?? throw new ArgumentException(nameof(obj));
    //3:条件演算子の2,3つ目の引数
    return a.Length == 0 ? "enmpty" :
        a.Length < 5 ? "short" :
        throw new InvalidOperationException("too long");
}
```
ubuntuでpsql: FATAL:  Peer authentication failed for userの対応にハマった話

#はじめに
pg_hba.conf を $PGDATA の下に作成・修正しても、掲題のエラーが解消しなかったときの対応メモ

#前提
pg_hba.conf の設定は理解していることを前提とします。

#環境
- ubuntu18.04 
- posgres 10

# 結論
pg_hba.confの場所が違っていた。

postgresユーザでPeer接続して、pg_hba.confを認識している場所を見る。

```
postgres=# SHOW hba_file;
              hba_file
-------------------------------------
 /etc/postgresql/10/main/pg_hba.conf
(1 row)
```

なんと/etc/の下に存在していた。このファイルを修正してpostgresを再起動することで解決。

```
# "local" is for Unix domain socket connections only
#local   all             all                                     peer
local   all             all                                     md5
```
プログラムの怖いところ　ライブラリのバージョンアップ

# はじめに
本記事はライブラリのバージョンアップが原因でプログラムが動かなくなり、どの様に原因を調査して解決まで行き着いたかについて、システム開発の一助となるストーリーをご紹介します。

## 概要
とあるtoCのシステムにおけるバックエンドのプログラム（API）で軽微な修正を行い、デプロイしたときの話になります。

本番環境と開発環境が存在し、開発環境でテストした上で本番環境でリリース作業を実施。本番環境でデプロイ後、システムの一部機能で正常性が確認できない事態が発生しました。

バックエンドはDockerで開発を行っているため、デプロイ時に`docker compose build`でビルドを毎回行っています。デプロイ自体は成功しているため、ライブラリのバージョンアップが関係しているのではないかと予想していましたが、のちに調査が難航することになるとは、このときは予想していませんでした。。

当該事象発生時は原因究明に至らなかったため、切り戻しを実施し、リリース作業は中断。翌日に原因調査を行いました。

![question_head_gakuzen_boy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/db9ced18-f76a-d564-2011-4790917455ce.png)

## 原因調査
前提として本番環境と開発環境で使用していたソースは、一部機能をマージしてないなど環境差異は発生していましたが今回発生した事象に関係はありません。

調査を開始し、開発環境で事象を再現させるために確認を行いましたが、同様の事象は発生しませんでした。その後、本番環境で使用したソースを開発環境でデプロイすると事象が再現しました。

開発環境で事象再現後、デバッグするために本番環境で使用したソースの不具合が発生している箇所に`console.log(e)`でログ出力する様にしてデバッグを行いました。

不具合が発生している箇所に対するAPIのリクエストを実行し、サーバ側のログを確認すると、データベースのあるテーブルのカラムが見つからないと言うエラーメッセージが出力されていました。

仮説としてプログラムで利用していたORMライブラリのバージョンが上がったため、今まで許容していたデータベースに対する接続がエラーになっているのではないかという考えに辿りつきました。

![animal_chara_computer_azarashi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/f06e1a18-fd86-9d31-5dfc-908e0c717e78.png)

## 解決方法
本番環境で稼働中のコンテナで生成された`yarn.lock`ファイルと、開発環境でデプロイしたコンテナの`yarn.lock`ファイルのORMライブラリのバージョンを比較すると、開発環境のコンテナのマイナーバージョンが**1**桁だけ上がっていることを確認しました。

検証として`package-lock.json`のORMライブラリのバージョンを、本番環境で稼働中のコンテナで生成されたバージョンと同じバージョンに固定すると、事象が再現しないことが確認できました。

よって暫定対応としては、ORMのライブラリのバージョンを固定しないことで一旦は解決しましたが、今後の運用として色々と課題を認識しました。

![shinpai_man.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/3caa555d-1f4d-a37b-2d03-aa332bbc9f09.png)


## DevOps
DevOps観点で感じた課題について以下に記載します。

**※本記事の内容は、あくまで考え方の一例であり、必ずしも全ての考え方がシステムに適合したり、ここに書いている内容で満たされている訳ではありません。**

- **ライブラリのバージョン固定**
保守性を高める場合はライブラリのバージョンを上げないように固定することが望ましいですが、セキュリティとトレードオフになります。また、バージョンアップする場合は確認の工数もかかります。`npm outdated`コマンドを実行すると、現在インストールされているバージョン、現在のバージョン指定でインストールされる最新バージョン、リリースされている最新バージョンが表示されます。

- **テストの再現性**
当たり前ですが極力環境差異をなくしたテスト方法の考案及びテスト環境を構築し、テストを実施することが望ましいです。※参考：[3.6 本番環境とテスト環境の差異に関する教訓（T6）](https://www.ipa.go.jp/files/000049542.pdf)

- **本質的なアプローチ**
今回の様な事象は技術的な手段で解決する以前に、開発や運用ポリシー等を定義していればこの様なリスクを軽減する可能性は上がります。

# おわりに
本事象を通して改めて学んだのは、プログラムは数字1桁が変わるだけで動かなくなるという恐ろしさと、DevOpsの**重要性**です。

DevOpsは文化です。DevOpsは人が作る必要があるため、言うだけは簡単ですがシステムのあるべき姿を計画し、実行して継続することは大変です。

この失敗を次に生かしてシステム開発のライフサイクルを短縮し、ソフトウェア品質の高い継続的デリバリーを実現していきたいと思いました。
localhost:3000がESETで遭難した

#tl; dr

- 初めてRailsのサーバーを立ち上げたが、`localhost:3000`にまずアクセスできない
- ESET（セキュリティソフト）のパーソナルファイアウォールが悪さをしているらしい
- `localhost:3000`の替わりに`127.0.0.1:3000`でアクセスできた

######参考にしたサイト
[eset を入れた mac で、 [::1] で開発中ウェブアプリケーションに接続できないのは何故?]
(https://ja.stackoverflow.com/questions/66740/eset-%E3%82%92%E5%85%A5%E3%82%8C%E3%81%9F-mac-%E3%81%A7-1-%E3%81%A7%E9%96%8B%E7%99%BA%E4%B8%AD%E3%82%A6%E3%82%A7%E3%83%96%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AB%E6%8E%A5%E7%B6%9A%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%AF%E4%BD%95%E6%95%85)

######インターネットのことがわかってない
IPv6経由ではアクセスできず、IPv4経由だとアクセスできるという状態らしい。
そもそもIPアドレスがなんなのか、なぜ解決したのかもよく分からないので、本を読むなりして行きたい。
基礎から学ぶ　人工知能の教科書　第3章　章末問題

# はじめに
機械学習の勉強として、「*[基礎から学ぶ　人工知能の教科書](https://www.ohmsha.co.jp/book/9784274224263/)*」 を読んでいます。

この本の特徴は、章末問題に`Python`の簡単なプログラムが載っていてるところです。

ここでは、それを`Ruby`にて写経しています。
# 第3章　章末問題
```kneighbor.rb
itemdata = [[30, 50, 'A'], [65, 40, 'B'],
            [90, 100, 'A'], [90, 60, 'B'],
            [70, 60, 'B'], [40, 50, 'A'],
            [80, 50, 'B']]

print '分類対象の高さを入力してください：'
h = gets.to_i
print '分類対象の上部表面積を入力してください：'
a = gets.to_i

print itemdata.sort_by{|x, y, _| (x - h) ** 2 + (y - a) ** 2}
```
k近傍法による分類問題を解くプログラムを作成する問題です。

*[k近傍法 - wikipedia](https://ja.wikipedia.org/wiki/K%E8%BF%91%E5%82%8D%E6%B3%95#:~:text=k%E8%BF%91%E5%82%8D%E6%B3%95%EF%BC%88%E3%82%B1%E3%82%A4%E3%81%8D%E3%82%93,%E6%8E%A2%E7%B4%A2%E5%95%8F%E9%A1%8C%E3%81%AE%E4%B8%80%E3%81%A4%E3%80%82)*

```
分類対象の高さを入力してください：50
分類対象の上部表面積を入力してください：50
[[40, 50, "A"], [65, 40, "B"], [30, 50, "A"], [70, 60, "B"], [80, 50, "B"], [90, 60, "B"], [90, 100, "A"]]
```
例えば、`高さ50 上部表面積50`のデータは、`A`に分類されます。
# まとめ
+ 第3章まで読んだ
Visual じゃないほうの C++ を Windows & MinGW で動かしてみる

OS:Windows 10

#参考情報
インストールに際しては @pengincoalition さんの
[windowsで快適なC/C++開発環境を作る](https://qiita.com/pengincoalition/items/2bc1e0a80b114d6c49a6)
を参考にさせて頂きました。

コードの実装については
江添亮のC++入門 [Web版](https://ezoeryou.github.io/cpp-intro/) [書籍版](https://www.amazon.co.jp/%E6%B1%9F%E6%B7%BB%E4%BA%AE%E3%81%AEC-%E5%85%A5%E9%96%80-%E6%B1%9F%E6%B7%BB-%E4%BA%AE/dp/4048930710/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E6%B1%9F%E6%B7%BB%E4%BA%AE%E3%81%AEC%2B%2B%E5%85%A5%E9%96%80&qid=1594332683&s=books&sr=1-1)
を参考にさせて頂きました。

投稿後の 2020/07/10 に @kazatsuyu さん、@yuki12 さんからいたいだいたコメントでは
MSYS2/MinGW-w64 もあるとのことですが（ご指摘と情報提供、ありがとうございます）、今回は32ビット版でやっています

#コンパイラのインストール

使うコンパイラは32ビット版MinGWです。
http://www.mingw.org/
から
mingw-get-setup.exe
をダウンロードして実行します。

[Install]を進めてみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/a22b2ac9-2935-0d06-1494-07a5f21dbbd6.png)

MinGW Install Manager がセットアップされて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/7f61b698-03c1-e33e-6c23-a268b71f2a80.png)

表示された画面から
mingw32-base
mingw32-gcc-g++
の２つを選択したのち、メニューバーの[Installation]を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/18f891c5-aba9-cf49-6c8e-b0b6e40f8043.png)

あとは環境変数の Path に "C:\MinGW\bin" を追加しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/d7b59941-455b-9910-f244-c8e694e21ff4.png)

コマンドプロンプトから gcc -v を入力して出力の最後にgcc versionが表示されれば完了です。

```
C:\>gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/9.2.0/lto-wrapper.exe
Target: mingw32
Configured with: ../src/gcc-9.2.0/configure --build=x86_64-pc-linux-gnu --host=mingw32 --target=mingw32 --disable-win32-registry --with-arch=i586 --with-tune=generic --enable-static --enable-shared --enable-threads --enable-languages=c,c++,objc,obj-c++,fortran,ada --with-dwarf2 --disable-sjlj-exceptions --enable-version-specific-runtime-libs --enable-libgomp --disable-libvtv --with-libiconv-prefix=/mingw --with-libintl-prefix=/mingw --enable-libstdcxx-debug --disable-build-format-warnings --prefix=/mingw --with-gmp=/mingw --with-mpfr=/mingw --with-mpc=/mingw --with-isl=/mingw --enable-nls --with-pkgversion='MinGW.org GCC Build-20200227-1'
Thread model: win32
gcc version 9.2.0 (MinGW.org GCC Build-20200227-1)
```

#C++ コードの作成
実装用のディレクトリを作成します。

```
C:\>mkdir cpp
```

以下のコードをエディターで作成して hello.cpp として格納します。

```
# include <iostream>

int main()
{
    std::cout << "hello";
}
```

#コンパイルと実行

```
C:\>cd cpp
```

コンパイルのコマンドを実行します。

```
C:\cpp>g++ -o hello hello.cpp
```

ディレクトリの内容を見てみると hello.exe という実行ファイルが生成されていることが確認できます。

```
c:\cpp>dir
 ドライブ C のボリューム ラベルは Windows です
 ボリューム シリアル番号は xxxx-xxxx です
 c:\cpp のディレクトリ

2020/07/10  08:48    <DIR>          .
2020/07/10  08:48    <DIR>          ..
2020/07/10  06:48                69 hello.cpp
2020/07/10  06:49            47,192 hello.exe
               2 個のファイル              47,261 バイト
```
hello と入力してみると "hello"が出力されました。

```
c:\cpp>hello
hello
```
現場で見てきたDocumentRootの位置サンプル

## 初めに
今までいくつかの現場にアサインしてきましたが、DocumentRootの位置が現場により異なりました。
正直DocumentRootの位置は`/tmp`等やめたほうが良いパス以外は好きにして構わないと思うのですが、全くの初心者の頃皆目見当がつかなかったので、少し纏めてみたいと思います。
説明に過不足ありましたら是非ご一報ください！

※Linux系のサーバにデプロイする前提の内容となります。
　また、Javascript、PHPのWebアプリケーションのみとなります。

## DocumentRootとは
Webアプリケーションにアクセスされたとき、Webサーバが参照する際に __基準となるディレクトリの位置__ を定義するための仕組みです。
例
`https://sample.com/index.html`でアクセスされた際、
`DocumentRoot→/var/www/html`の場合、
`/var/www/html/index.html`が参照されレスポンスされる。

つまりこの場合`/var/www/html`が基準のディレクトリとなります。

## /var/www/html/[アプリケーション名]
ApacheやNginX等よく使われるWebサーバのデフォルトのDocumentRootです。
デフォルトのままですのでシンプルで、兎に角スピード重視という意味合いの印象です。

## /var/www/vhosts/[アプリケーション名]
仮想ホストを利用している際に良く`/var/www/vhosts/`配下に指定するようです。
仮想ホストについては以下のApacheの公式ページの通り、一つのWebサーバで複数のドメインを運用したい際に利用します。
https://httpd.apache.org/docs/2.2/ja/vhosts/examples.html

## /home/www/[アプリケーション名]
`www`というアプリケーション実行ユーザを作成して、その実行ユーザのhomeディレクトリを指定していました。勿論`www`以外の実行ユーザ名でも問題ないと思います。
アプリケーション実行ユーザ、DBユーザ、cron実行ユーザ...と役割をしっかり分けてセキュリティを意識した作りで見られました。

以上です。

## ちなみに
以下のコラム、PDFで纏められていますが、
https://www.atmarkit.co.jp/ait/articles/0108/07/news002.html
https://www.pathname.com/fhs/pub/fhs-2.3.pdf

それぞれ思想に沿ってディレクトリが切られています。
`/var`: 変更されるデータ
`/home`: ユーザーのホームディレクトリ
`/opt`: 追加アプリケーション(Javaで使うTomcatではここのサブディレクトリがDocumentRootになります)

ここら辺のディレクトリをDocumentRootに指定するのは、至極自然な発想なのですね！

## 最後に
私の見てきた現場ですと、おおよそ上記のパターンに収まっていました。
利用しているサーバ、サービスによって異なるかと思いますので、違った構成や意見がありましたら是非コメントくださると嬉しいです！